Skip to content

Commit dbf500e

Browse files
authored
docs: add deep controls add on
We've integrated the [storybook-addon-deep-controls package](https://github.com/eliasm307/storybook-addon-deep-controls) into our Storybook setup to enhance the developer experience when working with complex, nested object props in our component stories. This addon transforms the way we interact with deeply nested properties by breaking them down into individual, user-friendly controls instead of requiring manual JSON editing.
1 parent 325ac7d commit dbf500e

File tree

39 files changed

+763
-222
lines changed

39 files changed

+763
-222
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
"prettier": "^2.8.7",
8888
"react-test-renderer": "18.3.1",
8989
"storybook": "^8.3.6",
90+
"storybook-addon-deep-controls": "^0.9.5",
9091
"style-loader": "^4.0.0",
9192
"svgo": "^1.3.2",
9293
"syncpack": "^10.9.3",
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const tipAlignmentOptions = [
2+
'top-center',
3+
'bottom-center',
4+
'left-center',
5+
'right-center',
6+
] as const;
7+
8+
export const closeButtonPropsArgTypes = ({
9+
defaultTipText,
10+
defaultTipAlignment,
11+
}: {
12+
defaultTipText: string;
13+
defaultTipAlignment: (typeof tipAlignmentOptions)[number];
14+
}) =>
15+
({
16+
closeButtonProps: {
17+
table: {
18+
disable: true, // Disable the closeButtonProps property from the storybook table in favor of the nested args
19+
},
20+
},
21+
'closeButtonProps.hidden': {
22+
control: 'boolean',
23+
table: {
24+
type: { summary: 'boolean' },
25+
},
26+
description:
27+
'Whether to hide the default close button and pass your own through children to close the modal',
28+
},
29+
'closeButtonProps.ref': {
30+
table: {
31+
type: { summary: 'React.Ref<HTMLButtonElement>' },
32+
},
33+
description:
34+
'An optional ref to be passed to the close button for programmatic access',
35+
},
36+
'closeButtonProps.tip': {
37+
control: 'text',
38+
description: 'The close button tooltip text',
39+
table: {
40+
type: { summary: 'string' },
41+
defaultValue: { summary: defaultTipText },
42+
},
43+
},
44+
'closeButtonProps.tipAlignment': {
45+
control: 'radio',
46+
options: tipAlignmentOptions,
47+
description: 'The alignment of the tooltip',
48+
table: {
49+
type: {
50+
summary: tipAlignmentOptions.join(' | '),
51+
},
52+
defaultValue: { summary: defaultTipAlignment },
53+
},
54+
},
55+
'closeButtonProps.disabled': {
56+
control: 'boolean',
57+
table: {
58+
type: { summary: 'boolean' },
59+
},
60+
description: 'Whether to disable the default close button',
61+
},
62+
} as const);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './closeButtonProps';
2+
export * from './infotip';
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
export const infotipNestedArgTypes = {
2+
infotip: {
3+
table: {
4+
disable: true, // Disable the infotip property from the storybook table in favor of the nested args
5+
},
6+
},
7+
'infotip.emphasis': {
8+
control: 'radio',
9+
options: ['high', 'low'],
10+
table: {
11+
defaultValue: { summary: 'low' },
12+
type: { summary: 'high | low' },
13+
},
14+
},
15+
'infotip.alignment': {
16+
control: 'radio',
17+
options: ['bottom-left', 'bottom-right', 'top-left', 'top-right'],
18+
table: {
19+
defaultValue: { summary: 'top-right' },
20+
type: { summary: 'bottom-left | bottom-right | top-left | top-right' },
21+
},
22+
},
23+
'infotip.placement': {
24+
control: 'radio',
25+
options: ['floating', 'inline'],
26+
table: {
27+
defaultValue: { summary: 'inline' },
28+
type: { summary: 'floating | inline' },
29+
},
30+
},
31+
'infotip.narrow': {
32+
control: 'boolean',
33+
table: {
34+
type: { summary: 'boolean' },
35+
},
36+
description:
37+
'Forces the tooltip to be its narrowest width. For use along the edges of the page or other tight spaces.',
38+
},
39+
'infotip.inheritDims': {
40+
control: 'boolean',
41+
table: {
42+
type: { summary: 'boolean' },
43+
},
44+
description:
45+
'If ToolTipWrapper should inherit the dimensions of the parent element. Can only be used for inline tips.',
46+
},
47+
'infotip.info': {
48+
control: 'text',
49+
table: {
50+
type: { summary: 'string' },
51+
},
52+
description: 'The text for the infotip.',
53+
},
54+
} as const;

