From c733d0bb0771b91cf3127e68d80a8875caefd51a Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Wed, 13 Mar 2024 15:31:47 +0000 Subject: [PATCH 1/8] Start replacing icons from notifications --- code/lib/manager-api/package.json | 1 + .../src/modules/{whatsnew.ts => whatsnew.tsx} | 4 +- code/lib/types/src/modules/api.ts | 7 +-- .../NotificationItem.stories.tsx | 49 ++++++------------- .../notifications/NotificationItem.tsx | 20 ++------ 5 files changed, 26 insertions(+), 55 deletions(-) rename code/lib/manager-api/src/modules/{whatsnew.ts => whatsnew.tsx} (96%) diff --git a/code/lib/manager-api/package.json b/code/lib/manager-api/package.json index 8832ff4bd12f..e74feebf8a7f 100644 --- a/code/lib/manager-api/package.json +++ b/code/lib/manager-api/package.json @@ -49,6 +49,7 @@ "@storybook/core-events": "workspace:*", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", + "@storybook/icons": "workspace:*", "@storybook/router": "workspace:*", "@storybook/theming": "workspace:*", "@storybook/types": "workspace:*", diff --git a/code/lib/manager-api/src/modules/whatsnew.ts b/code/lib/manager-api/src/modules/whatsnew.tsx similarity index 96% rename from code/lib/manager-api/src/modules/whatsnew.ts rename to code/lib/manager-api/src/modules/whatsnew.tsx index 8f465325d503..abdda88d6b10 100644 --- a/code/lib/manager-api/src/modules/whatsnew.ts +++ b/code/lib/manager-api/src/modules/whatsnew.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { global } from '@storybook/global'; import type { WhatsNewCache, WhatsNewData } from '@storybook/core-events'; import { @@ -7,6 +8,7 @@ import { TOGGLE_WHATS_NEW_NOTIFICATIONS, } from '@storybook/core-events'; import type { ModuleFn } from '../lib/types'; +import { StorybookIcon } from '@storybook/icons'; export type SubState = { whatsNewData?: WhatsNewData; @@ -95,7 +97,7 @@ export const init: ModuleFn = ({ fullAPI, store, provider }) => { headline: whatsNewData.title, subHeadline: "Learn what's new in Storybook", }, - icon: { name: 'storybook' }, + icon: , onClear({ dismissed }: any) { if (dismissed) { setWhatsNewCache({ lastDismissedPost: whatsNewData.url }); diff --git a/code/lib/types/src/modules/api.ts b/code/lib/types/src/modules/api.ts index cee23ca903ee..0a690f551f60 100644 --- a/code/lib/types/src/modules/api.ts +++ b/code/lib/types/src/modules/api.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import type { ReactElement } from 'react'; +import type { ReactElement, ReactNode } from 'react'; import type { RenderData } from '../../../router/src/types'; import type { Channel } from '../../../channels/src'; import type { ThemeVars } from '../../../theming/src/types'; @@ -127,10 +127,7 @@ export interface API_Notification { headline: string; subHeadline?: string | any; }; - icon?: { - name: string; - color?: string; - }; + icon?: ReactNode; onClear?: (options: OnClearOptions) => void; } diff --git a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx index 87755129055e..3850cd9cd5d9 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx @@ -2,6 +2,11 @@ import React from 'react'; import { LocationProvider } from '@storybook/router'; import type { Meta, StoryObj } from '@storybook/react'; import NotificationItem from './NotificationItem'; +import { + AccessibilityIcon as AccessibilityIconIcon, + BookIcon as BookIconIcon, + FaceHappyIcon, +} from '@storybook/icons'; const meta = { component: NotificationItem, @@ -78,10 +83,7 @@ export const LinkIconWithColor: Story = { content: { headline: 'Storybook with a smile!', }, - icon: { - name: 'facehappy', - color: 'hotpink', - }, + icon: , link: '/some/path', }, }, @@ -97,10 +99,7 @@ export const LinkIconWithColorSubHeadline: Story = { headline: 'Storybook X.X is available with a smile! Download now ยป', subHeadline: 'This link also has a sub headline', }, - icon: { - name: 'facehappy', - color: 'tomato', - }, + icon: , link: '/some/path', }, }, @@ -115,9 +114,7 @@ export const BookIcon: Story = { content: { headline: 'Storybook has a book icon!', }, - icon: { - name: 'book', - }, + icon: , link: '/some/path', }, }, @@ -133,9 +130,7 @@ export const StrongSubHeadline: Story = { headline: 'Storybook has a book icon!', subHeadline: Strong subHeadline, }, - icon: { - name: 'book', - }, + icon: , link: '/some/path', }, }, @@ -155,9 +150,7 @@ export const StrongEmphasizedSubHeadline: Story = { ), }, - icon: { - name: 'book', - }, + icon: , link: '/some/path', }, }, @@ -173,9 +166,7 @@ export const BookIconSubHeadline: Story = { headline: 'Storybook has a book icon!', subHeadline: 'Find out more!', }, - icon: { - name: 'book', - }, + icon: , link: '/some/path', }, }, @@ -192,9 +183,7 @@ export const BookIconLongSubHeadline: Story = { subHeadline: 'Find out more! by clicking on on buttons and downloading some applications. Find out more! by clicking on buttons and downloading some applications', }, - icon: { - name: 'book', - }, + icon: , link: '/some/path', }, }, @@ -210,9 +199,7 @@ export const AccessibilityIcon: Story = { headline: 'Storybook has a accessibility icon!', subHeadline: 'It is here!', }, - icon: { - name: 'accessibility', - }, + icon: , link: '/some/path', }, }, @@ -228,10 +215,7 @@ export const AccessibilityGoldIcon: Story = { headline: 'Accessibility icon!', subHeadline: 'It is gold!', }, - icon: { - name: 'accessibility', - color: 'gold', - }, + icon: , link: '/some/path', }, }, @@ -246,10 +230,7 @@ export const AccessibilityGoldIconLongHeadLineNoSubHeadline: Story = { content: { headline: 'Storybook notifications has a accessibility icon it can be any color!', }, - icon: { - name: 'accessibility', - color: 'gold', - }, + icon: , link: '/some/path', }, }, diff --git a/code/ui/manager/src/components/notifications/NotificationItem.tsx b/code/ui/manager/src/components/notifications/NotificationItem.tsx index 3131d2116cbe..2928f3bcd152 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.tsx @@ -2,8 +2,8 @@ import type { FC, SyntheticEvent } from 'react'; import React from 'react'; import { type State } from '@storybook/manager-api'; import { Link } from '@storybook/router'; -import { styled, useTheme } from '@storybook/theming'; -import { Icons, IconButton, type IconsProps } from '@storybook/components'; +import { styled } from '@storybook/theming'; +import { IconButton } from '@storybook/components'; import { transparentize } from 'polished'; import { CloseAltIcon } from '@storybook/icons'; @@ -47,10 +47,11 @@ const NotificationIconWrapper = styled.div(() => ({ alignItems: 'center', })); -const NotificationTextWrapper = styled.div(() => ({ +const NotificationTextWrapper = styled.div(({ theme }) => ({ width: '100%', display: 'flex', flexDirection: 'column', + color: theme.base === 'dark' ? theme.color.mediumdark : theme.color.mediumlight, })); const Headline = styled.div<{ hasIcon: boolean }>(({ theme, hasIcon }) => ({ @@ -76,20 +77,9 @@ const ItemContent: FC> = ({ icon, content: { headline, subHeadline }, }) => { - const theme = useTheme(); - const defaultColor = theme.base === 'dark' ? theme.color.mediumdark : theme.color.mediumlight; return ( <> - {!icon || ( - - - - )} + {!icon || {icon}} {headline} From bf048c9fa4a37eb50b167c88f9ffe73cfd4707fc Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Wed, 13 Mar 2024 15:49:26 +0000 Subject: [PATCH 2/8] Add Storybook icons --- code/lib/manager-api/package.json | 2 +- code/yarn.lock | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/lib/manager-api/package.json b/code/lib/manager-api/package.json index e74feebf8a7f..fcba902bf424 100644 --- a/code/lib/manager-api/package.json +++ b/code/lib/manager-api/package.json @@ -49,7 +49,7 @@ "@storybook/core-events": "workspace:*", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/icons": "workspace:*", + "@storybook/icons": "^1.2.5", "@storybook/router": "workspace:*", "@storybook/theming": "workspace:*", "@storybook/types": "workspace:*", diff --git a/code/yarn.lock b/code/yarn.lock index 2a8cf58a01de..2fb0fb333137 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -5970,6 +5970,7 @@ __metadata: "@storybook/core-events": "workspace:*" "@storybook/csf": "npm:^0.1.2" "@storybook/global": "npm:^5.0.0" + "@storybook/icons": "npm:^1.2.5" "@storybook/router": "workspace:*" "@storybook/theming": "workspace:*" "@storybook/types": "workspace:*" From 459d18e842ef91f6ddea8386dbc79d4cada40026 Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Wed, 13 Mar 2024 16:38:02 +0000 Subject: [PATCH 3/8] Made it backward compatible --- code/lib/types/src/modules/api.ts | 7 ++++++- .../notifications/NotificationItem.stories.tsx | 18 ++++++++++++++++++ .../notifications/NotificationItem.tsx | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/code/lib/types/src/modules/api.ts b/code/lib/types/src/modules/api.ts index 0a690f551f60..c45e1e89cb81 100644 --- a/code/lib/types/src/modules/api.ts +++ b/code/lib/types/src/modules/api.ts @@ -127,7 +127,12 @@ export interface API_Notification { headline: string; subHeadline?: string | any; }; - icon?: ReactNode; + icon?: + | ReactNode + | { + name: string; + color?: string; + }; onClear?: (options: OnClearOptions) => void; } diff --git a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx index 3850cd9cd5d9..5d58559b465b 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx @@ -235,3 +235,21 @@ export const AccessibilityGoldIconLongHeadLineNoSubHeadline: Story = { }, }, }; + +export const WithOldIconFormat: Story = { + args: { + ...Simple.args, + notification: { + id: '13', + onClear, + content: { + headline: 'Storybook notifications has a accessibility icon it can be any color!', + }, + icon: { + name: 'accessibility', + color: 'gold', + }, + link: '/some/path', + }, + }, +}; diff --git a/code/ui/manager/src/components/notifications/NotificationItem.tsx b/code/ui/manager/src/components/notifications/NotificationItem.tsx index 2928f3bcd152..0b4728b2950a 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.tsx @@ -79,7 +79,7 @@ const ItemContent: FC> = ({ }) => { return ( <> - {!icon || {icon}} + {React.isValidElement(icon) && {icon}} {headline} From 94017eb748d5e8c2856ba23d77f7c27b5086c1a8 Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Wed, 13 Mar 2024 16:43:14 +0000 Subject: [PATCH 4/8] Improve types --- code/lib/types/src/modules/api.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/code/lib/types/src/modules/api.ts b/code/lib/types/src/modules/api.ts index c45e1e89cb81..657665ffc15a 100644 --- a/code/lib/types/src/modules/api.ts +++ b/code/lib/types/src/modules/api.ts @@ -120,6 +120,13 @@ interface OnClearOptions { dismissed: boolean; } +/** + * @deprecated Use ReactNode for the icon instead. + */ +interface OldIconType { + name: string; + color?: string; +} export interface API_Notification { id: string; link: string; @@ -127,12 +134,7 @@ export interface API_Notification { headline: string; subHeadline?: string | any; }; - icon?: - | ReactNode - | { - name: string; - color?: string; - }; + icon?: OldIconType | React.ReactNode; onClear?: (options: OnClearOptions) => void; } From 58993f63ba5e6f2a6b21dec8ed89f75464ead5ca Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Wed, 13 Mar 2024 16:44:54 +0000 Subject: [PATCH 5/8] Update api.ts --- code/lib/types/src/modules/api.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/lib/types/src/modules/api.ts b/code/lib/types/src/modules/api.ts index 657665ffc15a..ad8c0d838f11 100644 --- a/code/lib/types/src/modules/api.ts +++ b/code/lib/types/src/modules/api.ts @@ -123,7 +123,7 @@ interface OnClearOptions { /** * @deprecated Use ReactNode for the icon instead. */ -interface OldIconType { +interface DeprecatedIconType { name: string; color?: string; } @@ -134,7 +134,7 @@ export interface API_Notification { headline: string; subHeadline?: string | any; }; - icon?: OldIconType | React.ReactNode; + icon?: React.ReactNode | DeprecatedIconType; onClear?: (options: OnClearOptions) => void; } From 63b12f4baf6e5d50e36e89933b294d26dc493d5c Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Wed, 13 Mar 2024 17:50:18 +0000 Subject: [PATCH 6/8] Improve backward compatibility --- code/lib/types/src/modules/api.ts | 1 + .../notifications/NotificationItem.tsx | 24 ++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/code/lib/types/src/modules/api.ts b/code/lib/types/src/modules/api.ts index ad8c0d838f11..98e0e70a25e6 100644 --- a/code/lib/types/src/modules/api.ts +++ b/code/lib/types/src/modules/api.ts @@ -122,6 +122,7 @@ interface OnClearOptions { /** * @deprecated Use ReactNode for the icon instead. + * @see https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#icons-is-deprecated */ interface DeprecatedIconType { name: string; diff --git a/code/ui/manager/src/components/notifications/NotificationItem.tsx b/code/ui/manager/src/components/notifications/NotificationItem.tsx index 0b4728b2950a..0028f87749cf 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.tsx @@ -2,8 +2,9 @@ import type { FC, SyntheticEvent } from 'react'; import React from 'react'; import { type State } from '@storybook/manager-api'; import { Link } from '@storybook/router'; -import { styled } from '@storybook/theming'; -import { IconButton } from '@storybook/components'; +import { styled, useTheme } from '@storybook/theming'; +import type { IconsProps } from '@storybook/components'; +import { IconButton, Icons } from '@storybook/components'; import { transparentize } from 'polished'; import { CloseAltIcon } from '@storybook/icons'; @@ -45,6 +46,11 @@ const NotificationIconWrapper = styled.div(() => ({ display: 'flex', marginRight: 10, alignItems: 'center', + + svg: { + width: 16, + height: 16, + }, })); const NotificationTextWrapper = styled.div(({ theme }) => ({ @@ -77,9 +83,21 @@ const ItemContent: FC> = ({ icon, content: { headline, subHeadline }, }) => { + const theme = useTheme(); + const defaultColor = theme.base === 'dark' ? theme.color.mediumdark : theme.color.mediumlight; + return ( <> - {React.isValidElement(icon) && {icon}} + {!icon || ( + + {React.isValidElement(icon) + ? icon + : typeof icon === 'object' && + 'name' in icon && ( + + )} + + )} {headline} From 87e6c29724b8f4e0ea0788d89ff6968ad3ad9e18 Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Wed, 13 Mar 2024 17:51:16 +0000 Subject: [PATCH 7/8] Update api.ts --- code/lib/types/src/modules/api.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/code/lib/types/src/modules/api.ts b/code/lib/types/src/modules/api.ts index 98e0e70a25e6..cfff86e68620 100644 --- a/code/lib/types/src/modules/api.ts +++ b/code/lib/types/src/modules/api.ts @@ -135,6 +135,7 @@ export interface API_Notification { headline: string; subHeadline?: string | any; }; + // TODO: Remove DeprecatedIconType in 9.0 icon?: React.ReactNode | DeprecatedIconType; onClear?: (options: OnClearOptions) => void; } From 6d771ed5289b544b73e03c3f8190dd802f73c4c2 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Wed, 20 Mar 2024 10:16:42 +0100 Subject: [PATCH 8/8] remove unused import --- code/lib/types/src/modules/api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/types/src/modules/api.ts b/code/lib/types/src/modules/api.ts index cfff86e68620..1ccc98cc9e24 100644 --- a/code/lib/types/src/modules/api.ts +++ b/code/lib/types/src/modules/api.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import type { ReactElement, ReactNode } from 'react'; +import type { ReactElement } from 'react'; import type { RenderData } from '../../../router/src/types'; import type { Channel } from '../../../channels/src'; import type { ThemeVars } from '../../../theming/src/types';