@recursica/mui-adapter 0.2.0 → 0.3.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 (84) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/mui-adapter.cjs +1 -1
  3. package/dist/mui-adapter.cjs.map +1 -1
  4. package/dist/mui-adapter.css +1 -1
  5. package/dist/mui-adapter.js +249 -90
  6. package/dist/mui-adapter.js.map +1 -1
  7. package/dist/src/components/Box/Box.d.ts +2 -3
  8. package/dist/src/components/Button/Button.d.ts +33 -2
  9. package/dist/src/components/Container/Container.d.ts +8 -2
  10. package/dist/src/components/Flex/Flex.d.ts +25 -2
  11. package/dist/src/components/Group/Group.d.ts +10 -2
  12. package/dist/src/components/Link/Link.d.ts +13 -2
  13. package/dist/src/components/Stack/Stack.d.ts +8 -2
  14. package/dist/src/components/Text/Text.d.ts +18 -2
  15. package/dist/src/components/Title/Title.d.ts +17 -2
  16. package/dist/src/components/Typography/Typography.d.ts +27 -0
  17. package/dist/src/utils/filterStylingProps.d.ts +3 -0
  18. package/package.json +2 -1
  19. package/src/Introduction.stories.tsx +113 -110
  20. package/src/OverStyling.tsx +18 -23
  21. package/src/Version.tsx +14 -21
  22. package/src/components/Accordion/Accordion.stories.tsx +19 -0
  23. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +19 -0
  24. package/src/components/Avatar/Avatar.stories.tsx +19 -0
  25. package/src/components/Badge/Badge.stories.tsx +19 -0
  26. package/src/components/Box/Box.stories.tsx +19 -10
  27. package/src/components/Box/Box.tsx +11 -14
  28. package/src/components/Box/IMPLEMENTATION_NOTES.md +5 -0
  29. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +19 -0
  30. package/src/components/Button/BUTTON_IMPLEMENTATION_NOTES.md +17 -0
  31. package/src/components/Button/Button.module.css +300 -0
  32. package/src/components/Button/Button.stories.tsx +136 -5
  33. package/src/components/Button/Button.tsx +116 -5
  34. package/src/components/Card/Card.stories.tsx +19 -0
  35. package/src/components/Checkbox/Checkbox.stories.tsx +19 -0
  36. package/src/components/Chip/Chip.stories.tsx +19 -0
  37. package/src/components/Container/Container.stories.tsx +19 -0
  38. package/src/components/Container/Container.tsx +56 -5
  39. package/src/components/Container/IMPLEMENTATION_NOTES.md +5 -0
  40. package/src/components/DatePicker/DatePicker.stories.tsx +19 -0
  41. package/src/components/Dropdown/Dropdown.stories.tsx +19 -0
  42. package/src/components/FileInput/FileInput.stories.tsx +19 -0
  43. package/src/components/FileUpload/FileUpload.stories.tsx +19 -0
  44. package/src/components/Flex/Flex.stories.tsx +19 -0
  45. package/src/components/Flex/Flex.tsx +77 -5
  46. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +19 -0
  47. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +19 -0
  48. package/src/components/Group/Group.stories.tsx +133 -5
  49. package/src/components/Group/Group.tsx +57 -5
  50. package/src/components/HoverCard/HoverCard.stories.tsx +19 -0
  51. package/src/components/Label/Label.stories.tsx +19 -0
  52. package/src/components/Link/Link.module.css +133 -0
  53. package/src/components/Link/Link.stories.tsx +52 -4
  54. package/src/components/Link/Link.tsx +47 -5
  55. package/src/components/Loader/Loader.stories.tsx +19 -0
  56. package/src/components/Menu/Menu.stories.tsx +19 -0
  57. package/src/components/Modal/Modal.stories.tsx +19 -0
  58. package/src/components/NumberInput/NumberInput.stories.tsx +19 -0
  59. package/src/components/Pagination/Pagination.stories.tsx +19 -0
  60. package/src/components/Panel/Panel.stories.tsx +19 -0
  61. package/src/components/Radio/Radio.stories.tsx +19 -0
  62. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +19 -0
  63. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +19 -0
  64. package/src/components/Slider/Slider.stories.tsx +19 -0
  65. package/src/components/Stack/Stack.stories.tsx +118 -5
  66. package/src/components/Stack/Stack.tsx +37 -5
  67. package/src/components/Stepper/Stepper.stories.tsx +19 -0
  68. package/src/components/Switch/Switch.stories.tsx +19 -0
  69. package/src/components/Table/Table.stories.tsx +19 -0
  70. package/src/components/Tabs/Tabs.stories.tsx +19 -0
  71. package/src/components/Text/Text.stories.tsx +87 -3
  72. package/src/components/Text/Text.tsx +27 -4
  73. package/src/components/TextArea/TextArea.stories.tsx +19 -0
  74. package/src/components/TextField/TextField.stories.tsx +19 -0
  75. package/src/components/TimePicker/TimePicker.stories.tsx +19 -0
  76. package/src/components/Timeline/Timeline.stories.tsx +19 -0
  77. package/src/components/Title/Title.stories.tsx +68 -3
  78. package/src/components/Title/Title.tsx +29 -5
  79. package/src/components/Toast/Toast.stories.tsx +19 -0
  80. package/src/components/Tooltip/Tooltip.stories.tsx +19 -0
  81. package/src/components/TransferList/TransferList.stories.tsx +19 -0
  82. package/src/components/Typography/Typography.tsx +42 -0
  83. package/src/utils/ColorSchemeWrapper.tsx +1 -5
  84. package/src/utils/filterStylingProps.ts +13 -1
