@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.
- package/ARCHITECTURE.md +15 -0
- package/CHANGELOG.md +6 -0
- package/SETUP.md +77 -0
- package/USAGE.md +55 -0
- package/dist/mui-adapter.cjs +26 -26
- package/dist/mui-adapter.cjs.map +1 -1
- package/dist/mui-adapter.css +1 -1
- package/dist/mui-adapter.js +3721 -3511
- package/dist/mui-adapter.js.map +1 -1
- package/dist/src/components/Accordion/Accordion.d.ts +9 -29
- package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +2 -5
- package/dist/src/components/Autocomplete/Autocomplete.d.ts +4 -8
- package/dist/src/components/Avatar/Avatar.d.ts +1 -6
- package/dist/src/components/Badge/Badge.d.ts +1 -4
- package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +2 -3
- package/dist/src/components/Button/Button.d.ts +2 -17
- package/dist/src/components/Card/Card.d.ts +2 -4
- package/dist/src/components/Checkbox/Checkbox.d.ts +4 -6
- package/dist/src/components/Checkbox/CheckboxGroup.d.ts +8 -6
- package/dist/src/components/Chip/Chip.d.ts +2 -11
- package/dist/src/components/Container/Container.d.ts +1 -5
- package/dist/src/components/DatePicker/DatePicker.d.ts +2 -1
- package/dist/src/components/Dropdown/Dropdown.d.ts +4 -14
- package/dist/src/components/Flex/Flex.d.ts +2 -22
- package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +2 -7
- package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +3 -18
- package/dist/src/components/Group/Group.d.ts +2 -7
- package/dist/src/components/HoverCard/HoverCard.d.ts +13 -39
- package/dist/src/components/Label/Label.d.ts +2 -9
- package/dist/src/components/Link/Link.d.ts +2 -6
- package/dist/src/components/Loader/Loader.d.ts +2 -7
- package/dist/src/components/Menu/Menu.d.ts +24 -98
- package/dist/src/components/Modal/Modal.d.ts +32 -31
- package/dist/src/components/NumberInput/NumberInput.d.ts +3 -5
- package/dist/src/components/Pagination/Pagination.d.ts +8 -41
- package/dist/src/components/Panel/Panel.d.ts +5 -18
- package/dist/src/components/Radio/Radio.d.ts +4 -4
- package/dist/src/components/Radio/RadioGroup.d.ts +3 -7
- package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +2 -5
- package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +5 -15
- package/dist/src/components/Slider/Slider.d.ts +4 -14
- package/dist/src/components/Stack/Stack.d.ts +2 -5
- package/dist/src/components/Stepper/Stepper.d.ts +36 -16
- package/dist/src/components/Switch/Switch.d.ts +4 -4
- package/dist/src/components/Switch/SwitchGroup.d.ts +4 -4
- package/dist/src/components/Table/Table.d.ts +2 -1
- package/dist/src/components/Tabs/Tabs.d.ts +11 -26
- package/dist/src/components/Text/Text.d.ts +2 -16
- package/dist/src/components/TextArea/TextArea.d.ts +3 -9
- package/dist/src/components/TextField/TextField.d.ts +3 -7
- package/dist/src/components/TimePicker/TimePicker.d.ts +2 -1
- package/dist/src/components/Timeline/Timeline.d.ts +2 -1
- package/dist/src/components/Timeline/TimelineItem.d.ts +2 -13
- package/dist/src/components/Title/Title.d.ts +2 -15
- package/dist/src/components/Toast/Toast.d.ts +11 -16
- package/dist/src/components/Tooltip/Tooltip.d.ts +7 -21
- package/dist/src/components/TransferList/TransferList.d.ts +2 -1
- package/dist/src/components/Typography/Typography.d.ts +1 -1
- package/dist/src/utils/RequireAccessibleLabel.d.ts +1 -18
- package/dist/src/utils/filterStylingProps.d.ts +1 -11
- package/llms.txt +16 -0
- package/package.json +6 -2
- package/src/components/Accordion/Accordion.module.css +1 -2
- package/src/components/Accordion/Accordion.stories.tsx +0 -18
- package/src/components/Accordion/Accordion.tsx +19 -23
- package/src/components/AssistiveElement/AssistiveElement.module.css +32 -29
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +10 -27
- package/src/components/AssistiveElement/AssistiveElement.tsx +11 -15
- package/src/components/Autocomplete/Autocomplete.module.css +17 -18
- package/src/components/Autocomplete/Autocomplete.stories.tsx +7 -16
- package/src/components/Autocomplete/Autocomplete.tsx +27 -45
- package/src/components/Avatar/Avatar.tsx +2 -13
- package/src/components/Badge/Badge.tsx +2 -5
- package/src/components/Breadcrumb/Breadcrumb.tsx +1 -4
- package/src/components/Button/Button.module.css +19 -61
- package/src/components/Button/Button.stories.tsx +24 -23
- package/src/components/Button/Button.tsx +7 -18
- package/src/components/Card/Card.module.css +36 -0
- package/src/components/Card/Card.tsx +6 -4
- package/src/components/Checkbox/Checkbox.module.css +27 -10
- package/src/components/Checkbox/Checkbox.tsx +124 -24
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +43 -23
- package/src/components/Chip/Chip.module.css +52 -34
- package/src/components/Chip/Chip.tsx +45 -47
- package/src/components/Container/Container.stories.tsx +103 -20
- package/src/components/Container/Container.tsx +1 -13
- package/src/components/DatePicker/DatePicker.stories.tsx +125 -19
- package/src/components/DatePicker/DatePicker.tsx +3 -1
- package/src/components/Dropdown/Dropdown.tsx +7 -9
- package/src/components/FileInput/FileInput.stories.tsx +2 -19
- package/src/components/FileUpload/FileUpload.stories.tsx +2 -19
- package/src/components/Flex/Flex.stories.tsx +113 -20
- package/src/components/Flex/Flex.tsx +16 -26
- package/src/components/FormControlLayout/FormControlLayout.stories.tsx +0 -8
- package/src/components/FormControlLayout/FormControlLayout.tsx +18 -7
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +1 -10
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +12 -21
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +11 -30
- package/src/components/Group/Group.stories.tsx +6 -30
- package/src/components/Group/Group.tsx +14 -9
- package/src/components/HoverCard/HoverCard.tsx +72 -75
- package/src/components/Label/Label.module.css +4 -0
- package/src/components/Label/Label.stories.tsx +18 -12
- package/src/components/Label/Label.tsx +3 -9
- package/src/components/Link/Link.module.css +4 -3
- package/src/components/Link/Link.stories.tsx +2 -8
- package/src/components/Link/Link.tsx +1 -5
- package/src/components/Loader/Loader.module.css +1 -2
- package/src/components/Loader/Loader.tsx +1 -7
- package/src/components/Menu/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Menu/Menu.stories.tsx +106 -188
- package/src/components/Menu/Menu.tsx +34 -280
- package/src/components/Modal/Modal.tsx +158 -160
- package/src/components/NumberInput/NumberInput.tsx +6 -18
- package/src/components/Pagination/IMPLEMENTATION_NOTES.md +3 -0
- package/src/components/Pagination/Pagination.module.css +12 -24
- package/src/components/Pagination/Pagination.stories.tsx +0 -8
- package/src/components/Pagination/Pagination.tsx +20 -140
- package/src/components/Panel/Panel.tsx +7 -30
- package/src/components/Radio/Radio.module.css +25 -10
- package/src/components/Radio/Radio.tsx +51 -19
- package/src/components/Radio/RadioGroup.stories.tsx +117 -0
- package/src/components/Radio/RadioGroup.tsx +26 -12
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +6 -6
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +5 -36
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +9 -13
- package/src/components/SegmentedControl/SegmentedControl.module.css +23 -47
- package/src/components/SegmentedControl/SegmentedControl.tsx +44 -14
- package/src/components/Slider/Slider.module.css +1 -4
- package/src/components/Slider/Slider.stories.tsx +3 -3
- package/src/components/Slider/Slider.tsx +26 -25
- package/src/components/Stack/Stack.stories.tsx +4 -25
- package/src/components/Stack/Stack.tsx +1 -5
- package/src/components/Stepper/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Stepper/Stepper.stories.tsx +56 -43
- package/src/components/Stepper/Stepper.tsx +89 -87
- package/src/components/Switch/Switch.module.css +21 -0
- package/src/components/Switch/Switch.tsx +63 -16
- package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
- package/src/components/Switch/SwitchGroup.tsx +27 -18
- package/src/components/Table/Table.stories.tsx +1 -19
- package/src/components/Table/Table.tsx +3 -1
- package/src/components/Tabs/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Tabs/Tabs.stories.tsx +41 -24
- package/src/components/Tabs/Tabs.tsx +49 -66
- package/src/components/Text/Text.stories.tsx +5 -17
- package/src/components/Text/Text.tsx +1 -15
- package/src/components/TextArea/TextArea.tsx +7 -17
- package/src/components/TextField/TextField.stories.tsx +1 -27
- package/src/components/TextField/TextField.tsx +4 -6
- package/src/components/TimePicker/TimePicker.stories.tsx +2 -19
- package/src/components/TimePicker/TimePicker.tsx +3 -1
- package/src/components/Timeline/Timeline.tsx +4 -1
- package/src/components/Timeline/TimelineItem.tsx +1 -12
- package/src/components/Title/Title.stories.tsx +0 -18
- package/src/components/Title/Title.tsx +1 -7
- package/src/components/Toast/Toast.stories.tsx +1 -1
- package/src/components/Toast/Toast.tsx +62 -28
- package/src/components/Tooltip/Tooltip.tsx +11 -37
- package/src/components/TransferList/TransferList.stories.tsx +1 -19
- package/src/components/TransferList/TransferList.tsx +3 -1
- package/src/utils/RequireAccessibleLabel.ts +1 -12
- 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
|
|
62
|
-
background: transparent
|
|
63
|
-
|
|
64
|
-
border
|
|
65
|
-
|
|
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)
|
|
94
|
-
border-color: var(--chip-border)
|
|
95
|
-
color: var(--chip-text)
|
|
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
|
-
.
|
|
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]
|
|
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]
|
|
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]
|
|
162
|
-
opacity: var(--recursica_brand_states_disabled
|
|
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)
|
|
169
|
-
width: var(
|
|
170
|
-
|
|
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
|
-
.
|
|
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
|
-
.
|
|
238
|
+
.removeIconWrapper:focus-visible {
|
|
221
239
|
box-shadow: 0 0 0 2px var(--chip-border); /* HARDCODE: Focus indication */
|
|
222
240
|
}
|
|
223
241
|
|
|
224
|
-
.
|
|
242
|
+
.removeIconWrapper svg {
|
|
225
243
|
width: 100%;
|
|
226
244
|
height: 100%;
|
|
227
245
|
}
|
|
228
246
|
|
|
229
|
-
.root[data-icon-only]
|
|
247
|
+
.root.root[data-icon-only] {
|
|
230
248
|
padding-left: var(
|
|
231
249
|
--recursica_ui-kit_components_chip_properties_vertical-padding
|
|
232
|
-
)
|
|
250
|
+
);
|
|
233
251
|
padding-right: var(
|
|
234
252
|
--recursica_ui-kit_components_chip_properties_vertical-padding
|
|
235
|
-
)
|
|
253
|
+
);
|
|
236
254
|
}
|
|
@@ -6,19 +6,7 @@ import {
|
|
|
6
6
|
} from "../../utils/filterStylingProps";
|
|
7
7
|
import styles from "./Chip.module.css";
|
|
8
8
|
|
|
9
|
-
|
|
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
|
-
|
|
67
|
-
|
|
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
|
-
|
|
103
|
-
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
136
|
-
|
|
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 {
|
|
4
|
+
import { Text } from "../Text/Text";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
54
|
+
|
|
55
|
+
type Story = StoryObj<ContainerStoryProps>;
|
|
32
56
|
|
|
33
57
|
export const Default: Story = {
|
|
34
|
-
|
|
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
|
-
|
|
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 {
|
|
4
|
+
import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
|
|
4
5
|
|
|
5
6
|
const meta: Meta<typeof DatePicker> = {
|
|
6
|
-
title: "UI-Kit
|
|
7
|
+
title: "UI-Kit/DatePicker",
|
|
7
8
|
component: DatePicker,
|
|
8
9
|
tags: ["autodocs"],
|
|
9
10
|
parameters: {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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>;
|