@windstream/react-shared-components 0.0.1

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 (112) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +360 -0
  3. package/dist/core.d.ts +389 -0
  4. package/dist/index.d.ts +389 -0
  5. package/dist/index.esm.js +35 -0
  6. package/dist/index.esm.js.map +1 -0
  7. package/dist/index.js +35 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/styles.css +3 -0
  10. package/dist/utils/index.d.ts +11 -0
  11. package/dist/utils/index.esm.js +2 -0
  12. package/dist/utils/index.esm.js.map +1 -0
  13. package/dist/utils/index.js +2 -0
  14. package/dist/utils/index.js.map +1 -0
  15. package/package.json +151 -0
  16. package/src/components/accordion/Accordion.stories.tsx +225 -0
  17. package/src/components/accordion/index.tsx +36 -0
  18. package/src/components/accordion/types.ts +10 -0
  19. package/src/components/alert-card/AlertCard.stories.tsx +172 -0
  20. package/src/components/alert-card/index.tsx +35 -0
  21. package/src/components/alert-card/types.ts +9 -0
  22. package/src/components/brand-button/BrandButton.stories.tsx +221 -0
  23. package/src/components/brand-button/helpers.ts +35 -0
  24. package/src/components/brand-button/index.tsx +90 -0
  25. package/src/components/brand-button/types.ts +27 -0
  26. package/src/components/button/Button.stories.tsx +108 -0
  27. package/src/components/button/index.tsx +23 -0
  28. package/src/components/button/types.ts +14 -0
  29. package/src/components/call-button/CallButton.stories.tsx +324 -0
  30. package/src/components/call-button/index.tsx +80 -0
  31. package/src/components/call-button/types.ts +9 -0
  32. package/src/components/checkbox/Checkbox.stories.tsx +248 -0
  33. package/src/components/checkbox/index.tsx +185 -0
  34. package/src/components/checkbox/types.ts +24 -0
  35. package/src/components/checklist/Checklist.stories.tsx +151 -0
  36. package/src/components/checklist/index.tsx +33 -0
  37. package/src/components/checklist/types.ts +6 -0
  38. package/src/components/collapse/Collapse.stories.tsx +256 -0
  39. package/src/components/collapse/index.tsx +44 -0
  40. package/src/components/collapse/types.ts +6 -0
  41. package/src/components/divider/Divider.stories.tsx +206 -0
  42. package/src/components/divider/index.tsx +23 -0
  43. package/src/components/divider/type.ts +3 -0
  44. package/src/components/input/Input.stories.tsx +358 -0
  45. package/src/components/input/index.tsx +174 -0
  46. package/src/components/input/types.ts +37 -0
  47. package/src/components/link/Link.stories.tsx +163 -0
  48. package/src/components/link/index.tsx +96 -0
  49. package/src/components/link/types.ts +25 -0
  50. package/src/components/list/List.stories.tsx +272 -0
  51. package/src/components/list/index.tsx +86 -0
  52. package/src/components/list/list-item/index.tsx +36 -0
  53. package/src/components/list/list-item/types.ts +13 -0
  54. package/src/components/list/types.ts +29 -0
  55. package/src/components/material-icon/MaterialIcon.stories.tsx +330 -0
  56. package/src/components/material-icon/constants.ts +95 -0
  57. package/src/components/material-icon/index.tsx +44 -0
  58. package/src/components/material-icon/types.ts +31 -0
  59. package/src/components/modal/Modal.stories.tsx +171 -0
  60. package/src/components/modal/index.tsx +168 -0
  61. package/src/components/modal/types.ts +24 -0
  62. package/src/components/radio-button/RadioButton.stories.tsx +307 -0
  63. package/src/components/radio-button/index.tsx +73 -0
  64. package/src/components/radio-button/types.ts +22 -0
  65. package/src/components/see-more/SeeMore.stories.tsx +182 -0
  66. package/src/components/see-more/index.tsx +38 -0
  67. package/src/components/see-more/types.ts +4 -0
  68. package/src/components/select/Select.stories.tsx +410 -0
  69. package/src/components/select/index.tsx +150 -0
  70. package/src/components/select/types.ts +34 -0
  71. package/src/components/select-plan-button/SelectPlanButton.stories.tsx +160 -0
  72. package/src/components/select-plan-button/index.tsx +21 -0
  73. package/src/components/select-plan-button/types.ts +4 -0
  74. package/src/components/skeleton/Skeleton.stories.tsx +180 -0
  75. package/src/components/skeleton/index.tsx +61 -0
  76. package/src/components/skeleton/types.ts +4 -0
  77. package/src/components/spinner/Spinner.stories.tsx +335 -0
  78. package/src/components/spinner/index.tsx +44 -0
  79. package/src/components/spinner/types.ts +5 -0
  80. package/src/components/text/Text.stories.tsx +302 -0
  81. package/src/components/text/index.tsx +26 -0
  82. package/src/components/text/types.ts +45 -0
  83. package/src/components/tooltip/Tooltip.stories.tsx +220 -0
  84. package/src/components/tooltip/index.tsx +78 -0
  85. package/src/components/tooltip/types.ts +7 -0
  86. package/src/components/view-cart-button/ViewCartButton.stories.tsx +241 -0
  87. package/src/components/view-cart-button/index.tsx +39 -0
  88. package/src/components/view-cart-button/types.ts +5 -0
  89. package/src/hooks/use-body-scroll-lock.ts +31 -0
  90. package/src/index.ts +81 -0
  91. package/src/setupTests.ts +46 -0
  92. package/src/stories/DocsTemplate.tsx +26 -0
  93. package/src/stories/assets/accessibility.png +0 -0
  94. package/src/stories/assets/accessibility.svg +1 -0
  95. package/src/stories/assets/addon-library.png +0 -0
  96. package/src/stories/assets/assets.png +0 -0
  97. package/src/stories/assets/avif-test-image.avif +0 -0
  98. package/src/stories/assets/context.png +0 -0
  99. package/src/stories/assets/discord.svg +1 -0
  100. package/src/stories/assets/docs.png +0 -0
  101. package/src/stories/assets/figma-plugin.png +0 -0
  102. package/src/stories/assets/github.svg +1 -0
  103. package/src/stories/assets/share.png +0 -0
  104. package/src/stories/assets/styling.png +0 -0
  105. package/src/stories/assets/testing.png +0 -0
  106. package/src/stories/assets/theming.png +0 -0
  107. package/src/stories/assets/tutorials.svg +1 -0
  108. package/src/stories/assets/youtube.svg +1 -0
  109. package/src/styles/globals.css +50 -0
  110. package/src/types/global.d.ts +9 -0
  111. package/src/utils/index.ts +49 -0
  112. package/tailwind.config.cjs +524 -0
