Skip to content

Commit 553e3c0

Browse files
mm-wangclaude
andauthored
[core] Add Storybook stories for Control Card (#7944)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 22635e2 commit 553e3c0

3 files changed

Lines changed: 520 additions & 0 deletions

File tree

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/* !
2+
* (c) Copyright 2026 Palantir Technologies Inc. All rights reserved.
3+
*/
4+
5+
import type { Meta, StoryObj } from "@storybook/react-vite";
6+
import { useArgs, useCallback } from "storybook/preview-api";
7+
8+
import { Alignment, Elevation } from "../../common";
9+
10+
import { CheckboxCard } from "./checkboxCard";
11+
12+
const meta: Meta<typeof CheckboxCard> = {
13+
title: "Core/Control Card/CheckboxCard",
14+
component: CheckboxCard,
15+
decorators: [
16+
Story => (
17+
<div style={{ display: "flex", justifyContent: "center", alignItems: "center", minWidth: "400px" }}>
18+
<Story />
19+
</div>
20+
),
21+
],
22+
parameters: {
23+
layout: "centered",
24+
},
25+
tags: ["autodocs"],
26+
args: {
27+
label: "Checkbox option",
28+
checked: false,
29+
disabled: false,
30+
showAsSelectedWhenChecked: true,
31+
compact: false,
32+
elevation: Elevation.ZERO,
33+
alignIndicator: Alignment.START,
34+
},
35+
argTypes: {
36+
label: {
37+
control: "text",
38+
},
39+
checked: {
40+
control: "boolean",
41+
},
42+
disabled: {
43+
control: "boolean",
44+
},
45+
showAsSelectedWhenChecked: {
46+
control: "boolean",
47+
},
48+
compact: {
49+
control: "boolean",
50+
},
51+
elevation: {
52+
control: "select",
53+
options: Object.values(Elevation),
54+
},
55+
alignIndicator: {
56+
control: "select",
57+
options: Object.values(Alignment),
58+
},
59+
onChange: { action: "changed" },
60+
},
61+
} satisfies Meta<typeof CheckboxCard>;
62+
63+
export default meta;
64+
type Story = StoryObj<typeof meta>;
65+
66+
/**
67+
* A basic checkbox card with default styling.
68+
*/
69+
export const Default: Story = {
70+
args: {
71+
label: "Checkbox option",
72+
},
73+
render: function RenderDefault(args) {
74+
const [, updateArgs] = useArgs();
75+
const handleChange = useCallback(() => updateArgs({ checked: !args.checked }), [args.checked, updateArgs]);
76+
return <CheckboxCard {...args} onChange={handleChange} />;
77+
},
78+
};
79+
80+
/**
81+
* Use the `compact` prop to render a medium or large checkbox card.
82+
*/
83+
export const CompactExample: Story = {
84+
name: "Compact",
85+
argTypes: {
86+
compact: { table: { disable: true } },
87+
},
88+
render: function RenderCompact(args) {
89+
const [, updateArgs] = useArgs();
90+
const handleChange = useCallback(() => updateArgs({ checked: !args.checked }), [args.checked, updateArgs]);
91+
92+
return (
93+
<div style={{ display: "flex", flexDirection: "column", gap: 8, minWidth: 300 }}>
94+
<CheckboxCard {...args} label="Default" defaultChecked={true} onChange={handleChange} />
95+
<CheckboxCard {...args} compact={true} label="Compact" defaultChecked={true} onChange={handleChange} />
96+
</div>
97+
);
98+
},
99+
};
100+
101+
/**
102+
* Checkbox cards support `disabled`, `checked`, and `selected` states.
103+
*/
104+
export const StateExample: Story = {
105+
name: "State",
106+
argTypes: {
107+
disabled: { table: { disable: true } },
108+
checked: { table: { disable: true } },
109+
},
110+
render: function RenderState(args) {
111+
const [, updateArgs] = useArgs();
112+
const handleChange = useCallback(() => updateArgs({ checked: !args.checked }), [args.checked, updateArgs]);
113+
114+
return (
115+
<div style={{ display: "flex", flexDirection: "column", gap: 8, minWidth: 300 }}>
116+
<CheckboxCard {...args} label="Default" onChange={handleChange} />
117+
<CheckboxCard {...args} label="Checked" checked={true} onChange={handleChange} />
118+
<CheckboxCard {...args} label="Disabled" disabled={true} />
119+
<CheckboxCard {...args} label="Disabled Checked" disabled={true} checked={true} />
120+
<CheckboxCard
121+
{...args}
122+
label="No selected styling"
123+
checked={true}
124+
showAsSelectedWhenChecked={false}
125+
onChange={handleChange}
126+
/>
127+
</div>
128+
);
129+
},
130+
};
131+
132+
/**
133+
* Use the `alignIndicator` prop to render start or end-aligned.
134+
*/
135+
export const AlignIndicatorExample: Story = {
136+
name: "Align Indicator",
137+
argTypes: {
138+
alignIndicator: { table: { disable: true } },
139+
},
140+
render: function RenderAlignIndicator(args) {
141+
const [, updateArgs] = useArgs();
142+
const handleChange = useCallback(() => updateArgs({ checked: !args.checked }), [args.checked, updateArgs]);
143+
144+
return (
145+
<div style={{ display: "flex", flexDirection: "column", gap: 8, minWidth: 300 }}>
146+
<CheckboxCard
147+
{...args}
148+
alignIndicator={Alignment.START}
149+
label="Align start"
150+
defaultChecked={true}
151+
onChange={handleChange}
152+
/>
153+
<CheckboxCard
154+
{...args}
155+
alignIndicator={Alignment.END}
156+
label="Align end"
157+
defaultChecked={true}
158+
onChange={handleChange}
159+
/>
160+
</div>
161+
);
162+
},
163+
};
164+
165+
/**
166+
* Interactive playground with all props toggleable via Storybook controls.
167+
*/
168+
export const Playground: Story = {
169+
args: {
170+
label: "Playground checkbox card",
171+
},
172+
render: function RenderPlayground(args) {
173+
const [, updateArgs] = useArgs();
174+
const handleChange = useCallback(() => updateArgs({ checked: !args.checked }), [args.checked, updateArgs]);
175+
return <CheckboxCard {...args} onChange={handleChange} />;
176+
},
177+
};
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/* !
2+
* (c) Copyright 2026 Palantir Technologies Inc. All rights reserved.
3+
*/
4+
5+
import type { Meta, StoryObj } from "@storybook/react-vite";
6+
import { useArgs, useCallback } from "storybook/preview-api";
7+
8+
import { Alignment, Elevation } from "../../common";
9+
10+
import { RadioCard } from "./radioCard";
11+
12+
const meta: Meta<typeof RadioCard> = {
13+
title: "Core/Control Card/RadioCard",
14+
component: RadioCard,
15+
decorators: [
16+
Story => (
17+
<div style={{ display: "flex", justifyContent: "center", alignItems: "center", minWidth: "400px" }}>
18+
<Story />
19+
</div>
20+
),
21+
],
22+
parameters: {
23+
layout: "centered",
24+
},
25+
tags: ["autodocs"],
26+
args: {
27+
label: "Radio option",
28+
checked: false,
29+
disabled: false,
30+
showAsSelectedWhenChecked: true,
31+
compact: false,
32+
elevation: Elevation.ZERO,
33+
},
34+
argTypes: {
35+
label: {
36+
control: "text",
37+
},
38+
checked: {
39+
control: "boolean",
40+
},
41+
disabled: {
42+
control: "boolean",
43+
},
44+
showAsSelectedWhenChecked: {
45+
control: "boolean",
46+
},
47+
compact: {
48+
control: "boolean",
49+
},
50+
elevation: {
51+
control: "select",
52+
options: Object.values(Elevation),
53+
},
54+
alignIndicator: {
55+
control: "select",
56+
options: Object.values(Alignment),
57+
},
58+
onChange: { action: "changed" },
59+
},
60+
} satisfies Meta<typeof RadioCard>;
61+
62+
export default meta;
63+
type Story = StoryObj<typeof meta>;
64+
65+
/**
66+
* A basic radio card with default styling.
67+
*/
68+
export const Default: Story = {
69+
args: {
70+
label: "Radio option",
71+
},
72+
render: function RenderDefault(args) {
73+
const [, updateArgs] = useArgs();
74+
const handleChange = useCallback(() => updateArgs({ checked: !args.checked }), [args.checked, updateArgs]);
75+
return <RadioCard {...args} onChange={handleChange} />;
76+
},
77+
};
78+
79+
/**
80+
* Use the `compact` prop to render a more condensed radio card.
81+
*/
82+
export const CompactExample: Story = {
83+
name: "Compact",
84+
argTypes: {
85+
compact: { table: { disable: true } },
86+
},
87+
render: function RenderCompact(args) {
88+
const [, updateArgs] = useArgs();
89+
const handleChange = useCallback(() => updateArgs({ checked: !args.checked }), [args.checked, updateArgs]);
90+
91+
return (
92+
<div style={{ display: "flex", flexDirection: "column", gap: 8, minWidth: 300 }}>
93+
<RadioCard {...args} label="Default" defaultChecked={true} onChange={handleChange} />
94+
<RadioCard {...args} compact={true} label="Compact" defaultChecked={true} onChange={handleChange} />
95+
</div>
96+
);
97+
},
98+
};
99+
100+
/**
101+
* Radio cards support `disabled`, `checked`, and `selected` states.
102+
*/
103+
export const StateExample: Story = {
104+
name: "State",
105+
argTypes: {
106+
disabled: { table: { disable: true } },
107+
checked: { table: { disable: true } },
108+
},
109+
render: function RenderState(args) {
110+
return (
111+
<div style={{ display: "flex", flexDirection: "column", gap: 8, minWidth: 300 }}>
112+
<RadioCard {...args} label="Default" />
113+
<RadioCard {...args} label="Checked" checked={true} />
114+
<RadioCard {...args} label="Disabled" disabled={true} />
115+
<RadioCard {...args} label="Disabled Checked" disabled={true} checked={true} />
116+
<RadioCard {...args} label="No selected styling" checked={true} showAsSelectedWhenChecked={false} />
117+
</div>
118+
);
119+
},
120+
};
121+
122+
/**
123+
* Use the `alignIndicator` prop to render start or end-aligned.
124+
*/
125+
export const AlignIndicatorExample: Story = {
126+
name: "Align Indicator",
127+
argTypes: {
128+
alignIndicator: { table: { disable: true } },
129+
},
130+
render: function RenderAlignIndicator(args) {
131+
const [, updateArgs] = useArgs();
132+
const handleChange = useCallback(() => updateArgs({ checked: !args.checked }), [args.checked, updateArgs]);
133+
134+
return (
135+
<div style={{ display: "flex", flexDirection: "column", gap: 8, minWidth: 300 }}>
136+
<RadioCard
137+
{...args}
138+
alignIndicator={Alignment.START}
139+
label="Align start"
140+
defaultChecked={true}
141+
onChange={handleChange}
142+
/>
143+
<RadioCard
144+
{...args}
145+
alignIndicator={Alignment.END}
146+
label="Align end"
147+
defaultChecked={true}
148+
onChange={handleChange}
149+
/>
150+
</div>
151+
);
152+
},
153+
};
154+
155+
/**
156+
* Interactive playground with all props toggleable via Storybook controls.
157+
*/
158+
export const Playground: Story = {
159+
args: {
160+
label: "Playground radio card",
161+
},
162+
render: function RenderPlayground(args) {
163+
const [, updateArgs] = useArgs();
164+
const handleChange = useCallback(() => updateArgs({ checked: !args.checked }), [args.checked, updateArgs]);
165+
return <RadioCard {...args} onChange={handleChange} />;
166+
},
167+
};

0 commit comments

Comments
 (0)