@recursica/adapter-mantine-v8 1.3.4 → 1.3.6

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 (60) hide show
  1. package/.storybook/commonArgTypes.ts +148 -0
  2. package/CHANGELOG.md +12 -0
  3. package/package.json +2 -2
  4. package/src/Introduction.stories.tsx +149 -0
  5. package/src/components/Accordion/Accordion.stories.tsx +189 -0
  6. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +68 -0
  7. package/src/components/AutoComplete/AutoComplete.stories.tsx +336 -0
  8. package/src/components/Avatar/Avatar.stories.tsx +92 -0
  9. package/src/components/Badge/Badge.stories.tsx +78 -0
  10. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +114 -0
  11. package/src/components/Button/Button.stories.tsx +192 -0
  12. package/src/components/Card/Card.stories.tsx +76 -0
  13. package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +4 -0
  14. package/src/components/Checkbox/Checkbox.stories.tsx +97 -0
  15. package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
  16. package/src/components/Chip/Chip.stories.tsx +128 -0
  17. package/src/components/Container/Container.stories.tsx +118 -0
  18. package/src/components/DatePicker/DatePicker.stories.tsx +158 -0
  19. package/src/components/Dropdown/Dropdown.stories.tsx +252 -0
  20. package/src/components/FileInput/FileInput.stories.tsx +313 -0
  21. package/src/components/FileUpload/FileUpload.stories.tsx +362 -0
  22. package/src/components/Flex/Flex.stories.tsx +128 -0
  23. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +118 -0
  24. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +129 -0
  25. package/src/components/Group/Group.stories.tsx +120 -0
  26. package/src/components/Heading/Heading.stories.tsx +112 -0
  27. package/src/components/HoverCard/HoverCard.stories.tsx +172 -0
  28. package/src/components/Label/Label.stories.tsx +131 -0
  29. package/src/components/LayoutGrid/LayoutGrid.stories.tsx +61 -0
  30. package/src/components/Link/Link.stories.tsx +58 -0
  31. package/src/components/Loader/Loader.stories.tsx +123 -0
  32. package/src/components/Menu/Menu.stories.tsx +370 -0
  33. package/src/components/Modal/Modal.stories.tsx +105 -0
  34. package/src/components/NativeInputA11y.dom.test.tsx +60 -0
  35. package/src/components/NumberInput/NumberInput.stories.tsx +96 -0
  36. package/src/components/Pagination/Pagination.stories.tsx +48 -0
  37. package/src/components/Panel/Panel.stories.tsx +219 -0
  38. package/src/components/Popover/Popover.stories.tsx +133 -0
  39. package/src/components/Radio/RADIO_IMPLEMENTATION_NOTES.md +5 -0
  40. package/src/components/Radio/Radio.stories.tsx +93 -0
  41. package/src/components/Radio/RadioGroup.stories.tsx +117 -0
  42. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +163 -0
  43. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +106 -0
  44. package/src/components/Slider/Slider.stories.tsx +282 -0
  45. package/src/components/Stack/Stack.stories.tsx +108 -0
  46. package/src/components/Stepper/Stepper.stories.tsx +148 -0
  47. package/src/components/Switch/SWITCH_IMPLEMENTATION_NOTES.md +4 -0
  48. package/src/components/Switch/Switch.stories.tsx +114 -0
  49. package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
  50. package/src/components/Table/Table.stories.tsx +140 -0
  51. package/src/components/Tabs/Tabs.stories.tsx +154 -0
  52. package/src/components/Text/Text.stories.tsx +148 -0
  53. package/src/components/TextArea/TextArea.stories.tsx +94 -0
  54. package/src/components/TextField/TextField.stories.tsx +162 -0
  55. package/src/components/TimePicker/TimePicker.stories.tsx +141 -0
  56. package/src/components/Timeline/Timeline.stories.tsx +128 -0
  57. package/src/components/Toast/Toast.stories.tsx +67 -0
  58. package/src/components/Tooltip/Tooltip.stories.tsx +165 -0
  59. package/src/components/TransferList/TransferList.stories.tsx +121 -0
  60. package/src/components/Tree/Tree.stories.tsx +104 -0