packages/styleguide/.storybook/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const config: StorybookConfig = {
1212
getAbsolutePath('@nx/react/plugins/storybook', ''),
1313
getAbsolutePath('@storybook/addon-links'),
1414
getAbsolutePath('@storybook/addon-designs'),
15+
getAbsolutePath('storybook-addon-deep-controls'),
1516
],
1617

1718
framework: {
@@ -45,6 +46,7 @@ const config: StorybookConfig = {
4546
...config.resolve,
4647
alias: {
4748
'~styleguide/blocks': resolve(__dirname, './components/'),
49+
'~styleguide/argTypes': resolve(__dirname, './argTypes/'),
4850
'@codecademy/gamut-styles$': resolve(
4951
__dirname,
5052
'../../gamut-styles/src'

packages/styleguide/.storybook/preview.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const preview: Preview = {
1010
backgrounds: {
1111
disable: true,
1212
},
13+
deepControls: { enabled: true },
1314
docs: {
1415
container: DocsContainer,
1516
theme: theme,

packages/styleguide/src/lib/Atoms/Badge/Badge.stories.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ const meta: Meta<typeof Badge> = {
99
args: { children: 'Badge' },
1010
argTypes: {
1111
icon: {
12-
control: {
13-
type: 'select',
14-
},
12+
control: 'select',
1513
options: Object.keys(icons),
1614
mapping: icons,
1715
},

packages/styleguide/src/lib/Atoms/Buttons/CTAButton/CTAButton.stories.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,11 @@ const meta: Meta<typeof CTAButton> = {
66
args: {
77
children: 'Click Me',
88
disabled: false,
9-
size: 'normal',
109
},
1110
argTypes: {
1211
href: {
1312
description: 'If defined, component will use an anchor tag',
14-
},
15-
size: {
16-
control: {
17-
type: 'select',
18-
options: ['normal', 'small', 'large'],
19-
},
13+
type: 'string',
2014
},
2115
as: {
2216
table: {

packages/styleguide/src/lib/Atoms/Buttons/FillButton/FillButton.stories.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { FillButton } from '@codecademy/gamut';
2-
import { SearchIcon } from '@codecademy/gamut-icons';
2+
import * as icons from '@codecademy/gamut-icons';
33
import type { Meta, StoryObj } from '@storybook/react';
44

55
const meta: Meta<typeof FillButton> = {
@@ -12,17 +12,16 @@ const meta: Meta<typeof FillButton> = {
1212
argTypes: {
1313
href: {
1414
description: 'If defined, component will use an anchor tag',
15+
type: 'string',
1516
},
1617
size: {
17-
control: {
18-
type: 'select',
19-
options: ['normal', 'small', 'large'],
20-
},
18+
control: 'radio',
19+
options: ['normal', 'small', 'large'],
2120
},
2221
icon: {
23-
control: {
24-
options: [SearchIcon],
25-
},
22+
control: 'select',
23+
options: Object.keys(icons),
24+
mapping: icons,
2625
},
2726
as: {
2827
table: {

packages/styleguide/src/lib/Atoms/Buttons/IconButton/IconButton.stories.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,28 @@
11
import { IconButton } from '@codecademy/gamut';
22
import * as icons from '@codecademy/gamut-icons';
33
import type { Meta, StoryObj } from '@storybook/react';
4+
import type { TypeWithDeepControls } from 'storybook-addon-deep-controls';
45

5-
const meta: Meta<typeof IconButton> = {
6+
const meta: TypeWithDeepControls<Meta<typeof IconButton>> = {
67
component: IconButton,
78
args: {
8-
children: 'Click Me',
99
disabled: false,
1010
size: 'normal',
1111
icon: icons.SearchIcon,
1212
tip: 'ToolTip',
13-
tipProps: { placement: 'floating' },
13+
tipProps: { placement: 'floating', alignment: 'top-center' },
1414
},
1515
argTypes: {
1616
href: {
1717
description: 'If defined, component will use an anchor tag',
18+
type: 'string',
1819
},
1920
size: {
20-
control: {
21-
type: 'select',
22-
options: ['normal', 'small', 'large'],
23-
},
21+
control: 'radio',
22+
options: ['normal', 'small', 'large'],
2423
},
2524
icon: {
26-
control: {
27-
type: 'select',
28-
},
25+
control: 'select',
2926
options: Object.keys(icons),
3027
mapping: icons,
3128
},
@@ -34,6 +31,14 @@ const meta: Meta<typeof IconButton> = {
3431
disable: true,
3532
},
3633
},
34+
'tipProps.placement': {
35+
control: 'radio',
36+
options: ['floating', 'inline'],
37+
},
38+
'tipProps.alignment': {
39+
control: 'radio',
40+
options: ['top-center', 'bottom-center', 'left-center', 'right-center'],
41+
},
3742
},
3843
};
3944

0 commit comments

Comments
 (0)