Skip to content

Commit

Permalink
[NO-TICKET] Upgrade React types to fix Storybook 8 branch (#3080)
Browse files Browse the repository at this point in the history
* WIP: Try upgrading the react types and working through errors

Here's the summary of errors we're starting with:

```
Found 109 errors in 28 files.

Errors  Files
     4  packages/design-system/src/components/Accordion/Accordion.stories.tsx:8
     3  packages/design-system/src/components/Alert/Alert.stories.tsx:6
     1  packages/design-system/src/components/Autocomplete/utils.tsx:15
    11  packages/design-system/src/components/ChoiceList/ChoiceList.stories.tsx:7
     4  packages/design-system/src/components/Drawer/Drawer.stories.tsx:29
    12  packages/design-system/src/components/Dropdown/Dropdown.stories.tsx:8
     6  packages/design-system/src/components/Dropdown/Dropdown.tsx:171
     1  packages/design-system/src/components/Dropdown/DropdownMenuOption.tsx:66
     5  packages/design-system/src/components/HelpDrawer/HelpDrawer.stories.tsx:29
     4  packages/design-system/src/components/IdleTimeout/IdleTimeout.stories.tsx:10
     4  packages/design-system/src/components/PrivacySettingsDialog/PrivacySettingsDialog.stories.tsx:17
     6  packages/design-system/src/components/Spinner/Spinner.stories.tsx:6
    23  packages/design-system/src/components/TextField/TextField.stories.tsx:10
     2  packages/design-system/src/components/Tooltip/Tooltip.tsx:357
     1  packages/design-system/src/components/UsaBanner/UsaBanner.stories.tsx:5
     1  packages/design-system/src/components/web-components/ds-accordion/ds-accordion.tsx:22
     1  packages/design-system/src/components/web-components/preactement/define.test.tsx:35
     1  packages/docs/src/components/content/ContentRenderer.tsx:111
     1  packages/docs/src/components/content/EmbeddedExample.tsx:17
     2  packages/docs/src/components/layout/SideNav/SideNav.tsx:25
     2  packages/docs/src/components/layout/TableOfContents.tsx:43
     1  packages/docs/src/components/page-templates/BlogPage.tsx:18
     1  packages/docs/src/pages/blog.tsx:33
     2  packages/ds-healthcare-gov/src/components/Accordion/Accordion.stories.tsx:8
     2  packages/ds-medicare-gov/src/components/Card/Card.stories.tsx:6
     5  packages/ds-medicare-gov/src/components/HelpDrawer/HelpDrawer.stories.tsx:31
     1  packages/ds-medicare-gov/src/components/SimpleFooter/SimpleFooter.stories.tsx:6
     2  packages/ds-medicare-gov/src/components/Stars/stars.stories.tsx:6
```

* Fixing the first batch of errors (down to 89 from 109)

* Remove custom docs config for Drawer storybook page and fix VRTs

Add new interaction VRTs for dialog and drawer, and don't have any of the stories open them automatically

* Trying to fix missing Drawer story controls but failing

I was hoping fixing these types would do it.

* Ignore errors coming from react-aria types

* Two different ways of getting around the errors for inlining the doc page JSX

* Down to 24 errors

* Finished fixing all the errors in the core package (down to 20 now)

* Huh, the errors just go away after making some edits to the yarn lockfile

I think I'll go back and undo some of my previous commits to see if I need them

* Just realized there was some dead code in here

* Revert "Ignore errors coming from react-aria types"

This reverts commit f4fac88.

* Revert more of the react-aria changes

This reverts part of commit ffc035d.

* I can revert this change too

* Oh no, these new arg tables do not look good

It seems as though the type inference has gotten worse in this version. Instead of the type for Badge `size` being listed as `big` (only supports big), it is now reported as `literal`. For `string | React.ReactNode`, it only says `union`. Instead of `type` being `checkbox` and `radio`, it’s `union`. Instead of `ReactNode` for `React.ReactNode`, it prints out as `ReactReactNode`

* Revert "Oh no, these new arg tables do not look good"

This reverts commit 6811f4b.

* Changing the default settings to use the typescript docgen results in much fewer changes

See storybookjs/storybook#26496
  • Loading branch information
pwolfert committed Jul 12, 2024
1 parent 6332291 commit 7dd4c50
Show file tree
Hide file tree
Showing 152 changed files with 160 additions and 190 deletions.
27 changes: 27 additions & 0 deletions .storybook/docs/NoStoryDocTemplate.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Meta, Title, Subtitle, Description, ArgTypes } from '@storybook/blocks';
import { HtmlElementArgs } from './HtmlElementArgs';

