Skip to content

Commit fc023a4

Browse files
authored
FE-21: Design System: Add checkbox (#7886)
1 parent 519794b commit fc023a4

File tree

10 files changed

+471
-33
lines changed

10 files changed

+471
-33
lines changed

libs/@hashintel/ds-components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"motion": "12.23.24"
4343
},
4444
"devDependencies": {
45-
"@figma/code-connect": "1.3.6",
45+
"@figma/code-connect": "1.3.7",
4646
"@local/eslint": "0.0.0-private",
4747
"@local/tsconfig": "0.0.0-private",
4848
"@pandacss/dev": "1.4.3",
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import figma from "@figma/code-connect";
2+
3+
import { Checkbox } from "./checkbox";
4+
5+
/**
6+
* -- This file was auto-generated by Code Connect --
7+
* `props` includes a mapping from your code props to Figma properties.
8+
* You should check this is correct, and update the `example` function
9+
* to return the code example you'd like to see in Figma
10+
*/
11+
12+
figma.connect(
13+
Checkbox,
14+
"https://www.figma.com/design/WmnosvOvi4Blw0HK0jh1mG/Design-System?node-id=384%3A25638",
15+
{
16+
props: {
17+
// These props were automatically mapped based on your linked code:
18+
checked: figma.enum("checked", {
19+
false: false,
20+
true: true,
21+
indeterminate: "indeterminate",
22+
}),
23+
disabled: figma.enum("_state", {
24+
disabled: true,
25+
}),
26+
label: figma.string("label"),
27+
// No matching props could be found for these Figma properties:
28+
// "showLabel": figma.boolean('_showLabel'),
29+
// "label": figma.string('label'),
30+
// "showIcon": figma.boolean('_showIcon'),
31+
// "icon": figma.instance('Icon')
32+
},
33+
example: (props) => (
34+
<Checkbox
35+
checked={props.checked}
36+
disabled={props.disabled}
37+
label={props.label}
38+
/>
39+
),
40+
},
41+
);
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
import type { Meta, StoryObj } from "@storybook/react-vite";
2+
import { useState } from "react";
3+
4+
import { Checkbox, type CheckboxProps } from "./checkbox";
5+
6+
const meta: Meta<CheckboxProps> = {
7+
title: "Components/Checkbox",
8+
component: Checkbox,
9+
parameters: {
10+
layout: "centered",
11+
docs: {
12+
description: {
13+
component: `
14+
# Checkbox Component
15+
16+
A simple checkbox component built with @ark-ui/react and styled with PandaCSS.
17+
18+
## States
19+
20+
- **Unchecked**: Default empty state
21+
- **Checked**: Selected state with checkmark
22+
- **Indeterminate**: Partial selection state with minus icon
23+
- **Disabled**: Non-interactive state
24+
25+
## Interactions
26+
27+
- **Hover**: Slightly darker border and background
28+
- **Focus**: Blue outline ring
29+
- **Disabled**: Reduced opacity and muted colors
30+
`,
31+
},
32+
},
33+
},
34+
argTypes: {
35+
checked: {
36+
control: "radio",
37+
options: [false, true, "indeterminate"],
38+
description: "The checked state of the checkbox",
39+
},
40+
disabled: {
41+
control: "boolean",
42+
description: "Whether the checkbox is disabled",
43+
},
44+
invalid: {
45+
control: "boolean",
46+
description: "Whether the checkbox is in an invalid state",
47+
},
48+
readOnly: {
49+
control: "boolean",
50+
description: "Whether the checkbox is read-only",
51+
},
52+
required: {
53+
control: "boolean",
54+
description: "Whether the checkbox is required",
55+
},
56+
label: {
57+
control: "text",
58+
description: "Label text for the checkbox",
59+
},
60+
onCheckedChange: {
61+
action: "checked changed",
62+
description: "Callback when the checked state changes",
63+
},
64+
},
65+
args: {
66+
disabled: false,
67+
invalid: false,
68+
readOnly: false,
69+
required: false,
70+
label: "Label",
71+
},
72+
};
73+
74+
export default meta;
75+
76+
type Story = StoryObj<typeof meta>;
77+
78+
/**
79+
* Default checkbox in unchecked state
80+
*/
81+
export const Default: Story = {
82+
args: {
83+
checked: false,
84+
},
85+
};
86+
87+
/**
88+
* Checkbox in checked state
89+
*/
90+
export const Checked: Story = {
91+
args: {
92+
checked: true,
93+
},
94+
};
95+
96+
/**
97+
* Checkbox in indeterminate state (partial selection)
98+
*/
99+
export const Indeterminate: Story = {
100+
args: {
101+
checked: "indeterminate",
102+
},
103+
};
104+
105+
/**
106+
* Disabled checkbox states
107+
*/
108+
export const Disabled: Story = {
109+
argTypes: {},
110+
parameters: {
111+
actions: { disable: true },
112+
interactions: { disable: true },
113+
controls: { disable: true },
114+
},
115+
render: () => (
116+
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
117+
{/* Enabled Row */}
118+
<div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
119+
<Checkbox label="Unchecked" checked={false} />
120+
<Checkbox label="Checked" checked />
121+
<Checkbox label="Indeterminate" checked="indeterminate" />
122+
</div>
123+
{/* Disabled Row */}
124+
<div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
125+
<Checkbox label="Unchecked" disabled checked={false} />
126+
<Checkbox label="Checked" disabled checked />
127+
<Checkbox label="Indeterminate" disabled checked="indeterminate" />
128+
</div>
129+
</div>
130+
),
131+
};
132+
133+
/**
134+
* Interactive checkbox with controlled state
135+
*/
136+
export const Interactive: Story = {
137+
argTypes: {},
138+
parameters: {
139+
actions: { disable: true },
140+
interactions: { disable: true },
141+
controls: { disable: true },
142+
},
143+
render: () => {
144+
const [checked, setChecked] = useState<boolean | "indeterminate">(false);
145+
146+
return (
147+
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
148+
<Checkbox
149+
label="Interactive Checkbox"
150+
checked={checked}
151+
onCheckedChange={setChecked}
152+
/>
153+
154+
<div style={{ display: "flex", gap: "8px" }}>
155+
<button
156+
type="button"
157+
onClick={() => setChecked(false)}
158+
style={{
159+
padding: "4px 12px",
160+
borderRadius: "4px",
161+
border: "1px solid #ccc",
162+
background: "white",
163+
cursor: "pointer",
164+
}}
165+
>
166+
Uncheck
167+
</button>
168+
<button
169+
type="button"
170+
onClick={() => setChecked(true)}
171+
style={{
172+
padding: "4px 12px",
173+
borderRadius: "4px",
174+
border: "1px solid #ccc",
175+
background: "white",
176+
cursor: "pointer",
177+
}}
178+
>
179+
Check
180+
</button>
181+
<button
182+
type="button"
183+
onClick={() => setChecked("indeterminate")}
184+
style={{
185+
padding: "4px 12px",
186+
borderRadius: "4px",
187+
border: "1px solid #ccc",
188+
background: "white",
189+
cursor: "pointer",
190+
}}
191+
>
192+
Set Indeterminate
193+
</button>
194+
</div>
195+
</div>
196+
);
197+
},
198+
};

0 commit comments

Comments
 (0)