@@ -6,6 +6,25 @@ const meta: Meta<typeof AssistiveElement> = {
6
6
  title: "UI-Kit/🚧 AssistiveElement",
7
7
  component: AssistiveElement,
8
8
  tags: ["autodocs"],
9
+ parameters: {
10
+ controls: {
11
+ include: [
12
+ "layer",
13
+ "withLayer",
14
+ "children",
15
+ "component",
16
+ "variant",
17
+ "size",
18
+ "icon",
19
+ "disabled",
20
+ "href",
21
+ "onClick",
22
+ "onChange",
23
+ "value",
24
+ "checked",
25
+ ],
26
+ },
27
+ },
9
28
  };
10
29
 
11
30
  export default meta;
@@ -6,6 +6,25 @@ const meta: Meta<typeof Avatar> = {
6
6
  title: "UI-Kit/🚧 Avatar",
7
7
  component: Avatar,
8
8
  tags: ["autodocs"],
9
+ parameters: {
10
+ controls: {
11
+ include: [
12
+ "layer",
13
+ "withLayer",
14
+ "children",
15
+ "component",
16
+ "variant",
17
+ "size",
18
+ "icon",
19
+ "disabled",
20
+ "href",
21
+ "onClick",
22
+ "onChange",
23
+ "value",
24
+ "checked",
25
+ ],
26
+ },
27
+ },
9
28
  };
10
29
 
11
30
  export default meta;
@@ -6,6 +6,25 @@ const meta: Meta<typeof Badge> = {
6
6
  title: "UI-Kit/🚧 Badge",
7
7
  component: Badge,
8
8
  tags: ["autodocs"],
9
+ parameters: {
10
+ controls: {
11
+ include: [
12
+ "layer",
13
+ "withLayer",
14
+ "children",
15
+ "component",
16
+ "variant",
17
+ "size",
18
+ "icon",
19
+ "disabled",
20
+ "href",
21
+ "onClick",
22
+ "onChange",
23
+ "value",
24
+ "checked",
25
+ ],
26
+ },
27
+ },
9
28
  };
10
29
 
11
30
  export default meta;
@@ -12,6 +12,23 @@ const meta: Meta<typeof Box> = {
12
12
  "The `Box` component is the foundational layout primitive. It accepts all standard MUI layout properties (like `m`, `mt`, `p`, `px`, etc.), but natively intercepts **Recursica Spacing Tokens** (e.g., `rec-none`, `rec-sm`, `rec-default`, `rec-md`, `rec-lg`, `rec-xl`, `rec-2xl`). This allows developers to use Recursica's strict design tokens seamlessly alongside standard MUI spacing.",
13
13
  },
14
14
  },
15
+ controls: {
16
+ include: [
17
+ "layer",
18
+ "withLayer",
19
+ "children",
20
+ "component",
21
+ "variant",
22
+ "size",
23
+ "icon",
24
+ "disabled",
25
+ "href",
26
+ "onClick",
27
+ "onChange",
28
+ "value",
29
+ "checked",
30
+ ],
31
+ },
15
32
  },
16
33
  };
17
34
 
@@ -24,11 +41,7 @@ export const Default: Story = {
24
41
  m: "20px",
25
42
  },
