Skip to content

Commit

Permalink
Fix Wrong union description with TypeScript styleguidist#1621
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuruog committed Jul 12, 2020
1 parent a8b5e7a commit 742c059
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 88 deletions.
128 changes: 65 additions & 63 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -84,6 +85,7 @@
"remark": "^11.0.1",
"strip-html-comments": "^1.0.0",
"terser-webpack-plugin": "^2.2.1",
"tippy.js": "6.2.5",
"to-ast": "^1.0.0",
"type-detect": "^4.0.8",
"unist-util-visit": "^2.0.0",
Expand Down Expand Up @@ -209,6 +211,9 @@
"modulePaths": [
"./src/client"
],
"moduleNameMapper": {
"\\.(css|scss|less)$": "<rootDir>/test/__mocks__/styleMock.js"
},
"testPathIgnorePatterns": [
"<rootDir>/lib/",
"<rootDir>/examples/",
Expand Down
15 changes: 15 additions & 0 deletions src/client/rsg-components/ComplexType/ComplexType.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { shallow } from 'enzyme';
import { ComplexTypeRenderer, styles } from './ComplexTypeRenderer';

const props = {
classes: classes(styles),
name: 'color',
raw: '"blue" | "red"',
};

it('renderer should render complex type', () => {
const actual = shallow(<ComplexTypeRenderer {...props} />);

expect(actual).toMatchSnapshot();
});
75 changes: 75 additions & 0 deletions src/client/rsg-components/ComplexType/ComplexTypeRenderer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from 'react';
import PropTypes from 'prop-types';
import { MdInfoOutline } from 'react-icons/md';
import Tippy from '@tippyjs/react';
import 'tippy.js/dist/tippy.css';
import 'tippy.js/themes/light-border.css';

import Styled, { JssInjectedProps } from 'rsg-components/Styled';
import Text from 'rsg-components/Text';

import * as Rsg from '../../../typings';

export const styles = ({ fontFamily, fontSize, color, space, borderRadius }: Rsg.Theme) => ({
type: {
position: 'relative',
fontFamily: fontFamily.monospace,
fontSize: fontSize.small,
color: color.base,
'& span': {
marginRight: space[0],
cursor: 'pointer',
},
'& .tippy-content': {
fontSize: fontSize.small,
color: color.type,
},
'& .tippy-box': {
padding: space[1],
border: `1px ${color.border} solid`,
borderRadius,
background: color.baseBackground,
boxShadow: [[0, 2, 4, 'rgba(0,0,0,.15)']],
},
'& .tippy-box[data-placement^=right]>.tippy-arrow': {
left: 1,
width: 16,
height: 16,
},
},
name: {
display: 'inline-flex',
alignItems: 'center',
cursor: 'pointer',
},
});

interface ComplexTypeProps extends JssInjectedProps {
name: string;
raw: string;
}

export const ComplexTypeRenderer: React.FunctionComponent<ComplexTypeProps> = ({
classes,
name,
raw,
}) => {
return (
<div className={classes.type}>
<Tippy content={raw} interactive theme="light-border" placement="right">
<div className={classes.name} role="button" tabIndex={0}>
<Text>{name}</Text>
<MdInfoOutline />
</div>
</Tippy>
</div>
);
};

ComplexTypeRenderer.propTypes = {
classes: PropTypes.objectOf(PropTypes.string.isRequired).isRequired,
name: PropTypes.string.isRequired,
raw: PropTypes.string.isRequired,
};

export default Styled<ComplexTypeProps>(styles)(ComplexTypeRenderer);
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renderer should render complex type 1`] = `
<div
className="type"
>
<ForwardRef(TippyWrapper)
content="\\"blue\\" | \\"red\\""
interactive={true}
placement="right"
theme="light-border"
>
<div
className="name"
role="button"
tabIndex={0}
>
<Styled(Text)>
color
</Styled(Text)>
<MdInfoOutline />
</div>
</ForwardRef(TippyWrapper)>
</div>
`;
1 change: 1 addition & 0 deletions src/client/rsg-components/ComplexType/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'rsg-components/ComplexType/ComplexTypeRenderer';
27 changes: 18 additions & 9 deletions src/client/rsg-components/Props/Props.spec.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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', () => {
Expand All @@ -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', () => {
Expand Down
24 changes: 8 additions & 16 deletions src/client/rsg-components/Props/renderType.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -28,31 +28,23 @@ export function renderType(type: ExtendedPropTypeDescriptor): string {
}
}

function renderComplexType(name: string, title: string): React.ReactNode {
return (
<Text size="small" underlined title={title}>
{name}
</Text>
);
}

function renderAdvancedType(type: TypeDescriptor): React.ReactNode {
if (!type) {
return 'unknown';
return <Type>unknown</Type>;
}

switch (type.name) {
case 'enum':
return type.name;
return <Type>{type.name}</Type>;
case 'literal':
return type.value;
return <Type>{type.value}</Type>;
case 'signature':
return renderComplexType(type.type, type.raw);
return <ComplexType name={type.type} raw={type.raw} />;
case 'union':
case 'tuple':
return renderComplexType(type.name, type.raw);
return <ComplexType name={type.name} raw={type.raw} />;
default:
return (type as any).raw || (type as any).name;
return <Type>{(type as any).raw || (type as any).name}</Type>;
}
}

Expand All @@ -62,7 +54,7 @@ export default function renderTypeColumn(prop: PropDescriptor): React.ReactNode
return null;
}
if (prop.flowType || prop.tsType) {
return <Type>{renderAdvancedType(type as any)}</Type>;
return renderAdvancedType(type as any);
}
return <Type>{renderType(type)}</Type>;
}
1 change: 1 addition & 0 deletions test/__mocks__/styleMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = {};

0 comments on commit 742c059

Please sign in to comment.