From 6322a8f82b1c09bb2618dba42eef84a02ce43b5d Mon Sep 17 00:00:00 2001 From: Daniel Lu Date: Fri, 22 Jul 2022 11:42:56 -0700 Subject: [PATCH 1/5] add checkbox to enable strict mode on a story by story basis --- .storybook/main.js | 5 +---- .storybook/preview.js | 2 ++ .storybook/strictmode.js | 39 +++++++++++++++++++++++++++++++++++++++ package.json | 1 - 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 .storybook/strictmode.js diff --git a/.storybook/main.js b/.storybook/main.js index f5bb57f3271..361a4787318 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -36,8 +36,5 @@ module.exports = { } return resultConfig; - }, - reactOptions: { - strictMode: process.env.STRICT_MODE - }, + } }; diff --git a/.storybook/preview.js b/.storybook/preview.js index e31d1ad5141..24662fc594e 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -2,6 +2,7 @@ import {configureActions} from '@storybook/addon-actions'; import React from 'react'; import {VerticalCenter} from './layout'; import {withProviderSwitcher} from './custom-addons/provider'; +import {withStrictModeSwitcher} from './strictmode'; // decorator order matters, the last one will be the outer most @@ -23,5 +24,6 @@ export const decorators = [ {story()} ), + withStrictModeSwitcher, withProviderSwitcher ]; diff --git a/.storybook/strictmode.js b/.storybook/strictmode.js new file mode 100644 index 00000000000..51e076f9e8d --- /dev/null +++ b/.storybook/strictmode.js @@ -0,0 +1,39 @@ +import {Checkbox} from '@react-spectrum/checkbox'; +import {defaultTheme} from './constants'; +import {makeDecorator} from '@storybook/addons'; +import {Provider} from '@react-spectrum/provider'; +import React, {StrictMode, useState} from 'react'; + +function StrictModeDecorator(props) { + let {children} = props; + let [selected, setSelected] = useState(false); + let wrapper = selected ? ( + + {children} + + ) : children; + + return ( + + setSelected(selected => !selected)}> + Toggle strict mode + + {wrapper} + + ); +} + +export const withStrictModeSwitcher = makeDecorator({ + name: 'withStrictModeSwitcher', + parameterName: 'strictModeSwitcher', + wrapper: (getStory, context) => { + return ( + + {getStory(context)} + + ); + } +}); diff --git a/package.json b/package.json index d6a22d33b56..101d4c6c4b6 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "install-16": "yarn add -W react@^16.8.0 react-dom@^16.8.0 @testing-library/react@^12 @testing-library/react-hooks@^8", "install-17": "yarn add -W react@^17 react-dom@^17 @testing-library/react@^12 @testing-library/react-hooks@^8", "start": "cross-env NODE_ENV=storybook start-storybook -p 9003 --ci -c '.storybook'", - "start-strict": "cross-env NODE_ENV=storybook STRICT_MODE=1 start-storybook -p 9003 --ci -c '.storybook'", "build:storybook": "build-storybook -c .storybook -o dist/$(git rev-parse HEAD)/storybook", "build:storybook-16": "build-storybook -c .storybook -o dist/$(git rev-parse HEAD)/storybook-16", "build:storybook-17": "build-storybook -c .storybook -o dist/$(git rev-parse HEAD)/storybook-17", From 5f08d973d1d4a104e06fcd29123c4af0feab228c Mon Sep 17 00:00:00 2001 From: Daniel Lu Date: Fri, 22 Jul 2022 14:35:39 -0700 Subject: [PATCH 2/5] checkbox for strict --- .storybook/custom-addons/strictmode/index.js | 23 ++++++++++ .../custom-addons/strictmode/register.js | 43 +++++++++++++++++++ .storybook/main.js | 3 +- .storybook/preview.js | 21 ++++++++- .storybook/strictmode.js | 39 ----------------- 5 files changed, 87 insertions(+), 42 deletions(-) create mode 100644 .storybook/custom-addons/strictmode/index.js create mode 100644 .storybook/custom-addons/strictmode/register.js delete mode 100644 .storybook/strictmode.js diff --git a/.storybook/custom-addons/strictmode/index.js b/.storybook/custom-addons/strictmode/index.js new file mode 100644 index 00000000000..0395c7c4a78 --- /dev/null +++ b/.storybook/custom-addons/strictmode/index.js @@ -0,0 +1,23 @@ +import {makeDecorator} from '@storybook/addons'; +import React, {StrictMode} from 'react'; + +function StrictModeDecorator(props) { + let {children, strictMode} = props; + return strictMode ? ( + + {children} + + ) : children; +} + +export const withStrictModeSwitcher = makeDecorator({ + name: 'withStrictModeSwitcher', + parameterName: 'strictModeSwitcher', + wrapper: (getStory, context) => { + return ( + + {getStory(context)} + + ); + } +}); diff --git a/.storybook/custom-addons/strictmode/register.js b/.storybook/custom-addons/strictmode/register.js new file mode 100644 index 00000000000..4469350e840 --- /dev/null +++ b/.storybook/custom-addons/strictmode/register.js @@ -0,0 +1,43 @@ +import React, { useCallback } from 'react'; +import {FORCE_RE_RENDER} from '@storybook/core-events'; +import {useGlobals} from '@storybook/api'; +import {addons, types} from '@storybook/addons'; + +const ExampleToolbar = () => { + const [globals, updateGlobals] = useGlobals(); + const isChecked = globals['strictMode'] || false; + + // Function that will update the global value and trigger a UI refresh. + const refreshAndUpdateGlobal = () => { + // Updates Storybook global value + updateGlobals({ + ['strictMode']: !isChecked, + }), + // Invokes Storybook's addon API method (with the FORCE_RE_RENDER) event to trigger a UI refresh + addons.getChannel().emit(FORCE_RE_RENDER); + }; + + const toggle = useCallback(() => refreshAndUpdateGlobal(), [isChecked]); + + return ( +
+
+ +
+
+ ); +}; + +addons.register('StrictModeSwitcher', () => { + addons.add('StrictModeSwitcher', { + title: 'Strict mode switcher', + type: types.TOOL, + //👇 Shows the Toolbar UI element if either the Canvas or Docs tab is active + match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)), + render: () => ( + + ), + }); +}); diff --git a/.storybook/main.js b/.storybook/main.js index 361a4787318..2dc53d599c4 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -11,7 +11,8 @@ module.exports = { 'storybook-dark-mode', './custom-addons/provider/register', './custom-addons/descriptions/register', - './custom-addons/theme/register' + './custom-addons/theme/register', + './custom-addons/strictmode/register' ], typescript: { check: false, diff --git a/.storybook/preview.js b/.storybook/preview.js index 24662fc594e..ea0d01783fc 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -2,7 +2,7 @@ import {configureActions} from '@storybook/addon-actions'; import React from 'react'; import {VerticalCenter} from './layout'; import {withProviderSwitcher} from './custom-addons/provider'; -import {withStrictModeSwitcher} from './strictmode'; +import {withStrictModeSwitcher} from './custom-addons/strictmode'; // decorator order matters, the last one will be the outer most @@ -15,7 +15,24 @@ export const parameters = { storySort: (a, b) => a[1].kind === b[1].kind ? 0 : a[1].id.localeCompare(b[1].id, undefined, { numeric: true }), }, a11y: {}, - layout: 'fullscreen' + layout: 'fullscreen', + args: { + isQuiet: false + }, + argType: { + isQuiet: { + control: {type: 'boolean'} + }, + }, + controls: {} +}; + +export const globalTypes = { + strictMode: { + name: 'strictMode', + description: 'Global tracker for strict mode', + defaultValue: false + }, }; export const decorators = [ diff --git a/.storybook/strictmode.js b/.storybook/strictmode.js deleted file mode 100644 index 51e076f9e8d..00000000000 --- a/.storybook/strictmode.js +++ /dev/null @@ -1,39 +0,0 @@ -import {Checkbox} from '@react-spectrum/checkbox'; -import {defaultTheme} from './constants'; -import {makeDecorator} from '@storybook/addons'; -import {Provider} from '@react-spectrum/provider'; -import React, {StrictMode, useState} from 'react'; - -function StrictModeDecorator(props) { - let {children} = props; - let [selected, setSelected] = useState(false); - let wrapper = selected ? ( - - {children} - - ) : children; - - return ( - - setSelected(selected => !selected)}> - Toggle strict mode - - {wrapper} - - ); -} - -export const withStrictModeSwitcher = makeDecorator({ - name: 'withStrictModeSwitcher', - parameterName: 'strictModeSwitcher', - wrapper: (getStory, context) => { - return ( - - {getStory(context)} - - ); - } -}); From 002ff44de76e5b35244187a70c49b5c2e64a6482 Mon Sep 17 00:00:00 2001 From: Daniel Lu Date: Tue, 13 Dec 2022 16:01:00 -0800 Subject: [PATCH 3/5] getting rid of storybook globals in favor of state the globals are updating anymore for some reason... --- .storybook/custom-addons/strictmode/index.js | 24 +++++++++--- .../custom-addons/strictmode/register.js | 39 +++++++++---------- .storybook/preview.js | 8 ---- 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/.storybook/custom-addons/strictmode/index.js b/.storybook/custom-addons/strictmode/index.js index 0395c7c4a78..59b52262157 100644 --- a/.storybook/custom-addons/strictmode/index.js +++ b/.storybook/custom-addons/strictmode/index.js @@ -1,9 +1,23 @@ -import {makeDecorator} from '@storybook/addons'; -import React, {StrictMode} from 'react'; +import {addons, makeDecorator} from '@storybook/addons'; +import {getQueryParams} from '@storybook/client-api'; +import React, {StrictMode, useEffect, useState} from 'react'; function StrictModeDecorator(props) { - let {children, strictMode} = props; - return strictMode ? ( + let {children} = props; + let [isStrict, setStrict] = useState(getQueryParams()?.strict || false); + + useEffect(() => { + let channel = addons.getChannel(); + let updateStrict = (val) => { + setStrict(val); + }; + channel.on('strict/updated', updateStrict); + return () => { + channel.removeListener('strict/updated', updateStrict); + }; + }, []); + + return isStrict ? ( {children} @@ -15,7 +29,7 @@ export const withStrictModeSwitcher = makeDecorator({ parameterName: 'strictModeSwitcher', wrapper: (getStory, context) => { return ( - + {getStory(context)} ); diff --git a/.storybook/custom-addons/strictmode/register.js b/.storybook/custom-addons/strictmode/register.js index 4469350e840..15030a54bc7 100644 --- a/.storybook/custom-addons/strictmode/register.js +++ b/.storybook/custom-addons/strictmode/register.js @@ -1,43 +1,40 @@ -import React, { useCallback } from 'react'; -import {FORCE_RE_RENDER} from '@storybook/core-events'; -import {useGlobals} from '@storybook/api'; import {addons, types} from '@storybook/addons'; +import {getQueryParams} from '@storybook/client-api'; +import React, {useEffect, useState} from 'react'; -const ExampleToolbar = () => { - const [globals, updateGlobals] = useGlobals(); - const isChecked = globals['strictMode'] || false; - - // Function that will update the global value and trigger a UI refresh. - const refreshAndUpdateGlobal = () => { - // Updates Storybook global value - updateGlobals({ - ['strictMode']: !isChecked, - }), - // Invokes Storybook's addon API method (with the FORCE_RE_RENDER) event to trigger a UI refresh - addons.getChannel().emit(FORCE_RE_RENDER); +const StrictModeToolBar = ({api}) => { + let channel = addons.getChannel(); + let [isStrict, setStrict] = useState(getQueryParams()?.strict || false); + let onChange = () => { + setStrict((old) => { + channel.emit('strict/updated', !old); + return !old; + }) }; - const toggle = useCallback(() => refreshAndUpdateGlobal(), [isChecked]); + useEffect(() => { + api.setQueryParams({ + 'strict': isStrict + }); + }); return (
); }; -addons.register('StrictModeSwitcher', () => { +addons.register('StrictModeSwitcher', (api) => { addons.add('StrictModeSwitcher', { title: 'Strict mode switcher', type: types.TOOL, //👇 Shows the Toolbar UI element if either the Canvas or Docs tab is active match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)), - render: () => ( - - ), + render: () => }); }); diff --git a/.storybook/preview.js b/.storybook/preview.js index 4c0b2c46a8b..bc696a5a6b5 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -24,14 +24,6 @@ export const parameters = { } }; -export const globalTypes = { - strictMode: { - name: 'strictMode', - description: 'Global tracker for strict mode', - defaultValue: false - } -}; - export const decorators = [ Story => ( From e829d36cc44ed593d4cfb08d3f4e17419cff500b Mon Sep 17 00:00:00 2001 From: Daniel Lu Date: Tue, 13 Dec 2022 16:31:04 -0800 Subject: [PATCH 4/5] me dumb, me forget to convert to boolean --- .storybook/custom-addons/strictmode/index.js | 2 +- .storybook/custom-addons/strictmode/register.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.storybook/custom-addons/strictmode/index.js b/.storybook/custom-addons/strictmode/index.js index 59b52262157..49415f62acf 100644 --- a/.storybook/custom-addons/strictmode/index.js +++ b/.storybook/custom-addons/strictmode/index.js @@ -4,7 +4,7 @@ import React, {StrictMode, useEffect, useState} from 'react'; function StrictModeDecorator(props) { let {children} = props; - let [isStrict, setStrict] = useState(getQueryParams()?.strict || false); + let [isStrict, setStrict] = useState(getQueryParams()?.strict === 'true' || false); useEffect(() => { let channel = addons.getChannel(); diff --git a/.storybook/custom-addons/strictmode/register.js b/.storybook/custom-addons/strictmode/register.js index 15030a54bc7..2b6ea781837 100644 --- a/.storybook/custom-addons/strictmode/register.js +++ b/.storybook/custom-addons/strictmode/register.js @@ -4,7 +4,7 @@ import React, {useEffect, useState} from 'react'; const StrictModeToolBar = ({api}) => { let channel = addons.getChannel(); - let [isStrict, setStrict] = useState(getQueryParams()?.strict || false); + let [isStrict, setStrict] = useState(getQueryParams()?.strict === 'true' || false); let onChange = () => { setStrict((old) => { channel.emit('strict/updated', !old); From ed3f5bd33bd58037cc254f9c89b04f9a8cf710c0 Mon Sep 17 00:00:00 2001 From: Daniel Lu Date: Tue, 13 Dec 2022 16:32:49 -0800 Subject: [PATCH 5/5] removing style --- .storybook/custom-addons/strictmode/register.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.storybook/custom-addons/strictmode/register.js b/.storybook/custom-addons/strictmode/register.js index 2b6ea781837..b226fe1e0b3 100644 --- a/.storybook/custom-addons/strictmode/register.js +++ b/.storybook/custom-addons/strictmode/register.js @@ -22,7 +22,7 @@ const StrictModeToolBar = ({api}) => {