@mzc-fe/design-system 0.0.1 → 0.0.2-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/dist/components/accordion.d.ts +7 -0
  2. package/dist/components/alert-dialog.d.ts +14 -0
  3. package/dist/components/alert.d.ts +9 -0
  4. package/dist/components/aspect-ratio.d.ts +3 -0
  5. package/dist/components/avatar.d.ts +6 -0
  6. package/dist/components/badge.d.ts +9 -0
  7. package/dist/components/breadcrumb.d.ts +11 -0
  8. package/dist/components/button-group.d.ts +11 -0
  9. package/dist/components/button.d.ts +10 -0
  10. package/dist/components/calendar.d.ts +8 -0
  11. package/dist/components/card.d.ts +9 -0
  12. package/dist/components/carousel.d.ts +19 -0
  13. package/dist/components/chart.d.ts +40 -0
  14. package/dist/components/checkbox.d.ts +4 -0
  15. package/dist/components/collapsible.d.ts +5 -0
  16. package/dist/components/command.d.ts +18 -0
  17. package/dist/components/context-menu.d.ts +25 -0
  18. package/dist/components/dialog.d.ts +15 -0
  19. package/dist/components/drawer.d.ts +13 -0
  20. package/dist/components/dropdown-menu.d.ts +25 -0
  21. package/dist/components/empty.d.ts +11 -0
  22. package/dist/components/field.d.ts +24 -0
  23. package/dist/components/form.d.ts +24 -0
  24. package/dist/components/hover-card.d.ts +6 -0
  25. package/dist/components/input-group.d.ts +16 -0
  26. package/dist/components/input-otp.d.ts +11 -0
  27. package/dist/components/input.d.ts +3 -0
  28. package/dist/components/item.d.ts +23 -0
  29. package/dist/components/kbd.d.ts +3 -0
  30. package/dist/components/label.d.ts +4 -0
  31. package/dist/components/menubar.d.ts +26 -0
  32. package/dist/components/navigation-menu.d.ts +14 -0
  33. package/dist/components/pagination.d.ts +13 -0
  34. package/dist/components/popover.d.ts +7 -0
  35. package/dist/components/progress.d.ts +4 -0
  36. package/dist/components/radio-group.d.ts +5 -0
  37. package/dist/components/resizable.d.ts +8 -0
  38. package/dist/components/scroll-area.d.ts +5 -0
  39. package/dist/components/select.d.ts +15 -0
  40. package/dist/components/separator.d.ts +4 -0
  41. package/dist/components/sheet.d.ts +13 -0
  42. package/dist/components/sidebar.d.ts +69 -0
  43. package/dist/components/skeleton.d.ts +2 -0
  44. package/dist/components/slider.d.ts +4 -0
  45. package/dist/components/sonner.d.ts +3 -0
  46. package/dist/components/spinner.d.ts +2 -0
  47. package/dist/components/switch.d.ts +4 -0
  48. package/dist/components/table.d.ts +10 -0
  49. package/dist/components/tabs.d.ts +7 -0
  50. package/dist/components/textarea.d.ts +3 -0
  51. package/dist/components/toggle-group.d.ts +9 -0
  52. package/dist/components/toggle.d.ts +9 -0
  53. package/dist/components/tooltip.d.ts +7 -0
  54. package/dist/design-system.css +1 -0
  55. package/dist/design-system.es.js +30200 -0
  56. package/dist/design-system.umd.js +260 -0
  57. package/dist/foundations/ThemeProvider.d.ts +13 -0
  58. package/dist/hooks/use-mobile.d.ts +1 -0
  59. package/dist/index.d.ts +54 -0
  60. package/dist/lib/utils.d.ts +2 -0
  61. package/package.json +14 -1
  62. package/.husky/pre-push +0 -21
  63. package/.storybook/main.ts +0 -11
  64. package/.storybook/preview.tsx +0 -30
  65. package/.vscode/settings.json +0 -12
  66. package/.vscode/tailwind.json +0 -105
  67. package/bitbucket-pipelines.yml +0 -50
  68. package/components.json +0 -21
  69. package/eslint.config.js +0 -38
  70. package/src/components/accordion.stories.tsx +0 -258
  71. package/src/components/accordion.test.tsx +0 -390
  72. package/src/components/accordion.tsx +0 -64
  73. package/src/components/alert-dialog.stories.tsx +0 -213
  74. package/src/components/alert-dialog.test.tsx +0 -80
  75. package/src/components/alert-dialog.tsx +0 -155
  76. package/src/components/alert.stories.tsx +0 -84
  77. package/src/components/alert.test.tsx +0 -35
  78. package/src/components/alert.tsx +0 -66
  79. package/src/components/aspect-ratio.stories.tsx +0 -97
  80. package/src/components/aspect-ratio.test.tsx +0 -47
  81. package/src/components/aspect-ratio.tsx +0 -11
  82. package/src/components/avatar.stories.tsx +0 -76
  83. package/src/components/avatar.test.tsx +0 -50
  84. package/src/components/avatar.tsx +0 -51
  85. package/src/components/badge.stories.tsx +0 -64
  86. package/src/components/badge.test.tsx +0 -34
  87. package/src/components/badge.tsx +0 -46
  88. package/src/components/breadcrumb.stories.tsx +0 -86
  89. package/src/components/breadcrumb.test.tsx +0 -74
  90. package/src/components/breadcrumb.tsx +0 -109
  91. package/src/components/button-group.stories.tsx +0 -62
  92. package/src/components/button-group.tsx +0 -83
  93. package/src/components/button.stories.tsx +0 -118
  94. package/src/components/button.test.tsx +0 -64
  95. package/src/components/button.tsx +0 -62
  96. package/src/components/calendar.stories.tsx +0 -81
  97. package/src/components/calendar.tsx +0 -220
  98. package/src/components/card.stories.tsx +0 -110
  99. package/src/components/card.test.tsx +0 -56
  100. package/src/components/card.tsx +0 -92
  101. package/src/components/carousel.stories.tsx +0 -90
  102. package/src/components/carousel.tsx +0 -239
  103. package/src/components/chart.tsx +0 -357
  104. package/src/components/checkbox.stories.tsx +0 -108
  105. package/src/components/checkbox.test.tsx +0 -67
  106. package/src/components/checkbox.tsx +0 -32
  107. package/src/components/collapsible.stories.tsx +0 -106
  108. package/src/components/collapsible.test.tsx +0 -92
  109. package/src/components/collapsible.tsx +0 -31
  110. package/src/components/command.stories.tsx +0 -90
  111. package/src/components/command.tsx +0 -182
  112. package/src/components/context-menu.stories.tsx +0 -63
  113. package/src/components/context-menu.tsx +0 -252
  114. package/src/components/dialog.stories.tsx +0 -128
  115. package/src/components/dialog.tsx +0 -141
  116. package/src/components/drawer.stories.tsx +0 -104
  117. package/src/components/drawer.tsx +0 -135
  118. package/src/components/dropdown-menu.stories.tsx +0 -97
  119. package/src/components/dropdown-menu.tsx +0 -255
  120. package/src/components/empty.stories.tsx +0 -90
  121. package/src/components/empty.test.tsx +0 -55
  122. package/src/components/empty.tsx +0 -104
  123. package/src/components/field.tsx +0 -246
  124. package/src/components/form.tsx +0 -168
  125. package/src/components/hover-card.stories.tsx +0 -66
  126. package/src/components/hover-card.tsx +0 -44
  127. package/src/components/input-group.stories.tsx +0 -57
  128. package/src/components/input-group.test.tsx +0 -40
  129. package/src/components/input-group.tsx +0 -170
  130. package/src/components/input-otp.stories.tsx +0 -94
  131. package/src/components/input-otp.test.tsx +0 -60
  132. package/src/components/input-otp.tsx +0 -75
  133. package/src/components/input.stories.tsx +0 -94
  134. package/src/components/input.test.tsx +0 -53
  135. package/src/components/input.tsx +0 -21
  136. package/src/components/item.tsx +0 -193
  137. package/src/components/kbd.stories.tsx +0 -100
  138. package/src/components/kbd.test.tsx +0 -28
  139. package/src/components/kbd.tsx +0 -28
  140. package/src/components/label.stories.tsx +0 -48
  141. package/src/components/label.test.tsx +0 -28
  142. package/src/components/label.tsx +0 -24
  143. package/src/components/menubar.tsx +0 -274
  144. package/src/components/navigation-menu.tsx +0 -168
  145. package/src/components/pagination.stories.tsx +0 -107
  146. package/src/components/pagination.tsx +0 -127
  147. package/src/components/popover.stories.tsx +0 -102
  148. package/src/components/popover.tsx +0 -48
  149. package/src/components/progress.stories.tsx +0 -76
  150. package/src/components/progress.test.tsx +0 -36
  151. package/src/components/progress.tsx +0 -29
  152. package/src/components/radio-group.stories.tsx +0 -73
  153. package/src/components/radio-group.test.tsx +0 -74
  154. package/src/components/radio-group.tsx +0 -45
  155. package/src/components/resizable.stories.tsx +0 -120
  156. package/src/components/resizable.tsx +0 -54
  157. package/src/components/scroll-area.stories.tsx +0 -64
  158. package/src/components/scroll-area.test.tsx +0 -46
  159. package/src/components/scroll-area.tsx +0 -58
  160. package/src/components/select.stories.tsx +0 -111
  161. package/src/components/select.test.tsx +0 -90
  162. package/src/components/select.tsx +0 -188
  163. package/src/components/separator.stories.tsx +0 -76
  164. package/src/components/separator.test.tsx +0 -24
  165. package/src/components/separator.tsx +0 -28
  166. package/src/components/sheet.stories.tsx +0 -122
  167. package/src/components/sheet.tsx +0 -137
  168. package/src/components/sidebar.tsx +0 -726
  169. package/src/components/skeleton.stories.tsx +0 -53
  170. package/src/components/skeleton.test.tsx +0 -24
  171. package/src/components/skeleton.tsx +0 -13
  172. package/src/components/slider.stories.tsx +0 -97
  173. package/src/components/slider.test.tsx +0 -49
  174. package/src/components/slider.tsx +0 -63
  175. package/src/components/sonner.stories.tsx +0 -96
  176. package/src/components/sonner.tsx +0 -38
  177. package/src/components/spinner.stories.tsx +0 -54
  178. package/src/components/spinner.test.tsx +0 -30
  179. package/src/components/spinner.tsx +0 -16
  180. package/src/components/switch.stories.tsx +0 -108
  181. package/src/components/switch.test.tsx +0 -62
  182. package/src/components/switch.tsx +0 -31
  183. package/src/components/table.stories.tsx +0 -139
  184. package/src/components/table.test.tsx +0 -85
  185. package/src/components/table.tsx +0 -114
  186. package/src/components/tabs.stories.tsx +0 -99
  187. package/src/components/tabs.test.tsx +0 -64
  188. package/src/components/tabs.tsx +0 -66
  189. package/src/components/textarea.stories.tsx +0 -89
  190. package/src/components/textarea.test.tsx +0 -53
  191. package/src/components/textarea.tsx +0 -18
  192. package/src/components/toggle-group.stories.tsx +0 -108
  193. package/src/components/toggle-group.test.tsx +0 -66
  194. package/src/components/toggle-group.tsx +0 -81
  195. package/src/components/toggle.stories.tsx +0 -98
  196. package/src/components/toggle.test.tsx +0 -42
  197. package/src/components/toggle.tsx +0 -45
  198. package/src/components/tooltip.stories.tsx +0 -111
  199. package/src/components/tooltip.tsx +0 -61
  200. package/src/foundations/README.md +0 -141
  201. package/src/foundations/ThemeProvider.tsx +0 -77
  202. package/src/foundations/color.css +0 -232
  203. package/src/foundations/color.stories.tsx +0 -719
  204. package/src/foundations/palette.css +0 -249
  205. package/src/foundations/spacing.css +0 -8
  206. package/src/foundations/typography.css +0 -143
  207. package/src/foundations/typography.stories.tsx +0 -17
  208. package/src/hooks/use-mobile.ts +0 -19
  209. package/src/index.css +0 -176
  210. package/src/index.ts +0 -336
  211. package/src/lib/utils.ts +0 -6
  212. package/src/test/setup.ts +0 -8
  213. package/src/vite-env.d.ts +0 -1
  214. package/tsconfig.app.json +0 -33
  215. package/tsconfig.json +0 -13
  216. package/tsconfig.node.json +0 -25
  217. package/vite.config.ts +0 -30
  218. package/vitest.config.ts +0 -25
  219. /package/{public → dist}/vite.svg +0 -0