@@ -0,0 +1,163 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import { ReadOnlyField } from "./ReadOnlyField";
4
+ import { EmptyValueRenderer } from "@recursica/adapter-common";
5
+
6
+ const meta: Meta<typeof ReadOnlyField> = {
7
+ title: "UI Kit/ReadOnlyField",
8
+ component: ReadOnlyField,
9
+ tags: ["autodocs"],
10
+ parameters: {
11
+ docs: {
12
+ description: {
13
+ component:
14
+ "The ReadOnlyField safely natively wraps data sets bypassing active HTML interaction hooks while natively retaining exact bounding visual layouts defined by internal Design System Tokens. Useful for creating strict data-review profiles or conditional form read-overs.",
15
+ },
16
+ },
17
+ },
18
+ args: {
19
+ label: "Read Only Label",
20
+ value: "Fixed Data Set Value",
21
+ assistiveText: "Helper description text beneath the node.",
22
+ type: "text",
23
+ },
24
+ argTypes: {
25
+ type: {
26
+ control: "select",
27
+ options: ["text", "number"], // Add more as we support them
28
+ },
29
+ labelWithEditIcon: {
30
+ control: "boolean",
31
+ },
32
+ // We cannot natively control a React.ElementType through standard primitive storybook panels.
33
+ },
34
+ };
35
+
36
+ export default meta;
37
+
38
+ type Story = StoryObj<typeof ReadOnlyField>;
39
+
40
+ /**
41
+ * Playground story demonstrating standard structural blocks of the ReadOnlyField module dynamically.
42
+ */
43
+ export const Default: Story = {
44
+ args: {},
45
+ };
46
+
47
+ /**
48
+ * Shows the default handler replacing missing mapping data directly with 'N/A'.
49
+ */
50
+ export const EmptyValue: Story = {
51
+ args: {
52
+ value: "",
53
+ label: "Empty String Evaluated Automatically (Default 'N/A')",
54
+ },
55
+ };
56
+
57
+ const CustomEmptyTextRenderer: React.FC<{ value?: any }> & {
58
+ check?: (v: any) => boolean;
59
+ } = (props) => <EmptyValueRenderer {...props} emptyText="No Data Found" />;
60
+ CustomEmptyTextRenderer.check = EmptyValueRenderer.check;
61
+
62
+ /**
63
+ * Demonstrates overriding the baseline verbiage internally utilizing the exported `EmptyValueRenderer` while inheriting default evaluation checks.
64
+ */
65
+ export const CustomEmptyText: Story = {
66
+ args: {
67
+ value: null,
68
+ label: "Custom Empty Text Default",
69
+ emptyValueComponent: CustomEmptyTextRenderer,
70
+ },
71
+ };
72
+
73
+ const CustomEmptyCheckRenderer: React.FC<{ value?: any }> & {
74
+ check?: (v: any) => boolean;
75
+ } = () => {
76
+ return <i>Custom HTML Markup Provided</i>;
77
+ };
78
+ CustomEmptyCheckRenderer.check = (val) => val === "EMPTY_MOCK";
79
+
80
+ /**
81
+ * Validates a fully overridden emptyValueComponent injecting custom rendering boundaries alongside explicitly tailored validation rules evaluating datasets dynamically.
82
+ */
83
+ export const CustomEmptyRenderer: Story = {
84
+ args: {
85
+ value: "EMPTY_MOCK",
86
+ label: "Custom Logic Evaluation Binding",
87
+ emptyValueComponent: CustomEmptyCheckRenderer,
88
+ },
89
+ };
90
+
91
+ /**
92
+ * Validates the core read-only label execution and base default spacing bindings globally.
93
+ */
94
+ export const StackedDefault: Story = {
95
+ args: {
96
+ formLayout: "stacked",
97
+ value: "Some fixed readable text",
98
+ },
99
+ };
100
+
101
+ /**
102
+ * Binds side-by-side structures globally maintaining correct inline gutter layouts.
103
+ */
104
+ export const SideBySide: Story = {
105
+ args: {
106
+ formLayout: "side-by-side",
107
+ value: "Some fixed readable text mapping horizontally",
108
+ },
109
+ };
110
+
111
+ /**
112
+ * Tests the fallback structural logic when Edit icon natively overrides required bindings.
113
+ */
114
+ export const WithEditIcon: Story = {
115
+ args: {
116
+ labelWithEditIcon: true,
117
+ required: true,
118
+ value: "Editable fixed structure",
119
+ },
120
+ };
121
+
122
+ /**
123
+ * Demonstrates how the generic ReadOnlyField handles mapping different internal data types.
124
+ * Currently, all types safely default to string extraction mapping into the text renderer natively.
125
+ */
126
+ export const DataTypes: Story = {
127
+ args: {},
128
+ render: () => (
129
+ <div style={{ display: "flex", flexDirection: "column", gap: "24px" }}>
130
+ <ReadOnlyField
131
+ label="Text Mapping"
132
+ type="text"
133
+ value="Standard string output"
134
+ />
135
+ <ReadOnlyField label="Number Mapping" type="number" value={1234567.89} />
136
+ <ReadOnlyField
137
+ label="Date Mapping"
138
+ type="date"
139
+ value={new Date("2026-04-28T12:00:00Z").toLocaleDateString()}
140
+ />
141
+ <ReadOnlyField
142
+ label="Boolean Mapping (True)"
143
+ type="boolean"
144
+ value={true}
145
+ />
146
+ <ReadOnlyField
147
+ label="Boolean Mapping (False)"
148
+ type="boolean"
149
+ value={false}
150
+ />
151
+ <ReadOnlyField
152
+ label="Switch Mapping (True -> On)"
153
+ type="switch"
154
+ value={true}
155
+ />
156
+ <ReadOnlyField
157
+ label="Switch Mapping (False -> Off)"
158
+ type="switch"
159
+ value={false}
160
+ />
161
+ </div>
162
+ ),
163
+ };
@@ -0,0 +1,106 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { SegmentedControl } from "./SegmentedControl";
3
+
4
+ const meta: Meta<typeof SegmentedControl> = {
5
+ title: "UI-Kit/SegmentedControl",
6
+ component: SegmentedControl,
7
+ tags: ["autodocs"],
8
+ parameters: {
9
+ docs: {
10
+ description: {
11
+ component:
12
+ "SegmentedControl provides a linear set of two or more segments, each of which functions as a mutually exclusive button.",
13
+ },
14
+ },
15
+ },
16
+ argTypes: {
17
+ orientation: {
18
+ control: "radio",
19
+ options: ["horizontal", "vertical"],
20
+ },
21
+ fullWidth: {
22
+ control: "boolean",
23
+ },
24
+ disabled: {
25
+ control: "boolean",
26
+ },
27
+ data: { table: { disable: true } },
28
+ defaultChecked: { table: { disable: true } },
29
+ },
30
+ } satisfies Meta<typeof SegmentedControl>;
31
+
32
+ export default meta;
33
+ type Story = StoryObj<typeof SegmentedControl>;
34
+
35
+ export const Default: Story = {
36
+ args: {
37
+ data: ["React", "Angular", "Vue", "Svelte"],
38
+ orientation: "horizontal",
39
+ fullWidth: false,
40
+ },
41
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
42
+ render: ({ withLayer, layer, ...args }: any) => {
43
+ return <SegmentedControl {...args} />;
44
+ },
45
+ };
46
+
47
+ export const FullWidth: Story = {
48
+ args: {
49
+ data: ["Daily", "Weekly", "Monthly"],
50
+ fullWidth: true,
51
+ },
52
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
53
+ render: ({ withLayer, layer, ...args }: any) => {
54
+ return <SegmentedControl {...args} />;
55
+ },
56
+ };
57
+
58
+ export const Vertical: Story = {
59
+ args: {
60
+ data: ["Option 1", "Option 2", "Option 3"],
61
+ orientation: "vertical",
62
+ },
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
64
+ render: ({ withLayer, layer, ...args }: any) => {
65
+ return <SegmentedControl {...args} />;
66
+ },
67
+ };
68
+
69
+ export const Disabled: Story = {
70
+ args: {
71
+ data: ["Preview", "Code", "Edit"],
72
+ disabled: true,
73
+ },
74
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
75
+ render: ({ withLayer, layer, ...args }: any) => {
76
+ return <SegmentedControl {...args} />;
77
+ },
78
+ };
79
+
80
+ const CheckIcon = () => (
81
+ <svg
82
+ viewBox="0 0 24 24"
83
+ fill="none"
84
+ xmlns="http://www.w3.org/2000/svg"
85
+ stroke="currentColor"
86
+ strokeWidth="2"
87
+ strokeLinecap="round"
88
+ strokeLinejoin="round"
89
+ >
90
+ <polyline points="20 6 9 17 4 12" />
91
+ </svg>
92
+ );
93
+
94
+ export const WithIcons: Story = {
95
+ args: {
96
+ data: [
97
+ { value: "daily", label: "Daily", icon: <CheckIcon /> },
98
+ { value: "weekly", label: "Weekly", icon: <CheckIcon /> },
99
+ { value: "monthly", label: "Monthly", icon: <CheckIcon /> },
100
+ ],
101
+ },
102
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
103
+ render: ({ withLayer, layer, ...args }: any) => {
104
+ return <SegmentedControl {...args} />;
105
+ },
106
+ };
@@ -0,0 +1,282 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Slider } from "./Slider";
3
+ import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
4
+
5
+ const meta: Meta<typeof Slider> = {
6
+ title: "UI-Kit/Slider",
7
+ component: Slider,
8
+ tags: ["autodocs"],
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component: `
13
+ The \`Slider\` component wraps Mantine's Slider to support a premium design system, a bidirectional input state,
14
+ custom min/max labels, step indicators, and strict states like error, disabled, and read-only.
15
+
16
+ ### Architecture
17
+ The component uses Recursica's unified \`FormControlWrapper\` and \`<WithReadOnlyWrapper>\` to render consistent form layouts (stacked, side-by-side) and read-only representations.
18
+ All visual properties map perfectly to token values inside \`Slider.module.css\`.
19
+ `,
20
+ },
21
+ },
22
+ },
23
+ argTypes: {
24
+ ...formControlArgTypes,
25
+ disabled: {
26
+ control: "boolean",
27
+ description: "Disables both the slider track and the text input field.",
28
+ },
29
+ error: {
30
+ control: "text",
31
+ description:
32
+ "Places the slider in an error state with custom border/icon highlights.",
33
+ },
34
+ required: {
35
+ control: "boolean",
36
+ },
37
+ label: {
38
+ control: "text",
39
+ description: "Outer form control label.",
40
+ },
41
+ assistiveText: {
42
+ control: "text",
43
+ description: "Assistive text rendered below or beside the component.",
44
+ },
45
+ readOnly: {
46
+ control: "boolean",
47
+ description: "Puts the component in static read-only mode.",
48
+ },
49
+ showInput: {
50
+ control: "boolean",
51
+ description: "Controls whether the numeric input box is visible.",
52
+ },
53
+ showMinMaxLabels: {
54
+ control: "boolean",
55
+ description: "Toggles rendering of min/max labels below the track.",
56
+ },
57
+ },
58
+ };
59
+
60
+ export default meta;
61
+
62
+ type Story = StoryObj<typeof Slider>;
63
+
64
+ export const Default: Story = {
65
+ args: {
66
+ label: "Auditory Threshold",
67
+ assistiveText: "Specify the maximum decibel frequency boundary.",
68
+ defaultValue: 60,
69
+ min: 10,
70
+ max: 100,
71
+ step: 1,
72
+ showMinMaxLabels: true,
73
+ },
74
+ };
75
+
76
+ export const WithInputField: Story = {
77
+ args: {
78
+ ...Default.args,
79
+ showInput: true,
80
+ },
81
+ };
82
+
83
+ export const SideBySideLayout: Story = {
84
+ args: {
85
+ ...Default.args,
86
+ formLayout: "side-by-side",
87
+ },
88
+ };
89
+
90
+ export const Disabled: Story = {
91
+ args: {
92
+ label: "Decommissioned Server Node",
93
+ assistiveText: "Modifications to this environment are frozen.",
94
+ defaultValue: 35,
95
+ disabled: true,
96
+ },
97
+ };
98
+
99
+ export const ErrorState: Story = {
100
+ args: {
101
+ label: "Core Temperature Alert",
102
+ assistiveText:
103
+ "Severe core degradation across the hypervisor socket cluster.",
104
+ defaultValue: 85,
105
+ error: "Thermal overload threshold exceeded.",
106
+ required: true,
107
+ },
108
+ };
109
+
110
+ export const StaticReadOnly: Story = {
111
+ args: {
112
+ label: "System Calibration Metrics",
113
+ assistiveText:
114
+ "Frozen baseline calibrations derived during initial staging.",
115
+ value: 65,
116
+ readOnly: true,
117
+ },
118
+ };
119
+
120
+ export const EditableReadOnly: Story = {
121
+ args: {
122
+ label: "Adaptive Node Output",
123
+ assistiveText:
124
+ "Click edit to unlock bidirectional input parameter boundaries.",
125
+ defaultValue: 15,
126
+ readOnly: true,
127
+ labelWithEditIcon: true,
128
+ },
129
+ };
130
+
131
+ export const WithMarks: Story = {
132
+ args: {
133
+ label: "Interactive Marks Map",
134
+ defaultValue: 50,
135
+ min: 0,
136
+ max: 100,
137
+ step: 10,
138
+ marks: [
139
+ { value: 0, label: "0%" },
140
+ { value: 25, label: "25%" },
141
+ { value: 50, label: "50%" },
142
+ { value: 75, label: "75%" },
143
+ { value: 100, label: "100%" },
144
+ ],
145
+ showMinMaxLabels: false,
146
+ },
147
+ };
148
+
149
+ export const WithIconsAndLabels: Story = {
150
+ args: {
151
+ label: "Volume",
152
+ assistiveText:
153
+ "Icons flank the track; min/max labels replace the raw bounds.",
154
+ defaultValue: 60,
155
+ minLabel: "Quiet",
156
+ maxLabel: "Loud",
157
+ tooltipLabel: (value: number) => `${value}%`,
158
+ icon: (
159
+ <svg
160
+ xmlns="http://www.w3.org/2000/svg"
161
+ width="16"
162
+ height="16"
163
+ viewBox="0 0 24 24"
164
+ fill="none"
165
+ stroke="currentColor"
166
+ strokeWidth="2"
167
+ strokeLinecap="round"
168
+ strokeLinejoin="round"
169
+ >
170
+ <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon>
171
+ </svg>
172
+ ),
173
+ trailingIcon: (
174
+ <svg
175
+ xmlns="http://www.w3.org/2000/svg"
176
+ width="16"
177
+ height="16"
178
+ viewBox="0 0 24 24"
179
+ fill="none"
180
+ stroke="currentColor"
181
+ strokeWidth="2"
182
+ strokeLinecap="round"
183
+ strokeLinejoin="round"
184
+ >
185
+ <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon>
186
+ <path d="M15.54 8.46a5 5 0 0 1 0 7.07"></path>
187
+ <path d="M19.07 4.93a10 10 0 0 1 0 14.14"></path>
188
+ </svg>
189
+ ),
190
+ },
191
+ };
192
+
193
+ export const RangeMode: Story = {
194
+ args: {
195
+ label: "Price Range",
196
+ assistiveText: "Pass a [number, number] tuple to render two thumbs.",
197
+ defaultValue: [20, 80],
198
+ min: 0,
199
+ max: 100,
200
+ showMinMaxLabels: true,
201
+ },
202
+ };
203
+
204
+ export const RangeModeWithInputs: Story = {
205
+ args: {
206
+ ...RangeMode.args,
207
+ showInput: true,
208
+ },
209
+ };
210
+
211
+ export const RangeModeWithIconsAndInputs: Story = {
212
+ args: {
213
+ label: "Price Range",
214
+ assistiveText:
215
+ "Full range usage: leading/trailing icons, min/max label overrides, and both bound inputs.",
216
+ defaultValue: [20, 80],
217
+ min: 0,
218
+ max: 100,
219
+ showInput: true,
220
+ minLabel: "$0",
221
+ maxLabel: "$100",
222
+ tooltipLabel: (value: number) => `$${value}`,
223
+ icon: (
224
+ <svg
225
+ xmlns="http://www.w3.org/2000/svg"
226
+ width="16"
227
+ height="16"
228
+ viewBox="0 0 24 24"
229
+ fill="none"
230
+ stroke="currentColor"
231
+ strokeWidth="2"
232
+ strokeLinecap="round"
233
+ strokeLinejoin="round"
234
+ >
235
+ <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon>
236
+ </svg>
237
+ ),
238
+ trailingIcon: (
239
+ <svg
240
+ xmlns="http://www.w3.org/2000/svg"
241
+ width="16"
242
+ height="16"
243
+ viewBox="0 0 24 24"
244
+ fill="none"
245
+ stroke="currentColor"
246
+ strokeWidth="2"
247
+ strokeLinecap="round"
248
+ strokeLinejoin="round"
249
+ >
250
+ <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon>
251
+ <path d="M15.54 8.46a5 5 0 0 1 0 7.07"></path>
252
+ <path d="M19.07 4.93a10 10 0 0 1 0 14.14"></path>
253
+ </svg>
254
+ ),
255
+ },
256
+ };
257
+
258
+ export const FormLayouts: Story = {
259
+ render: () => (
260
+ <div
261
+ style={{
262
+ display: "flex",
263
+ flexDirection: "column",
264
+ gap: "2.5rem",
265
+ maxWidth: 600,
266
+ }}
267
+ >
268
+ <Slider
269
+ label="Stacked Layout"
270
+ assistiveText="This is the standard top-to-bottom stacked form layout."
271
+ defaultValue={40}
272
+ formLayout="stacked"
273
+ />
274
+ <Slider
275
+ label="Side-by-Side Layout"
276
+ assistiveText="This is the side-by-side layout aligning label beside control."
277
+ defaultValue={60}
278
+ formLayout="side-by-side"
279
+ />
280
+ </div>
281
+ ),
282
+ };
@@ -0,0 +1,108 @@
1
+ import React from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import { Stack } from "./Stack";
4
+ import { Button } from "../Button";
5
+ import { Text } from "../Text/Text";
6
+
7
+ type StackStoryProps = React.ComponentProps<typeof Stack>;
8
+
9
+ const meta: Meta<StackStoryProps> = {
10
+ title: "UI-Kit/Stack",
11
+ component: Stack,
12
+ tags: ["autodocs"],
13
+ parameters: {
14
+ docs: {
15
+ description: {
16
+ component:
17
+ "Stack is a flex vertical layout container that maps directly to Mantine's Stack component allowing safe layout property passing.",
18
+ },
19
+ },
20
+ },
21
+ args: {
22
+ gap: "rec-default",
23
+ align: "stretch",
24
+ justify: "flex-start",
25
+ },
26
+ argTypes: {
27
+ gap: {
28
+ control: "select",
29
+ options: [
30
+ "rec-none",
31
+ "rec-sm",
32
+ "rec-default",
33
+ "rec-md",
34
+ "rec-lg",
35
+ "rec-xl",
36
+ "rec-2xl",
37
+ "xs",
38
+ "sm",
39
+ "md",
40
+ "lg",
41
+ "xl",
42
+ ],
43
+ description: "Gap between elements",
44
+ },
45
+ align: {
46
+ control: "select",
47
+ options: ["flex-start", "center", "flex-end", "stretch"],
48
+ description: "Align-items property",
49
+ },
50
+ justify: {
51
+ control: "select",
52
+ options: [
53
+ "flex-start",
54
+ "center",
55
+ "flex-end",
56
+ "space-between",
57
+ "space-around",
58
+ ],
59
+ description: "Justify-content property",
60
+ },
61
+ defaultChecked: {
62
+ table: { disable: true },
63
+ },
64
+ },
65
+ };
66
+
67
+ export default meta;
68
+
69
+ type Story = StoryObj<StackStoryProps>;
70
+
71
+ export const Default: Story = {
72
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
73
+ render: ({ withLayer, layer, ...args }: any) => (
74
+ <Stack {...args}>
75
+ <Button variant="solid">Primary Block</Button>
76
+ <Button variant="outline">Secondary Block</Button>
77
+ <Text>Text element within Stack</Text>
78
+ </Stack>
79
+ ),
80
+ };
81
+
82
+ export const StaticGapSmall: Story = {
83
+ args: {
84
+ gap: "rec-sm",
85
+ },
86
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
87
+ render: ({ withLayer, layer, ...args }: any) => (
88
+ <Stack {...args}>
89
+ <Button variant="solid">Item 1</Button>
90
+ <Button variant="solid">Item 2</Button>
91
+ <Button variant="solid">Item 3</Button>
92
+ </Stack>
93
+ ),
94
+ };
95
+
96
+ export const StaticGapLarge: Story = {
97
+ args: {
98
+ gap: "rec-xl",
99
+ },
100
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
101
+ render: ({ withLayer, layer, ...args }: any) => (
102
+ <Stack {...args}>
103
+ <Button variant="solid">Item 1</Button>
104
+ <Button variant="solid">Item 2</Button>
105
+ <Button variant="solid">Item 3</Button>
106
+ </Stack>
107
+ ),
108
+ };