26
43
  render: (args) => (
27
- <Box
28
- {...args}
29
- style={{ border: "1px solid gray", padding: "10px" }}
30
- overStyled={true}
31
- />
44
+ <Box {...args} style={{ border: "1px solid gray", padding: "10px" }} />
32
45
  ),
33
46
  };
34
47
 
@@ -40,11 +53,7 @@ export const WithRecursicaTokens: Story = {
40
53
  },
41
54
  render: (args) => (
42
55
  <div style={{ border: "1px dashed #ccc", display: "inline-block" }}>
43
- <Box
44
- {...args}
45
- style={{ backgroundColor: "rgba(0,0,0,0.1)" }}
46
- overStyled={true}
47
- />
56
+ <Box {...args} style={{ backgroundColor: "rgba(0,0,0,0.1)" }} />
48
57
  </div>
49
58
  ),
50
59
  };
@@ -1,26 +1,23 @@
1
+ /**
2
+ * Box layout wrapper.
3
+ *
4
+ * NOTE: Box is the lowest-level primitive layout component. It explicitly ALLOWS
5
+ * the `sx` prop as an escape hatch. It does not use the strict RecursicaOverStyled gatekeeper
6
+ * or any style stripping utilities.
7
+ */
1
8
  import React, { forwardRef } from "react";
2
9
  import { Box as MUIBox, type BoxProps as MUIBoxProps } from "@mui/material";
3
- import {
4
- filterStylingProps,
5
- type RecursicaOverStyled,
6
- } from "../../utils/filterStylingProps";
7
10
 
8
- export type BoxProps<C extends React.ElementType = "div"> = RecursicaOverStyled<
9
- MUIBoxProps<C, { component?: C }>
11
+ export type BoxProps<C extends React.ElementType = "div"> = MUIBoxProps<
12
+ C,
13
+ { component?: C }
10
14
  >;
11
15
 
