diff --git a/.storybook/main.ts b/.storybook/main.ts index 91ca38ce..57d928d9 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -2,7 +2,7 @@ import type { StorybookConfig } from '@storybook/react-vite'; import { mergeConfig } from 'vite'; import turbosnap from 'vite-plugin-turbosnap'; -import { CHROMATIC_BASE_URL } from '../src/constants'; +import { CHROMATIC_BASE_URL } from '../src/constants.ts'; const useDistVersion = process.env.CHROMATIC_USE_DIST_VERSION === 'true'; diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 57ca7819..d73b1c4b 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -22,7 +22,6 @@ import { GraphQLClientProvider } from '../src/utils/graphQLClient'; import { storyWrapper } from '../src/utils/storyWrapper'; import { TelemetryProvider } from '../src/utils/TelemetryContext'; import { useSessionState } from '../src/utils/useSessionState'; -import { action } from 'storybook/actions'; // Initialize MSW initialize({ @@ -225,11 +224,11 @@ const preview: Preview = { argTypesRegex: '^on[A-Z].*', }, backgrounds: { - disable: true, + disabled: true, }, viewport: { disable: true, - viewports: { + options: { default: { name: 'Default', styles: { width: '960px', height: '720px' } }, }, }, diff --git a/package.json b/package.json index b176d1e6..c8a410c7 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ }, "dependencies": { "@neoconfetti/react": "^1.0.0", - "chromatic": "^13.3.3", + "chromatic": "^13.3.4", "filesize": "^10.0.12", "jsonfile": "^6.1.0", "strip-ansi": "^7.1.0" @@ -67,10 +67,10 @@ "@graphql-codegen/cli": "^5.0.5", "@graphql-typed-document-node/core": "^3.2.0", "@parcel/watcher": "^2.4.1", - "@storybook/addon-designs": "^10.0.1", - "@storybook/addon-docs": "^9.0.0", - "@storybook/icons": "^1.4.0", - "@storybook/react-vite": "^9.0.0", + "@storybook/addon-designs": "^11.0.3", + "@storybook/addon-docs": "^10.1.0", + "@storybook/icons": "^2.0.1", + "@storybook/react-vite": "^10.1.0", "@types/jsonfile": "^6.1.1", "@types/node": "^22.13.5", "@types/pluralize": "^0.0.29", @@ -91,10 +91,10 @@ "eslint-plugin-prettier": "^5.2.3", "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-simple-import-sort": "^12.1.1", - "eslint-plugin-storybook": "^9.0.0", + "eslint-plugin-storybook": "^10.1.0", "graphql": "^16.8.1", "msw": "^2.0.0", - "msw-storybook-addon": "2.0.4", + "msw-storybook-addon": "^2.0.6", "npm-run-all": "^4.1.5", "pluralize": "^8.0.0", "polished": "^4.2.2", @@ -105,7 +105,7 @@ "react-dom": "^18.3.1", "react-joyride": "^2.7.2", "rimraf": "^3.0.2", - "storybook": "^9.0.0", + "storybook": "^10.1.0", "ts-dedent": "^2.2.0", "tsup": "^6.6.3", "typescript": "^5.7.3", @@ -119,7 +119,7 @@ "zx": "^1.14.1" }, "peerDependencies": { - "storybook": "^0.0.0-0 || ^9.0.0 || ^9.1.0-0 || ^9.2.0-0 || ^10.0.0-0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0" + "storybook": "^10.1.0" }, "packageManager": "yarn@4.10.3", "engines": { diff --git a/src/TestProviderRender.tsx b/src/TestProviderRender.tsx index c5397519..fc2d7e87 100644 --- a/src/TestProviderRender.tsx +++ b/src/TestProviderRender.tsx @@ -3,7 +3,7 @@ import { PlayHollowIcon, StopAltIcon } from '@storybook/icons'; import pluralize from 'pluralize'; import React, { useCallback, useContext, useEffect, useRef } from 'react'; import { Link } from 'storybook/internal/components'; -import { Button, ProgressSpinner, TooltipNote, WithTooltip } from 'storybook/internal/components'; +import { Button, ProgressSpinner } from 'storybook/internal/components'; import { experimental_getTestProviderStore, experimental_useStatusStore, @@ -235,43 +235,31 @@ export const TestProviderRender = () => { {warning ? null : testProviderState === 'test-provider-state:running' ? ( - } + - + + + + ) : ( - } + - + + )} diff --git a/src/components/Accordions.tsx b/src/components/Accordions.tsx index 48aea244..bbd5174c 100644 --- a/src/components/Accordions.tsx +++ b/src/components/Accordions.tsx @@ -6,10 +6,9 @@ import { StopIcon as Stop, TimerIcon as Timer, } from '@storybook/icons'; +import { ActionList } from 'storybook/internal/components'; import { styled } from 'storybook/theming'; -import { IconButton } from './IconButton'; - export const Accordions = styled.div({ display: 'flex', flexDirection: 'column', @@ -77,7 +76,7 @@ export const CloseIcon = styled(Close)({ marginLeft: 'auto', }); -export const CloseButton: typeof IconButton = styled(IconButton)({ +export const CloseButton = styled(ActionList.Button)({ margin: -5, marginLeft: 'auto', }); diff --git a/src/components/ActionButton.tsx b/src/components/ActionButton.tsx index 79aabab1..8de895fe 100644 --- a/src/components/ActionButton.tsx +++ b/src/components/ActionButton.tsx @@ -1,100 +1,13 @@ -import { darken, lighten } from 'polished'; -import { ComponentProps } from 'react'; -import { styled, type Theme } from 'storybook/theming'; +import { ActionList } from 'storybook/internal/components'; +import { styled } from 'storybook/theming'; -import { IconButton } from './IconButton'; - -const themeColors = ({ theme, status, variant }: { theme: Theme } & ActionButtonProps) => { - if (variant === 'outline') { - return { - color: theme.base === 'light' ? theme.color.dark : theme.color.medium, - backgroundColor: theme.background.app, - borderColor: theme.base === 'light' ? theme.color.medium : theme.color.darker, - '&:hover': { - color: theme.base === 'light' ? theme.color.darkest : theme.color.lighter, - backgroundColor: darken(0.03, theme.background.app), - }, - }; - } - if (status === 'positive') { - return { - color: theme.color.positiveText, - backgroundColor: theme.background.positive, - borderColor: lighten(0.5, theme.color.positiveText), - '&:hover': { - color: theme.color.positiveText, - backgroundColor: darken(0.05, theme.background.positive), - }, - }; - } - if (status === 'warning') { - return { - color: theme.color.warningText, - backgroundColor: theme.background.warning, - borderColor: lighten(0.5, theme.color.warningText), - '&:hover': { - color: theme.color.warningText, - backgroundColor: darken(0.05, theme.background.warning), - }, - }; - } - return { - color: theme.color.lightest, - backgroundColor: theme.color.secondary, - borderWidth: 0, - borderColor: - theme.base === 'light' - ? lighten(0.2, theme.color.secondary) - : darken(0.1, theme.color.secondary), - '&:hover': { - color: theme.color.lightest, - backgroundColor: darken(0.05, theme.color.secondary), - }, - }; -}; - -interface ActionButtonProps extends ComponentProps { - square?: boolean; - side?: 'left' | 'right'; -} - -export const ActionButton: React.FC = styled(IconButton)( - ({ square }) => ({ - border: `1px solid transparent`, - boxShadow: 'none', - fontSize: 12, - fontWeight: 700, +export const ActionButton = styled(ActionList.Button)({ + '@container (max-width: 299px)': { height: 28, - padding: square ? '8px 6px' : 8, - transition: 'background-color 150ms ease-out', - '@container (min-width: 300px)': { - height: 32, - width: square ? 32 : 'auto', - padding: square ? '9px 8px' : 9, - }, - '@container (min-width: 800px)': { - height: 28, - fontSize: 12, - width: square ? 28 : 'auto', - padding: square ? '8px 6px' : 8, - }, - }), - themeColors, - ({ side }) => ({ - ...(side === 'left' && { - borderRightWidth: 1, - borderTopRightRadius: 0, - borderBottomRightRadius: 0, - }), - ...(side === 'right' && { - borderLeftWidth: 0, - borderTopLeftRadius: 0, - borderBottomLeftRadius: 0, - }), - }) -); - -export const ButtonGroup = styled.div({ - display: 'flex', - flexDirection: 'row', + padding: '0 7px', + }, + '@container (min-width: 800px)': { + height: 28, + padding: '0 7px', + }, }); diff --git a/src/components/BrowserSelector.tsx b/src/components/BrowserSelector.tsx index bcab49f3..a3330ae7 100644 --- a/src/components/BrowserSelector.tsx +++ b/src/components/BrowserSelector.tsx @@ -1,6 +1,5 @@ -import { ChevronDownIcon } from '@storybook/icons'; -import React, { ComponentProps } from 'react'; -import { WithTooltip } from 'storybook/internal/components'; +import React from 'react'; +import { ActionList, PopoverProvider } from 'storybook/internal/components'; import { styled } from 'storybook/theming'; import { Browser, BrowserInfo, ComparisonResult } from '../gql/graphql'; @@ -10,8 +9,6 @@ import { EdgeIcon } from './icons/EdgeIcon'; import { FirefoxIcon } from './icons/FirefoxIcon'; import { SafariIcon } from './icons/SafariIcon'; import { StatusDot, StatusDotWrapper } from './StatusDot'; -import { TooltipMenu } from './TooltipMenu'; -import { TooltipNote } from './TooltipNote'; const browserIcons = { [Browser.Chrome]: , @@ -20,36 +17,18 @@ const browserIcons = { [Browser.Edge]: , } as const; -const IconWrapper = styled.div(({ theme }) => ({ - alignItems: 'center', - color: theme.base === 'light' ? theme.color.dark : theme.color.light, - display: 'inline-flex', - gap: 6, - height: 16, - margin: '6px 7px', - - svg: { - verticalAlign: 'top', - }, -})); - -const Label = styled.span(({ theme }) => ({ - color: theme.base === 'light' ? theme.color.dark : theme.color.light, +const ButtonLabel = styled(ActionList.Text)({ display: 'none', - fontSize: theme.typography.size.s1, - fontWeight: theme.typography.weight.bold, '@container (min-width: 300px)': { display: 'inline-block', }, +}); - '+ svg': { - color: theme.base === 'light' ? theme.color.dark : theme.color.light, - }, - - 'button:hover > &, button:hover > & + svg': { - color: theme.color.secondary, - }, +const ItemLabel = styled(ActionList.Text)<{ active?: boolean }>(({ theme, active }) => ({ + minWidth: 80, + color: active ? theme.color.secondary : 'inherit', + fontWeight: active ? theme.typography.weight.bold : 'inherit', })); type BrowserData = Pick; @@ -79,47 +58,54 @@ export const BrowserSelector = ({ icon = {icon}; } - type Link = ComponentProps['links'][0]; - - const links = - browserResults.length > 1 && - browserResults.map( - ({ browser, result }): Link => ({ - active: selectedBrowser === browser, - id: browser.id, - onClick: () => onSelectBrowser(browser), - right: !isAccepted && - ![ComparisonResult.Equal, ComparisonResult.Skipped].includes(aggregate) && ( - - ), - icon: browserIcons[browser.key], - title: browser.name, - }) + if (browserResults.length === 1) { + return ( + + {icon} + {selectedBrowser.name} + ); + } + + const links = browserResults.map(({ browser, result }) => ({ + id: browser.id, + title: browser.name, + icon: browserIcons[browser.key], + right: !isAccepted && + ![ComparisonResult.Equal, ComparisonResult.Skipped].includes(aggregate) && ( + + ), + onClick: () => onSelectBrowser(browser), + active: selectedBrowser.name === browser.name, + })); + return ( - - } - > - {links ? ( - - {icon} - - - - ) : ( - - {icon} - - + ( + + {links.map((link) => ( + + { + link.onClick(); + onHide(); + }} + > + {link.icon} + {link.title} + {link.right && {link.right}} + + + ))} + )} - + > + + {icon} + {selectedBrowser.name} + + ); }; diff --git a/src/components/FooterMenu.tsx b/src/components/FooterMenu.tsx index afb80428..966aaf27 100644 --- a/src/components/FooterMenu.tsx +++ b/src/components/FooterMenu.tsx @@ -1,5 +1,6 @@ -import { CogIcon, EllipsisIcon, QuestionIcon, ShareAltIcon, UserIcon } from '@storybook/icons'; +import { ChromaticIcon, CogIcon, EllipsisIcon, QuestionIcon, UserIcon } from '@storybook/icons'; import React from 'react'; +import { ActionList, PopoverProvider } from 'storybook/internal/components'; import { experimental_getStatusStore } from 'storybook/manager-api'; import { useAuthState } from '../AuthContext'; @@ -7,7 +8,6 @@ import { ADDON_ID, PROJECT_INFO } from '../constants'; import { useControlsDispatch } from '../screens/VisualTests/ControlsContext'; import { ProjectInfoPayload } from '../types'; import { useSharedState } from '../utils/useSharedState'; -import { TooltipMenu } from './TooltipMenu'; export const FooterMenu = () => { const { accessToken, setAccessToken, subdomain } = useAuthState(); @@ -15,51 +15,80 @@ export const FooterMenu = () => { const [projectInfo] = useSharedState(PROJECT_INFO); const statusStore = experimental_getStatusStore(ADDON_ID); const { projectId } = projectInfo || {}; - const links = [ - { - id: 'learn', - title: 'About this addon', - icon: , - href: 'https://www.chromatic.com/docs/visual-tests-addon/', - target: '_blank', - }, - { - id: 'configuration', - title: 'Configuration', - icon: , - onClick: () => toggleConfig(), - }, - ...(projectId - ? [ - { - id: 'visit', - title: 'View project on Chromatic', - icon: , - href: projectId - ? `https://${subdomain}.chromatic.com/builds?appId=${projectId?.split(':')[1]}` - : `https://${subdomain}.chromatic.com/start`, - target: '_blank', - }, - ] - : []), - ...(accessToken - ? [ - { - id: 'logout', - title: 'Log out', - icon: , - onClick: () => { - statusStore.unset(); - setAccessToken(null); - }, - }, - ] - : []), - ]; return ( - - - + ( + + + + + + + About this addon + + + + + { + toggleConfig(); + onHide(); + }} + > + + + + Configuration + + + + {projectId && ( + + + + + + View project on Chromatic + + + )} + + {accessToken && ( + + { + statusStore.unset(); + setAccessToken(null); + onHide(); + }} + > + + + + Log out + + + )} + + )} + > + + + + ); }; diff --git a/src/components/IconButton.tsx b/src/components/IconButton.tsx deleted file mode 100644 index 6f52eef6..00000000 --- a/src/components/IconButton.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { ComponentProps } from 'react'; -import { IconButton as BaseIconButton } from 'storybook/internal/components'; -import { styled, type Theme } from 'storybook/theming'; - -const getStatusStyles = (theme: Theme, status?: IconButtonProps['status']) => - (status && - { - positive: { color: theme.color.positiveText }, - warning: { color: theme.color.warningText }, - }[status]) || - {}; - -interface IconButtonProps extends ComponentProps { - active?: boolean; - as?: string; - status?: 'positive' | 'warning'; -} - -export const IconButton: React.FC = styled(BaseIconButton)( - ({ active, variant, theme }) => ({ - display: 'inline-flex', - alignItems: 'center', - verticalAlign: 'top', - gap: 6, - margin: 0, - color: active || variant === 'outline' ? theme.color.secondary : theme.color.mediumdark, - fontWeight: 'normal', - '& > svg': { - width: 'auto', - }, - }), - ({ active, status, theme }) => !active && getStatusStyles(theme, status), - ({ active, theme }) => { - const isLightTheme = theme.background.content === theme.color.lightest; - const activeBg = isLightTheme ? 'rgb(241,248,255)' : 'rgb(28,37,45)'; - const hoverBg = isLightTheme ? 'rgb(229,243,255)' : 'rgb(29,44,56)'; - return { - '--bg-color': active ? activeBg : theme.background.content, - '&:hover': { - '--bg-color': hoverBg, - color: theme.color.secondary, - }, - }; - } -); diff --git a/src/components/ModeSelector.tsx b/src/components/ModeSelector.tsx index d7b26cda..da02f1a1 100644 --- a/src/components/ModeSelector.tsx +++ b/src/components/ModeSelector.tsx @@ -1,64 +1,24 @@ -import { ChevronDownIcon, DiamondIcon } from '@storybook/icons'; +import { DiamondIcon } from '@storybook/icons'; import React from 'react'; -import { WithTooltip } from 'storybook/internal/components'; +import { ActionList, PopoverProvider } from 'storybook/internal/components'; import { styled } from 'storybook/theming'; import { ComparisonResult, TestMode } from '../gql/graphql'; import { aggregateResult } from '../utils/aggregateResult'; import { StatusDot, StatusDotWrapper } from './StatusDot'; -import { TooltipMenu } from './TooltipMenu'; -import { TooltipNote } from './TooltipNote'; -const IconWrapper = styled.div(({ theme }) => ({ - alignItems: 'center', - color: theme.base === 'light' ? theme.color.darkest : theme.color.light, - display: 'inline-flex', - gap: 6, - height: 14, - margin: '7px 7px', - - svg: { - verticalAlign: 'top', - - path: { - fill: theme.base === 'light' ? theme.color.dark : theme.color.light, - }, - }, -})); - -const StyledTooltipMenu = styled(TooltipMenu)(({ theme }) => ({ - button: { - svg: { - verticalAlign: 'top', - - path: { - fill: theme.base === 'light' ? theme.color.dark : theme.color.light, - }, - }, - - '&:hover': { - svg: { - path: { - fill: theme.color.secondary, - }, - }, - }, - }, -})); - -const Label = styled.span(({ theme }) => ({ - color: theme.base === 'light' ? theme.color.dark : theme.color.light, +const ButtonLabel = styled(ActionList.Text)({ display: 'none', - fontSize: theme.typography.size.s1, - fontWeight: theme.typography.weight.bold, '@container (min-width: 300px)': { display: 'inline-block', }, +}); - 'button:hover > &': { - color: theme.color.secondary, - }, +const ItemLabel = styled(ActionList.Text)<{ active?: boolean }>(({ theme, active }) => ({ + minWidth: 80, + color: active ? theme.color.secondary : 'inherit', + fontWeight: active ? theme.typography.weight.bold : 'inherit', })); type ModeData = Pick; @@ -90,48 +50,59 @@ export const ModeSelector = ({ icon = {icon}; } - const links = - modeResults.length > 1 && - modeResults - .map(({ mode, result }) => ({ - id: mode.name, - title: mode.name, - right: !isAccepted && - ![ComparisonResult.Equal, ComparisonResult.Skipped].includes(aggregate) && ( - - ), - onClick: () => onSelectMode(mode), - active: selectedMode.name === mode.name, - })) - .sort((a, b) => { - if (!modeOrder) return 0; - const ia = modeOrder.indexOf(a.title); - const ib = modeOrder.indexOf(b.title); - return ia !== -1 && ib !== -1 ? ia - ib : 0; - }); + if (modeResults.length === 1) { + return ( + + {icon} + {selectedMode.name} + + ); + } + + const links = modeResults + .map(({ mode, result }) => ({ + id: mode.name, + title: mode.name, + right: !isAccepted && + ![ComparisonResult.Equal, ComparisonResult.Skipped].includes(aggregate) && ( + + ), + onClick: () => onSelectMode(mode), + active: selectedMode.name === mode.name, + })) + .sort((a, b) => { + if (!modeOrder) return 0; + const ia = modeOrder.indexOf(a.title); + const ib = modeOrder.indexOf(b.title); + return ia !== -1 && ib !== -1 ? ia - ib : 0; + }); return ( - - } - > - {links ? ( - - {icon} - - - - ) : ( - - {icon} - - + ( + + {links.map((link) => ( + + { + link.onClick(); + onHide(); + }} + > + {link.title} + {link.right && {link.right}} + + + ))} + )} - + > + + {icon} + {selectedMode.name} + + ); }; diff --git a/src/components/Screen.tsx b/src/components/Screen.tsx index dfdfc3c0..feddba82 100644 --- a/src/components/Screen.tsx +++ b/src/components/Screen.tsx @@ -1,6 +1,7 @@ import { CloseIcon } from '@storybook/icons'; import pluralize from 'pluralize'; import React, { ReactNode, useCallback, useState } from 'react'; +import { ActionList } from 'storybook/internal/components'; import { styled } from 'storybook/theming'; import { CONFIG_INFO, CONFIG_INFO_DISMISSED } from '../constants'; @@ -10,7 +11,6 @@ import { ConfigInfoPayload } from '../types'; import { useSharedState } from '../utils/useSharedState'; import { Link } from './design-system'; import { FooterMenu } from './FooterMenu'; -import { IconButton } from './IconButton'; import { Col, Section } from './layout'; const Bar = styled.div(({ theme }) => ({ @@ -83,9 +83,9 @@ export const ConfigSection = ({ Configuration could be improved. {configLink} - + - + diff --git a/src/components/TooltipMenu.stories.tsx b/src/components/TooltipMenu.stories.tsx deleted file mode 100644 index 7203162d..00000000 --- a/src/components/TooltipMenu.stories.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react-vite'; -import React from 'react'; -import { fn, userEvent, within } from 'storybook/test'; - -import { Container } from './Container'; -import { StatusDot } from './StatusDot'; -import { TooltipMenu } from './TooltipMenu'; - -const meta = { - component: TooltipMenu, - args: { - children: 'Menu', - note: 'Click to open menu', - links: [ - { id: '1', onClick: fn().mockName('1'), title: 'One' }, - { id: '2', onClick: fn().mockName('2'), title: 'Two' }, - { id: '3', onClick: fn().mockName('3'), title: 'Three' }, - ], - }, - decorators: [ - (Story) => ( - - - - ), - ], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Default = {} satisfies Story; - -export const Hover = { - play: async ({ canvasElement }) => { - const buttons = await within(canvasElement).findAllByRole('button'); - buttons.forEach((button) => userEvent.hover(button)); - }, -} satisfies Story; - -export const Open = { - play: async ({ canvasElement }) => { - const buttons = await within(canvasElement).findAllByRole('button'); - buttons.forEach((button) => userEvent.click(button)); - }, -} satisfies Story; - -export const Icons = { - args: { - links: [ - { id: '1', onClick: fn().mockName('1'), title: 'One', icon: '🍔' }, - { id: '2', onClick: fn().mockName('2'), title: 'Two', icon: '🍟' }, - { id: '3', onClick: fn().mockName('3'), title: 'Three', icon: '🥤' }, - ], - }, - play: Open.play, -} satisfies Story; - -export const Status = { - args: { - links: [ - { - id: '1', - onClick: fn().mockName('1'), - title: 'One', - right: , - }, - { id: '2', onClick: fn().mockName('2'), title: 'Two', right: }, - { - id: '3', - onClick: fn().mockName('3'), - title: 'Three', - right: , - }, - ], - }, - play: Open.play, -} satisfies Story; diff --git a/src/components/TooltipMenu.tsx b/src/components/TooltipMenu.tsx deleted file mode 100644 index 0b6ad981..00000000 --- a/src/components/TooltipMenu.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import React, { ComponentProps } from 'react'; -import { TooltipLinkList, WithTooltip } from 'storybook/internal/components'; -import { styled } from 'storybook/theming'; - -import { IconButton } from './IconButton'; -import { TooltipNote } from './TooltipNote'; - -const TooltipWrapper = styled.div({ - '& > div': { - minWidth: 120, - }, -}); - -interface TooltipMenuProps - extends Omit, 'children' | 'tooltip' | 'onVisibleChange'> { - children: React.ReactNode | ((active: boolean) => React.ReactNode); - links: ComponentProps['links']; - note?: ComponentProps['note']; -} - -function mapLinks(onClick: () => void) { - return ( - link: ComponentProps['links'][number] - ): ComponentProps['links'][number] => { - if (Array.isArray(link)) { - return link.map(mapLinks(onClick)) as ComponentProps['links'][number]; - } - - if ('onClick' in link && typeof link.onClick === 'function') { - return { - ...link, - onClick: (...args: unknown[]) => { - onClick(); - // @ts-ignore (too complex to type, due to multiple types of links and it being in an array of arrays) - link.onClick?.(...args); - }, - }; - } - return link; - }; -} - -export const TooltipMenu = ({ children, links, note, ...props }: TooltipMenuProps) => { - const [active, setActive] = React.useState(false); - - const menu = ( - setActive(visible)} - tooltip={({ onHide }) => ( - - ['links']} - /> - - )} - trigger="click" - {...props} - > - {typeof children === 'function' ? ( - children(active) - ) : ( - {children} - )} - - ); - - if (note) { - return ( - } trigger="hover" hasChrome={false}> - {menu} - - ); - } - - return menu; -}; diff --git a/src/components/TooltipNote.tsx b/src/components/TooltipNote.tsx deleted file mode 100644 index c8e76e76..00000000 --- a/src/components/TooltipNote.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { TooltipNote as OriginalTooltip } from 'storybook/internal/components'; -import { styled } from 'storybook/theming'; - -export const TooltipNote = styled(OriginalTooltip)({ - marginBottom: '-4px', - marginTop: '-4px', - left: -8, -}); diff --git a/src/constants.ts b/src/constants.ts index 6cbbf08b..b0913804 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,8 +1,6 @@ -export const { - CHROMATIC_INDEX_URL, - CHROMATIC_BASE_URL = CHROMATIC_INDEX_URL || 'https://www.chromatic.com', - CHROMATIC_API_URL = `${CHROMATIC_BASE_URL}/api`, -} = process.env; +export const CHROMATIC_INDEX_URL = process.env.CHROMATIC_INDEX_URL; +export const CHROMATIC_BASE_URL = process.env.CHROMATIC_BASE_URL || CHROMATIC_INDEX_URL || 'https://www.chromatic.com'; +export const CHROMATIC_API_URL = process.env.CHROMATIC_API_URL || `${CHROMATIC_BASE_URL}/api`; export const PACKAGE_NAME = '@chromatic-com/storybook'; diff --git a/src/dev.ts b/src/dev.ts index 851054a3..a3dd8763 100644 --- a/src/dev.ts +++ b/src/dev.ts @@ -1,6 +1,8 @@ -import config from './preset'; +import { fileURLToPath } from 'node:url'; + +import config from './preset.ts'; export default { ...config, - managerEntries: [require.resolve('./manager.tsx')], + managerEntries: [fileURLToPath(import.meta.resolve('./manager.tsx'))], }; diff --git a/src/manager.tsx b/src/manager.tsx index 3374fa2f..8c593b5e 100644 --- a/src/manager.tsx +++ b/src/manager.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { type Addon_TestProviderType, Addon_TypesEnum } from 'storybook/internal/types'; import { addons, experimental_getStatusStore } from 'storybook/manager-api'; -import { ADDON_ID, PANEL_ID, PARAM_KEY, TEST_PROVIDER_ID } from './constants'; +import { ADDON_ID, PANEL_ID, PARAM_KEY, TEST_PROVIDER_ID } from './constants.ts'; import { Panel } from './Panel'; import { TestProviderRender } from './TestProviderRender'; diff --git a/src/preset.ts b/src/preset.ts index ec6c6634..5db3fa16 100644 --- a/src/preset.ts +++ b/src/preset.ts @@ -1,5 +1,6 @@ import { watch } from 'node:fs'; import { readFile } from 'node:fs/promises'; +import { createRequire } from 'node:module'; import { dirname, join, normalize, relative } from 'node:path'; import { @@ -29,18 +30,20 @@ import { STOP_BUILD, TELEMETRY, TEST_PROVIDER_ID, -} from './constants'; -import { runChromaticBuild, stopChromaticBuild } from './runChromaticBuild'; +} from './constants.ts'; +import { runChromaticBuild, stopChromaticBuild } from './runChromaticBuild.ts'; import { ConfigInfoPayload, ConfigurationUpdate, GitInfoPayload, LocalBuildProgress, ProjectInfoPayload, -} from './types'; -import { ChannelFetch } from './utils/ChannelFetch'; -import { SharedState } from './utils/SharedState'; -import { updateChromaticConfig } from './utils/updateChromaticConfig'; +} from './types.ts'; +import { ChannelFetch } from './utils/ChannelFetch.ts'; +import { SharedState } from './utils/SharedState.ts'; +import { updateChromaticConfig } from './utils/updateChromaticConfig.ts'; + +const require = createRequire(import.meta.url); const chromaticLogger = createLogger(undefined, CONFIG_OVERRIDES); diff --git a/src/runChromaticBuild.ts b/src/runChromaticBuild.ts index 57198fdb..48e06b22 100644 --- a/src/runChromaticBuild.ts +++ b/src/runChromaticBuild.ts @@ -6,10 +6,10 @@ import { hasProgressEvent, INITIAL_BUILD_PAYLOAD_JSON, isKnownStep, -} from './buildSteps'; -import { CONFIG_OVERRIDES } from './constants'; -import { LocalBuildProgress } from './types'; -import { SharedState } from './utils/SharedState'; +} from './buildSteps.ts'; +import { CONFIG_OVERRIDES } from './constants.ts'; +import { LocalBuildProgress } from './types.ts'; +import { SharedState } from './utils/SharedState.ts'; const ESTIMATED_PROGRESS_INTERVAL = 2000; diff --git a/src/screens/Authentication/AuthHeader.tsx b/src/screens/Authentication/AuthHeader.tsx index b7cf8ee1..52faa6f7 100644 --- a/src/screens/Authentication/AuthHeader.tsx +++ b/src/screens/Authentication/AuthHeader.tsx @@ -1,17 +1,8 @@ import { ChevronLeftIcon, QuestionIcon } from '@storybook/icons'; import React from 'react'; -import { WithTooltip } from 'storybook/internal/components'; -import { styled } from 'storybook/theming'; +import { ActionList } from 'storybook/internal/components'; -import { IconButton } from '../../components/IconButton'; import { Bar, Col } from '../../components/layout'; -import { TooltipNote } from '../../components/TooltipNote'; - -const HeaderButton = styled(IconButton)(({ theme }) => ({ - color: theme.base === 'light' ? 'currentColor' : theme.color.medium, - fontSize: theme.typography.size.s2, - fontWeight: theme.typography.weight.bold, -})); interface AuthHeaderProps { onBack?: () => void; @@ -21,25 +12,18 @@ export const AuthHeader = ({ onBack }: AuthHeaderProps) => ( {onBack && ( - + Back - + )} - } - > - - - - - - + + + + + ); diff --git a/src/screens/Authentication/SetSubdomain.tsx b/src/screens/Authentication/SetSubdomain.tsx index 65b5317b..9aadd91d 100644 --- a/src/screens/Authentication/SetSubdomain.tsx +++ b/src/screens/Authentication/SetSubdomain.tsx @@ -88,7 +88,7 @@ export const SetSubdomain = ({ onBack, onSignIn }: SetSubdomainProps) => { error={inputError} errorTooltipPlacement="top" /> - + Continue diff --git a/src/screens/Authentication/SignIn.tsx b/src/screens/Authentication/SignIn.tsx index e3a2fc6d..a21842e0 100644 --- a/src/screens/Authentication/SignIn.tsx +++ b/src/screens/Authentication/SignIn.tsx @@ -38,10 +38,10 @@ export const SignIn = ({ onBack, onSignIn, onSignInWithSSO }: SignInProps) => ( - - diff --git a/src/screens/Authentication/Verify.tsx b/src/screens/Authentication/Verify.tsx index 986f32df..17d994da 100644 --- a/src/screens/Authentication/Verify.tsx +++ b/src/screens/Authentication/Verify.tsx @@ -154,7 +154,12 @@ export const Verify = ({ ))} - diff --git a/src/screens/Authentication/Welcome.tsx b/src/screens/Authentication/Welcome.tsx index 87d94c9a..64c1acff 100644 --- a/src/screens/Authentication/Welcome.tsx +++ b/src/screens/Authentication/Welcome.tsx @@ -109,10 +109,10 @@ export const Welcome = ({ onNext, onUninstall }: WelcomeProps) => { - - ( Awaiting changes... )} - @@ -129,6 +129,7 @@ const ChangesDetected = ({ - @@ -71,10 +71,10 @@ export const CatchAChangeComplete = ({ It's time to review changes! - - diff --git a/src/screens/Onboarding/InitialBuild.tsx b/src/screens/Onboarding/InitialBuild.tsx index e2230674..a3be259e 100644 --- a/src/screens/Onboarding/InitialBuild.tsx +++ b/src/screens/Onboarding/InitialBuild.tsx @@ -47,10 +47,16 @@ export const InitialBuild = ({ - - diff --git a/src/screens/Onboarding/InitialBuildComplete.tsx b/src/screens/Onboarding/InitialBuildComplete.tsx index e843982c..d171171a 100644 --- a/src/screens/Onboarding/InitialBuildComplete.tsx +++ b/src/screens/Onboarding/InitialBuildComplete.tsx @@ -42,10 +42,10 @@ export const InitialBuildComplete = ({ onCatchAChange, onSkip }: InitialBuildCom Let's see the superpower of catching visual changes. - - diff --git a/src/screens/Onboarding/Onboarding.tsx b/src/screens/Onboarding/Onboarding.tsx index 252d8d84..4e34c767 100644 --- a/src/screens/Onboarding/Onboarding.tsx +++ b/src/screens/Onboarding/Onboarding.tsx @@ -66,10 +66,10 @@ export const Onboarding = ({ return ( - - @@ -83,7 +83,7 @@ export const Onboarding = ({ billingUrl={localBuildProgress.errorDetailsUrl} suspensionReason={AccountSuspensionReason.ExceededThreshold} > - diff --git a/src/screens/VisualTests/BuildEyebrow.tsx b/src/screens/VisualTests/BuildEyebrow.tsx index a3c0fbc6..49aa29c8 100644 --- a/src/screens/VisualTests/BuildEyebrow.tsx +++ b/src/screens/VisualTests/BuildEyebrow.tsx @@ -7,13 +7,12 @@ import { SyncIcon, } from '@storybook/icons'; import React, { useEffect, useRef } from 'react'; -import { Link } from 'storybook/internal/components'; +import { ActionList, Link } from 'storybook/internal/components'; import { keyframes, styled } from 'storybook/theming'; import { BUILD_STEP_CONFIG, BUILD_STEP_ORDER } from '../../buildSteps'; import { BuildProgressLabel } from '../../components/BuildProgressLabel'; import { Code } from '../../components/Code'; -import { IconButton } from '../../components/IconButton'; import { LocalBuildProgress } from '../../types'; const spin = keyframes({ @@ -27,7 +26,7 @@ const SpinIcon = styled(SyncIcon)({ const stepIconStyle = { width: 10, marginRight: 8 }; -const Header = styled.button<{ isWarning?: boolean }>(({ isWarning, onClick, theme }) => { +const Header = styled.div<{ isWarning?: boolean }>(({ isWarning, onClick, theme }) => { const warningColor = theme.base === 'light' ? theme.background.warning : '#2e271a'; return { position: 'relative', @@ -212,23 +211,23 @@ export const BuildEyebrow = ({ const isWarning = aborted || errored; return ( <> -
+
{errored ? ( - - - + + + ) : ( - + - + )}
diff --git a/src/screens/VisualTests/BuildResults.tsx b/src/screens/VisualTests/BuildResults.tsx index 76320746..acfac0df 100644 --- a/src/screens/VisualTests/BuildResults.tsx +++ b/src/screens/VisualTests/BuildResults.tsx @@ -17,12 +17,9 @@ import { BuildStatus, TestResult } from '../../gql/graphql'; import { LocalBuildProgress } from '../../types'; import { useBuildState, useSelectedBuildState, useSelectedStoryState } from './BuildContext'; import { BuildEyebrow } from './BuildEyebrow'; -import { useControlsDispatch, useControlsState } from './ControlsContext'; -import { RenderSettings } from './RenderSettings'; import { useReviewTestState } from './ReviewTestContext'; import { useRunBuildState } from './RunBuildContext'; import { SnapshotComparison } from './SnapshotComparison'; -import { Warnings } from './Warnings'; interface BuildResultsProps { branch: string; @@ -49,8 +46,6 @@ export const BuildResults = ({ switchToLastBuildOnBranch, storyId, }: BuildResultsProps) => { - const { settingsVisible, warningsVisible } = useControlsState(); - const { toggleSettings, toggleWarnings } = useControlsDispatch(); const { isRunning, startBuild, stopBuild } = useRunBuildState(); const { lastBuildOnBranch, lastBuildOnBranchIsReady, lastBuildOnBranchIsSelectable } = @@ -124,6 +119,7 @@ export const BuildResults = ({ + diff --git a/src/screens/VisualTests/ControlsContext.tsx b/src/screens/VisualTests/ControlsContext.tsx index 3f31e624..4dc9929f 100644 --- a/src/screens/VisualTests/ControlsContext.tsx +++ b/src/screens/VisualTests/ControlsContext.tsx @@ -4,8 +4,6 @@ import { useRequiredContext } from '../../utils/useRequiredContext'; const initialControls = { configVisible: false, - settingsVisible: false, - warningsVisible: false, baselineImageVisible: false, focusVisible: false, diffVisible: false, @@ -24,8 +22,6 @@ const handlers = { toggleDiff: toggle('diffVisible'), toggleFocus: toggle('focusVisible'), toggleConfig: toggle('configVisible'), - toggleSettings: toggle('settingsVisible'), - toggleWarnings: toggle('warningsVisible'), toggleBaselineImage: toggle('baselineImageVisible'), } as const; @@ -45,8 +41,6 @@ export const useControlsDispatch = () => { toggleDiff: (visible?: boolean) => dispatch({ type: 'toggleDiff', payload: visible }), toggleFocus: (visible?: boolean) => dispatch({ type: 'toggleFocus', payload: visible }), toggleConfig: (visible?: boolean) => dispatch({ type: 'toggleConfig', payload: visible }), - toggleSettings: (visible?: boolean) => dispatch({ type: 'toggleSettings', payload: visible }), - toggleWarnings: (visible?: boolean) => dispatch({ type: 'toggleWarnings', payload: visible }), toggleBaselineImage: (visible?: boolean) => dispatch({ type: 'toggleBaselineImage', payload: visible }), }), diff --git a/src/screens/VisualTests/NoBuild.tsx b/src/screens/VisualTests/NoBuild.tsx index 96c6858e..99147705 100644 --- a/src/screens/VisualTests/NoBuild.tsx +++ b/src/screens/VisualTests/NoBuild.tsx @@ -49,7 +49,13 @@ export const NoBuild = ({ const getDetails = () => { const button = ( - @@ -79,7 +85,12 @@ export const NoBuild = ({ {queryError.networkError.message} - @@ -100,7 +111,12 @@ export const NoBuild = ({ - diff --git a/src/screens/VisualTests/RenderSettings.stories.tsx b/src/screens/VisualTests/RenderSettings.stories.tsx deleted file mode 100644 index 43b4b9b4..00000000 --- a/src/screens/VisualTests/RenderSettings.stories.tsx +++ /dev/null @@ -1,51 +0,0 @@ -// @ts-nocheck TODO: Address SB 8 type errors -import type { Meta, StoryObj } from '@storybook/react-vite'; -import { graphql, HttpResponse } from 'msw'; - -import { ProjectQueryQuery } from '../../gql/graphql'; -import { panelModes } from '../../modes'; -import { GraphQLClientProvider } from '../../utils/graphQLClient'; -import { storyWrapper } from '../../utils/storyWrapper'; -import { withFigmaDesign } from '../../utils/withFigmaDesign'; -import { RenderSettings } from './RenderSettings'; - -const meta = { - component: RenderSettings, - decorators: [storyWrapper(GraphQLClientProvider)], - parameters: { - chromatic: { - modes: panelModes, - }, - msw: { - handlers: [ - graphql.query('ProjectQuery', () => - HttpResponse.json({ - data: { - project: { - id: '123', - name: 'acme', - webUrl: 'https://www.chromatic.com/passedBuilds?appId=123', - lastBuild: { - branch: 'main', - number: 123, - }, - }, - } satisfies ProjectQueryQuery, - }) - ), - ], - }, - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - args: { - // build: passedBuild, - }, - parameters: withFigmaDesign( - 'https://www.figma.com/file/GFEbCgCVDtbZhngULbw2gP/Visual-testing-in-Storybook?type=design&node-id=508-525764&t=18c1zI1SMe76dWYk-4' - ), -}; diff --git a/src/screens/VisualTests/RenderSettings.tsx b/src/screens/VisualTests/RenderSettings.tsx deleted file mode 100644 index c02e69b0..00000000 --- a/src/screens/VisualTests/RenderSettings.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React from 'react'; - -import { - Accordion, - Accordions, - CloseButton, - CloseIcon, - ContrastIcon, - Heading, - InfoIcon, - ParagraphIcon, - StopIcon, - TimerIcon, -} from '../../components/Accordions'; - -interface RenderSettingsProps { - onClose: () => void; -} - -export const RenderSettings = ({ onClose }: RenderSettingsProps) => { - return ( - - - - Render settings - - - - - -

- - Delay: 300ms -

-

- - Animation pause: Ends -

-

- - Threshold: 0.2 -

-

- - Anti-alias: Included -

-
- - - Bounding box - - -
-
Width:
-
Fill viewport
-
Height:
-
Hug contents
-
-
-
- ); -}; diff --git a/src/screens/VisualTests/SnapshotComparison.stories.tsx b/src/screens/VisualTests/SnapshotComparison.stories.tsx index 170487d2..d3279985 100644 --- a/src/screens/VisualTests/SnapshotComparison.stories.tsx +++ b/src/screens/VisualTests/SnapshotComparison.stories.tsx @@ -8,7 +8,7 @@ import { findByRole, fireEvent, screen, userEvent, within } from 'storybook/test import { Browser, ComparisonResult, TestResult, TestStatus } from '../../gql/graphql'; import { panelModes } from '../../modes'; -import { playAll } from '../../utils/playAll'; +import { playAll, playSequentially } from '../../utils/playAll'; import { makeComparison, makeTest, makeTests } from '../../utils/storyData'; import { storyWrapper } from '../../utils/storyWrapper'; import { BuildProvider } from './BuildContext'; @@ -87,7 +87,7 @@ export const Default = {} satisfies Story; export const Spotlight = { play: playAll(async ({ canvasElement }) => { const canvas = within(canvasElement); - const button = await canvas.findByRole('button', { name: 'Show spotlight' }); + const button = await canvas.findByRole('switch', { name: 'Show spotlight' }); await userEvent.click(button); }), } satisfies Story; @@ -95,7 +95,7 @@ export const Spotlight = { export const SpotlightOnly = { play: playAll(Spotlight, async ({ canvasElement }) => { const canvas = within(canvasElement); - const button = await canvas.findByRole('button', { name: 'Hide diff' }); + const button = await canvas.findByRole('switch', { name: 'Hide diff' }); await userEvent.click(button); }), } satisfies Story; @@ -209,23 +209,21 @@ export const SwitchingMode = { })) ), }, - play: playAll(async ({ canvasElement, canvasIndex }) => { - const canvas = within(canvasElement); - const menu = await canvas.findByRole('button', { name: '320px' }); + play: playSequentially(async ({ canvas }) => { + const menu = await canvas.findByRole('button', { name: 'Switch mode' }); await userEvent.click(menu); - const items = await screen.findAllByText('1200px'); - await userEvent.click(items[canvasIndex]); + const mode = await screen.findByRole('button', { name: '1200px' }); + await userEvent.click(mode); }), } satisfies Story; export const SwitchingBrowser = { parameters: SwitchingMode.parameters, - play: playAll(async ({ canvasElement, canvasIndex }) => { - const canvas = within(canvasElement); - const menu = await canvas.findByRole('button', { name: 'Chrome' }); + play: playSequentially(async ({ canvas }) => { + const menu = await canvas.findByRole('button', { name: 'Switch browser' }); await userEvent.click(menu); - const items = await screen.findAllByText('Safari'); - await userEvent.click(items[canvasIndex]); + const browser = await screen.findByRole('button', { name: 'Safari' }); + await userEvent.click(browser); }), } satisfies Story; diff --git a/src/screens/VisualTests/SnapshotComparison.tsx b/src/screens/VisualTests/SnapshotComparison.tsx index 1b2f2941..72b707f8 100644 --- a/src/screens/VisualTests/SnapshotComparison.tsx +++ b/src/screens/VisualTests/SnapshotComparison.tsx @@ -130,7 +130,7 @@ export const SnapshotComparison = ({ storyId, }: SnapshotComparisonProps) => { const { baselineImageVisible, diffVisible, focusVisible } = useControlsState(); - const { toggleBaselineImage, toggleSettings, toggleWarnings } = useControlsDispatch(); + const { toggleBaselineImage } = useControlsDispatch(); const selectedBuild = useSelectedBuildState(); const startedAt: Date = 'startedAt' in selectedBuild && selectedBuild.startedAt; @@ -174,8 +174,6 @@ export const SnapshotComparison = ({ isNewBrowser ) { toggleBaselineImage(false); - toggleSettings(false); - toggleWarnings(false); } prevSelectedComparisonIdRef.current = selectedStory.selectedComparison?.id; @@ -186,8 +184,6 @@ export const SnapshotComparison = ({ storyId, selectedStory, toggleBaselineImage, - toggleSettings, - toggleWarnings, isNewStory, isNewMode, isNewBrowser, diff --git a/src/screens/VisualTests/SnapshotControls.stories.tsx b/src/screens/VisualTests/SnapshotControls.stories.tsx index 3201bbee..9bd4c6d4 100644 --- a/src/screens/VisualTests/SnapshotControls.stories.tsx +++ b/src/screens/VisualTests/SnapshotControls.stories.tsx @@ -1,9 +1,9 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import { expect, fn } from 'storybook/test'; -import { fireEvent, screen, userEvent, within } from 'storybook/test'; +import { screen, userEvent } from 'storybook/test'; import { panelModes } from '../../modes'; -import { playAll } from '../../utils/playAll'; +import { playAll, playSequentially } from '../../utils/playAll'; import { storyWrapper } from '../../utils/storyWrapper'; import { BuildProvider } from './BuildContext'; import { ControlsProvider } from './ControlsContext'; @@ -81,33 +81,31 @@ export const Unreviewable = { } satisfies Story; export const ToggleDiff = { - play: playAll(async ({ canvasElement }) => { - const canvas = within(canvasElement); - const button = await canvas.findByRole('button', { name: 'Hide diff' }); - fireEvent.click(button); + play: playAll(async ({ canvas }) => { + const button = await canvas.findByRole('switch', { name: 'Hide diff' }); + await userEvent.click(button); }), } satisfies Story; export const ToggleBaseline = { - play: playAll(async ({ canvasElement }) => { - const canvas = within(canvasElement); + play: playAll(async ({ canvas }) => { const button = await canvas.findByRole('button', { name: 'Show baseline snapshot' }); - fireEvent.click(button); + await userEvent.click(button); }), } satisfies Story; export const BatchAcceptOptions = { - play: playAll(async ({ canvasElement }) => { - const canvas = within(canvasElement); + play: playSequentially(async ({ canvas }) => { + await userEvent.keyboard('[Escape]'); const menu = await canvas.findByRole('button', { name: 'Batch accept options' }); await userEvent.click(menu); }), } satisfies Story; export const BatchAcceptedBuild = { - play: playAll(BatchAcceptOptions, async ({ canvasIndex, parameters }) => { - const items = await screen.findAllByText('Accept entire build'); - await userEvent.click(items[canvasIndex]); + play: playSequentially(BatchAcceptOptions, async ({ parameters }) => { + const action = await screen.findByText('Accept entire build'); + await userEvent.click(action); await expect(parameters.reviewTest.acceptTest).toHaveBeenCalledWith( parameters.selectedBuild.testsForStory.nodes[0].id, 'BUILD' diff --git a/src/screens/VisualTests/SnapshotControls.tsx b/src/screens/VisualTests/SnapshotControls.tsx index 4d518907..17eff9ae 100644 --- a/src/screens/VisualTests/SnapshotControls.tsx +++ b/src/screens/VisualTests/SnapshotControls.tsx @@ -8,17 +8,15 @@ import { TransferIcon, UndoIcon, } from '@storybook/icons'; +import { darken, lighten } from 'polished'; import React from 'react'; -import { WithTooltip } from 'storybook/internal/components'; +import { ActionList, PopoverProvider } from 'storybook/internal/components'; import { styled } from 'storybook/theming'; -import { ActionButton, ButtonGroup } from '../../components/ActionButton'; -import { IconButton } from '../../components/IconButton'; +import { ActionButton } from '../../components/ActionButton'; import { ProgressIcon } from '../../components/icons/ProgressIcon'; import { Placeholder } from '../../components/Placeholder'; import { Text } from '../../components/Text'; -import { TooltipMenu } from '../../components/TooltipMenu'; -import { TooltipNote } from '../../components/TooltipNote'; import { ComparisonResult, ReviewTestBatch, TestStatus } from '../../gql/graphql'; import { useSelectedStoryState } from './BuildContext'; import { useControlsDispatch, useControlsState } from './ControlsContext'; @@ -60,16 +58,6 @@ const Controls = styled.div({ }, }); -const DisabledIconWrapper = styled.div(({ theme }) => ({ - padding: 9, - '> svg': { - display: 'block', - }, - path: { - fill: theme.color.mediumdark, - }, -})); - const Actions = styled.div<{ showDivider?: boolean }>(({ theme, showDivider }) => ({ gridArea: 'actions', display: 'flex', @@ -90,6 +78,47 @@ const Actions = styled.div<{ showDivider?: boolean }>(({ theme, showDivider }) = }, })); +const Action = styled(ActionList.Action)({ + height: 'auto', + flex: '0 1 100%', +}); + +const ActionContent = styled(ActionList.Text)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + alignItems: 'flex-start', + flex: '0 1 100%', + padding: '8px 0', + gap: 2, + span: { + color: theme.textMutedColor, + }, +})); + +const ReviewButton = styled(ActionButton)<{ + side: 'left' | 'right'; + status?: 'positive'; +}>(({ theme, side, status }) => ({ + ...(status === 'positive' && { + backgroundColor: theme.background.positive, + border: `1px solid ${lighten(0.35, theme.color.positive)}`, + color: theme.color.positiveText, + '&:hover': { + backgroundColor: darken(0.05, theme.background.positive), + }, + }), + ...(side === 'left' && { + borderTopRightRadius: 0, + borderBottomRightRadius: 0, + }), + ...(side === 'right' && { + borderTopLeftRadius: 0, + borderBottomLeftRadius: 0, + borderLeft: + status === 'positive' ? 'none' : `1px solid ${theme.base === 'dark' ? '#0006' : '#fff6'}`, + }), +})); + export const SnapshotControls = ({ isOutdated }: { isOutdated: boolean }) => { const { baselineImageVisible, diffVisible, focusVisible } = useControlsState(); const { toggleBaselineImage, toggleDiff, toggleFocus } = useControlsDispatch(); @@ -129,212 +158,190 @@ export const SnapshotControls = ({ isOutdated }: { isOutdated: boolean }) => { {hasControls && ( - - } - trigger="hover" - hasChrome={false} + toggleBaselineImage()} > - toggleBaselineImage()} - > - - - - } - trigger="hover" - hasChrome={false} + + + toggleFocus(!focusVisible)} > - toggleFocus(!focusVisible)} - > - - - - } - trigger="hover" - hasChrome={false} + + + toggleDiff(!diffVisible)} > - toggleDiff(!diffVisible)} - > - - - + + )} {(isAcceptable || isUnacceptable) && ( {userCanReview && buildIsReviewable && isAcceptable && selectedTest && ( - - } - trigger="hover" - hasChrome={false} +
+ acceptTest(selectedTest.id, ReviewTestBatch.Spec)} + side="left" + variant="solid" > - acceptTest(selectedTest.id, ReviewTestBatch.Spec)} - side="left" - > - Accept - - - } - trigger="hover" - hasChrome={false} + Accept + + + ( + + + { + acceptTest(selectedTest.id, ReviewTestBatch.Component); + onHide(); + }} + > + + Accept component + Accept all unreviewed changes for this component + + + + + { + acceptTest(selectedTest.id, ReviewTestBatch.Build); + onHide(); + }} + > + + Accept entire build + + Accept all unreviewed changes for every story in the Storybook + + + + + + )} > - acceptTest(selectedTest.id, ReviewTestBatch.Component), - disabled: isReviewing, - loading: isReviewing, - }, - { - id: 'acceptBuild', - title: 'Accept entire build', - center: 'Accept all unreviewed changes for every story in the Storybook', - onClick: () => acceptTest(selectedTest.id, ReviewTestBatch.Build), - disabled: isReviewing, - loading: isReviewing, - }, - ]} + - {(active) => ( - - {isReviewing ? ( - - ) : ( - - )} - + {isReviewing ? ( + + ) : ( + )} - - - + + +
)} {userCanReview && buildIsReviewable && isUnacceptable && ( - - } - trigger="hover" - hasChrome={false} +
+ unacceptTest(selectedTest.id, ReviewTestBatch.Spec)} + side="left" + variant="solid" + status="positive" > - + Unaccept + + + ( + + + { + unacceptTest(selectedTest.id, ReviewTestBatch.Component); + onHide(); + }} + > + + Unaccept component + Unaccept all unreviewed changes for this component + + + + + { + unacceptTest(selectedTest.id, ReviewTestBatch.Build); + onHide(); + }} + > + + Unaccept entire build + + Unaccept all unreviewed changes for every story in the Storybook + + + + + + )} + > + unacceptTest(selectedTest.id, ReviewTestBatch.Spec)} - side="left" + ariaLabel="Batch accept options" + side="right" + variant="solid" status="positive" > - - Unaccept - - - } - trigger="hover" - hasChrome={false} - > - unacceptTest(selectedTest.id, ReviewTestBatch.Component), - disabled: isReviewing, - loading: isReviewing, - }, - { - id: 'unacceptBuild', - title: 'Unaccept entire build', - center: 'Unaccept all unreviewed changes for every story in the Storybook', - onClick: () => unacceptTest(selectedTest.id, ReviewTestBatch.Build), - disabled: isReviewing, - loading: isReviewing, - }, - ]} - > - {(active) => ( - - {isReviewing ? ( - - ) : ( - - )} - + {isReviewing ? ( + + ) : ( + )} - - - + + +
)} {!(userCanReview && buildIsReviewable) && ( - } - trigger="hover" - hasChrome={false} - > - - - - + + + )} - } - trigger="hover" - hasChrome={false} + - - {isOutdated ? : } - - + {isOutdated ? : } +
)} diff --git a/src/screens/VisualTests/StoryInfo.tsx b/src/screens/VisualTests/StoryInfo.tsx index 8e7c4cdd..14142c59 100644 --- a/src/screens/VisualTests/StoryInfo.tsx +++ b/src/screens/VisualTests/StoryInfo.tsx @@ -200,7 +200,7 @@ export const StoryInfo = ({ {showButton && ( - + {isRunning ? : } {isErrored ? 'Rerun tests' : 'Run tests'} diff --git a/src/screens/VisualTests/VisualTests.stories.tsx b/src/screens/VisualTests/VisualTests.stories.tsx index 35966633..5b86428e 100644 --- a/src/screens/VisualTests/VisualTests.stories.tsx +++ b/src/screens/VisualTests/VisualTests.stories.tsx @@ -942,27 +942,3 @@ export const CIBuildNewerThanCommit = { }); }, } satisfies Story; - -// export const RenderSettings = { -// parameters: { -// ...withFigmaDesign( -// "https://www.figma.com/file/GFEbCgCVDtbZhngULbw2gP/Visual-testing-in-Storybook?type=design&node-id=508-525764&t=18c1zI1SMe76dWYk-4" -// ), -// }, -// play: playAll(async ({ canvasElement }) => { -// const button = await findByRole(canvasElement, "button", { name: "Show render settings" }); -// await fireEvent.click(button); -// }), -// } satisfies Story; - -// export const Warnings = { -// parameters: { -// ...withFigmaDesign( -// "https://www.figma.com/file/GFEbCgCVDtbZhngULbw2gP/Visual-testing-in-Storybook?type=design&node-id=516-672810&t=18c1zI1SMe76dWYk-4" -// ), -// }, -// play: playAll(async ({ canvasElement }) => { -// const button = await findByRole(canvasElement, "button", { name: "Show warnings" }); -// await fireEvent.click(button); -// }), -// } satisfies Story; diff --git a/src/screens/VisualTests/Warnings.tsx b/src/screens/VisualTests/Warnings.tsx deleted file mode 100644 index eb9a2d98..00000000 --- a/src/screens/VisualTests/Warnings.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { DocumentIcon, SupportIcon } from '@storybook/icons'; -import React from 'react'; - -import { - Accordion, - Accordions, - CloseButton, - CloseIcon, - Heading, -} from '../../components/Accordions'; -import { Badge } from '../../components/Badge'; -import { Button } from '../../components/Button'; - -interface WarningsProps { - onClose: () => void; -} - -export const Warnings = ({ onClose }: WarningsProps) => ( - - - - Warnings - 2 - - - - -

- It's essential that your components and stories render in a consistent fashion to - prevent false positives. Two issues detected in this story may cause false positives. -

-

- - -

-
-
-); diff --git a/src/utils/ChannelFetch.ts b/src/utils/ChannelFetch.ts index 7a92343a..b7fbb043 100644 --- a/src/utils/ChannelFetch.ts +++ b/src/utils/ChannelFetch.ts @@ -1,6 +1,6 @@ import type { Channel } from 'storybook/internal/channels'; -import { FETCH_ABORTED, FETCH_REQUEST, FETCH_RESPONSE } from '../constants'; +import { FETCH_ABORTED, FETCH_REQUEST, FETCH_RESPONSE } from '../constants.ts'; type ChannelLike = Pick; diff --git a/src/utils/playAll.ts b/src/utils/playAll.ts index 0eea4f83..1da96547 100644 --- a/src/utils/playAll.ts +++ b/src/utils/playAll.ts @@ -1,6 +1,11 @@ import type { ReactRenderer } from '@storybook/react-vite'; import type { StoryAnnotations } from 'storybook/internal/types'; +import { within } from 'storybook/test'; +/** + * Runs a sequence of play functions on multiple canvases in parallel. + * This is generally preferable for performance as it runs on all canvases at the same time. + */ export function playAll>( ...sequence: (Story | Story['play'])[] ): Story['play'] { @@ -8,14 +13,42 @@ export function playAll>( const canvasNodes = context.canvasElement.querySelectorAll('[data-canvas]'); const canvasElements = canvasNodes.length ? Array.from(canvasNodes) : [context.canvasElement]; - await Promise.all( - sequence.flatMap((storyOrPlay) => - typeof storyOrPlay === 'function' - ? canvasElements.map((canvasElement, canvasIndex) => - storyOrPlay({ ...context, canvasElement, canvasIndex }) - ) - : storyOrPlay?.play?.(context) - ) - ); + for (const storyOrPlay of sequence) { + if (typeof storyOrPlay === 'function') { + await Promise.all( + canvasElements.map((canvasElement, canvasIndex) => { + const canvas = within(canvasElement); + return storyOrPlay({ ...context, canvas, canvasElement, canvasIndex }); + }) + ); + } else { + await storyOrPlay?.play?.(context); + } + } + }; +} + +/** + * Runs a sequence of play functions on multiple canvases sequentially. + * This is necessary when interacting with popovers, as no more than one can be open at a time. + */ +export function playSequentially>( + ...sequence: (Story | Story['play'])[] +): Story['play'] { + return async (context) => { + const canvasNodes = context.canvasElement.querySelectorAll('[data-canvas]'); + const canvasElements = canvasNodes.length ? Array.from(canvasNodes) : [context.canvasElement]; + + for (let canvasIndex = 0; canvasIndex < canvasElements.length; canvasIndex++) { + const canvasElement = canvasElements[canvasIndex]; + const canvas = within(canvasElement); + for (const storyOrPlay of sequence) { + if (typeof storyOrPlay === 'function') { + await storyOrPlay({ ...context, canvas, canvasElement, canvasIndex }); + } else { + await storyOrPlay?.play?.(context); + } + } + } }; } diff --git a/tsconfig.json b/tsconfig.json index 02d37a0d..cb291335 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "allowImportingTsExtensions": true, "allowSyntheticDefaultImports": true, "moduleResolution": "bundler", "baseUrl": ".", @@ -10,7 +11,7 @@ "isolatedModules": true, "jsx": "react", "lib": ["es2020", "dom"], - "module": "Preserve", + "module": "esnext", "noImplicitAny": true, "strict": true, "rootDir": "./src", diff --git a/yarn.lock b/yarn.lock index 8717fe6c..db208aa5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -451,10 +451,10 @@ __metadata: "@graphql-typed-document-node/core": "npm:^3.2.0" "@neoconfetti/react": "npm:^1.0.0" "@parcel/watcher": "npm:^2.4.1" - "@storybook/addon-designs": "npm:^10.0.1" - "@storybook/addon-docs": "npm:^9.0.0" - "@storybook/icons": "npm:^1.4.0" - "@storybook/react-vite": "npm:^9.0.0" + "@storybook/addon-designs": "npm:^11.0.3" + "@storybook/addon-docs": "npm:^10.1.0" + "@storybook/icons": "npm:^2.0.1" + "@storybook/react-vite": "npm:^10.1.0" "@types/jsonfile": "npm:^6.1.1" "@types/node": "npm:^22.13.5" "@types/pluralize": "npm:^0.0.29" @@ -467,7 +467,7 @@ __metadata: "@vitest/coverage-v8": "npm:^3.0.8" auto: "npm:^11.0.5" boxen: "npm:^5.0.1" - chromatic: "npm:^13.3.3" + chromatic: "npm:^13.3.4" date-fns: "npm:^2.30.0" dedent: "npm:^0.7.0" eslint: "npm:^9.21.0" @@ -476,12 +476,12 @@ __metadata: eslint-plugin-prettier: "npm:^5.2.3" eslint-plugin-react-hooks: "npm:^5.0.0" eslint-plugin-simple-import-sort: "npm:^12.1.1" - eslint-plugin-storybook: "npm:^9.0.0" + eslint-plugin-storybook: "npm:^10.1.0" filesize: "npm:^10.0.12" graphql: "npm:^16.8.1" jsonfile: "npm:^6.1.0" msw: "npm:^2.0.0" - msw-storybook-addon: "npm:2.0.4" + msw-storybook-addon: "npm:^2.0.6" npm-run-all: "npm:^4.1.5" pluralize: "npm:^8.0.0" polished: "npm:^4.2.2" @@ -492,7 +492,7 @@ __metadata: react-dom: "npm:^18.3.1" react-joyride: "npm:^2.7.2" rimraf: "npm:^3.0.2" - storybook: "npm:^9.0.0" + storybook: "npm:^10.1.0" strip-ansi: "npm:^7.1.0" ts-dedent: "npm:^2.2.0" tsup: "npm:^6.6.3" @@ -506,7 +506,7 @@ __metadata: zod: "npm:^3.22.2" zx: "npm:^1.14.1" peerDependencies: - storybook: ^0.0.0-0 || ^9.0.0 || ^9.1.0-0 || ^9.2.0-0 || ^10.0.0-0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 + storybook: ^10.1.0 languageName: unknown linkType: soft @@ -579,6 +579,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/aix-ppc64@npm:0.27.0" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/android-arm64@npm:0.17.19" @@ -593,6 +600,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/android-arm64@npm:0.27.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/android-arm@npm:0.17.19" @@ -607,6 +621,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/android-arm@npm:0.27.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/android-x64@npm:0.17.19" @@ -621,6 +642,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/android-x64@npm:0.27.0" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/darwin-arm64@npm:0.17.19" @@ -635,6 +663,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/darwin-arm64@npm:0.27.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/darwin-x64@npm:0.17.19" @@ -649,6 +684,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/darwin-x64@npm:0.27.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/freebsd-arm64@npm:0.17.19" @@ -663,6 +705,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/freebsd-arm64@npm:0.27.0" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/freebsd-x64@npm:0.17.19" @@ -677,6 +726,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/freebsd-x64@npm:0.27.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-arm64@npm:0.17.19" @@ -691,6 +747,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/linux-arm64@npm:0.27.0" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-arm@npm:0.17.19" @@ -705,6 +768,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/linux-arm@npm:0.27.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-ia32@npm:0.17.19" @@ -719,6 +789,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/linux-ia32@npm:0.27.0" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-loong64@npm:0.17.19" @@ -733,6 +810,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/linux-loong64@npm:0.27.0" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-mips64el@npm:0.17.19" @@ -747,6 +831,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/linux-mips64el@npm:0.27.0" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-ppc64@npm:0.17.19" @@ -761,6 +852,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/linux-ppc64@npm:0.27.0" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-riscv64@npm:0.17.19" @@ -775,6 +873,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/linux-riscv64@npm:0.27.0" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-s390x@npm:0.17.19" @@ -789,6 +894,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/linux-s390x@npm:0.27.0" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/linux-x64@npm:0.17.19" @@ -803,6 +915,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/linux-x64@npm:0.27.0" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-arm64@npm:0.25.11": version: 0.25.11 resolution: "@esbuild/netbsd-arm64@npm:0.25.11" @@ -810,6 +929,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-arm64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/netbsd-arm64@npm:0.27.0" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/netbsd-x64@npm:0.17.19" @@ -824,6 +950,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/netbsd-x64@npm:0.27.0" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-arm64@npm:0.25.11": version: 0.25.11 resolution: "@esbuild/openbsd-arm64@npm:0.25.11" @@ -831,6 +964,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-arm64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/openbsd-arm64@npm:0.27.0" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/openbsd-x64@npm:0.17.19" @@ -845,6 +985,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/openbsd-x64@npm:0.27.0" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openharmony-arm64@npm:0.25.11": version: 0.25.11 resolution: "@esbuild/openharmony-arm64@npm:0.25.11" @@ -852,6 +999,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openharmony-arm64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/openharmony-arm64@npm:0.27.0" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/sunos-x64@npm:0.17.19" @@ -866,6 +1020,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/sunos-x64@npm:0.27.0" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/win32-arm64@npm:0.17.19" @@ -880,6 +1041,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/win32-arm64@npm:0.27.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/win32-ia32@npm:0.17.19" @@ -894,6 +1062,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/win32-ia32@npm:0.27.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.17.19": version: 0.17.19 resolution: "@esbuild/win32-x64@npm:0.17.19" @@ -908,6 +1083,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.27.0": + version: 0.27.0 + resolution: "@esbuild/win32-x64@npm:0.27.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.7.0, @eslint-community/eslint-utils@npm:^4.8.0": version: 4.9.0 resolution: "@eslint-community/eslint-utils@npm:4.9.0" @@ -2514,16 +2696,16 @@ __metadata: languageName: node linkType: hard -"@storybook/addon-designs@npm:^10.0.1": - version: 10.0.2 - resolution: "@storybook/addon-designs@npm:10.0.2" +"@storybook/addon-designs@npm:^11.0.3": + version: 11.0.3 + resolution: "@storybook/addon-designs@npm:11.0.3" dependencies: "@figspec/react": "npm:^1.0.0" peerDependencies: - "@storybook/addon-docs": ^0.0.0-0 || ^9.0.0 || ^9.1.0-0 + "@storybook/addon-docs": ^10.0.0 || ^10.0.0-0 || ^10.1.0-0 || ^10.2.0-0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^0.0.0-0 || ^9.0.0 || ^9.1.0-0 + storybook: ^10.0.0 || ^10.0.0-0 || ^10.1.0-0 || ^10.2.0-0 peerDependenciesMeta: "@storybook/addon-docs": optional: true @@ -2531,48 +2713,62 @@ __metadata: optional: true react-dom: optional: true - checksum: 10c0/8d02487ad337570eabc7962131ee933bf3995fe4700211dc734958d3a59c31f981214c0bc651b574b76f6e97abf259603bd277b30693b45eea2abf64899aab74 + checksum: 10c0/ef023c6997368e3ae6f493feb53e3c157bfe685a6ffa2128a21e87d98bfb4fc6c1d44d1580c007b8302e1727f9721f36d67b85f846f100177b8eeb2091c8c2fc languageName: node linkType: hard -"@storybook/addon-docs@npm:^9.0.0": - version: 9.1.16 - resolution: "@storybook/addon-docs@npm:9.1.16" +"@storybook/addon-docs@npm:^10.1.0": + version: 10.1.0 + resolution: "@storybook/addon-docs@npm:10.1.0" dependencies: "@mdx-js/react": "npm:^3.0.0" - "@storybook/csf-plugin": "npm:9.1.16" - "@storybook/icons": "npm:^1.4.0" - "@storybook/react-dom-shim": "npm:9.1.16" + "@storybook/csf-plugin": "npm:10.1.0" + "@storybook/icons": "npm:^2.0.0" + "@storybook/react-dom-shim": "npm:10.1.0" react: "npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" react-dom: "npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" ts-dedent: "npm:^2.0.0" peerDependencies: - storybook: ^9.1.16 - checksum: 10c0/a508a81275c6cba040b9111ef45c783eb7758bfb2a3086d30321a488d15b4d3af622ab1d4aa37684015a1ddacc6e25ca5c2082752ff1ffabded6dbbc14cd4a95 + storybook: ^10.1.0 + checksum: 10c0/3da5ed05f47263b1034963c5ed59966a63f26c1a50a571ed77c7315e9305e0ae9b181aac1cfbdfcee4aa48fe32c3e826bbf7a29610f943392a312e19b18c9e80 languageName: node linkType: hard -"@storybook/builder-vite@npm:9.1.16": - version: 9.1.16 - resolution: "@storybook/builder-vite@npm:9.1.16" +"@storybook/builder-vite@npm:10.1.0": + version: 10.1.0 + resolution: "@storybook/builder-vite@npm:10.1.0" dependencies: - "@storybook/csf-plugin": "npm:9.1.16" + "@storybook/csf-plugin": "npm:10.1.0" + "@vitest/mocker": "npm:3.2.4" ts-dedent: "npm:^2.0.0" peerDependencies: - storybook: ^9.1.16 + storybook: ^10.1.0 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - checksum: 10c0/e84a4cec4722a902d59d008ec87bebf9306af27e4b61dadaade2e3befb6c723d2eaebe7eeada533c1c39e38717554bdae9306dabe19c5a228454b10048c921b0 + checksum: 10c0/b565e2fcb05d7caeae24f0a7f95d496f4210222c098184c99d74fa1f2d34df18fced43e9e60bbab424d1d13741441f03a5cd3e6a92e21c8a5a7482b4af5acc3f languageName: node linkType: hard -"@storybook/csf-plugin@npm:9.1.16": - version: 9.1.16 - resolution: "@storybook/csf-plugin@npm:9.1.16" +"@storybook/csf-plugin@npm:10.1.0": + version: 10.1.0 + resolution: "@storybook/csf-plugin@npm:10.1.0" dependencies: - unplugin: "npm:^1.3.1" + unplugin: "npm:^2.3.5" peerDependencies: - storybook: ^9.1.16 - checksum: 10c0/23499c1eec9fbf75a2f6a4ce14fc0ca18b4242695c029c6bc6a8159a44446da47dac453b8e01a6a824355a4be6134f3c174aa8d519a7d9f3216df2643f3860f9 + esbuild: "*" + rollup: "*" + storybook: ^10.1.0 + vite: "*" + webpack: "*" + peerDependenciesMeta: + esbuild: + optional: true + rollup: + optional: true + vite: + optional: true + webpack: + optional: true + checksum: 10c0/6da01fc2d5fcfd25e4c31096144bdc451423f8d358245b8e8cbb955669df9dbc501f7068453a63d67be5453f8e70b9773c954e1c3f9faa7bb27b18436dcaed3f languageName: node linkType: hard @@ -2583,64 +2779,65 @@ __metadata: languageName: node linkType: hard -"@storybook/icons@npm:^1.4.0": - version: 1.6.0 - resolution: "@storybook/icons@npm:1.6.0" +"@storybook/icons@npm:^2.0.0, @storybook/icons@npm:^2.0.1": + version: 2.0.1 + resolution: "@storybook/icons@npm:2.0.1" peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - checksum: 10c0/bbec9201a78a730195f9cf377b15856dc414a54d04e30d16c379d062425cc617bfd0d6586ba1716012cfbdab461f0c9693a6a52920f9bd09c7b4291fb116f59c + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/df2bbf1a5b50f12ab1bf78cae6de4dbf7c49df0e3a5f845553b51b20adbe8386a09fd172ea60342379f9284bb528cba2d0e2659cae6eb8d015cf92c8b32f1222 languageName: node linkType: hard -"@storybook/react-dom-shim@npm:9.1.16": - version: 9.1.16 - resolution: "@storybook/react-dom-shim@npm:9.1.16" +"@storybook/react-dom-shim@npm:10.1.0": + version: 10.1.0 + resolution: "@storybook/react-dom-shim@npm:10.1.0" peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^9.1.16 - checksum: 10c0/c46f540e9d9f905d1475daf73eee49b62ae4034c6911b175d6b8c51d622edbb302ec5156a91a5f807b6546e1965f02ef4e193a8f787c9de955d2691af31966f8 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.1.0 + checksum: 10c0/5545e858de3023426182a9a9e2bcd4dca2441366234826ea2cc70516eccd72a5188a572e03322517c84d54eff806c3be74ae1557ef8d85a013d4a68c20a05f18 languageName: node linkType: hard -"@storybook/react-vite@npm:^9.0.0": - version: 9.1.16 - resolution: "@storybook/react-vite@npm:9.1.16" +"@storybook/react-vite@npm:^10.1.0": + version: 10.1.0 + resolution: "@storybook/react-vite@npm:10.1.0" dependencies: "@joshwooding/vite-plugin-react-docgen-typescript": "npm:0.6.1" "@rollup/pluginutils": "npm:^5.0.2" - "@storybook/builder-vite": "npm:9.1.16" - "@storybook/react": "npm:9.1.16" - find-up: "npm:^7.0.0" + "@storybook/builder-vite": "npm:10.1.0" + "@storybook/react": "npm:10.1.0" + empathic: "npm:^2.0.0" magic-string: "npm:^0.30.0" react-docgen: "npm:^8.0.0" resolve: "npm:^1.22.8" tsconfig-paths: "npm:^4.2.0" peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^9.1.16 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.1.0 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - checksum: 10c0/f4f618a09f0541e1fb7e37dd72101055d3aa24e62d8cff32a9226b7c1de67697957e7c49b4aef154d321591311bf5244ddb7f7e9a248c6d8708dbe2fdf76b36c + checksum: 10c0/d61b40520afd71881710d8c3b7a1590ba9fa67fee236c2dc58a52d1e31f33c08fdd6cfded28ca8c484aedfb4c583cf243cac8d99fec045f3a8de6f3652ee0eac languageName: node linkType: hard -"@storybook/react@npm:9.1.16": - version: 9.1.16 - resolution: "@storybook/react@npm:9.1.16" +"@storybook/react@npm:10.1.0": + version: 10.1.0 + resolution: "@storybook/react@npm:10.1.0" dependencies: "@storybook/global": "npm:^5.0.0" - "@storybook/react-dom-shim": "npm:9.1.16" + "@storybook/react-dom-shim": "npm:10.1.0" + react-docgen: "npm:^8.0.2" peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^9.1.16 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.1.0 typescript: ">= 4.9.x" peerDependenciesMeta: typescript: optional: true - checksum: 10c0/45c02a726d91b80574c81277266230b818ae03aa34e29c832200c44f49f6e7d91991a859ec803accc404c5b06ab3f70a786075d02437eb7f336145e5c4cda2a8 + checksum: 10c0/2d05b1768dcaa69b53d7ccf8cc1273527c3b776b79c0246783a6e9378c5b7376660fc99908d0c3c9ab4ebeed9a7f6ff6085dee3157593c401ac0e8a644235d95 languageName: node linkType: hard @@ -3281,7 +3478,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.11.0, acorn@npm:^8.14.0, acorn@npm:^8.15.0, acorn@npm:^8.4.1": +"acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.4.1": version: 8.15.0 resolution: "acorn@npm:8.15.0" bin: @@ -3629,15 +3826,6 @@ __metadata: languageName: node linkType: hard -"better-opn@npm:^3.0.2": - version: 3.0.2 - resolution: "better-opn@npm:3.0.2" - dependencies: - open: "npm:^8.0.4" - checksum: 10c0/911ef25d44da75aabfd2444ce7a4294a8000ebcac73068c04a60298b0f7c7506b60421aa4cd02ac82502fb42baaff7e4892234b51e6923eded44c5a11185f2f5 - languageName: node - linkType: hard - "binary-extensions@npm:^2.0.0": version: 2.3.0 resolution: "binary-extensions@npm:2.3.0" @@ -3972,9 +4160,9 @@ __metadata: languageName: node linkType: hard -"chromatic@npm:^13.3.3": - version: 13.3.3 - resolution: "chromatic@npm:13.3.3" +"chromatic@npm:^13.3.4": + version: 13.3.4 + resolution: "chromatic@npm:13.3.4" peerDependencies: "@chromatic-com/cypress": ^0.*.* || ^1.0.0 "@chromatic-com/playwright": ^0.*.* || ^1.0.0 @@ -3987,7 +4175,7 @@ __metadata: chroma: dist/bin.js chromatic: dist/bin.js chromatic-cli: dist/bin.js - checksum: 10c0/6fc54df030113d91ef00a2050f5cb13ca182b355dae2c29cdd326fac6cf21d8ddc2cd93dc3f5db04379b7769d4df8e3ea5f18c3642e9e3a48545565f992a838c + checksum: 10c0/1800c1640dbc168b621daeca5895698cb5a0a1def50b9d1ada5ea99ce242bf1f70d15065460948b168eedea1f56422553184f4cce1d01a7816f32c60054d704d languageName: node linkType: hard @@ -4427,13 +4615,6 @@ __metadata: languageName: node linkType: hard -"define-lazy-prop@npm:^2.0.0": - version: 2.0.0 - resolution: "define-lazy-prop@npm:2.0.0" - checksum: 10c0/db6c63864a9d3b7dc9def55d52764968a5af296de87c1b2cc71d8be8142e445208071953649e0386a8cc37cfcf9a2067a47207f1eb9ff250c2a269658fdae422 - languageName: node - linkType: hard - "define-properties@npm:^1.2.1": version: 1.2.1 resolution: "define-properties@npm:1.2.1" @@ -4579,6 +4760,13 @@ __metadata: languageName: node linkType: hard +"empathic@npm:^2.0.0": + version: 2.0.0 + resolution: "empathic@npm:2.0.0" + checksum: 10c0/7d3b14b04a93b35c47bcc950467ec914fd241cd9acc0269b0ea160f13026ec110f520c90fae64720fde72cc1757b57f3f292fb606617b7fccac1f4d008a76506 + languageName: node + linkType: hard + "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -4758,17 +4946,6 @@ __metadata: languageName: node linkType: hard -"esbuild-register@npm:^3.5.0": - version: 3.6.0 - resolution: "esbuild-register@npm:3.6.0" - dependencies: - debug: "npm:^4.3.4" - peerDependencies: - esbuild: ">=0.12 <1" - checksum: 10c0/77193b7ca32ba9f81b35ddf3d3d0138efb0b1429d71b39480cfee932e1189dd2e492bd32bf04a4d0bc3adfbc7ec7381ceb5ffd06efe35f3e70904f1f686566d5 - languageName: node - linkType: hard - "esbuild@npm:^0.17.6": version: 0.17.19 resolution: "esbuild@npm:0.17.19" @@ -4846,7 +5023,96 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0, esbuild@npm:^0.25.0": +"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0": + version: 0.27.0 + resolution: "esbuild@npm:0.27.0" + dependencies: + "@esbuild/aix-ppc64": "npm:0.27.0" + "@esbuild/android-arm": "npm:0.27.0" + "@esbuild/android-arm64": "npm:0.27.0" + "@esbuild/android-x64": "npm:0.27.0" + "@esbuild/darwin-arm64": "npm:0.27.0" + "@esbuild/darwin-x64": "npm:0.27.0" + "@esbuild/freebsd-arm64": "npm:0.27.0" + "@esbuild/freebsd-x64": "npm:0.27.0" + "@esbuild/linux-arm": "npm:0.27.0" + "@esbuild/linux-arm64": "npm:0.27.0" + "@esbuild/linux-ia32": "npm:0.27.0" + "@esbuild/linux-loong64": "npm:0.27.0" + "@esbuild/linux-mips64el": "npm:0.27.0" + "@esbuild/linux-ppc64": "npm:0.27.0" + "@esbuild/linux-riscv64": "npm:0.27.0" + "@esbuild/linux-s390x": "npm:0.27.0" + "@esbuild/linux-x64": "npm:0.27.0" + "@esbuild/netbsd-arm64": "npm:0.27.0" + "@esbuild/netbsd-x64": "npm:0.27.0" + "@esbuild/openbsd-arm64": "npm:0.27.0" + "@esbuild/openbsd-x64": "npm:0.27.0" + "@esbuild/openharmony-arm64": "npm:0.27.0" + "@esbuild/sunos-x64": "npm:0.27.0" + "@esbuild/win32-arm64": "npm:0.27.0" + "@esbuild/win32-ia32": "npm:0.27.0" + "@esbuild/win32-x64": "npm:0.27.0" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/a3a1deec285337b7dfe25cbb9aa8765d27a0192b610a8477a39bf5bd907a6bdb75e98898b61fb4337114cfadb13163bd95977db14e241373115f548e235b40a2 + languageName: node + linkType: hard + +"esbuild@npm:^0.25.0": version: 0.25.11 resolution: "esbuild@npm:0.25.11" dependencies: @@ -5023,15 +5289,15 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-storybook@npm:^9.0.0": - version: 9.1.16 - resolution: "eslint-plugin-storybook@npm:9.1.16" +"eslint-plugin-storybook@npm:^10.1.0": + version: 10.1.0 + resolution: "eslint-plugin-storybook@npm:10.1.0" dependencies: "@typescript-eslint/utils": "npm:^8.8.1" peerDependencies: eslint: ">=8" - storybook: ^9.1.16 - checksum: 10c0/b5637962434ae777449ca9804452bf5c42cf5dcb1b62cc3c9d5e37e10f5728dd3d965b0aff780ef112844bd2f086ef81e8c5903106797334829e521a186a0937 + storybook: ^10.1.0 + checksum: 10c0/25fdfc21cde3f07c6d0a84690a434cb981808e6fdbd811b7c96b73b7aedaae7bbf1e9a20f009ed109803c408aa45de73d93049acc0e0e363a271a94f7074cf7b languageName: node linkType: hard @@ -5389,17 +5655,6 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^7.0.0": - version: 7.0.0 - resolution: "find-up@npm:7.0.0" - dependencies: - locate-path: "npm:^7.2.0" - path-exists: "npm:^5.0.0" - unicorn-magic: "npm:^0.1.0" - checksum: 10c0/e6ee3e6154560bc0ab3bc3b7d1348b31513f9bdf49a5dd2e952495427d559fa48cdf33953e85a309a323898b43fa1bfbc8b80c880dfc16068384783034030008 - languageName: node - linkType: hard - "flat-cache@npm:^4.0.0": version: 4.0.1 resolution: "flat-cache@npm:4.0.1" @@ -6246,15 +6501,6 @@ __metadata: languageName: node linkType: hard -"is-docker@npm:^2.0.0, is-docker@npm:^2.1.1": - version: 2.2.1 - resolution: "is-docker@npm:2.2.1" - bin: - is-docker: cli.js - checksum: 10c0/e828365958d155f90c409cdbe958f64051d99e8aedc2c8c4cd7c89dcf35329daed42f7b99346f7828df013e27deb8f721cf9408ba878c76eb9e8290235fbcdcc - languageName: node - linkType: hard - "is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" @@ -6507,15 +6753,6 @@ __metadata: languageName: node linkType: hard -"is-wsl@npm:^2.2.0": - version: 2.2.0 - resolution: "is-wsl@npm:2.2.0" - dependencies: - is-docker: "npm:^2.0.0" - checksum: 10c0/a6fa2d370d21be487c0165c7a440d567274fbba1a817f2f0bfa41cc5e3af25041d84267baa22df66696956038a43973e72fca117918c91431920bdef490fa25e - languageName: node - linkType: hard - "isarray@npm:^2.0.5": version: 2.0.5 resolution: "isarray@npm:2.0.5" @@ -6868,15 +7105,6 @@ __metadata: languageName: node linkType: hard -"locate-path@npm:^7.2.0": - version: 7.2.0 - resolution: "locate-path@npm:7.2.0" - dependencies: - p-locate: "npm:^6.0.0" - checksum: 10c0/139e8a7fe11cfbd7f20db03923cacfa5db9e14fa14887ea121345597472b4a63c1a42a8a5187defeeff6acf98fd568da7382aa39682d38f0af27433953a97751 - languageName: node - linkType: hard - "lodash.camelcase@npm:^4.3.0": version: 4.3.0 resolution: "lodash.camelcase@npm:4.3.0" @@ -7257,14 +7485,14 @@ __metadata: languageName: node linkType: hard -"msw-storybook-addon@npm:2.0.4": - version: 2.0.4 - resolution: "msw-storybook-addon@npm:2.0.4" +"msw-storybook-addon@npm:^2.0.6": + version: 2.0.6 + resolution: "msw-storybook-addon@npm:2.0.6" dependencies: is-node-process: "npm:^1.0.1" peerDependencies: msw: ^2.0.0 - checksum: 10c0/91cd85b0d6e3bdf8cc4f519b29da644d4df324a3fc6753a98b472488986aee888dfe4fc6a216a41057b01d10899e1e3a16ad253f63d7ae06f3dc3560fe5e561d + checksum: 10c0/e108e8bf247326f5475c1914fdcfaaa6603f1e46f0920ed40d1f1725e2c2f62698658ff8b7d75aee0a0ea1fc0a9714fd6caaf5278426b6dcefd5da381f462c8e languageName: node linkType: hard @@ -7598,17 +7826,6 @@ __metadata: languageName: node linkType: hard -"open@npm:^8.0.4": - version: 8.4.2 - resolution: "open@npm:8.4.2" - dependencies: - define-lazy-prop: "npm:^2.0.0" - is-docker: "npm:^2.1.1" - is-wsl: "npm:^2.2.0" - checksum: 10c0/bb6b3a58401dacdb0aad14360626faf3fb7fba4b77816b373495988b724fb48941cad80c1b65d62bb31a17609b2cd91c41a181602caea597ca80dfbcc27e84c9 - languageName: node - linkType: hard - "optionator@npm:^0.9.3": version: 0.9.4 resolution: "optionator@npm:0.9.4" @@ -7683,15 +7900,6 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^4.0.0": - version: 4.0.0 - resolution: "p-limit@npm:4.0.0" - dependencies: - yocto-queue: "npm:^1.0.0" - checksum: 10c0/a56af34a77f8df2ff61ddfb29431044557fcbcb7642d5a3233143ebba805fc7306ac1d448de724352861cb99de934bc9ab74f0d16fe6a5460bdbdf938de875ad - languageName: node - linkType: hard - "p-locate@npm:^2.0.0": version: 2.0.0 resolution: "p-locate@npm:2.0.0" @@ -7710,15 +7918,6 @@ __metadata: languageName: node linkType: hard -"p-locate@npm:^6.0.0": - version: 6.0.0 - resolution: "p-locate@npm:6.0.0" - dependencies: - p-limit: "npm:^4.0.0" - checksum: 10c0/d72fa2f41adce59c198270aa4d3c832536c87a1806e0f69dffb7c1a7ca998fb053915ca833d90f166a8c082d3859eabfed95f01698a3214c20df6bb8de046312 - languageName: node - linkType: hard - "p-map@npm:^4.0.0": version: 4.0.0 resolution: "p-map@npm:4.0.0" @@ -7860,13 +8059,6 @@ __metadata: languageName: node linkType: hard -"path-exists@npm:^5.0.0": - version: 5.0.0 - resolution: "path-exists@npm:5.0.0" - checksum: 10c0/b170f3060b31604cde93eefdb7392b89d832dfbc1bed717c9718cbe0f230c1669b7e75f87e19901da2250b84d092989a0f9e44d2ef41deb09aa3ad28e691a40a - languageName: node - linkType: hard - "path-is-absolute@npm:^1.0.0": version: 1.0.1 resolution: "path-is-absolute@npm:1.0.1" @@ -8189,7 +8381,7 @@ __metadata: languageName: node linkType: hard -"react-docgen@npm:^8.0.0": +"react-docgen@npm:^8.0.0, react-docgen@npm:^8.0.2": version: 8.0.2 resolution: "react-docgen@npm:8.0.2" dependencies: @@ -9182,21 +9374,20 @@ __metadata: languageName: node linkType: hard -"storybook@npm:^9.0.0": - version: 9.1.16 - resolution: "storybook@npm:9.1.16" +"storybook@npm:^10.1.0": + version: 10.1.0 + resolution: "storybook@npm:10.1.0" dependencies: "@storybook/global": "npm:^5.0.0" + "@storybook/icons": "npm:^2.0.0" "@testing-library/jest-dom": "npm:^6.6.3" "@testing-library/user-event": "npm:^14.6.1" "@vitest/expect": "npm:3.2.4" - "@vitest/mocker": "npm:3.2.4" "@vitest/spy": "npm:3.2.4" - better-opn: "npm:^3.0.2" - esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0" - esbuild-register: "npm:^3.5.0" + esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0" recast: "npm:^0.23.5" semver: "npm:^7.6.2" + use-sync-external-store: "npm:^1.5.0" ws: "npm:^8.18.0" peerDependencies: prettier: ^2 || ^3 @@ -9204,8 +9395,8 @@ __metadata: prettier: optional: true bin: - storybook: ./bin/index.cjs - checksum: 10c0/4265c5b764effbda608aaf14ce930cce69f5aca9433e54d785387e8c7ad8f3139fbd91264494e535927b21b065e921ab4a81539df38f222fb8878cb249cf2c26 + storybook: ./dist/bin/dispatcher.js + checksum: 10c0/a8a73cf033898b6d2c59f936a2089c62ecc10b494cb4e0a7d459e27bf9f45c60971f80a14370eda29155e31db84a0782820c6404af22641134c68a0e62e1ae38 languageName: node linkType: hard @@ -10010,13 +10201,6 @@ __metadata: languageName: node linkType: hard -"unicorn-magic@npm:^0.1.0": - version: 0.1.0 - resolution: "unicorn-magic@npm:0.1.0" - checksum: 10c0/e4ed0de05b0a05e735c7d8a2930881e5efcfc3ec897204d5d33e7e6247f4c31eac92e383a15d9a6bccb7319b4271ee4bea946e211bf14951fec6ff2cbbb66a92 - languageName: node - linkType: hard - "unique-filename@npm:^4.0.0": version: 4.0.0 resolution: "unique-filename@npm:4.0.0" @@ -10058,13 +10242,15 @@ __metadata: languageName: node linkType: hard -"unplugin@npm:^1.3.1": - version: 1.16.1 - resolution: "unplugin@npm:1.16.1" +"unplugin@npm:^2.3.5": + version: 2.3.11 + resolution: "unplugin@npm:2.3.11" dependencies: - acorn: "npm:^8.14.0" + "@jridgewell/remapping": "npm:^2.3.5" + acorn: "npm:^8.15.0" + picomatch: "npm:^4.0.3" webpack-virtual-modules: "npm:^0.6.2" - checksum: 10c0/dd5f8c5727d0135847da73cf03fb199107f1acf458167034886fda3405737dab871ad3926431b4f70e1e82cdac482ac1383cea4019d782a68515c8e3e611b6cc + checksum: 10c0/273c1eab0eca4470c7317428689295c31dbe8ab0b306504de9f03cd20c156debb4131bef24b27ac615862958c5dd950a3951d26c0723ea774652ab3624149cff languageName: node linkType: hard @@ -10143,6 +10329,15 @@ __metadata: languageName: node linkType: hard +"use-sync-external-store@npm:^1.5.0": + version: 1.6.0 + resolution: "use-sync-external-store@npm:1.6.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/35e1179f872a53227bdf8a827f7911da4c37c0f4091c29b76b1e32473d1670ebe7bcd880b808b7549ba9a5605c233350f800ffab963ee4a4ee346ee983b6019b + languageName: node + linkType: hard + "user-home@npm:^2.0.0": version: 2.0.0 resolution: "user-home@npm:2.0.0" @@ -10717,13 +10912,6 @@ __metadata: languageName: node linkType: hard -"yocto-queue@npm:^1.0.0": - version: 1.2.1 - resolution: "yocto-queue@npm:1.2.1" - checksum: 10c0/5762caa3d0b421f4bdb7a1926b2ae2189fc6e4a14469258f183600028eb16db3e9e0306f46e8ebf5a52ff4b81a881f22637afefbef5399d6ad440824e9b27f9f - languageName: node - linkType: hard - "yoctocolors-cjs@npm:^2.1.2": version: 2.1.3 resolution: "yoctocolors-cjs@npm:2.1.3"