@recursica/mui-adapter 0.6.0 → 0.7.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 (164) hide show
  1. package/ARCHITECTURE.md +15 -0
  2. package/CHANGELOG.md +6 -0
  3. package/SETUP.md +77 -0
  4. package/USAGE.md +55 -0
  5. package/dist/mui-adapter.cjs +26 -26
  6. package/dist/mui-adapter.cjs.map +1 -1
  7. package/dist/mui-adapter.css +1 -1
  8. package/dist/mui-adapter.js +3721 -3511
  9. package/dist/mui-adapter.js.map +1 -1
  10. package/dist/src/components/Accordion/Accordion.d.ts +9 -29
  11. package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +2 -5
  12. package/dist/src/components/Autocomplete/Autocomplete.d.ts +4 -8
  13. package/dist/src/components/Avatar/Avatar.d.ts +1 -6
  14. package/dist/src/components/Badge/Badge.d.ts +1 -4
  15. package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +2 -3
  16. package/dist/src/components/Button/Button.d.ts +2 -17
  17. package/dist/src/components/Card/Card.d.ts +2 -4
  18. package/dist/src/components/Checkbox/Checkbox.d.ts +4 -6
  19. package/dist/src/components/Checkbox/CheckboxGroup.d.ts +8 -6
  20. package/dist/src/components/Chip/Chip.d.ts +2 -11
  21. package/dist/src/components/Container/Container.d.ts +1 -5
  22. package/dist/src/components/DatePicker/DatePicker.d.ts +2 -1
  23. package/dist/src/components/Dropdown/Dropdown.d.ts +4 -14
  24. package/dist/src/components/Flex/Flex.d.ts +2 -22
  25. package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +2 -7
  26. package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +3 -18
  27. package/dist/src/components/Group/Group.d.ts +2 -7
  28. package/dist/src/components/HoverCard/HoverCard.d.ts +13 -39
  29. package/dist/src/components/Label/Label.d.ts +2 -9
  30. package/dist/src/components/Link/Link.d.ts +2 -6
  31. package/dist/src/components/Loader/Loader.d.ts +2 -7
  32. package/dist/src/components/Menu/Menu.d.ts +24 -98
  33. package/dist/src/components/Modal/Modal.d.ts +32 -31
  34. package/dist/src/components/NumberInput/NumberInput.d.ts +3 -5
  35. package/dist/src/components/Pagination/Pagination.d.ts +8 -41
  36. package/dist/src/components/Panel/Panel.d.ts +5 -18
  37. package/dist/src/components/Radio/Radio.d.ts +4 -4
  38. package/dist/src/components/Radio/RadioGroup.d.ts +3 -7
  39. package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +2 -5
  40. package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +5 -15
  41. package/dist/src/components/Slider/Slider.d.ts +4 -14
  42. package/dist/src/components/Stack/Stack.d.ts +2 -5
  43. package/dist/src/components/Stepper/Stepper.d.ts +36 -16
  44. package/dist/src/components/Switch/Switch.d.ts +4 -4
  45. package/dist/src/components/Switch/SwitchGroup.d.ts +4 -4
  46. package/dist/src/components/Table/Table.d.ts +2 -1
  47. package/dist/src/components/Tabs/Tabs.d.ts +11 -26
  48. package/dist/src/components/Text/Text.d.ts +2 -16
  49. package/dist/src/components/TextArea/TextArea.d.ts +3 -9
  50. package/dist/src/components/TextField/TextField.d.ts +3 -7
  51. package/dist/src/components/TimePicker/TimePicker.d.ts +2 -1
  52. package/dist/src/components/Timeline/Timeline.d.ts +2 -1
  53. package/dist/src/components/Timeline/TimelineItem.d.ts +2 -13
  54. package/dist/src/components/Title/Title.d.ts +2 -15
  55. package/dist/src/components/Toast/Toast.d.ts +11 -16
  56. package/dist/src/components/Tooltip/Tooltip.d.ts +7 -21
  57. package/dist/src/components/TransferList/TransferList.d.ts +2 -1
  58. package/dist/src/components/Typography/Typography.d.ts +1 -1
  59. package/dist/src/utils/RequireAccessibleLabel.d.ts +1 -18
  60. package/dist/src/utils/filterStylingProps.d.ts +1 -11
  61. package/llms.txt +16 -0
  62. package/package.json +6 -2
  63. package/src/components/Accordion/Accordion.module.css +1 -2
  64. package/src/components/Accordion/Accordion.stories.tsx +0 -18
  65. package/src/components/Accordion/Accordion.tsx +19 -23
  66. package/src/components/AssistiveElement/AssistiveElement.module.css +32 -29
  67. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +10 -27
  68. package/src/components/AssistiveElement/AssistiveElement.tsx +11 -15
  69. package/src/components/Autocomplete/Autocomplete.module.css +17 -18
  70. package/src/components/Autocomplete/Autocomplete.stories.tsx +7 -16
  71. package/src/components/Autocomplete/Autocomplete.tsx +27 -45
  72. package/src/components/Avatar/Avatar.tsx +2 -13
  73. package/src/components/Badge/Badge.tsx +2 -5
  74. package/src/components/Breadcrumb/Breadcrumb.tsx +1 -4
  75. package/src/components/Button/Button.module.css +19 -61
  76. package/src/components/Button/Button.stories.tsx +24 -23
  77. package/src/components/Button/Button.tsx +7 -18
  78. package/src/components/Card/Card.module.css +36 -0
  79. package/src/components/Card/Card.tsx +6 -4
  80. package/src/components/Checkbox/Checkbox.module.css +27 -10
  81. package/src/components/Checkbox/Checkbox.tsx +124 -24
  82. package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
  83. package/src/components/Checkbox/CheckboxGroup.tsx +43 -23
  84. package/src/components/Chip/Chip.module.css +52 -34
  85. package/src/components/Chip/Chip.tsx +45 -47
  86. package/src/components/Container/Container.stories.tsx +103 -20
  87. package/src/components/Container/Container.tsx +1 -13
  88. package/src/components/DatePicker/DatePicker.stories.tsx +125 -19
  89. package/src/components/DatePicker/DatePicker.tsx +3 -1
  90. package/src/components/Dropdown/Dropdown.tsx +7 -9
  91. package/src/components/FileInput/FileInput.stories.tsx +2 -19
  92. package/src/components/FileUpload/FileUpload.stories.tsx +2 -19
  93. package/src/components/Flex/Flex.stories.tsx +113 -20
  94. package/src/components/Flex/Flex.tsx +16 -26
  95. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +0 -8
  96. package/src/components/FormControlLayout/FormControlLayout.tsx +18 -7
  97. package/src/components/FormControlWrapper/FormControlWrapper.module.css +1 -10
  98. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +12 -21
  99. package/src/components/FormControlWrapper/FormControlWrapper.tsx +11 -30
  100. package/src/components/Group/Group.stories.tsx +6 -30
  101. package/src/components/Group/Group.tsx +14 -9
  102. package/src/components/HoverCard/HoverCard.tsx +72 -75
  103. package/src/components/Label/Label.module.css +4 -0
  104. package/src/components/Label/Label.stories.tsx +18 -12
  105. package/src/components/Label/Label.tsx +3 -9
  106. package/src/components/Link/Link.module.css +4 -3
  107. package/src/components/Link/Link.stories.tsx +2 -8
  108. package/src/components/Link/Link.tsx +1 -5
  109. package/src/components/Loader/Loader.module.css +1 -2
  110. package/src/components/Loader/Loader.tsx +1 -7
  111. package/src/components/Menu/IMPLEMENTATION_NOTES.md +4 -0
  112. package/src/components/Menu/Menu.stories.tsx +106 -188
  113. package/src/components/Menu/Menu.tsx +34 -280
  114. package/src/components/Modal/Modal.tsx +158 -160
  115. package/src/components/NumberInput/NumberInput.tsx +6 -18
  116. package/src/components/Pagination/IMPLEMENTATION_NOTES.md +3 -0
  117. package/src/components/Pagination/Pagination.module.css +12 -24
  118. package/src/components/Pagination/Pagination.stories.tsx +0 -8
  119. package/src/components/Pagination/Pagination.tsx +20 -140
  120. package/src/components/Panel/Panel.tsx +7 -30
  121. package/src/components/Radio/Radio.module.css +25 -10
  122. package/src/components/Radio/Radio.tsx +51 -19
  123. package/src/components/Radio/RadioGroup.stories.tsx +117 -0
  124. package/src/components/Radio/RadioGroup.tsx +26 -12
  125. package/src/components/ReadOnlyField/ReadOnlyField.module.css +6 -6
  126. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +5 -36
  127. package/src/components/ReadOnlyField/ReadOnlyField.tsx +9 -13
  128. package/src/components/SegmentedControl/SegmentedControl.module.css +23 -47
  129. package/src/components/SegmentedControl/SegmentedControl.tsx +44 -14
  130. package/src/components/Slider/Slider.module.css +1 -4
  131. package/src/components/Slider/Slider.stories.tsx +3 -3
  132. package/src/components/Slider/Slider.tsx +26 -25
  133. package/src/components/Stack/Stack.stories.tsx +4 -25
  134. package/src/components/Stack/Stack.tsx +1 -5
  135. package/src/components/Stepper/IMPLEMENTATION_NOTES.md +4 -0
  136. package/src/components/Stepper/Stepper.stories.tsx +56 -43
  137. package/src/components/Stepper/Stepper.tsx +89 -87
  138. package/src/components/Switch/Switch.module.css +21 -0
  139. package/src/components/Switch/Switch.tsx +63 -16
  140. package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
  141. package/src/components/Switch/SwitchGroup.tsx +27 -18
  142. package/src/components/Table/Table.stories.tsx +1 -19
  143. package/src/components/Table/Table.tsx +3 -1
  144. package/src/components/Tabs/IMPLEMENTATION_NOTES.md +4 -0
  145. package/src/components/Tabs/Tabs.stories.tsx +41 -24
  146. package/src/components/Tabs/Tabs.tsx +49 -66
  147. package/src/components/Text/Text.stories.tsx +5 -17
  148. package/src/components/Text/Text.tsx +1 -15
  149. package/src/components/TextArea/TextArea.tsx +7 -17
  150. package/src/components/TextField/TextField.stories.tsx +1 -27
  151. package/src/components/TextField/TextField.tsx +4 -6
  152. package/src/components/TimePicker/TimePicker.stories.tsx +2 -19
  153. package/src/components/TimePicker/TimePicker.tsx +3 -1
  154. package/src/components/Timeline/Timeline.tsx +4 -1
  155. package/src/components/Timeline/TimelineItem.tsx +1 -12
  156. package/src/components/Title/Title.stories.tsx +0 -18
  157. package/src/components/Title/Title.tsx +1 -7
  158. package/src/components/Toast/Toast.stories.tsx +1 -1
  159. package/src/components/Toast/Toast.tsx +62 -28
  160. package/src/components/Tooltip/Tooltip.tsx +11 -37
  161. package/src/components/TransferList/TransferList.stories.tsx +1 -19
  162. package/src/components/TransferList/TransferList.tsx +3 -1
  163. package/src/utils/RequireAccessibleLabel.ts +1 -12
  164. package/src/utils/filterStylingProps.ts +7 -20