12
16
  export const Box = forwardRef(function Box<C extends React.ElementType = "div">(
13
17
  props: BoxProps<C>,
14
18
  ref: React.Ref<Element>,
15
19
  ) {
16
- const { overStyled = false, ...rest } = props;
17
-
18
- const sanitizedProps = filterStylingProps(
19
- rest as Record<string, unknown>,
20
- overStyled,
21
- );
22
-
23
- return <MUIBox ref={ref} {...sanitizedProps} />;
20
+ return <MUIBox ref={ref} {...props} />;
24
21
  }) as <C extends React.ElementType = "div">(
25
22
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
23
  props: BoxProps<C> & { ref?: React.ForwardedRef<any> },
@@ -0,0 +1,5 @@
1
+ # Box Implementation Notes
2
+
3
+ ## `sx` Prop Exemption
4
+
5
+ By design, the `Box` component is the most permissive primitive in the UI kit. It explicitly allows the `sx` prop to pass through to the underlying MUI `Box`. It does not use any strict styling gatekeepers (`RecursicaOverStyled`, `filterSxProp`). It is intended to be used as a final escape hatch when the standard layout primitives or design system tokens cannot fulfill a unique layout requirement.
@@ -6,6 +6,25 @@ const meta: Meta<typeof Breadcrumb> = {
6
6
  title: "UI-Kit/🚧 Breadcrumb",
7
7
  component: Breadcrumb,
8
8
  tags: ["autodocs"],
9
+ parameters: {
10
+ controls: {
11
+ include: [
12
+ "layer",
13
+ "withLayer",
14
+ "children",
15
+ "component",
16
+ "variant",
17
+ "size",
18
+ "icon",
19
+ "disabled",
20
+ "href",
21
+ "onClick",
22
+ "onChange",
23
+ "value",
24
+ "checked",
25
+ ],
26
+ },
27
+ },
9
28
  };
10
29
 
11
30
  export default meta;
@@ -0,0 +1,17 @@
1
+ # Button Component Implementation Notes
2
+
3
+ **Implementation Philosophy:**
4
+ The Button component serves as a foundational building block in Recursica. This implementation wraps the `@mui/material/Button` component but **disables its native visual heuristics entirely.**
5
+
6
+ We explicitly pass `disableRipple` and `disableElevation` to block MUI's dynamic behaviors. Furthermore, we intentionally **do not** map our `variant` or `size` properties to MUI's native `variant` or `size` props because doing so would trigger MUI's internal CSS engines to inject styles that clash with our strict design tokens.
7
+
8
+ **Styling Strategy:**
9
+
10
+ - We utilize `filterStylingProps` to prevent rogue injections of `sx`, `style`, or `className` properties that would violate the design system.
11
+ - All styling is controlled directly via CSS Modules, mapping DOM attributes like `data-variant` and `data-size` to pure CSS selectors.
12
+ - Hover states are managed with a standard `::after` pseudo-element overlay hack rather than relying on native hover psuedo-selectors modifying background-color directly. This allows a clean `opacity` overlay based on the provided design tokens, which guarantees identical visual feedback behavior across all underlying themes without overriding background hues manually.
13
+ - The polymorphic `component` prop natively supported by MUI is safely forwarded to allow correct semantics (e.g. rendering as an `<a>` tag or using a router `Link`).
14
+
15
+ **Accessibility:**
16
+
17
+ - We inject a development-time warning explicitly requiring `aria-label` when the component detects an icon-only configuration.
@@ -0,0 +1,300 @@
1
+ /* Baseline and Reset */
2
+ .root {
3
+ box-sizing: border-box;
4
+ margin: 0;
5
+ border-style: solid;
6
+ overflow: hidden; /* Truncation bounding box */
7
+ position: relative;
8
+ transition: all 0.2s ease;
9
+ width: fit-content; /* Prevent stretching in flex columns */
10
+
11
+ /* Shared Defaults */
12
+ font-family: var(
13
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-family
14
+ );
15
+ font-size: var(
16
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-size
17
+ );
18
+ font-style: var(
19
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-style
20
+ );
21
+ font-weight: var(
22
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-weight
23
+ );
24
+ letter-spacing: var(
25
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_letter-spacing
26
+ );
27
+ line-height: var(
28
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_line-height
29
+ );
30
+ text-decoration: var(
31
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_text-decoration
32
+ );
33
+ text-transform: var(
34
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_text-transform
35
+ );
36
+ }
37
+
38
+ /* Reset MUI native properties */
39
+ .root {
40
+ text-transform: none;
41
+ min-width: 0;
42
+ color: inherit;
43
+ background-color: transparent;
44
+ }
45
+
46
+ /* Internal layout logic for Truncation */
47
+ .root > * {
48
+ min-width: 0;
49
+ position: relative;
50
+ z-index: 1;
51
+ }
52
+
53
+ .label {
54
+ display: flex;
55
+ align-items: center;
56
+ min-width: 0;
57
+ flex: 1 1 0;
58
+ }
59
+
60
+ .labelText {
61
+ display: block;
62
+ min-width: 0;
63
+ overflow: hidden;
64
+ text-overflow: ellipsis;
65
+ white-space: nowrap;
66
+ font-size: inherit;
67
+ line-height: inherit;
68
+ }
69
+
70
+ /* ==== SIZES ==== */
71
+ .root[data-size="default"] {
72
+ border-radius: var(
73
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_border-radius
74
+ );
75
+ height: var(
76
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_height
77
+ );
78
+ min-width: var(
79
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_min-width
80
+ );
81
+ padding: 0
82
+ var(
83
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_horizontal-padding
84
+ );
85
+ }
86
+ .root[data-size="default"] .labelText {
87
+ max-width: var(
88
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_max-label-width
89
+ );
90
+ }
91
+ .root[data-size="small"] {
92
+ border-radius: var(
93
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_border-radius
94
+ );
95
+ height: var(
96
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_height
97
+ );
98
+ min-width: var(
99
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_min-width
100
+ );
101
+ padding: 0
102
+ var(
103
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_horizontal-padding
104
+ );
105
+
106
+ /* Override specific typography for small */
107
+ font-family: var(
108
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_text_font-family,
109
+ var(
110
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-family
111
+ )
112
+ );
113
+ font-size: var(
114
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_text_font-size,
115
+ var(
116
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-size
117
+ )
118
+ );
119
+ font-weight: var(
120
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_text_font-weight,
121
+ var(
122
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-weight
123
+ )
124
+ );
125
+ }
126
+ .root[data-size="small"] .labelText {
127
+ max-width: var(
128
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_max-label-width
129
+ );
130
+ }
131
+
132
+ /* Icon Resets */
133
+ .iconWrapper {
134
+ display: flex;
135
+ align-items: center;
136
+ justify-content: center;
137
+ flex-shrink: 0;
138
+ }
139
+ .iconWrapper > * {
140
+ width: 100%;
141
+ height: 100%;
142
+ object-fit: contain;
143
+ }
144
+ .root[data-size="default"] .iconWrapper {
145
+ width: var(
146
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_icon
147
+ );
148
+ height: var(
149
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_icon
150
+ );
151
+ }
152
+ .root[data-size="small"] .iconWrapper {
153
+ width: var(
154
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_icon
155
+ );
156
+ height: var(
157
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_icon
158
+ );
159
+ }
160
+
161
+ /* MUI uses .MuiButton-startIcon and .MuiButton-endIcon */
162
+ .root[data-size="default"] .MuiButton-startIcon,
163
+ .root[data-size="default"] .MuiButton-endIcon {
164
+ margin-left: 0;
165
+ margin-right: var(
166
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_icon-text-gap
167
+ );
168
+ }
169
+ .root[data-size="small"] .MuiButton-startIcon,
170
+ .root[data-size="small"] .MuiButton-endIcon {
171
+ margin-left: 0;
172
+ margin-right: var(
173
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_icon-text-gap
174
+ );
175
+ }
176
+
177
+ /* Icon-only logic overrides */
178
+ .root[data-icon-only] .MuiButton-startIcon,
179
+ .root[data-icon-only] .MuiButton-endIcon {
180
+ margin-right: 0;
181
+ margin-left: 0;
182
+ }
183
+
184
+ /* Disabled */
185
+ .root[data-size="default"]:disabled,
186
+ .root[data-size="default"]:global(.Mui-disabled) {
187
+ opacity: var(
188
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_disabled-opacity
189
+ );
190
+ cursor: not-allowed;
191
+ }
192
+ .root[data-size="small"]:disabled,
193
+ .root[data-size="small"]:global(.Mui-disabled) {
194
+ opacity: var(
195
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_disabled-opacity
196
+ );
197
+ cursor: not-allowed;
198
+ }
199
+
200
+ /* Global Hover Hack Overlay */
201
+ .root::after {
202
+ content: "";
203
+ position: absolute;
204
+ inset: 0;
205
+ border-radius: inherit;
206
+ z-index: 0;
207
+ pointer-events: none;
208
+ transition: opacity 150ms ease;
209
+ opacity: 0;
210
+ }
211
+ .root[data-size="default"]::after {
212
+ background-color: var(
213
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_hover-color
214
+ );
215
+ }
216
+ .root[data-size="small"]::after {
217
+ background-color: var(
218
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_hover-color
219
+ );
220
+ }
221
+ .root:hover:not(:disabled):not(:global(.Mui-disabled))::after {
222
+ opacity: var(
223
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_hover-opacity,
224
+ 0.1
225
+ );
226
+ }
227
+
228
+ /* ==== VARIANTS ==== */
229
+
230
+ /* SOLID */
231
+ .root[data-variant="solid"] {
232
+ border-width: var(
233
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_border-size
234
+ );
235
+ box-shadow: var(
236
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_elevation
237
+ );
238
+ background-color: var(
239
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_background
240
+ );
241
+ border-color: var(
242
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_border-color
243
+ );
244
+ color: var(
245
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_text
246
+ );
247
+ }
248
+ .root[data-variant="solid"]:hover:not(:disabled):not(:global(.Mui-disabled)) {
249
+ color: var(
250
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_text-hover
251
+ );
252
+ }
253
+
254
+ /* OUTLINE */
255
+ .root[data-variant="outline"] {
256
+ border-width: var(
257
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_border-size
258
+ );
259
+ box-shadow: var(
260
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_elevation
261
+ );
262
+ background-color: var(
263
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_background
264
+ );
265
+ border-color: var(
266
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_border-color
267
+ );
268
+ color: var(
269
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_text
270
+ );
271
+ }
272
+ .root[data-variant="outline"]:hover:not(:disabled):not(:global(.Mui-disabled)) {
273
+ color: var(
274
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_text-hover
275
+ );
276
+ }
277
+
278
+ /* TEXT */
279
+ .root[data-variant="text"] {
280
+ border-width: var(
281
+ --recursica_ui-kit_components_button_variants_styles_text_properties_border-size
282
+ );
283
+ box-shadow: var(
284
+ --recursica_ui-kit_components_button_variants_styles_text_properties_elevation
285
+ );
286
+ background-color: var(
287
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_background
288
+ );
289
+ border-color: var(
290
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_border-color
291
+ );
292
+ color: var(
293
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_text
294
+ );
295
+ }
296
+ .root[data-variant="text"]:hover:not(:disabled):not(:global(.Mui-disabled)) {
297
+ color: var(
298
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_text-hover
299
+ );
300
+ }
@@ -1,16 +1,147 @@
1
+ import React from "react";
1
2
  import type { Meta, StoryObj } from "@storybook/react";
2
3
  import { Button } from "./Button";
3
- import { ComingSoon } from "@recursica/storybook-template";
4
+ import { Layer } from "@recursica/adapter-common";
4
5
 
5
- const meta: Meta<typeof Button> = {
6
- title: "UI-Kit/🚧 Button",
6
+ type ButtonStoryProps = React.ComponentProps<typeof Button>;
7
+
8
+ const meta: Meta<ButtonStoryProps> = {
9
+ title: "UI-Kit/Button",
7
10
  component: Button,
8
11
  tags: ["autodocs"],
12
+ argTypes: {
13
+ variant: {
14
+ control: "select",
15
+ options: ["solid", "outline", "text"],
16
+ description: "The visual variant of the button",
17
+ },
18
+ size: {
19
+ control: "radio",
20
+ options: ["default", "small"],
21
+ description: "The size of the button",
22
+ },
23
+ },
24
+ parameters: {
25
+ controls: {
26
+ include: [
27
+ "layer",
28
+ "withLayer",
29
+ "variant",
30
+ "size",
31
+ "children",
32
+ "component",
33
+ "icon",
34
+ "disabled",
35
+ "href",
36
+ "onClick",
37
+ "onChange",
38
+ "value",
39
+ "checked",
40
+ ],
41
+ },
42
+ },
9
43
  };
10
44
 
11
45
  export default meta;
12
- type Story = StoryObj<typeof Button>;
46
+
47
+ type Story = StoryObj<ButtonStoryProps>;
13
48
 
14
49
  export const Default: Story = {
15
- render: () => <ComingSoon componentName="Button" />,
50
+ args: {
51
+ children: "Explore Button",
52
+ variant: "solid",
53
+ size: "default",
54
+ disabled: false,
55
+ },
56
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
57
+ render: ({ withLayer, layer, ...args }: any) => {
58
+ return <Button {...args} />;
59
+ },
60
+ };
61
+
62
+ export const SolidDefault: Story = {
63
+ args: {
64
+ children: "Solid Default",
65
+ variant: "solid",
66
+ size: "default",
67
+ },
68
+ };
69
+
70
+ export const OutlineSmall: Story = {
71
+ args: {
72
+ children: "Outline Small",
73
+ variant: "outline",
74
+ size: "small",
75
+ },
76
+ };
77
+
78
+ export const TextWithIcon: Story = {
79
+ args: {
80
+ children: "Text With Icon",
81
+ variant: "text",
82
+ size: "default",
83
+ icon: (
84
+ <svg
85
+ xmlns="http://www.w3.org/2000/svg"
86
+ width="24"
87
+ height="24"
88
+ viewBox="0 0 24 24"
89
+ fill="none"
90
+ stroke="currentColor"
91
+ strokeWidth="2"
92
+ strokeLinecap="round"
93
+ strokeLinejoin="round"
94
+ >
95
+ <circle cx="11" cy="11" r="8"></circle>
96
+ <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
97
+ </svg>
98
+ ),
99
+ },
100
+ };
101
+
102
+ export const LayerOneSolid: Story = {
103
+ args: {
104
+ children: "Layer 1 Solid",
105
+ variant: "solid",
106
+ size: "default",
107
+ },
108
+ render: (args: ButtonStoryProps) => (
109
+ <Layer layer={1} style={{ padding: "24px" }}>
110
+ <Button {...args} />
111
+ </Layer>
112
+ ),
113
+ };
114
+
115
+ export const DisabledSolid: Story = {
116
+ args: {
117
+ children: "Disabled Solid",
118
+ variant: "solid",
119
+ size: "default",
120
+ disabled: true,
121
+ },
122
+ };
123
+
124
+ export const PolymorphicAsLink: Story = {
125
+ args: {
126
+ children: "Button as Link",
127
+ variant: "solid",
128
+ size: "default",
129
+ component: "a",
130
+ href: "https://example.com",
131
+ target: "_blank",
132
+ },
133
+ };
134
+
135
+ export const TruncatedLabel: Story = {
136
+ args: {
137
+ children:
138
+ "This is an exceptionally long button label designed to demonstrate how the component handles text overflow by applying an ellipsis rather than breaking the layout or wrapping to multiple lines.",
139
+ variant: "solid",
140
+ size: "default",
141
+ },
142
+ render: (args: ButtonStoryProps) => (
143
+ <div style={{ maxWidth: "250px" }}>
144
+ <Button {...args} />
145
+ </div>
146
+ ),
16
147
  };