@@ -0,0 +1,330 @@
1
+ import { MaterialIcon } from "./index";
2
+ import { DocsPage } from "@shared/stories/DocsTemplate";
3
+
4
+ import type { Meta, StoryObj } from "@storybook/react";
5
+
6
+ const meta: Meta<typeof MaterialIcon> = {
7
+ title: "Components/MaterialIcon",
8
+ component: MaterialIcon,
9
+ tags: ["autodocs"],
10
+ parameters: {
11
+ layout: "centered",
12
+ docs: {
13
+ page: DocsPage,
14
+ description: {
15
+ component:
16
+ "Material Design icon component with customizable size, color, and styling.",
17
+ },
18
+ },
19
+ },
20
+ argTypes: {
21
+ name: {
22
+ control: { type: "select" },
23
+ options: [
24
+ "home",
25
+ "search",
26
+ "check",
27
+ "settings",
28
+ "groups",
29
+ "mail",
30
+ "call",
31
+ "info",
32
+ ],
33
+ description: "Material icon name",
34
+ },
35
+ size: {
36
+ control: { type: "select" },
37
+ options: [20, 24, 32, 40, 48],
38
+ description: "Icon size",
39
+ },
40
+ weight: {
41
+ control: { type: "select" },
42
+ options: [100, 200, 300, 400, 500, 600, 700],
43
+ description: "Icon weight",
44
+ },
45
+ color: {
46
+ control: { type: "color" },
47
+ description: "Icon color",
48
+ },
49
+ className: {
50
+ control: { type: "text" },
51
+ description: "Additional CSS classes",
52
+ },
53
+ },
54
+ args: {
55
+ name: "home",
56
+ size: 24,
57
+ },
58
+ };
59
+
60
+ export default meta;
61
+ type Story = StoryObj<typeof meta>;
62
+
63
+ // Default icon
64
+ export const Default: Story = {
65
+ args: {},
66
+ };
67
+
68
+ // Different sizes
69
+ export const Sizes: Story = {
70
+ render: () => (
71
+ <div className="flex items-center gap-6">
72
+ <div className="text-center">
73
+ <MaterialIcon name="home" size={20} />
74
+ <p className="mt-1 text-xs">20px</p>
75
+ </div>
76
+ <div className="text-center">
77
+ <MaterialIcon name="home" size={24} />
78
+ <p className="mt-1 text-xs">24px</p>
79
+ </div>
80
+ <div className="text-center">
81
+ <MaterialIcon name="home" size={40} />
82
+ <p className="mt-1 text-xs">40px</p>
83
+ </div>
84
+ <div className="text-center">
85
+ <MaterialIcon name="home" size={48} />
86
+ <p className="mt-1 text-xs">48px</p>
87
+ </div>
88
+ </div>
89
+ ),
90
+ parameters: {
91
+ docs: {
92
+ description: {
93
+ story: "All available icon sizes.",
94
+ },
95
+ },
96
+ },
97
+ };
98
+
99
+ // Common icons
100
+ export const CommonIcons: Story = {
101
+ render: () => (
102
+ <div className="grid grid-cols-4 gap-4">
103
+ <div className="rounded-lg border p-4 text-center">
104
+ <MaterialIcon name="home" size={40} />
105
+ <p className="mt-2 text-sm">home</p>
106
+ </div>
107
+ <div className="rounded-lg border p-4 text-center">
108
+ <MaterialIcon name="search" size={40} />
109
+ <p className="mt-2 text-sm">search</p>
110
+ </div>
111
+ <div className="rounded-lg border p-4 text-center">
112
+ <MaterialIcon name="check" size={40} />
113
+ <p className="mt-2 text-sm">check</p>
114
+ </div>
115
+ <div className="rounded-lg border p-4 text-center">
116
+ <MaterialIcon name="settings" size={40} />
117
+ <p className="mt-2 text-sm">settings</p>
118
+ </div>
119
+ <div className="rounded-lg border p-4 text-center">
120
+ <MaterialIcon name="groups" size={40} />
121
+ <p className="mt-2 text-sm">groups</p>
122
+ </div>
123
+ <div className="rounded-lg border p-4 text-center">
124
+ <MaterialIcon name="mail" size={40} />
125
+ <p className="mt-2 text-sm">mail</p>
126
+ </div>
127
+ <div className="rounded-lg border p-4 text-center">
128
+ <MaterialIcon name="call" size={40} />
129
+ <p className="mt-2 text-sm">call</p>
130
+ </div>
131
+ <div className="rounded-lg border p-4 text-center">
132
+ <MaterialIcon name="info" size={40} />
133
+ <p className="mt-2 text-sm">info</p>
134
+ </div>
135
+ </div>
136
+ ),
137
+ parameters: {
138
+ docs: {
139
+ description: {
140
+ story: "Common Material Design icons.",
141
+ },
142
+ },
143
+ },
144
+ };
145
+
146
+ // Colored icons
147
+ export const ColoredIcons: Story = {
148
+ render: () => (
149
+ <div className="grid grid-cols-4 gap-4">
150
+ <div className="text-center">
151
+ <MaterialIcon name="check" size={40} color="#ef4444" />
152
+ <p className="mt-2 text-sm text-red-500">Red</p>
153
+ </div>
154
+ <div className="text-center">
155
+ <MaterialIcon name="check_circle" size={40} color="#10b981" />
156
+ <p className="mt-2 text-sm text-green-500">Green</p>
157
+ </div>
158
+ <div className="text-center">
159
+ <MaterialIcon name="info" size={40} color="#3b82f6" />
160
+ <p className="mt-2 text-sm text-blue-500">Blue</p>
161
+ </div>
162
+ <div className="text-center">
163
+ <MaterialIcon name="error" size={40} color="#f59e0b" />
164
+ <p className="mt-2 text-sm text-yellow-500">Yellow</p>
165
+ </div>
166
+ </div>
167
+ ),
168
+ parameters: {
169
+ docs: {
170
+ description: {
171
+ story: "Icons with different colors.",
172
+ },
173
+ },
174
+ },
175
+ };
176
+
177
+ // Icon with text
178
+ export const IconWithText: Story = {
179
+ render: () => (
180
+ <div className="space-y-4">
181
+ <div className="flex items-center gap-2">
182
+ <MaterialIcon name="mail" />
183
+ <span>Email notifications</span>
184
+ </div>
185
+ <div className="flex items-center gap-2">
186
+ <MaterialIcon name="call" />
187
+ <span>Phone support</span>
188
+ </div>
189
+ <div className="flex items-center gap-2">
190
+ <MaterialIcon name="forum" />
191
+ <span>Live chat</span>
192
+ </div>
193
+ <div className="flex items-center gap-2">
194
+ <MaterialIcon name="help" />
195
+ <span>Help center</span>
196
+ </div>
197
+ </div>
198
+ ),
199
+ parameters: {
200
+ docs: {
201
+ description: {
202
+ story: "Icons used alongside text content.",
203
+ },
204
+ },
205
+ },
206
+ };
207
+
208
+ // Interactive icons
209
+ export const InteractiveIcons: Story = {
210
+ render: () => (
211
+ <div className="grid grid-cols-3 gap-4">
212
+ <button className="rounded-lg border p-3 transition-colors hover:bg-gray-50">
213
+ <MaterialIcon name="check_box_outline_blank" size={40} />
214
+ <p className="mt-2 text-sm">Like</p>
215
+ </button>
216
+ <button className="rounded-lg border p-3 transition-colors hover:bg-gray-50">
217
+ <MaterialIcon name="share" size={40} />
218
+ <p className="mt-2 text-sm">Share</p>
219
+ </button>
220
+ <button className="rounded-lg border p-3 transition-colors hover:bg-gray-50">
221
+ <MaterialIcon name="check" size={40} />
222
+ <p className="mt-2 text-sm">Bookmark</p>
223
+ </button>
224
+ </div>
225
+ ),
226
+ parameters: {
227
+ docs: {
228
+ description: {
229
+ story: "Interactive icon buttons.",
230
+ },
231
+ },
232
+ },
233
+ };
234
+
235
+ // Status icons
236
+ export const StatusIcons: Story = {
237
+ render: () => (
238
+ <div className="grid grid-cols-4 gap-4">
239
+ <div className="text-center">
240
+ <MaterialIcon name="check_circle" size={40} />
241
+ <p className="mt-2 text-sm text-green-600">Success</p>
242
+ </div>
243
+ <div className="text-center">
244
+ <MaterialIcon name="error" size={40} />
245
+ <p className="mt-2 text-sm text-red-600">Error</p>
246
+ </div>
247
+ <div className="text-center">
248
+ <MaterialIcon name="error" size={40} />
249
+ <p className="mt-2 text-sm text-yellow-600">Warning</p>
250
+ </div>
251
+ <div className="text-center">
252
+ <MaterialIcon name="info" size={40} />
253
+ <p className="mt-2 text-sm text-blue-600">Info</p>
254
+ </div>
255
+ </div>
256
+ ),
257
+ parameters: {
258
+ docs: {
259
+ description: {
260
+ story: "Status and feedback icons.",
261
+ },
262
+ },
263
+ },
264
+ };
265
+
266
+ // All sizes showcase
267
+ export const AllSizes: Story = {
268
+ render: () => (
269
+ <div className="space-y-6">
270
+ <div>
271
+ <h3 className="mb-3 text-lg font-semibold">Icon Sizes</h3>
272
+ <div className="flex items-center gap-6">
273
+ <div className="text-center">
274
+ <MaterialIcon name="check" size={20} />
275
+ <p className="mt-1 text-xs">Small</p>
276
+ </div>
277
+ <div className="text-center">
278
+ <MaterialIcon name="check" size={24} />
279
+ <p className="mt-1 text-xs">Medium</p>
280
+ </div>
281
+ <div className="text-center">
282
+ <MaterialIcon name="check" size={40} />
283
+ <p className="mt-1 text-xs">Large</p>
284
+ </div>
285
+ <div className="text-center">
286
+ <MaterialIcon name="check" size={48} />
287
+ <p className="mt-1 text-xs">XLarge</p>
288
+ </div>
289
+ </div>
290
+ </div>
291
+
292
+ <div>
293
+ <h3 className="mb-3 text-lg font-semibold">Common Icons</h3>
294
+ <div className="grid grid-cols-6 gap-4">
295
+ <div className="text-center">
296
+ <MaterialIcon name="home" />
297
+ <p className="mt-1 text-xs">home</p>
298
+ </div>
299
+ <div className="text-center">
300
+ <MaterialIcon name="search" />
301
+ <p className="mt-1 text-xs">search</p>
302
+ </div>
303
+ <div className="text-center">
304
+ <MaterialIcon name="check" />
305
+ <p className="mt-1 text-xs">check</p>
306
+ </div>
307
+ <div className="text-center">
308
+ <MaterialIcon name="settings" />
309
+ <p className="mt-1 text-xs">settings</p>
310
+ </div>
311
+ <div className="text-center">
312
+ <MaterialIcon name="groups" />
313
+ <p className="mt-1 text-xs">groups</p>
314
+ </div>
315
+ <div className="text-center">
316
+ <MaterialIcon name="mail" />
317
+ <p className="mt-1 text-xs">mail</p>
318
+ </div>
319
+ </div>
320
+ </div>
321
+ </div>
322
+ ),
323
+ parameters: {
324
+ docs: {
325
+ description: {
326
+ story: "Complete showcase of all icon sizes and common icons.",
327
+ },
328
+ },
329
+ },
330
+ };
@@ -0,0 +1,95 @@
1
+ //If new icon need to add, Add iconname in iconNameList array and follow instruction in README.md
2
+ export const iconNameList = [
3
+ "info",
4
+ "download",
5
+ "featured_seasonal_and_gifts",
6
+ "visibility",
7
+ "paid",
8
+ "check_box",
9
+ "check_box_outline_blank",
10
+ "radio_button_unchecked",
11
+ "radio_button_checked",
12
+ "counter_1",
13
+ "counter_2",
14
+ "counter_3",
15
+ "error",
16
+ "search",
17
+ "cancel",
18
+ "router",
19
+ "broadcast_on_home",
20
+ "check",
21
+ "check_circle",
22
+ "lock",
23
+ "shield_lock",
24
+ "phone_in_talk",
25
+ "call",
26
+ "chevron_left",
27
+ "chevron_right",
28
+ "keyboard_arrow_down",
29
+ "keyboard_arrow_up",
30
+ "arrow_back",
31
+ "arrow_forward",
32
+ "help",
33
+ "home_pin",
34
+ "location_on",
35
+ "timer",
36
+ "schedule",
37
+ "add",
38
+ "remove",
39
+ "bolt",
40
+ "rocket",
41
+ "cloud_sync",
42
+ "close",
43
+ "groups",
44
+ "speed",
45
+ "mail",
46
+ "credit_card",
47
+ "language",
48
+ "forum",
49
+ "contract",
50
+ "local_atm",
51
+ "headset_mic",
52
+ "sensors",
53
+ "wifi",
54
+ "settings",
55
+ "home",
56
+ "devices",
57
+ "build",
58
+ "thumb_up",
59
+ "desktop_windows",
60
+ "block",
61
+ "all_inclusive",
62
+ "verified_user",
63
+ "extension",
64
+ "stadia_controller",
65
+ "visibility_off",
66
+ "close_fullscreen",
67
+ "progress_activity",
68
+ "travel_explore",
69
+ "share",
70
+ "business_center",
71
+ "upload",
72
+ "videocam",
73
+ "expand_circle_right",
74
+ "add_circle",
75
+ "do_not_disturb_on",
76
+ "expand_circle_up",
77
+ "expand_circle_down",
78
+ "replay",
79
+ "fiber_manual_record",
80
+ "menu",
81
+ "dangerous"
82
+ ] as const;
83
+
84
+ export const OpticalSizes = ["20dp", "24dp", "40dp", "48dp"] as const;
85
+ export const weights = [
86
+ "100",
87
+ "200",
88
+ "300",
89
+ "400",
90
+ "500",
91
+ "600",
92
+ "700",
93
+ ] as const;
94
+ export const emphasis = [-25, 0, 200] as const;
95
+ export const sizes = [20, 24, 32, 40, 48, 52] as const;
@@ -0,0 +1,44 @@
1
+ import React from "react";
2
+ import { cx } from "../../utils";
3
+ import type { IconProps } from "./types";
4
+
5
+ const MaterialIcon: React.FC<IconProps> = ({
6
+ name,
7
+ fill = 0,
8
+ opticalSize = "48dp",
9
+ weight = "200",
10
+ emphasis = 145,
11
+ size = 24,
12
+ color = "currentColor",
13
+ style = {},
14
+ className,
15
+ onClick,
16
+ dataTestId,
17
+ }) => {
18
+ const fontVariationSettings = `'FILL' ${fill}, 'wght' ${weight}, 'GRAD' ${emphasis}, 'opsz' ${opticalSize.substring(0, 2)}`;
19
+
20
+ const combinedStyle: React.CSSProperties = {
21
+ fontVariationSettings,
22
+ fontSize: `${size}px`,
23
+ fontFamily: "'Material Symbols Rounded'",
24
+ color: color || "currentColor",
25
+ ...style,
26
+ };
27
+
28
+ return (
29
+ <span
30
+ style={combinedStyle}
31
+ className={cx("material-symbols-rounded", className)}
32
+ onClick={onClick}
33
+ data-testid={dataTestId}
34
+ >
35
+ {name}
36
+ </span>
37
+ );
38
+ };
39
+
40
+ export { MaterialIcon };
41
+
42
+ MaterialIcon.displayName = "MaterialIcon";
43
+
44
+ export type { IconProps, IconName } from "./types";
@@ -0,0 +1,31 @@
1
+ import type { CSSProperties } from "react";
2
+ import {
3
+ emphasis,
4
+ iconNameList,
5
+ OpticalSizes,
6
+ sizes,
7
+ weights,
8
+ } from "./constants";
9
+
10
+ export type Fill = 1 | 0;
11
+
12
+ export type IconName = (typeof iconNameList)[number];
13
+
14
+ export type OpticalSize = (typeof OpticalSizes)[number];
15
+ export type Weight = (typeof weights)[number];
16
+ export type Emphasis = (typeof emphasis)[number];
17
+ export type Size = (typeof sizes)[number];
18
+
19
+ export type IconProps = {
20
+ name: IconName;
21
+ fill?: Fill;
22
+ opticalSize?: OpticalSize;
23
+ weight?: Weight;
24
+ emphasis?: Emphasis;
25
+ size?: Size;
26
+ color?: string;
27
+ style?: CSSProperties;
28
+ className?: string;
29
+ onClick?: () => void;
30
+ dataTestId?: string;
31
+ };
@@ -0,0 +1,171 @@
1
+ import { Modal } from "./index";
2
+ import { DocsPage } from "@shared/stories/DocsTemplate";
3
+
4
+ import type { Meta, StoryObj } from "@storybook/react";
5
+
6
+ const meta: Meta<typeof Modal> = {
7
+ title: "Components/Modal",
8
+ component: Modal,
9
+ tags: ["autodocs"],
10
+ parameters: {
11
+ layout: "centered",
12
+ docs: {
13
+ page: DocsPage,
14
+ description: {
15
+ component:
16
+ "A flexible modal component with customizable sizing, animations, and behavior options. Supports portal rendering, escape key handling, and overlay click dismissal.",
17
+ },
18
+ },
19
+ },
20
+ argTypes: {
21
+ isOpen: {
22
+ control: { type: "boolean" },
23
+ description: "Whether the modal is open",
24
+ },
25
+ title: {
26
+ control: { type: "text" },
27
+ description: "Optional title for the modal header",
28
+ },
29
+ size: {
30
+ control: { type: "select" },
31
+ options: ["xs", "sm", "md", "lg", "xl"],
32
+ description: "Modal size variant",
33
+ },
34
+ animation: {
35
+ control: { type: "select" },
36
+ options: ["popper", "bottomSheet"],
37
+ description: "Animation variant",
38
+ },
39
+ shape: {
40
+ control: { type: "select" },
41
+ options: ["rounded", "square"],
42
+ description: "Shape variant",
43
+ },
44
+ shouldCloseOnEsc: {
45
+ control: { type: "boolean" },
46
+ description: "Whether to close on escape key",
47
+ },
48
+ shouldCloseOnOverlayClick: {
49
+ control: { type: "boolean" },
50
+ description: "Whether to close on overlay click",
51
+ },
52
+ },
53
+ args: {
54
+ isOpen: true,
55
+ title: "Modal Title",
56
+ size: "md",
57
+ animation: "popper",
58
+ shape: "rounded",
59
+ shouldCloseOnEsc: true,
60
+ shouldCloseOnOverlayClick: true,
61
+ },
62
+ };
63
+
64
+ export default meta;
65
+ type Story = StoryObj<typeof Modal>;
66
+
67
+ export const Default: Story = {
68
+ args: {
69
+ children: (
70
+ <div className="space-y-4">
71
+ <p className="text-gray-600">
72
+ This is a default modal with some content. You can close it by clicking
73
+ the X button, pressing Escape, or clicking outside the modal.
74
+ </p>
75
+ <div className="flex justify-end space-x-2">
76
+ <button className="px-4 py-2 text-gray-600 hover:text-gray-800">
77
+ Cancel
78
+ </button>
79
+ <button className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
80
+ Confirm
81
+ </button>
82
+ </div>
83
+ </div>
84
+ ),
85
+ },
86
+ };
87
+
88
+ export const Small: Story = {
89
+ args: {
90
+ size: "xs",
91
+ children: (
92
+ <div className="text-center">
93
+ <p className="text-gray-600">Small modal content</p>
94
+ </div>
95
+ ),
96
+ },
97
+ };
98
+
99
+ export const Large: Story = {
100
+ args: {
101
+ size: "xl",
102
+ children: (
103
+ <div className="space-y-4">
104
+ <h3 className="text-lg font-semibold">Large Modal</h3>
105
+ <p className="text-gray-600">
106
+ This is a large modal that can accommodate more content. It's useful
107
+ for forms, detailed information, or complex layouts.
108
+ </p>
109
+ <div className="grid grid-cols-2 gap-4">
110
+ <div className="p-4 bg-gray-100 rounded">Content 1</div>
111
+ <div className="p-4 bg-gray-100 rounded">Content 2</div>
112
+ </div>
113
+ </div>
114
+ ),
115
+ },
116
+ };
117
+
118
+ export const BottomSheet: Story = {
119
+ args: {
120
+ animation: "bottomSheet",
121
+ size: "sm",
122
+ className: "top-auto bottom-0 max-w-none rounded-t-lg",
123
+ children: (
124
+ <div className="space-y-4">
125
+ <h3 className="text-lg font-semibold">Bottom Sheet</h3>
126
+ <p className="text-gray-600">
127
+ This modal slides up from the bottom, perfect for mobile interfaces.
128
+ </p>
129
+ <div className="space-y-2">
130
+ <button className="w-full p-3 text-left hover:bg-gray-100 rounded">
131
+ Option 1
132
+ </button>
133
+ <button className="w-full p-3 text-left hover:bg-gray-100 rounded">
134
+ Option 2
135
+ </button>
136
+ <button className="w-full p-3 text-left hover:bg-gray-100 rounded">
137
+ Option 3
138
+ </button>
139
+ </div>
140
+ </div>
141
+ ),
142
+ },
143
+ };
144
+
145
+ export const WithoutTitle: Story = {
146
+ args: {
147
+ title: undefined,
148
+ children: (
149
+ <div className="space-y-4">
150
+ <p className="text-gray-600">
151
+ This modal doesn't have a title in the header, but still has a close
152
+ button.
153
+ </p>
154
+ </div>
155
+ ),
156
+ },
157
+ };
158
+
159
+ export const NoCloseButton: Story = {
160
+ args: {
161
+ closeButtonClassName: "hidden",
162
+ children: (
163
+ <div className="space-y-4">
164
+ <p className="text-gray-600">
165
+ This modal doesn't have a close button. You can only close it by
166
+ pressing Escape or clicking outside.
167
+ </p>
168
+ </div>
169
+ ),
170
+ },
171
+ };