Skip to content

Commit ec36808

Browse files
feat: Hide controls if they are disabled using the built-in includeConditionalArg function (#714)
* Hide controls if they are disabled using the built-in `includeConditionalArg` function * Update packages/ondevice-controls/src/ControlsPanel.tsx * fix: use function to get include value * fix: tests --------- Co-authored-by: Daniel Williams <[email protected]>
1 parent babf9ed commit ec36808

File tree

3 files changed

+68
-14
lines changed

3 files changed

+68
-14
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Meta, StoryObj } from '@storybook/react';
2+
import { Text, View } from 'react-native';
3+
4+
type HiddenControlsProps = {
5+
value: number;
6+
padding: number;
7+
advanced: boolean;
8+
};
9+
const HiddenControls = ({ value, padding }: HiddenControlsProps) => {
10+
return (
11+
<View style={{ padding, gap: 10 }}>
12+
<Text>
13+
This is a story that allows you to hide controls based on other args. By default, you should
14+
be able to modify the value but not the padding of this component
15+
</Text>
16+
<Text>Your current chosen value is: {value}</Text>
17+
</View>
18+
);
19+
};
20+
21+
const meta = {
22+
component: HiddenControls,
23+
} satisfies Meta<typeof HiddenControls>;
24+
25+
export default meta;
26+
27+
type HiddenControlsStory = StoryObj<typeof meta>;
28+
29+
export const Basic: HiddenControlsStory = {
30+
argTypes: {
31+
value: { control: 'number' },
32+
advanced: { control: 'boolean' },
33+
padding: { control: 'number', if: { arg: 'advanced' } },
34+
},
35+
args: {
36+
padding: 10,
37+
value: 42,
38+
advanced: false,
39+
},
40+
};

packages/ondevice-controls/src/ControlsPanel.tsx

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import type { API } from 'storybook/internal/manager-api';
22
import { Channel } from 'storybook/internal/channels';
3-
import type { Args, StoryContextForLoaders } from 'storybook/internal/csf';
3+
import {
4+
type Args,
5+
type StoryContextForLoaders,
6+
includeConditionalArg,
7+
} from 'storybook/internal/csf';
48
import type { Renderer } from 'storybook/internal/types';
59
import React, { ComponentType, ReactElement, useCallback, useState } from 'react';
610
import NoControlsWarning from './NoControlsWarning';
@@ -47,6 +51,14 @@ type ApiStore = {
4751
_channel: Channel;
4852
};
4953

54+
function shouldIncludeArg(argType: ArgType, args: Args) {
55+
try {
56+
return includeConditionalArg(argType, args, {});
57+
} catch {
58+
return true;
59+
}
60+
}
61+
5062
const ControlsPanel = ({ api }: { api: API }) => {
5163
const store: ApiStore = api.store();
5264

@@ -63,7 +75,9 @@ const ControlsPanel = ({ api }: { api: API }) => {
6375
(prev, [key, argType]: [string, ArgType]) => {
6476
const isControl = Boolean(argType?.control);
6577

66-
return isControl
78+
const shouldInclude = shouldIncludeArg(argType, argsFromHook);
79+
80+
return isControl && shouldInclude
6781
? {
6882
...prev,
6983
[key]: {

packages/react-native/scripts/__snapshots__/generate.test.js.snap

+12-12
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ exports[`loader writeRequires when there are different file extensions writes th
44
"
55
/* do not change this file, it is auto generated by storybook. */
66
7-
import { start, updateView } from '@storybook/react-native';
7+
import { start, updateView, View } from '@storybook/react-native';
88
99
import "@storybook/addon-ondevice-notes/register";
1010
import "@storybook/addon-ondevice-controls/register";
@@ -23,7 +23,7 @@ import "@storybook/addon-ondevice-actions/register";
2323
2424
2525
declare global {
26-
var view: ReturnType<typeof start>;
26+
var view: View;
2727
var STORIES: typeof normalizedStories;
2828
}
2929
@@ -47,15 +47,15 @@ import "@storybook/addon-ondevice-actions/register";
4747
updateView(global.view, annotations, normalizedStories, );
4848
}
4949
50-
export const view: ReturnType<typeof start> = global.view;
50+
export const view: View = global.view;
5151
"
5252
`;
5353

5454
exports[`loader writeRequires when there is a configuration object writes the story imports 1`] = `
5555
"
5656
/* do not change this file, it is auto generated by storybook. */
5757
58-
import { start, updateView } from '@storybook/react-native';
58+
import { start, updateView, View } from '@storybook/react-native';
5959
6060
import "@storybook/addon-ondevice-notes/register";
6161
import "@storybook/addon-ondevice-controls/register";
@@ -74,7 +74,7 @@ import "@storybook/addon-ondevice-actions/register";
7474
7575
7676
declare global {
77-
var view: ReturnType<typeof start>;
77+
var view: View;
7878
var STORIES: typeof normalizedStories;
7979
}
8080
@@ -98,15 +98,15 @@ import "@storybook/addon-ondevice-actions/register";
9898
updateView(global.view, annotations, normalizedStories, );
9999
}
100100
101-
export const view: ReturnType<typeof start> = global.view;
101+
export const view: View = global.view;
102102
"
103103
`;
104104

105105
exports[`loader writeRequires when there is a story glob writes the story imports 1`] = `
106106
"
107107
/* do not change this file, it is auto generated by storybook. */
108108
109-
import { start, updateView } from '@storybook/react-native';
109+
import { start, updateView, View } from '@storybook/react-native';
110110
111111
import "@storybook/addon-ondevice-notes/register";
112112
import "@storybook/addon-ondevice-controls/register";
@@ -125,7 +125,7 @@ import "@storybook/addon-ondevice-actions/register";
125125
126126
127127
declare global {
128-
var view: ReturnType<typeof start>;
128+
var view: View;
129129
var STORIES: typeof normalizedStories;
130130
}
131131
@@ -149,15 +149,15 @@ import "@storybook/addon-ondevice-actions/register";
149149
updateView(global.view, annotations, normalizedStories, );
150150
}
151151
152-
export const view: ReturnType<typeof start> = global.view;
152+
export const view: View = global.view;
153153
"
154154
`;
155155

156156
exports[`loader writeRequires when there is no preview does not add preview related stuff 1`] = `
157157
"
158158
/* do not change this file, it is auto generated by storybook. */
159159
160-
import { start, updateView } from '@storybook/react-native';
160+
import { start, updateView, View } from '@storybook/react-native';
161161
162162
import "@storybook/addon-ondevice-notes/register";
163163
import "@storybook/addon-ondevice-controls/register";
@@ -176,7 +176,7 @@ import "@storybook/addon-ondevice-actions/register";
176176
177177
178178
declare global {
179-
var view: ReturnType<typeof start>;
179+
var view: View;
180180
var STORIES: typeof normalizedStories;
181181
}
182182
@@ -200,7 +200,7 @@ import "@storybook/addon-ondevice-actions/register";
200200
updateView(global.view, annotations, normalizedStories, );
201201
}
202202
203-
export const view: ReturnType<typeof start> = global.view;
203+
export const view: View = global.view;
204204
"
205205
`;
206206

0 commit comments

Comments
 (0)