@@ -23,10 +23,12 @@
23
23
  background: transparent; (Override mantine default)
24
24
  */
25
25
 
26
- .root {
26
+ .root.root {
27
27
  /* Set preset layout variables to override mantine defaults safely */
28
28
  box-sizing: border-box;
29
29
  display: inline-flex;
30
+ align-items: center;
31
+ justify-content: center;
30
32
 
31
33
  /* Token properties */
32
34
  --chip-height: max-content; /* Sizing is driven by padding and line height */
@@ -46,24 +48,45 @@
46
48
  --recursica_ui-kit_components_chip_variants_styles_unselected_properties_colors_close-icon-color
47
49
  );
48
50
 
51
+ /* Container geometry */
52
+ height: var(--chip-height);
49
53
  border-radius: var(
50
54
  --recursica_ui-kit_components_chip_properties_border-radius
51
55
  );
56
+ border-style: solid;
57
+ border-width: var(--recursica_ui-kit_components_chip_properties_border-size);
58
+ padding: var(--recursica_ui-kit_components_chip_properties_vertical-padding)
59
+ var(--recursica_ui-kit_components_chip_properties_horizontal-padding);
60
+
61
+ /* Gap for native MUI icons */
62
+ gap: var(--recursica_ui-kit_components_chip_properties_icon-text-gap);
63
+
64
+ /* Background and colors */
65
+ background-color: var(--chip-bg);
66
+ border-color: var(--chip-border);
67
+ color: var(--chip-text);
68
+ min-width: var(--recursica_ui-kit_components_chip_properties_min-width);
69
+ max-width: var(--recursica_ui-kit_components_chip_properties_max-width);
70
+ box-shadow: var(--recursica_ui-kit_components_chip_properties_elevation);
71
+
72
+ cursor: pointer;
73
+ user-select: none;
74
+ overflow: hidden;
75
+ transition: all 0.2s ease;
52
76
  }