@@ -1,89 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react-vite";
2
- import { Textarea } from "./textarea";
3
- import { Label } from "./label";
4
-
5
- const meta = {
6
- title: "Components/Textarea",
7
- component: Textarea,
8
- parameters: {
9
- layout: "padded",
10
- },
11
- tags: ["autodocs"],
12
- argTypes: {
13
- disabled: {
14
- control: "boolean",
15
- description: "Whether the textarea is disabled.",
16
- },
17
- placeholder: {
18
- control: "text",
19
- description: "Placeholder text.",
20
- },
21
- rows: {
22
- control: "number",
23
- description: "Number of visible text lines.",
24
- },
25
- },
26
- } satisfies Meta<typeof Textarea>;
27
-
28
- export default meta;
29
- type Story = StoryObj<typeof meta>;
30
-
31
- export const Default: Story = {
32
- args: {
33
- placeholder: "Type your message here...",
34
- },
35
- };
36
-
37
- export const WithLabel: Story = {
38
- render: () => (
39
- <div className="space-y-2 w-[350px]">
40
- <Label htmlFor="message">Message</Label>
41
- <Textarea id="message" placeholder="Type your message here..." />
42
- </div>
43
- ),
44
- };
45
-
46
- export const Sizes: Story = {
47
- render: () => (
48
- <div className="space-y-4 w-[350px]">
49
- <div className="space-y-2">
50
- <Label>Small (3 rows)</Label>
51
- <Textarea rows={3} placeholder="Small textarea..." />
52
- </div>
53
- <div className="space-y-2">
54
- <Label>Medium (5 rows)</Label>
55
- <Textarea rows={5} placeholder="Medium textarea..." />
56
- </div>
57
- <div className="space-y-2">
58
- <Label>Large (10 rows)</Label>
59
- <Textarea rows={10} placeholder="Large textarea..." />
60
- </div>
61
- </div>
62
- ),
63
- };
64
-
65
- export const Disabled: Story = {
66
- render: () => (
67
- <div className="space-y-2 w-[350px]">
68
- <Label>Disabled</Label>
69
- <Textarea disabled placeholder="This textarea is disabled" />
70
- </div>
71
- ),
72
- };
73
-
74
- export const WithError: Story = {
75
- render: () => (
76
- <div className="space-y-2 w-[350px]">
77
- <Label htmlFor="error">Message</Label>
78
- <Textarea
79
- id="error"
80
- placeholder="Type your message here..."
81
- aria-invalid="true"
82
- />
83
- <p className="text-sm text-destructive">
84
- Message must be at least 10 characters.
85
- </p>
86
- </div>
87
- ),
88
- };
89
-
@@ -1,53 +0,0 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { render } from "@testing-library/react";
3
- import userEvent from "@testing-library/user-event";
4
- import { Textarea } from "./textarea";
5
-
6
- describe("Textarea", () => {
7
- it("should render textarea element", () => {
8
- const { container } = render(<Textarea />);
9
- const textarea = container.querySelector('[data-slot="textarea"]');
10
- expect(textarea).toBeInTheDocument();
11
- });
12
-
13
- it("should display placeholder text", () => {
14
- const { getByPlaceholderText } = render(
15
- <Textarea placeholder="Enter your message..." />
16
- );
17
- expect(getByPlaceholderText("Enter your message...")).toBeInTheDocument();
18
- });
19
-
20
- it("should accept and display value", () => {
21
- const { container } = render(<Textarea value="test value" readOnly />);
22
- const textarea = container.querySelector('[data-slot="textarea"]') as HTMLTextAreaElement;
23
- expect(textarea.value).toBe("test value");
24
- });
25
-
26
- it("should be disabled when disabled prop is true", () => {
27
- const { container } = render(<Textarea disabled />);
28
- const textarea = container.querySelector('[data-slot="textarea"]') as HTMLTextAreaElement;
29
- expect(textarea).toBeDisabled();
30
- });
31
-
32
- it("should call onChange handler when value changes", async () => {
33
- const user = userEvent.setup();
34
- const handleChange = vi.fn();
35
- const { container } = render(<Textarea onChange={handleChange} />);
36
- const textarea = container.querySelector('[data-slot="textarea"]') as HTMLTextAreaElement;
37
- await user.type(textarea, "test");
38
- expect(handleChange).toHaveBeenCalled();
39
- });
40
-
41
- it("should apply aria-invalid attribute when invalid", () => {
42
- const { container } = render(<Textarea aria-invalid="true" />);
43
- const textarea = container.querySelector('[data-slot="textarea"]');
44
- expect(textarea).toHaveAttribute("aria-invalid", "true");
45
- });
46
-
47
- it("should support rows attribute", () => {
48
- const { container } = render(<Textarea rows={5} />);
49
- const textarea = container.querySelector('[data-slot="textarea"]') as HTMLTextAreaElement;
50
- expect(textarea.rows).toBe(5);
51
- });
52
- });
53
-
@@ -1,18 +0,0 @@
1
- import * as React from "react"
2
-
3
- import { cn } from "@/lib/utils"
4
-
5
- function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
6
- return (
7
- <textarea
8
- data-slot="textarea"
9
- className={cn(
10
- "border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
11
- className
12
- )}
13
- {...props}
14
- />
15
- )
16
- }
17
-
18
- export { Textarea }
@@ -1,108 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react-vite";
2
- import { ToggleGroup, ToggleGroupItem } from "./toggle-group";
3
- import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react";
4
-
5
- const meta = {
6
- title: "Components/ToggleGroup",
7
- component: ToggleGroup,
8
- parameters: {
9
- layout: "padded",
10
- },
11
- tags: ["autodocs"],
12
- argTypes: {
13
- type: {
14
- control: "select",
15
- options: ["single", "multiple"],
16
- description: "The type of toggle group.",
17
- },
18
- },
19
- } satisfies Meta<typeof ToggleGroup>;
20
-
21
- export default meta;
22
- type Story = StoryObj<typeof meta>;
23
-
24
- export const Default: Story = {
25
- args: {
26
- type: "single",
27
- },
28
- render: () => (
29
- <ToggleGroup type="single">
30
- <ToggleGroupItem value="bold" aria-label="Toggle bold">
31
- <BoldIcon />
32
- </ToggleGroupItem>
33
- <ToggleGroupItem value="italic" aria-label="Toggle italic">
34
- <ItalicIcon />
35
- </ToggleGroupItem>
36
- <ToggleGroupItem value="underline" aria-label="Toggle underline">
37
- <UnderlineIcon />
38
- </ToggleGroupItem>
39
- </ToggleGroup>
40
- ),
41
- };
42
-
43
- export const Multiple: Story = {
44
- args: {
45
- type: "multiple",
46
- },
47
- render: () => (
48
- <ToggleGroup type="multiple">
49
- <ToggleGroupItem value="bold" aria-label="Toggle bold">
50
- <BoldIcon />
51
- </ToggleGroupItem>
52
- <ToggleGroupItem value="italic" aria-label="Toggle italic">
53
- <ItalicIcon />
54
- </ToggleGroupItem>
55
- <ToggleGroupItem value="underline" aria-label="Toggle underline">
56
- <UnderlineIcon />
57
- </ToggleGroupItem>
58
- </ToggleGroup>
59
- ),
60
- };
61
-
62
- export const WithText: Story = {
63
- args: {
64
- type: "single",
65
- defaultValue: "center",
66
- },
67
- render: () => (
68
- <ToggleGroup type="single" defaultValue="center">
69
- <ToggleGroupItem value="left">Left</ToggleGroupItem>
70
- <ToggleGroupItem value="center">Center</ToggleGroupItem>
71
- <ToggleGroupItem value="right">Right</ToggleGroupItem>
72
- </ToggleGroup>
73
- ),
74
- };
75
-
76
- export const Variants: Story = {
77
- args: {
78
- type: "single",
79
- },
80
- render: () => (
81
- <div className="flex flex-col gap-4">
82
- <ToggleGroup type="single" variant="default">
83
- <ToggleGroupItem value="1">Option 1</ToggleGroupItem>
84
- <ToggleGroupItem value="2">Option 2</ToggleGroupItem>
85
- <ToggleGroupItem value="3">Option 3</ToggleGroupItem>
86
- </ToggleGroup>
87
- <ToggleGroup type="single" variant="outline">
88
- <ToggleGroupItem value="1">Option 1</ToggleGroupItem>
89
- <ToggleGroupItem value="2">Option 2</ToggleGroupItem>
90
- <ToggleGroupItem value="3">Option 3</ToggleGroupItem>
91
- </ToggleGroup>
92
- </div>
93
- ),
94
- };
95
-
96
- export const Disabled: Story = {
97
- args: {
98
- type: "single",
99
- disabled: true,
100
- },
101
- render: () => (
102
- <ToggleGroup type="single" disabled>
103
- <ToggleGroupItem value="1">Option 1</ToggleGroupItem>
104
- <ToggleGroupItem value="2">Option 2</ToggleGroupItem>
105
- <ToggleGroupItem value="3">Option 3</ToggleGroupItem>
106
- </ToggleGroup>
107
- ),
108
- };
@@ -1,66 +0,0 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { render } from "@testing-library/react";
3
- import userEvent from "@testing-library/user-event";
4
- import { ToggleGroup, ToggleGroupItem } from "./toggle-group";
5
-
6
- describe("ToggleGroup", () => {
7
- it("should render toggle group", () => {
8
- const { container } = render(
9
- <ToggleGroup type="single">
10
- <ToggleGroupItem value="item1">Item 1</ToggleGroupItem>
11
- </ToggleGroup>
12
- );
13
- const group = container.querySelector('[data-slot="toggle-group"]');
14
- expect(group).toBeInTheDocument();
15
- });
16
-
17
- it("should render toggle group items", () => {
18
- const { getByText } = render(
19
- <ToggleGroup type="single">
20
- <ToggleGroupItem value="item1">Item 1</ToggleGroupItem>
21
- <ToggleGroupItem value="item2">Item 2</ToggleGroupItem>
22
- </ToggleGroup>
23
- );
24
- expect(getByText("Item 1")).toBeInTheDocument();
25
- expect(getByText("Item 2")).toBeInTheDocument();
26
- });
27
-
28
- it("should call onValueChange when item is clicked in single mode", async () => {
29
- const user = userEvent.setup();
30
- const handleChange = vi.fn();
31
- const { getByText } = render(
32
- <ToggleGroup type="single" onValueChange={handleChange}>
33
- <ToggleGroupItem value="item1">Item 1</ToggleGroupItem>
34
- <ToggleGroupItem value="item2">Item 2</ToggleGroupItem>
35
- </ToggleGroup>
36
- );
37
- await user.click(getByText("Item 2"));
38
- expect(handleChange).toHaveBeenCalledWith("item2");
39
- });
40
-
41
- it("should support multiple selection", async () => {
42
- const user = userEvent.setup();
43
- const handleChange = vi.fn();
44
- const { getByText } = render(
45
- <ToggleGroup type="multiple" onValueChange={handleChange}>
46
- <ToggleGroupItem value="item1">Item 1</ToggleGroupItem>
47
- <ToggleGroupItem value="item2">Item 2</ToggleGroupItem>
48
- </ToggleGroup>
49
- );
50
- await user.click(getByText("Item 1"));
51
- await user.click(getByText("Item 2"));
52
- expect(handleChange).toHaveBeenCalledTimes(2);
53
- });
54
-
55
- it("should be disabled when disabled prop is true", () => {
56
- const { container } = render(
57
- <ToggleGroup type="single" disabled>
58
- <ToggleGroupItem value="item1">Item 1</ToggleGroupItem>
59
- </ToggleGroup>
60
- );
61
- const group = container.querySelector('[data-slot="toggle-group"]');
62
- // Radix UI toggle group may use aria-disabled or data-disabled
63
- expect(group).toBeInTheDocument();
64
- });
65
- });
66
-
@@ -1,81 +0,0 @@
1
- import * as React from "react";
2
- import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
3
- import { type VariantProps } from "class-variance-authority";
4
-
5
- import { cn } from "@/lib/utils";
6
- import { toggleVariants } from "@/components/toggle";
7
-
8
- const ToggleGroupContext = React.createContext<
9
- VariantProps<typeof toggleVariants> & {
10
- spacing?: number;
11
- }
12
- >({
13
- size: "default",
14
- variant: "default",
15
- spacing: 0,
16
- });
17
-
18
- function ToggleGroup({
19
- className,
20
- variant,
21
- size,
22
- spacing = 0,
23
- children,
24
- ...props
25
- }: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
26
- VariantProps<typeof toggleVariants> & {
27
- spacing?: number;
28
- }) {
29
- return (
30
- <ToggleGroupPrimitive.Root
31
- data-slot="toggle-group"
32
- data-variant={variant}
33
- data-size={size}
34
- data-spacing={spacing}
35
- style={{ "--gap": spacing } as React.CSSProperties}
36
- className={cn(
37
- "group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs",
38
- className
39
- )}
40
- {...props}
41
- >
42
- <ToggleGroupContext.Provider value={{ variant, size, spacing }}>
43
- {children}
44
- </ToggleGroupContext.Provider>
45
- </ToggleGroupPrimitive.Root>
46
- );
47
- }
48
-
49
- function ToggleGroupItem({
50
- className,
51
- children,
52
- variant,
53
- size,
54
- ...props
55
- }: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
56
- VariantProps<typeof toggleVariants>) {
57
- const context = React.useContext(ToggleGroupContext);
58
-
59
- return (
60
- <ToggleGroupPrimitive.Item
61
- data-slot="toggle-group-item"
62
- data-variant={context.variant || variant}
63
- data-size={context.size || size}
64
- data-spacing={context.spacing}
65
- className={cn(
66
- toggleVariants({
67
- variant: context.variant || variant,
68
- size: context.size || size,
69
- }),
70
- "w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10",
71
- "data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l",
72
- className
73
- )}
74
- {...props}
75
- >
76
- {children}
77
- </ToggleGroupPrimitive.Item>
78
- );
79
- }
80
-
81
- export { ToggleGroup, ToggleGroupItem };
@@ -1,98 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react-vite";
2
- import { Toggle } from "./toggle";
3
- import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react";
4
-
5
- const meta = {
6
- title: "Components/Toggle",
7
- component: Toggle,
8
- parameters: {
9
- layout: "padded",
10
- },
11
- tags: ["autodocs"],
12
- argTypes: {
13
- variant: {
14
- control: "select",
15
- options: ["default", "outline"],
16
- description: "The visual style variant of the toggle.",
17
- },
18
- size: {
19
- control: "select",
20
- options: ["default", "sm", "lg"],
21
- description: "The size of the toggle.",
22
- },
23
- pressed: {
24
- control: "boolean",
25
- description: "Whether the toggle is pressed.",
26
- },
27
- disabled: {
28
- control: "boolean",
29
- description: "Whether the toggle is disabled.",
30
- },
31
- },
32
- } satisfies Meta<typeof Toggle>;
33
-
34
- export default meta;
35
- type Story = StoryObj<typeof meta>;
36
-
37
- export const Default: Story = {
38
- args: {
39
- children: "Toggle",
40
- },
41
- };
42
-
43
- export const WithIcon: Story = {
44
- render: () => (
45
- <div className="flex gap-2">
46
- <Toggle aria-label="Toggle bold">
47
- <BoldIcon />
48
- </Toggle>
49
- <Toggle aria-label="Toggle italic">
50
- <ItalicIcon />
51
- </Toggle>
52
- <Toggle aria-label="Toggle underline">
53
- <UnderlineIcon />
54
- </Toggle>
55
- </div>
56
- ),
57
- };
58
-
59
- export const Variants: Story = {
60
- render: () => (
61
- <div className="flex flex-col gap-4">
62
- <div className="flex gap-2">
63
- <Toggle variant="default">Default</Toggle>
64
- <Toggle variant="outline">Outline</Toggle>
65
- </div>
66
- <div className="flex gap-2">
67
- <Toggle variant="default" pressed>
68
- Default Pressed
69
- </Toggle>
70
- <Toggle variant="outline" pressed>
71
- Outline Pressed
72
- </Toggle>
73
- </div>
74
- </div>
75
- ),
76
- };
77
-
78
- export const Sizes: Story = {
79
- render: () => (
80
- <div className="flex items-center gap-4">
81
- <Toggle size="sm">Small</Toggle>
82
- <Toggle size="default">Default</Toggle>
83
- <Toggle size="lg">Large</Toggle>
84
- </div>
85
- ),
86
- };
87
-
88
- export const Disabled: Story = {
89
- render: () => (
90
- <div className="flex gap-2">
91
- <Toggle disabled>Disabled</Toggle>
92
- <Toggle disabled pressed>
93
- Disabled Pressed
94
- </Toggle>
95
- </div>
96
- ),
97
- };
98
-
@@ -1,42 +0,0 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { render } from "@testing-library/react";
3
- import userEvent from "@testing-library/user-event";
4
- import { Toggle } from "./toggle";
5
-
6
- describe("Toggle", () => {
7
- it("should render toggle", () => {
8
- const { container } = render(<Toggle>Toggle</Toggle>);
9
- const toggle = container.querySelector('[data-slot="toggle"]');
10
- expect(toggle).toBeInTheDocument();
11
- });
12
-
13
- it("should be pressed when pressed prop is true", () => {
14
- const { container } = render(<Toggle pressed>Toggle</Toggle>);
15
- const toggle = container.querySelector('[data-slot="toggle"]');
16
- expect(toggle).toHaveAttribute("data-state", "on");
17
- });
18
-
19
- it("should call onPressedChange when clicked", async () => {
20
- const user = userEvent.setup();
21
- const handleChange = vi.fn();
22
- const { container } = render(
23
- <Toggle onPressedChange={handleChange}>Toggle</Toggle>
24
- );
25
- const toggle = container.querySelector('[data-slot="toggle"]') as HTMLElement;
26
- await user.click(toggle);
27
- expect(handleChange).toHaveBeenCalled();
28
- });
29
-
30
- it("should be disabled when disabled prop is true", () => {
31
- const { container } = render(<Toggle disabled>Toggle</Toggle>);
32
- const toggle = container.querySelector('[data-slot="toggle"]');
33
- expect(toggle).toHaveAttribute("data-disabled");
34
- });
35
-
36
- it("should apply variant classes", () => {
37
- const { container } = render(<Toggle variant="outline">Toggle</Toggle>);
38
- const toggle = container.querySelector('[data-slot="toggle"]');
39
- expect(toggle).toBeInTheDocument();
40
- });
41
- });
42
-
@@ -1,45 +0,0 @@
1
- import * as React from "react"
2
- import * as TogglePrimitive from "@radix-ui/react-toggle"
3
- import { cva, type VariantProps } from "class-variance-authority"
4
-
5
- import { cn } from "@/lib/utils"
6
-
7
- const toggleVariants = cva(
8
- "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
9
- {
10
- variants: {
11
- variant: {
12
- default: "bg-transparent",
13
- outline:
14
- "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
15
- },
16
- size: {
17
- default: "h-9 px-2 min-w-9",
18
- sm: "h-8 px-1.5 min-w-8",
19
- lg: "h-10 px-2.5 min-w-10",
20
- },
21
- },
22
- defaultVariants: {
23
- variant: "default",
24
- size: "default",
25
- },
26
- }
27
- )
28
-
29
- function Toggle({
30
- className,
31
- variant,
32
- size,
33
- ...props
34
- }: React.ComponentProps<typeof TogglePrimitive.Root> &
35
- VariantProps<typeof toggleVariants>) {
36
- return (
37
- <TogglePrimitive.Root
38
- data-slot="toggle"
39
- className={cn(toggleVariants({ variant, size, className }))}
40
- {...props}
41
- />
42
- )
43
- }
44
-
45
- export { Toggle, toggleVariants }