<Meta isTemplate />

<Title />
<Subtitle />

<Description />

## Props

{/*
* Note that ArgsTable is technically deprecated in v7, but Storybook has yet
* to offer a solid alternative for stories with subcomponents. This args
* table will render multiple tabs when there is a `subcomponents` property
* present in the story meta. See the following discussions:
*
* - https://github.com/storybookjs/storybook/issues/21253
* - https://github.com/storybookjs/storybook/issues/20782
*
* If they remove this feature, the path forward may be to create our own
* custom "doc block" that uses the
* [useOf](https://storybook.js.org/docs/react/api/doc-block-useof) hook.
*/}
<ArgTypes />
<HtmlElementArgs />
3 changes: 3 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const config: StorybookConfig = {
`../packages/docs/content/**/${extensionGlob}`,
],
staticDirs: ['../packages/design-system-tokens/dist/css-vars'],
typescript: {
reactDocgen: 'react-docgen-typescript',
},
framework: {
name: getAbsolutePath('@storybook/react-webpack5'),
options: {},
Expand Down
4 changes: 2 additions & 2 deletions packages/design-system/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@
],
"dependencies": {
"@popperjs/core": "^2.4.4",
"@types/react": "^18.2.6",
"@types/react-dom": "^17.0.10",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.0",
"@types/react-transition-group": "^4.4.5",
"case-it": "^1.0.1",
"chalk": "^5.0.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type * as React from 'react';
import { FunctionComponent } from 'react';
import classNames from 'classnames';

export interface AccordionProps {
Expand All @@ -21,11 +20,7 @@ export interface AccordionProps {
* For information about how and when to use this component,
* [refer to its full documentation page](https://design.cms.gov/components/accordion/).
*/
export const Accordion: FunctionComponent<AccordionProps> = ({
bordered,
children,
className,
}: AccordionProps) => {
export const Accordion = ({ bordered, children, className }: AccordionProps) => {
const classes = classNames('ds-c-accordion', bordered && 'ds-c-accordion--bordered', className);
return <div className={classes}>{children}</div>;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export interface AccordionItemState {
isOpen?: boolean;
}

export const AccordionItem: React.FC<AccordionItemProps> = ({
export const AccordionItem = ({
buttonClassName,
children,
contentClassName,
Expand All @@ -67,7 +67,7 @@ export const AccordionItem: React.FC<AccordionItemProps> = ({
onChange,
closeIconComponent,
openIconComponent,
}) => {
}: AccordionItemProps) => {
const contentClasses = classNames('ds-c-accordion__content', contentClassName);
const buttonClasses = classNames('ds-c-accordion__button', buttonClassName);
const HeadingTag = `h${headingLevel}` as const;
Expand Down
2 changes: 1 addition & 1 deletion packages/design-system/src/components/Alert/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export type AlertProps = BaseAlertProps &
* For information about how and when to use this component,
* [refer to its full documentation page](https://design.cms.gov/components/alert/).
*/
export const Alert: React.FC<AlertProps> = (props: AlertProps) => {
export const Alert = (props: AlertProps) => {
const { headingRef, bodyRef } = useAlertAnalytics(props);
const focusRef = useAutofocus(props.autoFocus);
const rootId = useId('alert--', props.id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export type ChoiceListProps = BaseChoiceListProps &
* props table below, including all valid attributes of the
* [HTML input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
*/
export const ChoiceList: React.FC<ChoiceListProps> = (props: ChoiceListProps) => {
export const ChoiceList = (props: ChoiceListProps) => {
const { onBlur, onComponentBlur, choices } = props;
const id = useId('choice-list--', props.id);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useDialog } from './useDialog';

const meta: Meta<typeof Dialog> = {
title: 'Components/Dialog',
component: Dialog as any,
component: Dialog,
args: {
alert: false,
children: (
Expand All @@ -31,7 +31,7 @@ export default meta;

type Story = StoryObj<typeof Dialog>;

export const DialogExample: Story = {
export const Default: Story = {
render: function Component(args) {
const [dialogOpen, updateOpen] = useState(false);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { test, expect } from '@playwright/test';
import themes from '../../../../../themes.json';

const sbID = 'components-dialog--default';
const storyUrl = `http://localhost:6006/iframe.html?viewMode=story&id=${sbID}`;

function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

Object.keys(themes).forEach((theme) => {
if (themes[theme].incomplete) return;

test(`Dialog open: ${theme}`, async ({ page }) => {
await page.goto(`${storyUrl}&globals=theme:${theme}`);
const elem = page.getByRole('button');
await elem.click();
await sleep(100);
await expect(page).toHaveScreenshot(`dialog--open--${theme}.png`, { fullPage: true });
});
});
33 changes: 3 additions & 30 deletions packages/design-system/src/components/Drawer/Drawer.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ArgTypes, Description, Subtitle, Title } from '@storybook/blocks';
import { action } from '@storybook/addon-actions';
import Drawer from './Drawer';
import { Button } from '../Button';
Expand All @@ -7,7 +6,7 @@ import { useArgs } from '@storybook/preview-api';

const meta: Meta<typeof Drawer> = {
title: 'Components/Drawer',
component: Drawer as any,
component: Drawer,
argTypes: {
backdropClickExits: {
// Until this pattern has solidified, we're not going to advertize this feature.
Expand All @@ -21,19 +20,6 @@ const meta: Meta<typeof Drawer> = {
footerBody: <p className="ds-text-body--md ds-u-margin--0">Footer content</p>,
heading: 'Drawer Heading',
},
// The Drawer was overlapping the docs page, so customizing the docs page to remove the examples
parameters: {
docs: {
page: () => (
<>
<Title />
<Subtitle />
<Description />
<ArgTypes exclude={['backdropClickExits']} />
</>
),
},
},
};
export default meta;

Expand Down Expand Up @@ -67,20 +53,7 @@ const drawerContent = (
</>
);

export const DrawerDefault: Story = {
render: function Component(args) {
return <Drawer {...args}>{drawerContent}</Drawer>;
},
};
export const DrawerWithStickyPositioning: Story = {
...DrawerDefault,
args: {
isFooterSticky: true,
isHeaderSticky: true,
},
};

export const DrawerToggleWithDrawer: Story = {
export const Default: Story = {
render: function Component() {
const [{ isDrawerVisible, ...args }, updateArgs] = useArgs();
const showDrawer = () => updateArgs({ isDrawerVisible: true });
Expand All @@ -102,7 +75,7 @@ export const DrawerToggleWithDrawer: Story = {
{drawerContent}
</Drawer>
<Button className="ds-c-drawer__toggle" variation="ghost" onClick={showDrawer}>
Drawer Toggle
Click to toggle drawer
</Button>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { test, expect } from '@playwright/test';
import themes from '../../../../../themes.json';

const sbID = 'components-drawer--default';
const storyUrl = `http://localhost:6006/iframe.html?viewMode=story&id=${sbID}`;

function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

Object.keys(themes).forEach((theme) => {
if (themes[theme].incomplete) return;

test(`Drawer open: ${theme}`, async ({ page }) => {
await page.goto(`${storyUrl}&globals=theme:${theme}`);
const elem = page.getByRole('button');
await elem.click();
await sleep(100);
await expect(page).toHaveScreenshot(`drawer--open--${theme}.png`, { fullPage: true });
});
});
2 changes: 1 addition & 1 deletion packages/design-system/src/components/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export const Drawer = (props: DrawerProps) => {

Drawer.defaultProps = {
hasFocusTrap: false,
headingLevel: '3',
headingLevel: '3' as const,
};

export default Drawer;
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ArgTypes, Description, Primary, Subtitle, Title } from '@storybook/blocks';
import { useState } from 'react';
import { HelpDrawer } from './HelpDrawer';
import { Button } from '../Button';
Expand All @@ -21,20 +20,6 @@ const meta: Meta<typeof HelpDrawer> = {
footerBody: 'Footer content',
heading: 'HelpDrawer Heading',
},
parameters: {
docs: {
// Customize so we can exclude the backdropClickExits
page: () => (
<>
<Title />
<Subtitle />
<Description />
<Primary />
<ArgTypes exclude={['backdropClickExits']} />
</>
),
},
},
};
export default meta;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
import IdleTimeout from './IdleTimeout';
import IdleTimeoutDialog from './IdleTimeoutDialog';
import { Title, Subtitle, Description, ArgTypes } from '@storybook/blocks';
import NoStoryDocTemplate from '../../../../../.storybook/docs/NoStoryDocTemplate.mdx';
import { action } from '@storybook/addon-actions';
import type { Meta, StoryObj } from '@storybook/react';
import { useArgs } from '@storybook/preview-api';

const DocsPage = () => (
<>
<Title />
<Subtitle />
<Description />
<ArgTypes of={IdleTimeout} />
</>
);

const meta: Meta<typeof IdleTimeout> = {
title: 'Components/IdleTimeout',
component: IdleTimeout,
parameters: {
docs: {
inlineStories: false,
page: DocsPage,
page: NoStoryDocTemplate,
},
},
args: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PrivacySettingsDialog from './PrivacySettingsDialog';
import { Title, Subtitle, Description, ArgTypes } from '@storybook/blocks';
import NoStoryDocTemplate from '../../../../../.storybook/docs/NoStoryDocTemplate.mdx';
import type { Meta, StoryObj } from '@storybook/react';

const meta: Meta<typeof PrivacySettingsDialog> = {
Expand All @@ -12,14 +12,7 @@ const meta: Meta<typeof PrivacySettingsDialog> = {
parameters: {
docs: {
// The dialog was overlapping the docs page, so customizing the docs page to remove the examples
page: () => (
<>
<Title />
<Subtitle />
<Description />
<ArgTypes of={PrivacySettingsDialog} />
</>
),
page: NoStoryDocTemplate,
},
},
};
Expand Down
3 changes: 1 addition & 2 deletions packages/design-system/src/components/Spinner/Spinner.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type * as React from 'react';
import classNames from 'classnames';
import { t } from '../i18n';

Expand Down Expand Up @@ -36,7 +35,7 @@ export interface SpinnerProps {
* For information about how and when to use this component,
* [refer to its full documentation page](https://design.cms.gov/components/spinner/).
*/
export const Spinner: React.FunctionComponent<SpinnerProps> = (props: SpinnerProps) => {
export const Spinner = (props: SpinnerProps) => {
const className = classNames(
'ds-c-spinner',
props.size && `ds-c-spinner--${props.size}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export type TextFieldProps = BaseTextFieldProps &
* For information about how and when to use this component,
* [refer to its full documentation page](https://design.cms.gov/components/text-field/).
*/
export const TextField: React.FC<TextFieldProps> = (props: TextFieldProps) => {
export const TextField = (props: TextFieldProps) => {
const { id: originalId, mask, labelMask, className, ...remainingProps } = props;
const id = useId('text-field--', originalId);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type * as React from 'react';
import { FunctionComponent } from 'react';
import classNames from 'classnames';

export type TextInputDefaultValue = string | number;
Expand Down Expand Up @@ -79,7 +78,7 @@ export type SingleLineTextInputProps = TextInputProps;
* `<TextInput>` is also exported for advanced design system use cases, where the internal component can be leveraged to build custom form components
* As an internal component, it's subject to more breaking changes. Exercise caution using `<TextInput>` outside of those special cases
*/
const TextInput: FunctionComponent<TextInputProps> = (props: TextInputProps) => {
const TextInput = (props: TextInputProps) => {
const {
ariaLabel,
fieldClassName,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type * as React from 'react';
import { useState } from 'react';
import classNames from 'classnames';
import useCssDebugger from '../utilities/useCssDebugger';
Expand Down Expand Up @@ -28,7 +27,7 @@ export interface UsaBannerProps {
* For information about how and when to use this component,
* [refer to its full documentation page](https://design.cms.gov/components/usa-banner/).
*/
export const UsaBanner: React.FunctionComponent<UsaBannerProps> = (props: UsaBannerProps) => {
export const UsaBanner = (props: UsaBannerProps) => {
useCssDebugger();

const [isBannerOpen, setBannerOpen] = useState<boolean>(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { h, Fragment, ComponentFactory } from 'preact';
import { h, ComponentFactory } from 'preact';
import { render } from '@testing-library/preact';
import { define } from './define';

Expand Down Expand Up @@ -32,11 +32,11 @@ interface IProps {

function Message({ customTitle, value, children }: IProps) {
return (
<Fragment>
<>
{customTitle && <h2>{customTitle}</h2>}
<em>{value}</em>
{children}
</Fragment>
</>
);
}

Expand Down
Loading

0 comments on commit 7dd4c50

Please sign in to comment.