53
77
 
54
78
  /* We target the mantine label directly because that is the visible container in Mantine's Chip */
55
- .label {
79
+ .label.label {
56
80
  box-sizing: border-box;
57
81
  display: inline-flex;
58
82
  align-items: center;
59
83
  justify-content: center;
60
84
 
61
- /* Reset mantine styles */
62
- background: transparent !important; /* HARDCODE: Mantine forces background styling on label */
63
- border-style: solid;
64
- border-width: var(--recursica_ui-kit_components_chip_properties_border-size);
65
- padding: var(--recursica_ui-kit_components_chip_properties_vertical-padding)
66
- var(--recursica_ui-kit_components_chip_properties_horizontal-padding) !important;
85
+ /* Reset MUI styles */
86
+ background: transparent;
87
+ padding: 0;
88
+ border: none;
89
+ border-radius: 0;
67
90
 
68
91
  /* Typography */
69
92
  font-family: var(
@@ -90,21 +113,18 @@
90
113
  );
91
114
 
92
115
  /* Token evaluation */
93
- background-color: var(--chip-bg) !important;
94
- border-color: var(--chip-border) !important;
95
- color: var(--chip-text) !important;
116
+ background-color: var(--chip-bg);
117
+ border-color: var(--chip-border);
118
+ color: var(--chip-text);
96
119
  min-width: var(--recursica_ui-kit_components_chip_properties_min-width);
97
120
  max-width: var(--recursica_ui-kit_components_chip_properties_max-width);
98
- box-shadow: var(
99
- --recursica_ui-kit_components_chip_properties_elevation,
100
- none
101
- );
121
+ box-shadow: var(--recursica_ui-kit_components_chip_properties_elevation);
102
122
 
103
123
  transition: all 0.2s ease;
104
124
  }
105
125
 
106
126
  /* Default (Unselected) hover/active interactions (Mantine overrides) */
107
- .label[data-checked] {
127
+ .root.root[data-checked] {
108
128
  --chip-bg: var(
109
129
  --recursica_ui-kit_components_chip_variants_styles_selected_properties_colors_background
110
130
  );
@@ -122,7 +142,7 @@
122
142
  );
123
143
  }
124
144
 
125
- .root[data-error] .label {
145
+ .root.root[data-error] {
126
146
  --chip-bg: var(
127
147
  --recursica_ui-kit_components_chip_variants_styles_error_properties_colors_background
128
148
  );
@@ -140,7 +160,7 @@
140
160
  );
141
161
  }
142
162
 
143
- .root[data-error] .label[data-checked] {
163
+ .root.root[data-error][data-checked] {
144
164
  --chip-bg: var(
145
165
  --recursica_ui-kit_components_chip_variants_styles_error-selected_properties_colors_background
146
166
  );
@@ -158,20 +178,16 @@
158
178
  );
159
179
  }
160
180
 
161
- .root[data-disabled] .label {
162
- opacity: var(--recursica_brand_states_disabled, 0.5);
181
+ .root.root[data-disabled] {
182
+ opacity: var(--recursica_brand_states_disabled);
163
183
  cursor: not-allowed;
164
184
  }
165
185
 
166
186
  /* Override Mantine's built-in check icon colors and size if we keep it */
167
- .mantineIconWrapper {
168
- color: var(--chip-icon) !important;
169
- width: var(
170
- --recursica_ui-kit_components_chip_properties_icon-size
171
- ) !important;
172
- height: var(
173
- --recursica_ui-kit_components_chip_properties_icon-size
174
- ) !important;
187
+ .mantineIconWrapper.mantineIconWrapper {
188
+ color: var(--chip-icon);
189
+ width: var(--recursica_ui-kit_components_chip_properties_icon-size);
190
+ height: var(--recursica_ui-kit_components_chip_properties_icon-size);
175
191
  margin-right: var(
176
192
  --recursica_ui-kit_components_chip_properties_icon-text-gap
177
193
  );
@@ -205,7 +221,7 @@
205
221
  height: 100%;
206
222
  }
207
223
 
208
- .removeIcon {
224
+ .removeIconWrapper {
209
225
  display: inline-flex;
210
226
  align-items: center;
211
227
  justify-content: center;
@@ -215,22 +231,24 @@
215
231
  cursor: pointer;
216
232
  border-radius: 50%; /* HARDCODE: Make focus ring rounded */
217
233
  outline: none;
234
+ /* Reset MUI icon defaults */
235
+ margin: 0;
218
236
  }
219
237
 
220
- .removeIcon:focus-visible {
238
+ .removeIconWrapper:focus-visible {
221
239
  box-shadow: 0 0 0 2px var(--chip-border); /* HARDCODE: Focus indication */
222
240
  }
223
241
 
224
- .removeIcon svg {
242
+ .removeIconWrapper svg {
225
243
  width: 100%;
226
244
  height: 100%;
227
245
  }
228
246
 
229
- .root[data-icon-only] .label {
247
+ .root.root[data-icon-only] {
230
248
  padding-left: var(
231
249
  --recursica_ui-kit_components_chip_properties_vertical-padding
232
- ) !important;
250
+ );
233
251
  padding-right: var(
234
252
  --recursica_ui-kit_components_chip_properties_vertical-padding
235
- ) !important;
253
+ );
236
254
  }
@@ -6,19 +6,7 @@ import {
6
6
  } from "../../utils/filterStylingProps";
7
7
  import styles from "./Chip.module.css";
8
8
 
9
- export interface RecursicaChipProps {
10
- /** Enables the error state styling */
11
- error?: boolean;
12
-
13
- /** Leading icon content */
14
- icon?: React.ReactNode;
15
-
16
- /** Called when the remove (X) icon is clicked. If provided, the remove icon will be displayed. */
17
- onRemove?: (e: React.MouseEvent<HTMLSpanElement, MouseEvent>) => void;
18
-
19
- /** Screen reader label for the remove button. Defaults to 'Remove' */
20
- removeLabel?: string;
21
- }
9
+ import { type RecursicaChipProps } from "@recursica/adapter-common";
22
10
 
23
11
  export type ChipProps = RecursicaOverStyled<
24
12
  Omit<MuiChipProps, "variant" | "size" | "color" | "radius"> &
@@ -45,13 +33,33 @@ function CloseIcon(props: React.ComponentPropsWithoutRef<"svg">) {
45
33
  );
46
34
  }
47
35
 
36
+ function CheckIcon(props: React.ComponentPropsWithoutRef<"svg">) {
37
+ return (
38
+ <svg
39
+ viewBox="0 0 10 7"
40
+ fill="none"
41
+ xmlns="http://www.w3.org/2000/svg"
42
+ {...props}
43
+ >
44
+ <path
45
+ d="M4 4.586L1.707 2.293A1 1 0 1 0 .293 3.707l3 3a.997.997 0 0 0 1.414 0l5-5A1 1 0 1 0 8.293.293L4 4.586z"
46
+ fill="currentColor"
47
+ fillRule="evenodd"
48
+ clipRule="evenodd"
49
+ />
50
+ </svg>
51
+ );
52
+ }
53
+
48
54
  export const Chip = forwardRef<HTMLInputElement, ChipProps>(function Chip(
49
55
  {
50
56
  error = false,
51
57
  icon,
52
58
  onRemove,
59
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
53
60
  removeLabel = "Remove",
54
61
  children,
62
+ checked,
55
63
  overStyled = false,
56
64
  ...rest
57
65
  },
@@ -63,9 +71,8 @@ export const Chip = forwardRef<HTMLInputElement, ChipProps>(function Chip(
63
71
  const mergedClassNames: Partial<Record<string, string>> = {
64
72
  root: styles.root,
65
73
  label: styles.label,
66
- input: styles.input,
67
- iconWrapper: styles.muiIconWrapper,
68
- checkIcon: styles.checkIcon,
74
+ icon: styles.leadingIcon,
75
+ deleteIcon: styles.removeIconWrapper,
69
76
  };
70
77
 
71
78
  const classNamesProp = restRecord.classNames;
@@ -88,6 +95,7 @@ export const Chip = forwardRef<HTMLInputElement, ChipProps>(function Chip(
88
95
 
89
96
  // Determine state
90
97
  const dataError = error ? "" : undefined;
98
+ const dataChecked = checked ? "" : undefined;
91
99
  const isIconOnly = !children && (!!icon || !!onRemove);
92
100
 
93
101
  return (
@@ -96,44 +104,34 @@ export const Chip = forwardRef<HTMLInputElement, ChipProps>(function Chip(
96
104
  className={finalClass}
97
105
  classes={mergedClassNames}
98
106
  {...(dataError !== undefined ? { "data-error": "" } : {})}
107
+ {...(dataChecked !== undefined ? { "data-checked": "" } : {})}
99
108
  {...(isIconOnly ? { "data-icon-only": "" } : {})}
100
109
  {...sanitizedProps}
101
- >
102
- <span className={styles.innerWrapper}>
103
- {icon && (
110
+ icon={
111
+ checked ? (
112
+ <span className={styles.mantineIconWrapper} aria-hidden>
113
+ <CheckIcon />
114
+ </span>
115
+ ) : icon ? (
104
116
  <span className={styles.leadingIcon} aria-hidden>
105
117
  {icon}
106
118
  </span>
107
- )}
108
-
109
- <span className={styles.children}>{children}</span>
110
-
111
- {onRemove && (
112
- <span
113
- role="button"
114
- className={styles.removeIcon}
115
- onClick={(e) => {
116
- e.preventDefault();
117
- e.stopPropagation();
118
- onRemove(e);
119
- }}
120
- aria-label={removeLabel}
121
- onKeyDown={(e) => {
122
- if (e.key === "Enter" || e.key === " ") {
123
- e.preventDefault();
124
- e.stopPropagation();
125
- onRemove(
126
- e as unknown as React.MouseEvent<HTMLSpanElement, MouseEvent>,
127
- );
128
- }
129
- }}
130
- tabIndex={0}
131
- >
119
+ ) : undefined
120
+ }
121
+ onDelete={onRemove}
122
+ deleteIcon={
123
+ onRemove ? (
124
+ <span className={styles.removeIconWrapper}>
132
125
  <CloseIcon />
133
126
  </span>
134
- )}
135
- </span>
136
- </MuiChip>
127
+ ) : undefined
128
+ }
129
+ label={
130
+ <span className={styles.innerWrapper}>
131
+ <span className={styles.children}>{children}</span>
132
+ </span>
133
+ }
134
+ />
137
135
  );
138
136
  });
139
137
 
@@ -1,35 +1,118 @@
1
+ import React from "react";
1
2
  import type { Meta, StoryObj } from "@storybook/react";
2
3
  import { Container } from "./Container";
3
- import { ComingSoon } from "@recursica/storybook-template";
4
+ import { Text } from "../Text/Text";
4
5
 
5
- const meta: Meta<typeof Container> = {
6
- title: "UI-Kit/🚧 Container",
6
+ type ContainerStoryProps = React.ComponentProps<typeof Container>;
7
+
8
+ const meta: Meta<ContainerStoryProps> = {
9
+ title: "UI-Kit/Container",
7
10
  component: Container,
8
11
  tags: ["autodocs"],
9
12
  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",
13
+ docs: {
14
+ description: {
15
+ component:
16
+ "Container is a generic layout wrapper that safely maps to Mantine's Container, standardizing maximum content widths across the application.",
17
+ },
18
+ },
19
+ },
20
+ args: {
21
+ size: "md",
22
+ fluid: false,
23
+ },
24
+ argTypes: {
25
+ size: {
26
+ control: "select",
27
+ options: [
28
+ "xs",
29
+ "sm",
30
+ "md",
31
+ "lg",
32
+ "xl",
33
+ "rec-sm",
34
+ "rec-default",
35
+ "rec-md",
36
+ "rec-lg",
37
+ "rec-xl",
38
+ "rec-2xl",
25
39
  ],
40
+ description:
41
+ "Maximum width defined by Mantine system sizes or Recursica sizes",
42
+ },
43
+ fluid: {
44
+ control: "boolean",
45
+ description: "If true, overrides size and sets max-width to 100%",
46
+ },
47
+ defaultChecked: {
48
+ table: { disable: true },
26
49
  },
27
50
  },
28
51
  };
29
52
 
30
53
  export default meta;
31
- type Story = StoryObj<typeof Container>;
54
+
55
+ type Story = StoryObj<ContainerStoryProps>;
32
56
 
33
57
  export const Default: Story = {
34
- render: () => <ComingSoon componentName="Container" />,
58
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
59
+ render: ({ withLayer, layer, ...args }: any) => (
60
+ <div style={{ backgroundColor: "#f0f0f0", padding: "16px" }}>
61
+ <Container
62
+ {...args}
63
+ style={{
64
+ backgroundColor: "white",
65
+ padding: "16px",
66
+ border: "1px solid #ccc",
67
+ }}
68
+ >
69
+ <Text>
70
+ This is a Container holding centered content. The background and
71
+ border are added just to demonstrate the layout bounds visually.
72
+ </Text>
73
+ </Container>
74
+ </div>
75
+ ),
76
+ };
77
+
78
+ export const SmallContainer: Story = {
79
+ args: {
80
+ size: "sm",
81
+ },
82
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
83
+ render: ({ withLayer, layer, ...args }: any) => (
84
+ <div style={{ backgroundColor: "#f0f0f0", padding: "16px" }}>
85
+ <Container
86
+ {...args}
87
+ style={{
88
+ backgroundColor: "white",
89
+ padding: "16px",
90
+ border: "1px solid #ccc",
91
+ }}
92
+ >
93
+ <Text>Small Container Layout</Text>
94
+ </Container>
95
+ </div>
96
+ ),
97
+ };
98
+
99
+ export const FluidContainer: Story = {
100
+ args: {
101
+ fluid: true,
102
+ },
103
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
104
+ render: ({ withLayer, layer, ...args }: any) => (
105
+ <div style={{ backgroundColor: "#f0f0f0", padding: "16px" }}>
106
+ <Container
107
+ {...args}
108
+ style={{
109
+ backgroundColor: "white",
110
+ padding: "16px",
111
+ border: "1px solid #ccc",
112
+ }}
113
+ >
114
+ <Text>Fluid Container Layout</Text>
115
+ </Container>
116
+ </div>
117
+ ),
35
118
  };
@@ -11,20 +11,8 @@ import {
11
11
  Container as MUIContainer,
12
12
  type ContainerProps as MUIContainerProps,
13
13
  } from "@mui/material";
14
- import { type RecursicaSpacing } from "../../utils/filterStylingProps";
15
14
 
16
- export interface RecursicaContainerProps {
17
- children?: React.ReactNode;
18
- size?:
19
- | "xs"
20
- | "sm"
21
- | "md"
22
- | "lg"
23
- | "xl"
24
- | RecursicaSpacing
25
- | (string & {})
26
- | number;
27
- }
15
+ import { type RecursicaContainerProps } from "@recursica/adapter-common";
28
16
 
29
17
  export type ContainerProps = Omit<MUIContainerProps, "maxWidth"> &
30
18
  RecursicaContainerProps;
@@ -1,35 +1,141 @@
1
+ import React from "react";
1
2
  import type { Meta, StoryObj } from "@storybook/react";
2
3
  import { DatePicker } from "./DatePicker";
3
- import { ComingSoon } from "@recursica/storybook-template";
4
+ import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
4
5
 
5
6
  const meta: Meta<typeof DatePicker> = {
6
- title: "UI-Kit/🚧 DatePicker",
7
+ title: "UI-Kit/DatePicker",
7
8
  component: DatePicker,
8
9
  tags: ["autodocs"],
9
10
  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
- ],
11
+ docs: {
12
+ description: {
13
+ component: `
14
+ The \`DatePicker\` primitive provides a unified calendar date selection input integrated directly into the \`FormControlWrapper\` architecture.
15
+
16
+ ### Architectural Decoupling
17
+ Recursica overrides the internal Mantine \`DatePickerInput\` wrapper defaults, safely injecting the date picker into our rigid structural layout systems. State modifiers (e.g. Focus, Errors, ReadOnly) hook seamlessly back onto our native CSS mapping architecture.
18
+
19
+ ### Examples
20
+ Always structure horizontal architectures via the generic \`formLayout\` parameter.
21
+ \`\`\`tsx
22
+ <DatePicker
23
+ label="Start Date"
24
+ assistiveText="Select the deployment kick-off date."
25
+ formLayout="stacked"
26
+ />
27
+ \`\`\`
28
+ `,
29
+ },
30
+ },
31
+ },
32
+ argTypes: {
33
+ ...formControlArgTypes,
34
+ disabled: {
35
+ control: "boolean",
36
+ description:
37
+ "Maps the formal disabled variable states structurally to the input core.",
38
+ },
39
+ error: {
40
+ control: "text",
41
+ description:
42
+ "Applies the strict error string boundary rendering invalid structures seamlessly.",
43
+ },
44
+ required: {
45
+ control: "boolean",
46
+ },
47
+ label: {
48
+ control: "text",
49
+ },
50
+ assistiveText: {
51
+ control: "text",
52
+ },
53
+ readOnly: {
54
+ control: "boolean",
55
+ description:
56
+ "Toggles structural read-only data presentation explicitly blocking standard component bindings.",
26
57
  },
27
58
  },
28
59
  };
29
60
 
30
61
  export default meta;
62
+
31
63
  type Story = StoryObj<typeof DatePicker>;
32
64
 
33
65
  export const Default: Story = {
34
- render: () => <ComingSoon componentName="DatePicker" />,
66
+ args: {
67
+ disabled: false,
68
+ label: "Project Deadline",
69
+ placeholder: "Select a deadline...",
70
+ assistiveText: "Specify the absolute cutoff for code submission.",
71
+ },
72
+ };
73
+
74
+ export const FormsSideBySide: Story = {
75
+ args: {
76
+ label: "Incident Start Date",
77
+ placeholder: "Pick date...",
78
+ assistiveText: "When did the incident originally occur?",
79
+ formLayout: "side-by-side",
80
+ },
81
+ };
82
+
83
+ export const WithLeadingIcon: Story = {
84
+ args: {
85
+ label: "Launch Date",
86
+ placeholder: "Select launch date...",
87
+ leftSection: (
88
+ <svg
89
+ width="24"
90
+ height="24"
91
+ viewBox="0 0 24 24"
92
+ fill="none"
93
+ stroke="currentColor"
94
+ strokeWidth="2"
95
+ strokeLinecap="round"
96
+ strokeLinejoin="round"
97
+ >
98
+ <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
99
+ <line x1="16" y1="2" x2="16" y2="6"></line>
100
+ <line x1="8" y1="2" x2="8" y2="6"></line>
101
+ <line x1="3" y1="10" x2="21" y2="10"></line>
102
+ </svg>
103
+ ),
104
+ },
105
+ };
106
+
107
+ export const Disabled: Story = {
108
+ args: {
109
+ label: "Disabled Date Range",
110
+ placeholder: "Disabled selection...",
111
+ disabled: true,
112
+ },
113
+ };
114
+
115
+ export const ErrorState: Story = {
116
+ args: {
117
+ label: "Execution Date",
118
+ placeholder: "Pick a valid date...",
119
+ error: "The chosen date conflicts with an existing deployment freeze.",
120
+ required: true,
121
+ },
122
+ };
123
+
124
+ export const StaticReadOnly: Story = {
125
+ args: {
126
+ label: "Static ReadOnly Review",
127
+ placeholder: "Ignored...",
128
+ value: new Date("2026-05-21"),
129
+ readOnly: true,
130
+ },
131
+ };
132
+
133
+ export const EditableReadOnly: Story = {
134
+ args: {
135
+ label: "Editable ReadOnly Review",
136
+ placeholder: "Ignored until active...",
137
+ defaultValue: new Date("2026-06-01"),
138
+ readOnly: true,
139
+ labelWithEditIcon: true,
140
+ },
35
141
  };
@@ -1,7 +1,9 @@
1
1
  import React from "react";
2
2
  import "./DatePicker.module.css";
3
+ import { type RecursicaDatePickerProps } from "@recursica/adapter-common";
3
4
 
4
- export type DatePickerProps = React.HTMLAttributes<HTMLDivElement>;
5
+ export type DatePickerProps = React.HTMLAttributes<HTMLDivElement> &
6
+ RecursicaDatePickerProps;
5
7
 
6
8
  export const DatePicker: React.FC<DatePickerProps> = (props) => {
7
9
  return <div {...props}>DatePicker</div>;