diff --git a/examples/sections/styleguide.config.js b/examples/sections/styleguide.config.js
index b0deab5ad..3b50a2631 100644
--- a/examples/sections/styleguide.config.js
+++ b/examples/sections/styleguide.config.js
@@ -93,8 +93,8 @@ module.exports = {
env === 'development'
? false
: {
- maxAssetSize: 1150000, // bytes
- maxEntrypointSize: 1150000, // bytes
+ maxAssetSize: 1200000, // bytes
+ maxEntrypointSize: 1200000, // bytes
hints: 'error',
},
}),
diff --git a/package-lock.json b/package-lock.json
index 02ac41708..676b7c8e7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2334,6 +2334,11 @@
}
}
},
+ "@popperjs/core": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.4.4.tgz",
+ "integrity": "sha512-1oO6+dN5kdIA3sKPZhRGJTfGVP4SWV6KqlMOwry4J3HfyD68sl/3KmG7DeYUzvN+RbhXDnv/D8vNNB8168tAMg=="
+ },
"@samverschueren/stream-to-observable": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz",
@@ -2504,6 +2509,14 @@
}
}
},
+ "@tippyjs/react": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.1.0.tgz",
+ "integrity": "sha512-g6Dpm46edr9T9z+BYxd/eJZa6QMFc4T4z5xrztxVlkti7AhNYf7OaE6b3Nh+boUZZ9wn8xkNq9VrQM5K4huwnQ==",
+ "requires": {
+ "tippy.js": "^6.2.0"
+ }
+ },
"@types/anymatch": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
@@ -3594,7 +3607,7 @@
},
"array-equal": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
"dev": true
},
@@ -3707,7 +3720,7 @@
},
"util": {
"version": "0.10.3",
- "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
"integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
"dev": true,
"requires": {
@@ -3828,7 +3841,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "^2.2.1",
@@ -3845,7 +3858,7 @@
},
"strip-ansi": {
"version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "^2.0.0"
@@ -4428,7 +4441,7 @@
},
"browserify-aes": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"dev": true,
"requires": {
@@ -4465,7 +4478,7 @@
},
"browserify-rsa": {
"version": "4.0.1",
- "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+ "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
"dev": true,
"requires": {
@@ -4624,7 +4637,7 @@
"dependencies": {
"callsites": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
"integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
"dev": true
}
@@ -4874,7 +4887,7 @@
},
"slice-ansi": {
"version": "0.0.4",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
+ "resolved": "http://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
"integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
"dev": true
},
@@ -4891,7 +4904,7 @@
},
"strip-ansi": {
"version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
@@ -5005,7 +5018,7 @@
},
"colors": {
"version": "0.6.2",
- "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
+ "resolved": "http://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
"integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w="
},
"combined-stream": {
@@ -5019,7 +5032,7 @@
},
"commander": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
+ "resolved": "http://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
"integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E="
},
"common-dir": {
@@ -5595,7 +5608,7 @@
},
"create-hash": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"dev": true,
"requires": {
@@ -5608,7 +5621,7 @@
},
"create-hmac": {
"version": "1.1.7",
- "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"dev": true,
"requires": {
@@ -5715,7 +5728,7 @@
},
"css-select": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
"integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
"dev": true,
"requires": {
@@ -5981,7 +5994,7 @@
"dependencies": {
"globby": {
"version": "6.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
"requires": {
"array-union": "^1.0.1",
@@ -5993,7 +6006,7 @@
"dependencies": {
"pify": {
"version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
}
}
@@ -6080,7 +6093,7 @@
},
"diffie-hellman": {
"version": "5.0.3",
- "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"dev": true,
"requires": {
@@ -6208,7 +6221,7 @@
},
"duplexer": {
"version": "0.1.1",
- "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+ "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E="
},
"duplexify": {
@@ -7004,7 +7017,7 @@
"dependencies": {
"doctrine": {
"version": "1.5.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "resolved": "http://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
"integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
"dev": true,
"requires": {
@@ -9712,7 +9725,7 @@
},
"is-obj": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
},
"is-observable": {
@@ -11898,7 +11911,7 @@
},
"jsesc": {
"version": "0.5.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0="
},
"json-parse-better-errors": {
@@ -12487,7 +12500,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
@@ -12525,7 +12538,7 @@
},
"strip-ansi": {
"version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
@@ -13759,7 +13772,7 @@
},
"os-tmpdir": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
},
"p-defer": {
@@ -13925,7 +13938,7 @@
},
"path-is-absolute": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-is-inside": {
@@ -14890,7 +14903,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -15442,7 +15455,7 @@
},
"safe-regex": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"requires": {
"ret": "~0.1.10"
@@ -15649,7 +15662,7 @@
},
"sha.js": {
"version": "2.4.11",
- "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"dev": true,
"requires": {
@@ -16568,7 +16581,7 @@
},
"strip-eof": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
},
"strip-final-newline": {
@@ -17046,7 +17059,7 @@
},
"through": {
"version": "2.3.8",
- "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
},
"through2": {
@@ -17094,6 +17107,14 @@
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
},
+ "tippy.js": {
+ "version": "6.2.6",
+ "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.2.6.tgz",
+ "integrity": "sha512-0tTL3WQNT0nWmpslhDryRahoBm6PT9fh1xXyDfOsvZpDzq52by2rF2nvsW0WX2j9nUZP/jSGDqfKJGjCtoGFKg==",
+ "requires": {
+ "@popperjs/core": "^2.4.4"
+ }
+ },
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -17125,7 +17146,7 @@
"dependencies": {
"ast-types": {
"version": "0.7.8",
- "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.7.8.tgz",
+ "resolved": "http://registry.npmjs.org/ast-types/-/ast-types-0.7.8.tgz",
"integrity": "sha1-kC0uDWDQcb3NRtwRXhgJ7RHBOKk="
},
"esprima": {
diff --git a/package.json b/package.json
index 3618d025e..006feb8e0 100644
--- a/package.json
+++ b/package.json
@@ -28,6 +28,7 @@
"node": ">=10"
},
"dependencies": {
+ "@tippyjs/react": "4.1.0",
"@vxna/mini-html-webpack-template": "^1.0.0",
"acorn": "^6.4.1",
"acorn-jsx": "^5.1.0",
diff --git a/src/client/rsg-components/ComplexType/ComplexType.spec.tsx b/src/client/rsg-components/ComplexType/ComplexType.spec.tsx
new file mode 100644
index 000000000..c51bf06a1
--- /dev/null
+++ b/src/client/rsg-components/ComplexType/ComplexType.spec.tsx
@@ -0,0 +1,20 @@
+import React from 'react';
+import { render, fireEvent } from '@testing-library/react';
+import ComplexType from './ComplexTypeRenderder';
+
+function renderComponent(name = 'color', raw = 'red | blue') {
+ return render();
+}
+
+describe('ComplexType', () => {
+ test('should render name', () => {
+ const { getByRole } = renderComponent();
+ expect(getByRole('button')).toHaveTextContent('color');
+ });
+
+ test('should render raw text in the tooltip', () => {
+ const { container, getByRole } = renderComponent();
+ fireEvent.focus(getByRole('button'));
+ expect(container.querySelector('[data-tippy-root]')).toHaveTextContent('red | blue');
+ });
+});
diff --git a/src/client/rsg-components/ComplexType/ComplexTypeRenderder.tsx b/src/client/rsg-components/ComplexType/ComplexTypeRenderder.tsx
new file mode 100644
index 000000000..c6f931450
--- /dev/null
+++ b/src/client/rsg-components/ComplexType/ComplexTypeRenderder.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import Styled, { JssInjectedProps } from 'rsg-components/Styled';
+import { MdInfoOutline } from 'react-icons/md';
+import Text from 'rsg-components/Text';
+import Tooltip from 'rsg-components/Tooltip';
+import * as Rsg from '../../../typings';
+
+export const styles = ({ space }: Rsg.Theme) => ({
+ complexType: {
+ alignItems: 'center',
+ display: 'inline-flex',
+ },
+ icon: {
+ marginLeft: space[0],
+ },
+});
+
+export interface ComplexTypeProps extends JssInjectedProps {
+ name: string;
+ raw: string;
+}
+
+function ComplexTypeRenderer({ classes, name, raw }: ComplexTypeProps) {
+ return (
+
+
+ {name}
+
+
+
+ );
+}
+
+export default Styled(styles)(ComplexTypeRenderer);
diff --git a/src/client/rsg-components/ComplexType/index.ts b/src/client/rsg-components/ComplexType/index.ts
new file mode 100644
index 000000000..8710c1335
--- /dev/null
+++ b/src/client/rsg-components/ComplexType/index.ts
@@ -0,0 +1 @@
+export { default } from 'rsg-components/ComplexType/ComplexTypeRenderder';
diff --git a/src/client/rsg-components/Props/Props.spec.tsx b/src/client/rsg-components/Props/Props.spec.tsx
index 83b9d80a9..71517f7b8 100644
--- a/src/client/rsg-components/Props/Props.spec.tsx
+++ b/src/client/rsg-components/Props/Props.spec.tsx
@@ -1,6 +1,6 @@
/* eslint-disable react/prop-types */
import React from 'react';
-import { render } from '@testing-library/react';
+import { render, fireEvent } from '@testing-library/react';
import { parse } from 'react-docgen';
import PropsRenderer, { columns, getRowKey } from './PropsRenderer';
import { unquote, getType, showSpaces, PropDescriptor } from './util';
@@ -513,7 +513,7 @@ describe('props columns', () => {
{
name: 'Foo',
description: 'Converts foo to bar',
- type: {type: 'NameExpression', name: 'Array' },
+ type: { type: 'NameExpression', name: 'Array' },
},
],
param: [
@@ -551,7 +551,7 @@ describe('props columns', () => {
{
title: 'Foo',
description: 'Returns foo from bar',
- type: {type: 'NameExpression', name: 'Array' },
+ type: { type: 'NameExpression', name: 'Array' },
},
],
},
@@ -658,21 +658,27 @@ describe('props columns', () => {
});
test('should render object type with body in tooltip', () => {
- const { getByText } = renderFn(['foo: { bar: string }']);
+ const { container, getByRole } = renderFn(['foo: { bar: string }']);
+ fireEvent.focus(getByRole('button'));
- expect(getByText('object').title).toMatchInlineSnapshot(`"{ bar: string }"`);
+ expect(getByRole('button')).toHaveTextContent('object');
+ expect(container.querySelector('[data-tippy-root]')).toHaveTextContent('{ bar: string }');
});
test('should render function type with body in tooltip', () => {
- const { getByText } = renderFn(['foo: () => void']);
+ const { container, getByRole } = renderFn(['foo: () => void']);
+ fireEvent.focus(getByRole('button'));
- expect(getByText('function').title).toMatchInlineSnapshot(`"() => void"`);
+ expect(getByRole('button')).toHaveTextContent('function');
+ expect(container.querySelector('[data-tippy-root]')).toHaveTextContent('() => void');
});
test('should render union type with body in tooltip', () => {
- const { getByText } = renderFn(['foo: "bar" | number']);
+ const { container, getByRole } = renderFn(['foo: "bar" | number']);
+ fireEvent.focus(getByRole('button'));
- expect(getByText('union').title).toMatchInlineSnapshot(`"\\"bar\\" | number"`);
+ expect(getByRole('button')).toHaveTextContent('union');
+ expect(container.querySelector('[data-tippy-root]')).toHaveTextContent('"bar" | number');
});
test('should render enum type', () => {
@@ -696,9 +702,12 @@ describe('props columns', () => {
});
test('should render tuple type with body in tooltip', () => {
- const { getByText } = renderFn(['foo: ["bar", number]']);
+ const { container, getByRole } = renderFn(['foo: ["bar", number]']);
- expect(getByText('tuple').title).toMatchInlineSnapshot(`"[\\"bar\\", number]"`);
+ fireEvent.focus(getByRole('button'));
+
+ expect(getByRole('button')).toHaveTextContent('tuple');
+ expect(container.querySelector('[data-tippy-root]')).toHaveTextContent('["bar", number]');
});
test('should render custom class type', () => {
@@ -722,6 +731,17 @@ describe('props columns', () => {
Description:"
`);
});
+
+ test('should render literal type', () => {
+ const { container } = renderFn(['foo: 1']);
+
+ expect(getText(container)).toMatchInlineSnapshot(`
+ "Prop name: foo
+ Type: 1
+ Default: Required
+ Description:"
+ `);
+ });
});
});
diff --git a/src/client/rsg-components/Props/renderType.tsx b/src/client/rsg-components/Props/renderType.tsx
index ba36c33e6..44e751545 100644
--- a/src/client/rsg-components/Props/renderType.tsx
+++ b/src/client/rsg-components/Props/renderType.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { PropTypeDescriptor } from 'react-docgen';
import Type from 'rsg-components/Type';
-import Text from 'rsg-components/Text';
+import ComplexType from 'rsg-components/ComplexType';
import { getType, PropDescriptor, TypeDescriptor } from './util';
@@ -28,31 +28,19 @@ export function renderType(type: ExtendedPropTypeDescriptor): string {
}
}
-function renderComplexType(name: string, title: string): React.ReactNode {
- return (
-
- {name}
-
- );
-}
-
-function renderAdvancedType(type: TypeDescriptor): React.ReactNode {
- if (!type) {
- return 'unknown';
- }
-
+function renderAdvancedType(type: PropTypeDescriptor | TypeDescriptor): React.ReactNode {
switch (type.name) {
case 'enum':
- return type.name;
+ return {type.name};
case 'literal':
- return type.value;
+ return {type.value};
case 'signature':
- return renderComplexType(type.type, type.raw);
+ return ;
case 'union':
case 'tuple':
- return renderComplexType(type.name, type.raw);
+ return ;
default:
- return (type as any).raw || (type as any).name;
+ return {(type as any).raw || (type as any).name};
}
}
@@ -62,7 +50,7 @@ export default function renderTypeColumn(prop: PropDescriptor): React.ReactNode
return null;
}
if (prop.flowType || prop.tsType) {
- return {renderAdvancedType(type as any)};
+ return renderAdvancedType(type);
}
return {renderType(type)};
}
diff --git a/src/client/rsg-components/Tooltip/Tooltip.spec.tsx b/src/client/rsg-components/Tooltip/Tooltip.spec.tsx
new file mode 100644
index 000000000..2f92c0e23
--- /dev/null
+++ b/src/client/rsg-components/Tooltip/Tooltip.spec.tsx
@@ -0,0 +1,66 @@
+import React from 'react';
+import { render, fireEvent, waitFor } from '@testing-library/react';
+import Tooltip, { TooltipPlacement } from './TooltipRenderer';
+
+function renderComponent(content = 'tooltip', placement?: TooltipPlacement) {
+ return render(
+
+
+
+ );
+}
+
+describe('Tooltip', () => {
+ test('should render child component as is', () => {
+ const { container, getByTestId } = renderComponent();
+ expect(container).toContainElement(getByTestId('child'));
+ });
+
+ test('should render content in the tooltop body', () => {
+ const { container, getByRole } = renderComponent();
+ fireEvent.focus(getByRole('button'));
+ expect(container.querySelector('[data-tippy-root]')).toHaveTextContent('tooltip');
+ });
+
+ test('should show the tooltip by focus in', async () => {
+ const { container, getByRole } = renderComponent();
+ fireEvent.focus(getByRole('button'));
+ await waitFor(() =>
+ expect(container.querySelector('[data-state="visible"]')).toBeInTheDocument()
+ );
+ });
+
+ test('should show the tooltip by click', async () => {
+ const { container, getByRole } = renderComponent();
+ fireEvent.click(getByRole('button'));
+ await waitFor(() =>
+ expect(container.querySelector('[data-state="visible"]')).toBeInTheDocument()
+ );
+ });
+
+ test('should show the tooltip by mouse enter', async () => {
+ const { container, getByRole } = renderComponent();
+ fireEvent.mouseEnter(getByRole('button'));
+ await waitFor(() =>
+ expect(container.querySelector('[data-state="visible"]')).toBeInTheDocument()
+ );
+ });
+
+ describe.each([['top'], ['right'], ['left'], ['bottom']])(
+ 'Test placement attribute',
+ placement => {
+ test(`should have ${placement} in data-placement attribute`, async () => {
+ // @ts-ignore
+ const { container, getByRole } = renderComponent(undefined, placement);
+ fireEvent.focus(getByRole('button'));
+ await waitFor(() =>
+ expect(container.querySelector('[data-state="visible"]')).toBeInTheDocument()
+ );
+ expect(container.querySelector('[data-placement]')).toHaveAttribute(
+ 'data-placement',
+ placement
+ );
+ });
+ }
+ );
+});
diff --git a/src/client/rsg-components/Tooltip/TooltipRenderer.tsx b/src/client/rsg-components/Tooltip/TooltipRenderer.tsx
new file mode 100644
index 000000000..f7492c01e
--- /dev/null
+++ b/src/client/rsg-components/Tooltip/TooltipRenderer.tsx
@@ -0,0 +1,51 @@
+import React from 'react';
+import Tippy from '@tippyjs/react';
+import Styled, { JssInjectedProps } from 'rsg-components/Styled';
+import * as Rsg from '../../../typings';
+
+export const styles = ({ space, color, borderRadius, fontSize }: Rsg.Theme) => ({
+ tooltip: {
+ '&.tippy-box': {
+ transitionProperty: [['opacity']],
+ '&[data-state="hidden"]': {
+ opacity: 0,
+ },
+ },
+ '& .tippy-content': {
+ padding: space[0],
+ border: `1px ${color.border} solid`,
+ borderRadius,
+ background: color.baseBackground,
+ boxShadow: [[0, 2, 4, 'rgba(0,0,0,.15)']],
+ fontSize: fontSize.small,
+ color: color.type,
+ },
+ },
+});
+
+export type TooltipPlacement = 'top' | 'right' | 'bottom' | 'left';
+
+export interface TooltipProps extends JssInjectedProps {
+ children: React.ReactNode;
+ content: React.ReactNode;
+ placement?: TooltipPlacement;
+}
+
+function TooltipRenderer({ classes, children, content, placement = 'top' }: TooltipProps) {
+ return (
+
+
+ {children}
+
+
+ );
+}
+
+export default Styled(styles)(TooltipRenderer);
diff --git a/src/client/rsg-components/Tooltip/index.ts b/src/client/rsg-components/Tooltip/index.ts
new file mode 100644
index 000000000..7d61a1a47
--- /dev/null
+++ b/src/client/rsg-components/Tooltip/index.ts
@@ -0,0 +1 @@
+export { default } from 'rsg-components/Tooltip/TooltipRenderer';
diff --git a/src/typings/dependencies/react-docgen.ts b/src/typings/dependencies/react-docgen.ts
index 0e01a0132..f9424b6eb 100644
--- a/src/typings/dependencies/react-docgen.ts
+++ b/src/typings/dependencies/react-docgen.ts
@@ -58,7 +58,6 @@ declare module 'react-docgen' {
| 'objectOf'
| 'shape'
| 'exact'
- | 'union'
| 'instanceOf'
| 'elementType';
value?: any;