@recursica/mui-adapter 0.5.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 +15 -0
- package/SETUP.md +77 -0
- package/USAGE.md +55 -0
- package/dist/mui-adapter.cjs +74 -1
- package/dist/mui-adapter.cjs.map +1 -1
- package/dist/mui-adapter.css +1 -1
- package/dist/mui-adapter.js +6863 -205
- package/dist/mui-adapter.js.map +1 -1
- package/dist/src/components/Accordion/Accordion.d.ts +43 -2
- package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +6 -2
- package/dist/src/components/Autocomplete/Autocomplete.d.ts +12 -2
- package/dist/src/components/Avatar/Avatar.d.ts +10 -3
- package/dist/src/components/Badge/Badge.d.ts +10 -3
- package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +9 -3
- package/dist/src/components/Button/Button.d.ts +2 -17
- package/dist/src/components/Card/Card.d.ts +38 -3
- package/dist/src/components/Checkbox/Checkbox.d.ts +13 -2
- package/dist/src/components/Checkbox/CheckboxGroup.d.ts +18 -0
- package/dist/src/components/Checkbox/index.d.ts +5 -1
- package/dist/src/components/Chip/Chip.d.ts +9 -2
- 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 +12 -2
- package/dist/src/components/Flex/Flex.d.ts +2 -22
- package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +5 -2
- package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +9 -2
- package/dist/src/components/Group/Group.d.ts +2 -7
- package/dist/src/components/HoverCard/HoverCard.d.ts +28 -2
- package/dist/src/components/Label/Label.d.ts +6 -2
- 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 +25 -3
- package/dist/src/components/Modal/Modal.d.ts +37 -2
- package/dist/src/components/NumberInput/NumberInput.d.ts +12 -2
- package/dist/src/components/Pagination/Pagination.d.ts +12 -3
- package/dist/src/components/Pagination/Pagination.icons.d.ts +8 -0
- package/dist/src/components/Panel/Panel.d.ts +52 -3
- package/dist/src/components/Radio/Radio.d.ts +13 -3
- package/dist/src/components/Radio/RadioGroup.d.ts +9 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +4 -2
- package/dist/src/components/ReadOnlyField/ReadOnlySwitchField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyTextField.d.ts +8 -0
- package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +28 -0
- package/dist/src/components/ReadOnlyField/index.d.ts +1 -0
- package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +21 -3
- package/dist/src/components/Slider/Slider.d.ts +18 -2
- package/dist/src/components/Stack/Stack.d.ts +2 -5
- package/dist/src/components/Stepper/Stepper.d.ts +41 -2
- package/dist/src/components/Switch/Switch.d.ts +10 -3
- package/dist/src/components/Switch/SwitchGroup.d.ts +13 -0
- package/dist/src/components/Table/Table.d.ts +2 -1
- package/dist/src/components/Tabs/Tabs.d.ts +20 -3
- package/dist/src/components/Text/Text.d.ts +2 -16
- package/dist/src/components/TextArea/TextArea.d.ts +12 -2
- package/dist/src/components/TextField/TextField.d.ts +12 -2
- package/dist/src/components/TimePicker/TimePicker.d.ts +2 -1
- package/dist/src/components/Timeline/Timeline.d.ts +15 -2
- package/dist/src/components/Timeline/TimelineItem.d.ts +18 -0
- package/dist/src/components/Title/Title.d.ts +2 -15
- package/dist/src/components/Toast/Toast.d.ts +20 -2
- package/dist/src/components/Tooltip/Tooltip.d.ts +28 -3
- 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 +14 -3
- package/src/components/Accordion/Accordion.module.css +294 -56
- package/src/components/Accordion/Accordion.stories.tsx +131 -21
- package/src/components/Accordion/Accordion.tsx +260 -5
- package/src/components/AssistiveElement/AssistiveElement.module.css +114 -20
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +60 -20
- package/src/components/AssistiveElement/AssistiveElement.tsx +81 -5
- package/src/components/Autocomplete/Autocomplete.module.css +319 -42
- package/src/components/Autocomplete/Autocomplete.stories.tsx +175 -23
- package/src/components/Autocomplete/Autocomplete.tsx +181 -6
- package/src/components/Avatar/Avatar.module.css +343 -73
- package/src/components/Avatar/Avatar.stories.tsx +94 -22
- package/src/components/Avatar/Avatar.tsx +99 -6
- package/src/components/Badge/Badge.module.css +127 -29
- package/src/components/Badge/Badge.stories.tsx +65 -22
- package/src/components/Badge/Badge.tsx +67 -6
- package/src/components/Breadcrumb/Breadcrumb.module.css +25 -5
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +57 -22
- package/src/components/Breadcrumb/Breadcrumb.tsx +59 -6
- 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 +154 -38
- package/src/components/Card/Card.stories.tsx +117 -19
- package/src/components/Card/Card.tsx +181 -5
- package/src/components/Checkbox/Checkbox.module.css +249 -39
- package/src/components/Checkbox/Checkbox.stories.tsx +81 -19
- package/src/components/Checkbox/Checkbox.tsx +246 -5
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +137 -0
- package/src/components/Checkbox/index.ts +6 -1
- package/src/components/Chip/Chip.module.css +246 -43
- package/src/components/Chip/Chip.stories.tsx +101 -21
- package/src/components/Chip/Chip.tsx +136 -6
- 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.module.css +291 -41
- package/src/components/Dropdown/Dropdown.stories.tsx +80 -21
- package/src/components/Dropdown/Dropdown.tsx +180 -6
- 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.module.css +92 -0
- package/src/components/FormControlLayout/FormControlLayout.stories.tsx +67 -20
- package/src/components/FormControlLayout/FormControlLayout.tsx +69 -4
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +87 -0
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +116 -22
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +126 -6
- package/src/components/Group/Group.stories.tsx +6 -30
- package/src/components/Group/Group.tsx +14 -9
- package/src/components/HoverCard/HoverCard.module.css +90 -22
- package/src/components/HoverCard/HoverCard.stories.tsx +158 -21
- package/src/components/HoverCard/HoverCard.tsx +147 -5
- package/src/components/Label/Label.module.css +140 -35
- package/src/components/Label/Label.stories.tsx +108 -21
- package/src/components/Label/Label.tsx +82 -5
- 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.module.css +285 -51
- package/src/components/Menu/Menu.stories.tsx +229 -25
- package/src/components/Menu/Menu.tsx +73 -6
- package/src/components/Modal/Modal.module.css +171 -35
- package/src/components/Modal/Modal.stories.tsx +66 -22
- package/src/components/Modal/Modal.tsx +215 -5
- package/src/components/NumberInput/NumberInput.module.css +276 -42
- package/src/components/NumberInput/NumberInput.stories.tsx +83 -20
- package/src/components/NumberInput/NumberInput.tsx +136 -6
- package/src/components/Pagination/IMPLEMENTATION_NOTES.md +3 -0
- package/src/components/Pagination/Pagination.icons.tsx +66 -0
- package/src/components/Pagination/Pagination.module.css +234 -20
- package/src/components/Pagination/Pagination.stories.tsx +34 -21
- package/src/components/Pagination/Pagination.tsx +74 -6
- package/src/components/Panel/Panel.module.css +206 -38
- package/src/components/Panel/Panel.stories.tsx +214 -22
- package/src/components/Panel/Panel.tsx +130 -5
- package/src/components/Radio/Radio.module.css +235 -37
- package/src/components/Radio/Radio.stories.tsx +77 -19
- package/src/components/Radio/Radio.tsx +210 -5
- package/src/components/Radio/RadioGroup.stories.tsx +117 -0
- package/src/components/Radio/RadioGroup.tsx +125 -0
- package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +53 -15
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +147 -19
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +105 -5
- package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
- package/src/components/ReadOnlyField/index.ts +1 -0
- package/src/components/SegmentedControl/SegmentedControl.module.css +179 -47
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +102 -20
- package/src/components/SegmentedControl/SegmentedControl.tsx +140 -6
- package/src/components/Slider/Slider.module.css +539 -86
- package/src/components/Slider/Slider.stories.tsx +157 -19
- package/src/components/Slider/Slider.tsx +283 -5
- 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.module.css +410 -71
- package/src/components/Stepper/Stepper.stories.tsx +146 -20
- package/src/components/Stepper/Stepper.tsx +147 -6
- package/src/components/Switch/Switch.module.css +259 -39
- package/src/components/Switch/Switch.stories.tsx +98 -19
- package/src/components/Switch/Switch.tsx +200 -6
- package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
- package/src/components/Switch/SwitchGroup.tsx +120 -0
- 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.module.css +422 -79
- package/src/components/Tabs/Tabs.stories.tsx +156 -20
- package/src/components/Tabs/Tabs.tsx +86 -6
- package/src/components/Text/Text.stories.tsx +5 -17
- package/src/components/Text/Text.tsx +1 -15
- package/src/components/TextArea/TextArea.module.css +155 -32
- package/src/components/TextArea/TextArea.stories.tsx +80 -21
- package/src/components/TextArea/TextArea.tsx +146 -6
- package/src/components/TextField/TextField.module.css +261 -42
- package/src/components/TextField/TextField.stories.tsx +147 -20
- package/src/components/TextField/TextField.tsx +169 -6
- package/src/components/TimePicker/TimePicker.stories.tsx +2 -19
- package/src/components/TimePicker/TimePicker.tsx +3 -1
- package/src/components/Timeline/Timeline.module.css +365 -76
- package/src/components/Timeline/Timeline.stories.tsx +114 -21
- package/src/components/Timeline/Timeline.tsx +83 -5
- package/src/components/Timeline/TimelineItem.tsx +90 -0
- package/src/components/Title/Title.stories.tsx +0 -18
- package/src/components/Title/Title.tsx +1 -7
- package/src/components/Toast/Toast.module.css +166 -28
- package/src/components/Toast/Toast.stories.tsx +54 -22
- package/src/components/Toast/Toast.tsx +124 -5
- package/src/components/Tooltip/Tooltip.module.css +89 -24
- package/src/components/Tooltip/Tooltip.stories.tsx +152 -22
- package/src/components/Tooltip/Tooltip.tsx +88 -5
- 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
|
@@ -1,8 +1,202 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Switch as MuiSwitch,
|
|
4
|
+
type SwitchProps as MuiSwitchProps,
|
|
5
|
+
} from "@mui/material";
|
|
6
|
+
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
3
7
|
|
|
4
|
-
|
|
8
|
+
import {
|
|
9
|
+
filterStylingProps,
|
|
10
|
+
type RecursicaOverStyled,
|
|
11
|
+
} from "../../utils/filterStylingProps";
|
|
12
|
+
import {
|
|
13
|
+
type RequireAccessibleLabel,
|
|
14
|
+
type RecursicaSwitchProps,
|
|
15
|
+
} from "@recursica/adapter-common";
|
|
16
|
+
import {
|
|
17
|
+
FormControlLayout,
|
|
18
|
+
type FormControlLayoutProps,
|
|
19
|
+
} from "../FormControlLayout/FormControlLayout";
|
|
20
|
+
import styles from "./Switch.module.css";
|
|
5
21
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
22
|
+
// Removed unused SwitchGroup import
|
|
23
|
+
|
|
24
|
+
export type SwitchWrapperProps = Omit<
|
|
25
|
+
MuiSwitchProps,
|
|
26
|
+
"size" | "color" | "radius" | "variant"
|
|
27
|
+
> &
|
|
28
|
+
RecursicaSwitchProps &
|
|
29
|
+
ReadOnlyControlProps &
|
|
30
|
+
Pick<
|
|
31
|
+
FormControlLayoutProps,
|
|
32
|
+
"formLayout" | "labelSize" | "controlMaxWidth" | "controlMinWidth"
|
|
33
|
+
>;
|
|
34
|
+
|
|
35
|
+
export type RecursicaSwitchPropsAlias =
|
|
36
|
+
RequireAccessibleLabel<SwitchWrapperProps>;
|
|
37
|
+
|
|
38
|
+
export type SwitchProps = RecursicaOverStyled<RecursicaSwitchPropsAlias>;
|
|
39
|
+
|
|
40
|
+
type SwitchComponent = any;
|
|
41
|
+
|
|
42
|
+
export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
|
43
|
+
function Switch(props, ref) {
|
|
44
|
+
const {
|
|
45
|
+
overStyled = false,
|
|
46
|
+
readOnly,
|
|
47
|
+
readOnlyComponent,
|
|
48
|
+
disabled,
|
|
49
|
+
// Removed thumbIcon from destructured props since it's not supported
|
|
50
|
+
formLayout,
|
|
51
|
+
labelSize,
|
|
52
|
+
controlMaxWidth,
|
|
53
|
+
controlMinWidth,
|
|
54
|
+
label,
|
|
55
|
+
description,
|
|
56
|
+
error,
|
|
57
|
+
style,
|
|
58
|
+
...rest
|
|
59
|
+
} = props;
|
|
60
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
61
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
62
|
+
|
|
63
|
+
// Actively delete dimension bindings that bypass the abstraction
|
|
64
|
+
delete restRecord["size"];
|
|
65
|
+
delete restRecord["color"];
|
|
66
|
+
delete restRecord["radius"];
|
|
67
|
+
delete restRecord["variant"];
|
|
68
|
+
|
|
69
|
+
const mergedClassNames: Partial<Record<string, string>> = {
|
|
70
|
+
root: styles.root,
|
|
71
|
+
body: styles.body,
|
|
72
|
+
track: styles.track,
|
|
73
|
+
thumb: styles.thumb,
|
|
74
|
+
trackLabel: styles.trackLabel,
|
|
75
|
+
labelWrapper: styles.labelWrapper,
|
|
76
|
+
label: styles.label,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const classNamesProp = restRecord.classNames;
|
|
80
|
+
if (
|
|
81
|
+
classNamesProp &&
|
|
82
|
+
typeof classNamesProp === "object" &&
|
|
83
|
+
!Array.isArray(classNamesProp)
|
|
84
|
+
) {
|
|
85
|
+
const o = classNamesProp as Partial<Record<string, string>>;
|
|
86
|
+
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
87
|
+
mergedClassNames.body = o.body ? `${styles.body} ${o.body}` : styles.body;
|
|
88
|
+
mergedClassNames.track = o.track
|
|
89
|
+
? `${styles.track} ${o.track}`
|
|
90
|
+
: styles.track;
|
|
91
|
+
mergedClassNames.thumb = o.thumb
|
|
92
|
+
? `${styles.thumb} ${o.thumb}`
|
|
93
|
+
: styles.thumb;
|
|
94
|
+
mergedClassNames.trackLabel = o.trackLabel
|
|
95
|
+
? `${styles.trackLabel} ${o.trackLabel}`
|
|
96
|
+
: styles.trackLabel;
|
|
97
|
+
mergedClassNames.labelWrapper = o.labelWrapper
|
|
98
|
+
? `${styles.labelWrapper} ${o.labelWrapper}`
|
|
99
|
+
: styles.labelWrapper;
|
|
100
|
+
mergedClassNames.label = o.label
|
|
101
|
+
? `${styles.label} ${o.label}`
|
|
102
|
+
: styles.label;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const classNameProp = restRecord.className as string | undefined;
|
|
106
|
+
const finalClass = classNameProp
|
|
107
|
+
? `${styles.root} ${classNameProp}`
|
|
108
|
+
: styles.root;
|
|
109
|
+
|
|
110
|
+
if (readOnly && !!readOnlyComponent) {
|
|
111
|
+
const isChecked = !!(restRecord.checked ?? restRecord.defaultChecked);
|
|
112
|
+
const ReadOnlyComp = readOnlyComponent;
|
|
113
|
+
const roNode = (
|
|
114
|
+
<ReadOnlyComp
|
|
115
|
+
{...props}
|
|
116
|
+
checked={isChecked}
|
|
117
|
+
label={restRecord.label as React.ReactNode}
|
|
118
|
+
/>
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
if (formLayout) {
|
|
122
|
+
return (
|
|
123
|
+
<FormControlLayout
|
|
124
|
+
formLayout={formLayout}
|
|
125
|
+
labelSize={labelSize}
|
|
126
|
+
controlMaxWidth={controlMaxWidth}
|
|
127
|
+
controlMinWidth={controlMinWidth}
|
|
128
|
+
>
|
|
129
|
+
{roNode}
|
|
130
|
+
</FormControlLayout>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return <>{roNode}</>;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// We omit Mui's sizing/coloring so we rely strictly on variables from Switch.module.css
|
|
138
|
+
const switchNode = (
|
|
139
|
+
<MuiSwitch
|
|
140
|
+
ref={ref as any}
|
|
141
|
+
className={!label ? `${finalClass} ${styles.inner}` : styles.inner}
|
|
142
|
+
classes={mergedClassNames}
|
|
143
|
+
disabled={readOnly || disabled}
|
|
144
|
+
data-disabled={readOnly || disabled || undefined}
|
|
145
|
+
// thumbIcon={thumbIcon ?? FinalThumbIcon}
|
|
146
|
+
{...(sanitizedProps as unknown as MuiSwitchProps)}
|
|
147
|
+
/>
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
const finalNode = label ? (
|
|
151
|
+
<div className={finalClass} style={style as React.CSSProperties}>
|
|
152
|
+
<div className={styles.body}>
|
|
153
|
+
{switchNode}
|
|
154
|
+
<div className={styles.labelWrapper}>
|
|
155
|
+
<label
|
|
156
|
+
className={styles.label}
|
|
157
|
+
htmlFor={restRecord.id as string}
|
|
158
|
+
data-disabled={readOnly || disabled ? true : undefined}
|
|
159
|
+
>
|
|
160
|
+
{label as React.ReactNode}
|
|
161
|
+
</label>
|
|
162
|
+
{description && (
|
|
163
|
+
<div
|
|
164
|
+
className={styles.description}
|
|
165
|
+
data-disabled={readOnly || disabled ? true : undefined}
|
|
166
|
+
>
|
|
167
|
+
{description}
|
|
168
|
+
</div>
|
|
169
|
+
)}
|
|
170
|
+
{error && (
|
|
171
|
+
<div
|
|
172
|
+
className={styles.error}
|
|
173
|
+
data-disabled={readOnly || disabled ? true : undefined}
|
|
174
|
+
>
|
|
175
|
+
{error}
|
|
176
|
+
</div>
|
|
177
|
+
)}
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
) : (
|
|
182
|
+
switchNode
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
if (formLayout) {
|
|
186
|
+
return (
|
|
187
|
+
<FormControlLayout
|
|
188
|
+
formLayout={formLayout}
|
|
189
|
+
labelSize={labelSize}
|
|
190
|
+
controlMaxWidth={controlMaxWidth}
|
|
191
|
+
controlMinWidth={controlMinWidth}
|
|
192
|
+
>
|
|
193
|
+
{finalNode}
|
|
194
|
+
</FormControlLayout>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return finalNode;
|
|
199
|
+
},
|
|
200
|
+
) as SwitchComponent;
|
|
201
|
+
|
|
202
|
+
Switch.displayName = "Switch";
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Switch } from "./Switch";
|
|
3
|
+
import { SwitchGroup } from "./SwitchGroup";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof SwitchGroup> = {
|
|
8
|
+
title: "UI-Kit/SwitchGroup",
|
|
9
|
+
component: SwitchGroup,
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
parameters: {
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component: `
|
|
15
|
+
The \`SwitchGroup\` component is the mandatory organizational wrapper for orchestrating \`Switch\` primitives into macro form layouts. It inherently leverages the \`FormControlWrapper\`, granting native access to structural alignments, assistive descriptions, and strict flex arrays.
|
|
16
|
+
|
|
17
|
+
### Supported Layout Vectors
|
|
18
|
+
- **\`formLayout="stacked"\`**: Top-to-bottom layout cascading the Label bounding box down vertically into a standard stacked switch array.
|
|
19
|
+
- **\`formLayout="side-by-side"\`**: Flow architecture pulling the grouping Label dynamically to the left while structurally organizing the internal switches cleanly alongside it horizontally.
|
|
20
|
+
|
|
21
|
+
> [!IMPORTANT]
|
|
22
|
+
> If you require a solitary \`Switch\` field to natively accept an overarching form label, assistive text, or align with other side-by-side components in a form column, you must wrap it inside a \`Switch.Group\` to trigger the \`FormControlWrapper\` mapping.
|
|
23
|
+
`,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
argTypes: {
|
|
28
|
+
...formControlArgTypes,
|
|
29
|
+
readOnly: {
|
|
30
|
+
control: "boolean",
|
|
31
|
+
description:
|
|
32
|
+
"Passes read-only lock natively down mapping inner switches into explicitly disabled states.",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default meta;
|
|
38
|
+
|
|
39
|
+
type Story = StoryObj<typeof SwitchGroup>;
|
|
40
|
+
|
|
41
|
+
export const Default: Story = {
|
|
42
|
+
args: {
|
|
43
|
+
formLayout: "stacked",
|
|
44
|
+
label: "Standard Group",
|
|
45
|
+
},
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
47
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
48
|
+
const [value, setValue] = useState<string[]>([]);
|
|
49
|
+
return (
|
|
50
|
+
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
51
|
+
<Switch value="1" label="Option 1" />
|
|
52
|
+
<Switch value="2" label="Option 2" />
|
|
53
|
+
</SwitchGroup>
|
|
54
|
+
);
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const StackedLayout: Story = {
|
|
59
|
+
args: {
|
|
60
|
+
formLayout: "stacked",
|
|
61
|
+
label: "Notification Settings",
|
|
62
|
+
description: "Manage your preferences.",
|
|
63
|
+
assistiveText: "We recommend turning these on.",
|
|
64
|
+
error: "",
|
|
65
|
+
required: true,
|
|
66
|
+
},
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
68
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
69
|
+
const [value, setValue] = useState<string[]>(["email"]);
|
|
70
|
+
return (
|
|
71
|
+
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
72
|
+
<Switch value="email" label="Email Alerts" />
|
|
73
|
+
<Switch value="push" label="Push Notifications" />
|
|
74
|
+
<Switch value="sms" label="SMS Messages" />
|
|
75
|
+
</SwitchGroup>
|
|
76
|
+
);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const SideBySideLayout: Story = {
|
|
81
|
+
args: {
|
|
82
|
+
...StackedLayout.args,
|
|
83
|
+
formLayout: "side-by-side",
|
|
84
|
+
labelSize: "default",
|
|
85
|
+
labelAlignment: "left",
|
|
86
|
+
},
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
88
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
89
|
+
const [value, setValue] = useState<string[]>([]);
|
|
90
|
+
return (
|
|
91
|
+
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
92
|
+
<Switch value="weekly" label="Weekly Digest" />
|
|
93
|
+
<Switch value="marketing" label="Marketing Emails" />
|
|
94
|
+
</SwitchGroup>
|
|
95
|
+
);
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const SolitaryFormControl: Story = {
|
|
100
|
+
args: {
|
|
101
|
+
formLayout: "side-by-side",
|
|
102
|
+
label: "Enable Backups",
|
|
103
|
+
description: "Automatically back up your data nightly.",
|
|
104
|
+
},
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
106
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
107
|
+
const [value, setValue] = useState<string[]>(["auto"]);
|
|
108
|
+
return (
|
|
109
|
+
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
110
|
+
<Switch value="auto" label="Auto-backup" />
|
|
111
|
+
</SwitchGroup>
|
|
112
|
+
);
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export const ReadOnly: Story = {
|
|
117
|
+
args: {
|
|
118
|
+
...StackedLayout.args,
|
|
119
|
+
readOnly: true,
|
|
120
|
+
},
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
122
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
123
|
+
const [value, setValue] = useState<string[]>(["email", "sms"]);
|
|
124
|
+
return (
|
|
125
|
+
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
126
|
+
<Switch value="email" label="Email Alerts" />
|
|
127
|
+
<Switch value="push" label="Push Notifications" />
|
|
128
|
+
<Switch value="sms" label="SMS Messages" />
|
|
129
|
+
</SwitchGroup>
|
|
130
|
+
);
|
|
131
|
+
},
|
|
132
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import React, { forwardRef } from "react";
|
|
3
|
+
import {
|
|
4
|
+
FormGroup as MuiFormGroup,
|
|
5
|
+
type FormGroupProps as MuiFormGroupProps,
|
|
6
|
+
} from "@mui/material";
|
|
7
|
+
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
8
|
+
import {
|
|
9
|
+
filterStylingProps,
|
|
10
|
+
type RecursicaOverStyled,
|
|
11
|
+
} from "../../utils/filterStylingProps";
|
|
12
|
+
import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
|
|
13
|
+
import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
|
|
14
|
+
import styles from "./Switch.module.css";
|
|
15
|
+
|
|
16
|
+
import { type RecursicaSwitchGroupProps as BaseRecursicaSwitchGroupProps } from "@recursica/adapter-common";
|
|
17
|
+
|
|
18
|
+
export interface RecursicaSwitchGroupProps
|
|
19
|
+
extends Omit<
|
|
20
|
+
MuiFormGroupProps,
|
|
21
|
+
| "size"
|
|
22
|
+
| "labelProps"
|
|
23
|
+
| "onChange"
|
|
24
|
+
| "classes"
|
|
25
|
+
| "ref"
|
|
26
|
+
| "value"
|
|
27
|
+
| "defaultValue"
|
|
28
|
+
>,
|
|
29
|
+
Omit<
|
|
30
|
+
RecursicaFormControlWrapperProps,
|
|
31
|
+
"controlMaxWidth" | "controlMinWidth" | "classes" | "onChange"
|
|
32
|
+
>,
|
|
33
|
+
ReadOnlyControlProps,
|
|
34
|
+
BaseRecursicaSwitchGroupProps {}
|
|
35
|
+
|
|
36
|
+
export type SwitchGroupProps = RecursicaOverStyled<RecursicaSwitchGroupProps>;
|
|
37
|
+
|
|
38
|
+
export const SwitchGroup = forwardRef<HTMLDivElement, SwitchGroupProps>(
|
|
39
|
+
function SwitchGroup(props, ref) {
|
|
40
|
+
const {
|
|
41
|
+
overStyled = false,
|
|
42
|
+
formLayout = "stacked",
|
|
43
|
+
|
|
44
|
+
// Label Wrappers
|
|
45
|
+
labelSize,
|
|
46
|
+
labelAlignment,
|
|
47
|
+
labelOptionalText,
|
|
48
|
+
labelWithEditIcon,
|
|
49
|
+
onLabelEditClick,
|
|
50
|
+
|
|
51
|
+
// Base Mui Extracted Attributes
|
|
52
|
+
label,
|
|
53
|
+
description,
|
|
54
|
+
assistiveText,
|
|
55
|
+
assistiveWithIcon,
|
|
56
|
+
error,
|
|
57
|
+
required,
|
|
58
|
+
// removed withAsterisk
|
|
59
|
+
id,
|
|
60
|
+
className,
|
|
61
|
+
style,
|
|
62
|
+
children,
|
|
63
|
+
readOnly,
|
|
64
|
+
readOnlyComponent,
|
|
65
|
+
emptyValueComponent,
|
|
66
|
+
value,
|
|
67
|
+
defaultValue,
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
69
|
+
onChange,
|
|
70
|
+
...rest
|
|
71
|
+
} = props;
|
|
72
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
73
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
74
|
+
|
|
75
|
+
// Delete prohibited sizing hooks from bypassing the variables
|
|
76
|
+
delete restRecord["size"];
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<WithReadOnlyWrapper
|
|
80
|
+
className={className}
|
|
81
|
+
style={style as React.CSSProperties}
|
|
82
|
+
controlMaxWidth="var(--recursica_ui-kit_components_switch-item_properties_label-max-width)"
|
|
83
|
+
controlMinWidth={undefined}
|
|
84
|
+
overStyled={overStyled as true}
|
|
85
|
+
// Strictly override. ARIA grouping prohibits interactive switches nested natively inside <label>.
|
|
86
|
+
formLayout={formLayout}
|
|
87
|
+
labelSize={labelSize}
|
|
88
|
+
labelAlignment={labelAlignment}
|
|
89
|
+
labelOptionalText={labelOptionalText}
|
|
90
|
+
labelWithEditIcon={labelWithEditIcon}
|
|
91
|
+
onLabelEditClick={onLabelEditClick}
|
|
92
|
+
label={label}
|
|
93
|
+
description={description}
|
|
94
|
+
assistiveText={assistiveText}
|
|
95
|
+
assistiveWithIcon={assistiveWithIcon}
|
|
96
|
+
error={error}
|
|
97
|
+
required={required}
|
|
98
|
+
id={id}
|
|
99
|
+
readOnly={readOnly && !!readOnlyComponent}
|
|
100
|
+
readOnlyComponent={readOnlyComponent}
|
|
101
|
+
emptyValueComponent={emptyValueComponent}
|
|
102
|
+
readOnlyType="text"
|
|
103
|
+
readOnlyValue={value !== undefined ? value : defaultValue}
|
|
104
|
+
readOnlyNativeProps={props}
|
|
105
|
+
activeComponent={
|
|
106
|
+
<MuiFormGroup
|
|
107
|
+
ref={ref}
|
|
108
|
+
{...(sanitizedProps as unknown as MuiFormGroupProps)}
|
|
109
|
+
className={`${styles.groupRoot} ${(sanitizedProps as any).className || ""}`.trim()}
|
|
110
|
+
data-layout={formLayout}
|
|
111
|
+
>
|
|
112
|
+
{children}
|
|
113
|
+
</MuiFormGroup>
|
|
114
|
+
}
|
|
115
|
+
/>
|
|
116
|
+
);
|
|
117
|
+
},
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
SwitchGroup.displayName = "SwitchGroup";
|
|
@@ -6,28 +6,10 @@ const meta: Meta<typeof Table> = {
|
|
|
6
6
|
title: "UI-Kit/🚧 Table",
|
|
7
7
|
component: Table,
|
|
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
|
-
},
|
|
28
9
|
};
|
|
29
10
|
|
|
30
11
|
export default meta;
|
|
12
|
+
|
|
31
13
|
type Story = StoryObj<typeof Table>;
|
|
32
14
|
|
|
33
15
|
export const Default: Story = {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { type RecursicaTableProps } from "@recursica/adapter-common";
|
|
2
3
|
|
|
3
|
-
export type TableProps = React.HTMLAttributes<HTMLDivElement
|
|
4
|
+
export type TableProps = React.HTMLAttributes<HTMLDivElement> &
|
|
5
|
+
RecursicaTableProps;
|
|
4
6
|
|
|
5
7
|
export const Table: React.FC<TableProps> = (props) => {
|
|
6
8
|
return <div {...props}>Table</div>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# Tabs Implementation Notes
|
|
2
|
+
|
|
3
|
+
- **Compositional API Dropped:** Mantine uses `<Tabs.List>`, `<Tabs.Tab>`, and `<Tabs.Panel>` natively with implicit context from `<Tabs>`. MUI relies on `@mui/lab/TabContext` and separates `Tabs` and `TabPanel`.
|
|
4
|
+
- **Monolithic API Adopted:** Following architectural review, we have opted to drop the broken dot-notation wrappers for `mui-adapter`. We now natively export `Tabs` (MUI List), `Tab` (MUI Item), and `TabPanel` (from `@mui/lab`). Developers must use `TabContext` (from `@mui/lab`) to manage state, just like native MUI. Storybook and visual regression tests have been updated to reflect this divergence while retaining core property mapping compatibility.
|