@recursica/mantine-adapter 0.10.0 → 0.12.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/CHANGELOG.md +16 -0
- package/README.md +6 -28
- package/dist/mantine-adapter.cjs +1 -1
- package/dist/mantine-adapter.cjs.map +1 -1
- package/dist/mantine-adapter.css +1 -1
- package/dist/mantine-adapter.js +1650 -1344
- package/dist/mantine-adapter.js.map +1 -1
- package/dist/src/components/Checkbox/Checkbox.d.ts +3 -1
- package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +21 -0
- package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +2 -0
- package/dist/src/components/Label/Label.d.ts +1 -3
- package/dist/src/components/Menu/Menu.d.ts +85 -3
- package/dist/src/components/Radio/Radio.d.ts +3 -1
- package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +6 -6
- package/dist/src/components/ReadOnlyField/ReadOnlySwitchField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +7 -1
- package/dist/src/components/ReadOnlyField/index.d.ts +2 -0
- package/dist/src/components/Switch/Switch.d.ts +3 -1
- package/dist/src/components/index.d.ts +1 -0
- package/dist/src/utils/RequireAccessibleLabel.d.ts +18 -0
- package/package.json +1 -1
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +6 -4
- package/src/components/Avatar/Avatar.stories.tsx +10 -5
- package/src/components/Badge/Badge.stories.tsx +2 -1
- package/src/components/Button/Button.stories.tsx +2 -4
- package/src/components/Checkbox/Checkbox.module.css +1 -1
- package/src/components/Checkbox/Checkbox.stories.tsx +24 -3
- package/src/components/Checkbox/Checkbox.tsx +72 -15
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +26 -25
- package/src/components/Checkbox/CheckboxGroup.tsx +38 -58
- package/src/components/Container/Container.stories.tsx +6 -3
- package/src/components/DatePicker/DatePicker.stories.tsx +1 -5
- package/src/components/Dropdown/Dropdown.stories.tsx +0 -3
- package/src/components/Dropdown/Dropdown.tsx +6 -5
- package/src/components/FileInput/FileInput.stories.tsx +1 -5
- package/src/components/FileUpload/FileUpload.stories.tsx +1 -5
- package/src/components/Flex/Flex.stories.tsx +6 -3
- package/src/components/FormControlLayout/FormControlLayout.module.css +80 -0
- package/src/components/FormControlLayout/FormControlLayout.stories.tsx +82 -0
- package/src/components/FormControlLayout/FormControlLayout.tsx +78 -0
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +3 -41
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +18 -5
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +28 -41
- package/src/components/Group/Group.stories.tsx +6 -3
- package/src/components/Label/Label.module.css +0 -37
- package/src/components/Label/Label.stories.tsx +8 -9
- package/src/components/Label/Label.tsx +2 -7
- package/src/components/Loader/Loader.stories.tsx +10 -5
- package/src/components/Menu/MENU_IMPLEMENTATION_NOTES.md +78 -0
- package/src/components/Menu/Menu.module.css +244 -0
- package/src/components/Menu/Menu.stories.tsx +309 -5
- package/src/components/Menu/Menu.tsx +317 -4
- package/src/components/NumberInput/NumberInput.stories.tsx +1 -5
- package/src/components/Radio/Radio.stories.tsx +22 -8
- package/src/components/Radio/Radio.tsx +134 -75
- package/src/components/Radio/RadioGroup.stories.tsx +26 -7
- package/src/components/Radio/RadioGroup.tsx +37 -57
- package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +43 -0
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +30 -3
- package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +3 -1
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +10 -2
- package/src/components/ReadOnlyField/index.ts +2 -0
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +1 -5
- package/src/components/Slider/Slider.stories.tsx +1 -5
- package/src/components/Stack/Stack.stories.tsx +6 -3
- package/src/components/Switch/Switch.module.css +2 -10
- package/src/components/Switch/Switch.stories.tsx +42 -27
- package/src/components/Switch/Switch.tsx +138 -89
- package/src/components/Switch/SwitchGroup.stories.tsx +28 -8
- package/src/components/Switch/SwitchGroup.tsx +37 -57
- package/src/components/TextArea/TextArea.stories.tsx +0 -3
- package/src/components/TextArea/TextArea.tsx +6 -5
- package/src/components/TextField/TextField.tsx +6 -5
- package/src/components/TimePicker/TimePicker.stories.tsx +1 -5
- package/src/components/index.ts +1 -0
- package/src/utils/RequireAccessibleLabel.ts +12 -0
|
@@ -11,15 +11,23 @@ import {
|
|
|
11
11
|
filterStylingProps,
|
|
12
12
|
type RecursicaOverStyled,
|
|
13
13
|
} from "../../utils/filterStylingProps";
|
|
14
|
+
import { type RequireAccessibleLabel } from "../../utils/RequireAccessibleLabel";
|
|
15
|
+
import {
|
|
16
|
+
FormControlLayout,
|
|
17
|
+
type FormControlLayoutProps,
|
|
18
|
+
} from "../FormControlLayout/FormControlLayout";
|
|
14
19
|
import styles from "./Switch.module.css";
|
|
15
20
|
|
|
16
21
|
import { SwitchGroup } from "./SwitchGroup";
|
|
17
22
|
|
|
18
|
-
export type RecursicaSwitchProps =
|
|
19
|
-
MantineSwitchProps,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
export type RecursicaSwitchProps = RequireAccessibleLabel<
|
|
24
|
+
Omit<MantineSwitchProps, "size" | "color" | "radius" | "variant"> &
|
|
25
|
+
ReadOnlyControlProps &
|
|
26
|
+
Pick<
|
|
27
|
+
FormControlLayoutProps,
|
|
28
|
+
"formLayout" | "labelSize" | "controlMaxWidth" | "controlMinWidth"
|
|
29
|
+
>
|
|
30
|
+
>;
|
|
23
31
|
|
|
24
32
|
export type SwitchProps = RecursicaOverStyled<RecursicaSwitchProps>;
|
|
25
33
|
|
|
@@ -29,91 +37,132 @@ type SwitchComponent = React.ForwardRefExoticComponent<
|
|
|
29
37
|
Group: typeof SwitchGroup;
|
|
30
38
|
};
|
|
31
39
|
|
|
32
|
-
export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
|
33
|
-
{
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
|
41
|
+
function Switch(props, ref) {
|
|
42
|
+
const {
|
|
43
|
+
overStyled = false,
|
|
44
|
+
readOnly,
|
|
45
|
+
readOnlyComponent,
|
|
46
|
+
disabled,
|
|
47
|
+
thumbIcon,
|
|
48
|
+
formLayout,
|
|
49
|
+
labelSize,
|
|
50
|
+
controlMaxWidth,
|
|
51
|
+
controlMinWidth,
|
|
52
|
+
...rest
|
|
53
|
+
} = props;
|
|
54
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
55
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
56
|
+
|
|
57
|
+
// Actively delete dimension bindings that bypass the abstraction
|
|
58
|
+
delete restRecord["size"];
|
|
59
|
+
delete restRecord["color"];
|
|
60
|
+
delete restRecord["radius"];
|
|
61
|
+
delete restRecord["variant"];
|
|
62
|
+
|
|
63
|
+
const mergedClassNames: Partial<Record<string, string>> = {
|
|
64
|
+
root: styles.root,
|
|
65
|
+
body: styles.body,
|
|
66
|
+
track: styles.track,
|
|
67
|
+
thumb: styles.thumb,
|
|
68
|
+
trackLabel: styles.trackLabel,
|
|
69
|
+
labelWrapper: styles.labelWrapper,
|
|
70
|
+
label: styles.label,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const classNamesProp = restRecord.classNames;
|
|
74
|
+
if (
|
|
75
|
+
classNamesProp &&
|
|
76
|
+
typeof classNamesProp === "object" &&
|
|
77
|
+
!Array.isArray(classNamesProp)
|
|
78
|
+
) {
|
|
79
|
+
const o = classNamesProp as Partial<Record<string, string>>;
|
|
80
|
+
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
81
|
+
mergedClassNames.body = o.body ? `${styles.body} ${o.body}` : styles.body;
|
|
82
|
+
mergedClassNames.track = o.track
|
|
83
|
+
? `${styles.track} ${o.track}`
|
|
84
|
+
: styles.track;
|
|
85
|
+
mergedClassNames.thumb = o.thumb
|
|
86
|
+
? `${styles.thumb} ${o.thumb}`
|
|
87
|
+
: styles.thumb;
|
|
88
|
+
mergedClassNames.trackLabel = o.trackLabel
|
|
89
|
+
? `${styles.trackLabel} ${o.trackLabel}`
|
|
90
|
+
: styles.trackLabel;
|
|
91
|
+
mergedClassNames.labelWrapper = o.labelWrapper
|
|
92
|
+
? `${styles.labelWrapper} ${o.labelWrapper}`
|
|
93
|
+
: styles.labelWrapper;
|
|
94
|
+
mergedClassNames.label = o.label
|
|
95
|
+
? `${styles.label} ${o.label}`
|
|
96
|
+
: styles.label;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const classNameProp = restRecord.className as string | undefined;
|
|
100
|
+
const finalClass = classNameProp
|
|
101
|
+
? `${styles.root} ${classNameProp}`
|
|
102
|
+
: styles.root;
|
|
103
|
+
|
|
104
|
+
if (readOnly && !!readOnlyComponent) {
|
|
105
|
+
const isChecked = !!(restRecord.checked ?? restRecord.defaultChecked);
|
|
106
|
+
const ReadOnlyComp = readOnlyComponent;
|
|
107
|
+
const roNode = (
|
|
108
|
+
<ReadOnlyComp
|
|
109
|
+
{...props}
|
|
110
|
+
checked={isChecked}
|
|
111
|
+
label={restRecord.label as React.ReactNode}
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
if (formLayout) {
|
|
116
|
+
return (
|
|
117
|
+
<FormControlLayout
|
|
118
|
+
formLayout={formLayout}
|
|
119
|
+
labelSize={labelSize}
|
|
120
|
+
controlMaxWidth={controlMaxWidth}
|
|
121
|
+
controlMinWidth={controlMinWidth}
|
|
122
|
+
>
|
|
123
|
+
{roNode}
|
|
124
|
+
</FormControlLayout>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return <>{roNode}</>;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const FinalThumbIcon = (
|
|
132
|
+
<div className={styles.thumbIconWrapper}>
|
|
133
|
+
<CheckIcon className={styles.checkIcon} />
|
|
134
|
+
<CloseIcon className={styles.closeIcon} />
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// We omit Mantine's sizing/coloring so we rely strictly on variables from Switch.module.css
|
|
139
|
+
const switchNode = (
|
|
140
|
+
<MantineSwitch
|
|
141
|
+
ref={ref}
|
|
142
|
+
className={finalClass}
|
|
143
|
+
classNames={mergedClassNames}
|
|
144
|
+
disabled={readOnly || disabled}
|
|
145
|
+
thumbIcon={thumbIcon ?? FinalThumbIcon}
|
|
146
|
+
{...(sanitizedProps as unknown as MantineSwitchProps)}
|
|
147
|
+
/>
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
if (formLayout) {
|
|
151
|
+
return (
|
|
152
|
+
<FormControlLayout
|
|
153
|
+
formLayout={formLayout}
|
|
154
|
+
labelSize={labelSize}
|
|
155
|
+
controlMaxWidth={controlMaxWidth}
|
|
156
|
+
controlMinWidth={controlMinWidth}
|
|
157
|
+
>
|
|
158
|
+
{switchNode}
|
|
159
|
+
</FormControlLayout>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return switchNode;
|
|
40
164
|
},
|
|
41
|
-
|
|
42
|
-
) {
|
|
43
|
-
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
44
|
-
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
45
|
-
|
|
46
|
-
// Actively delete dimension bindings that bypass the abstraction
|
|
47
|
-
delete restRecord["size"];
|
|
48
|
-
delete restRecord["color"];
|
|
49
|
-
delete restRecord["radius"];
|
|
50
|
-
delete restRecord["variant"];
|
|
51
|
-
|
|
52
|
-
if (readOnly && readOnlyComponent) {
|
|
53
|
-
// Safely fallback explicitly returning mapped elements natively without macro wrappers
|
|
54
|
-
return <>{readOnlyComponent}</>;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const mergedClassNames: Partial<Record<string, string>> = {
|
|
58
|
-
root: styles.root,
|
|
59
|
-
body: styles.body,
|
|
60
|
-
track: styles.track,
|
|
61
|
-
thumb: styles.thumb,
|
|
62
|
-
trackLabel: styles.trackLabel,
|
|
63
|
-
labelWrapper: styles.labelWrapper,
|
|
64
|
-
label: styles.label,
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const classNamesProp = restRecord.classNames;
|
|
68
|
-
if (
|
|
69
|
-
classNamesProp &&
|
|
70
|
-
typeof classNamesProp === "object" &&
|
|
71
|
-
!Array.isArray(classNamesProp)
|
|
72
|
-
) {
|
|
73
|
-
const o = classNamesProp as Partial<Record<string, string>>;
|
|
74
|
-
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
75
|
-
mergedClassNames.body = o.body ? `${styles.body} ${o.body}` : styles.body;
|
|
76
|
-
mergedClassNames.track = o.track
|
|
77
|
-
? `${styles.track} ${o.track}`
|
|
78
|
-
: styles.track;
|
|
79
|
-
mergedClassNames.thumb = o.thumb
|
|
80
|
-
? `${styles.thumb} ${o.thumb}`
|
|
81
|
-
: styles.thumb;
|
|
82
|
-
mergedClassNames.trackLabel = o.trackLabel
|
|
83
|
-
? `${styles.trackLabel} ${o.trackLabel}`
|
|
84
|
-
: styles.trackLabel;
|
|
85
|
-
mergedClassNames.labelWrapper = o.labelWrapper
|
|
86
|
-
? `${styles.labelWrapper} ${o.labelWrapper}`
|
|
87
|
-
: styles.labelWrapper;
|
|
88
|
-
mergedClassNames.label = o.label
|
|
89
|
-
? `${styles.label} ${o.label}`
|
|
90
|
-
: styles.label;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const classNameProp = restRecord.className as string | undefined;
|
|
94
|
-
const finalClass = classNameProp
|
|
95
|
-
? `${styles.root} ${classNameProp}`
|
|
96
|
-
: styles.root;
|
|
97
|
-
|
|
98
|
-
const FinalThumbIcon = (
|
|
99
|
-
<div className={styles.thumbIconWrapper}>
|
|
100
|
-
<CheckIcon className={styles.checkIcon} />
|
|
101
|
-
<CloseIcon className={styles.closeIcon} />
|
|
102
|
-
</div>
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
// We omit Mantine's sizing/coloring so we rely strictly on variables from Switch.module.css
|
|
106
|
-
return (
|
|
107
|
-
<MantineSwitch
|
|
108
|
-
ref={ref}
|
|
109
|
-
className={finalClass}
|
|
110
|
-
classNames={mergedClassNames}
|
|
111
|
-
disabled={readOnly || disabled}
|
|
112
|
-
thumbIcon={thumbIcon ?? FinalThumbIcon}
|
|
113
|
-
{...(sanitizedProps as unknown as MantineSwitchProps)}
|
|
114
|
-
/>
|
|
115
|
-
);
|
|
116
|
-
}) as SwitchComponent;
|
|
165
|
+
) as SwitchComponent;
|
|
117
166
|
|
|
118
167
|
Switch.displayName = "Switch";
|
|
119
168
|
Switch.Group = SwitchGroup;
|
|
@@ -39,6 +39,23 @@ export default meta;
|
|
|
39
39
|
type Story = StoryObj<typeof SwitchGroup>;
|
|
40
40
|
|
|
41
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 = {
|
|
42
59
|
args: {
|
|
43
60
|
formLayout: "stacked",
|
|
44
61
|
label: "Notification Settings",
|
|
@@ -47,7 +64,8 @@ export const Default: Story = {
|
|
|
47
64
|
error: "",
|
|
48
65
|
required: true,
|
|
49
66
|
},
|
|
50
|
-
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
68
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
51
69
|
const [value, setValue] = useState<string[]>(["email"]);
|
|
52
70
|
return (
|
|
53
71
|
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
@@ -61,12 +79,13 @@ export const Default: Story = {
|
|
|
61
79
|
|
|
62
80
|
export const SideBySideLayout: Story = {
|
|
63
81
|
args: {
|
|
64
|
-
...
|
|
82
|
+
...StackedLayout.args,
|
|
65
83
|
formLayout: "side-by-side",
|
|
66
84
|
labelSize: "default",
|
|
67
85
|
labelAlignment: "left",
|
|
68
86
|
},
|
|
69
|
-
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
88
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
70
89
|
const [value, setValue] = useState<string[]>([]);
|
|
71
90
|
return (
|
|
72
91
|
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
@@ -83,7 +102,8 @@ export const SolitaryFormControl: Story = {
|
|
|
83
102
|
label: "Enable Backups",
|
|
84
103
|
description: "Automatically back up your data nightly.",
|
|
85
104
|
},
|
|
86
|
-
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
106
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
87
107
|
const [value, setValue] = useState<string[]>(["auto"]);
|
|
88
108
|
return (
|
|
89
109
|
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
@@ -93,13 +113,13 @@ export const SolitaryFormControl: Story = {
|
|
|
93
113
|
},
|
|
94
114
|
};
|
|
95
115
|
|
|
96
|
-
export const
|
|
116
|
+
export const ReadOnly: Story = {
|
|
97
117
|
args: {
|
|
98
|
-
...
|
|
118
|
+
...StackedLayout.args,
|
|
99
119
|
readOnly: true,
|
|
100
|
-
readOnlyComponent: <span>2 Notifications Enabled</span>,
|
|
101
120
|
},
|
|
102
|
-
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
122
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
103
123
|
const [value, setValue] = useState<string[]>(["email", "sms"]);
|
|
104
124
|
return (
|
|
105
125
|
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
@@ -9,10 +9,8 @@ import {
|
|
|
9
9
|
filterStylingProps,
|
|
10
10
|
type RecursicaOverStyled,
|
|
11
11
|
} from "../../utils/filterStylingProps";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
type RecursicaFormControlWrapperProps,
|
|
15
|
-
} from "../FormControlWrapper/FormControlWrapper";
|
|
12
|
+
import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
|
|
13
|
+
import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
|
|
16
14
|
import styles from "./Switch.module.css";
|
|
17
15
|
|
|
18
16
|
export interface RecursicaSwitchGroupProps
|
|
@@ -26,8 +24,8 @@ export interface RecursicaSwitchGroupProps
|
|
|
26
24
|
export type SwitchGroupProps = RecursicaOverStyled<RecursicaSwitchGroupProps>;
|
|
27
25
|
|
|
28
26
|
export const SwitchGroup = forwardRef<HTMLDivElement, SwitchGroupProps>(
|
|
29
|
-
function SwitchGroup(
|
|
30
|
-
{
|
|
27
|
+
function SwitchGroup(props, ref) {
|
|
28
|
+
const {
|
|
31
29
|
overStyled = false,
|
|
32
30
|
formLayout = "stacked",
|
|
33
31
|
|
|
@@ -52,47 +50,19 @@ export const SwitchGroup = forwardRef<HTMLDivElement, SwitchGroupProps>(
|
|
|
52
50
|
children,
|
|
53
51
|
readOnly,
|
|
54
52
|
readOnlyComponent,
|
|
53
|
+
emptyValueComponent,
|
|
54
|
+
value,
|
|
55
|
+
defaultValue,
|
|
55
56
|
...rest
|
|
56
|
-
}
|
|
57
|
-
ref,
|
|
58
|
-
) {
|
|
57
|
+
} = props;
|
|
59
58
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
60
59
|
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
61
60
|
|
|
62
61
|
// Delete prohibited sizing hooks from bypassing the variables
|
|
63
62
|
delete restRecord["size"];
|
|
64
63
|
|
|
65
|
-
if (readOnly && readOnlyComponent) {
|
|
66
|
-
return (
|
|
67
|
-
<FormControlWrapper
|
|
68
|
-
className={className}
|
|
69
|
-
style={style as React.CSSProperties}
|
|
70
|
-
controlMaxWidth="var(--recursica_ui-kit_components_switch_properties_max-width)"
|
|
71
|
-
controlMinWidth={undefined}
|
|
72
|
-
overStyled={overStyled as true}
|
|
73
|
-
labelElement="div"
|
|
74
|
-
formLayout={formLayout}
|
|
75
|
-
labelSize={labelSize}
|
|
76
|
-
labelAlignment={labelAlignment}
|
|
77
|
-
labelOptionalText={labelOptionalText}
|
|
78
|
-
labelWithEditIcon={labelWithEditIcon}
|
|
79
|
-
onLabelEditClick={onLabelEditClick}
|
|
80
|
-
label={label}
|
|
81
|
-
description={description}
|
|
82
|
-
assistiveText={assistiveText}
|
|
83
|
-
assistiveWithIcon={assistiveWithIcon}
|
|
84
|
-
error={error}
|
|
85
|
-
required={required}
|
|
86
|
-
withAsterisk={withAsterisk}
|
|
87
|
-
id={id}
|
|
88
|
-
>
|
|
89
|
-
{readOnlyComponent}
|
|
90
|
-
</FormControlWrapper>
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
64
|
return (
|
|
95
|
-
<
|
|
65
|
+
<WithReadOnlyWrapper
|
|
96
66
|
className={className}
|
|
97
67
|
style={style as React.CSSProperties}
|
|
98
68
|
controlMaxWidth="var(--recursica_ui-kit_components_switch_properties_max-width)"
|
|
@@ -113,24 +83,34 @@ export const SwitchGroup = forwardRef<HTMLDivElement, SwitchGroupProps>(
|
|
|
113
83
|
required={required}
|
|
114
84
|
withAsterisk={withAsterisk}
|
|
115
85
|
id={id}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
86
|
+
readOnly={readOnly && !!readOnlyComponent}
|
|
87
|
+
readOnlyComponent={readOnlyComponent}
|
|
88
|
+
emptyValueComponent={emptyValueComponent}
|
|
89
|
+
readOnlyType="text"
|
|
90
|
+
readOnlyValue={value !== undefined ? value : defaultValue}
|
|
91
|
+
readOnlyNativeProps={props}
|
|
92
|
+
activeComponent={
|
|
93
|
+
<MantineSwitch.Group
|
|
94
|
+
ref={ref}
|
|
95
|
+
/* Natively bind local disabled lock dynamically */
|
|
96
|
+
{...(sanitizedProps as unknown as MantineSwitchGroupProps)}
|
|
97
|
+
disabled={readOnly || (restRecord as any).disabled}
|
|
98
|
+
value={value}
|
|
99
|
+
defaultValue={defaultValue}
|
|
100
|
+
>
|
|
101
|
+
<div className={styles.groupRoot}>
|
|
102
|
+
{React.Children.map(children, (child) => {
|
|
103
|
+
if (React.isValidElement(child)) {
|
|
104
|
+
return React.cloneElement(child as React.ReactElement<any>, {
|
|
105
|
+
disabled: readOnly || (child.props as any).disabled,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return child;
|
|
109
|
+
})}
|
|
110
|
+
</div>
|
|
111
|
+
</MantineSwitch.Group>
|
|
112
|
+
}
|
|
113
|
+
/>
|
|
134
114
|
);
|
|
135
115
|
},
|
|
136
116
|
);
|
|
@@ -40,8 +40,8 @@ export interface RecursicaTextAreaProps
|
|
|
40
40
|
export type TextAreaProps = RecursicaOverStyled<RecursicaTextAreaProps>;
|
|
41
41
|
|
|
42
42
|
export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
|
|
43
|
-
function TextArea(
|
|
44
|
-
{
|
|
43
|
+
function TextArea(props, ref) {
|
|
44
|
+
const {
|
|
45
45
|
overStyled = false,
|
|
46
46
|
formLayout = "stacked",
|
|
47
47
|
|
|
@@ -64,12 +64,11 @@ export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
|
|
|
64
64
|
disabled,
|
|
65
65
|
readOnly,
|
|
66
66
|
readOnlyComponent,
|
|
67
|
+
emptyValueComponent,
|
|
67
68
|
value,
|
|
68
69
|
defaultValue,
|
|
69
70
|
...rest
|
|
70
|
-
}
|
|
71
|
-
ref,
|
|
72
|
-
) {
|
|
71
|
+
} = props;
|
|
73
72
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
74
73
|
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
75
74
|
|
|
@@ -121,8 +120,10 @@ export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
|
|
|
121
120
|
id={id}
|
|
122
121
|
readOnly={readOnly}
|
|
123
122
|
readOnlyComponent={readOnlyComponent}
|
|
123
|
+
emptyValueComponent={emptyValueComponent}
|
|
124
124
|
readOnlyType="text"
|
|
125
125
|
readOnlyValue={value !== undefined ? value : defaultValue}
|
|
126
|
+
readOnlyNativeProps={props}
|
|
126
127
|
activeComponent={
|
|
127
128
|
/* Naked Input execution safely decoupled from Mantine's macro Input.Wrapper DOM hooks */
|
|
128
129
|
<MantineTextarea
|
|
@@ -28,8 +28,8 @@ export interface RecursicaTextFieldProps
|
|
|
28
28
|
export type TextFieldProps = RecursicaOverStyled<RecursicaTextFieldProps>;
|
|
29
29
|
|
|
30
30
|
export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
31
|
-
function TextField(
|
|
32
|
-
{
|
|
31
|
+
function TextField(props, ref) {
|
|
32
|
+
const {
|
|
33
33
|
overStyled = false,
|
|
34
34
|
formLayout = "stacked",
|
|
35
35
|
|
|
@@ -52,12 +52,11 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
52
52
|
disabled,
|
|
53
53
|
readOnly,
|
|
54
54
|
readOnlyComponent,
|
|
55
|
+
emptyValueComponent,
|
|
55
56
|
value,
|
|
56
57
|
defaultValue,
|
|
57
58
|
...rest
|
|
58
|
-
}
|
|
59
|
-
ref,
|
|
60
|
-
) {
|
|
59
|
+
} = props;
|
|
61
60
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
62
61
|
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
63
62
|
|
|
@@ -113,8 +112,10 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
113
112
|
id={id}
|
|
114
113
|
readOnly={readOnly}
|
|
115
114
|
readOnlyComponent={readOnlyComponent}
|
|
115
|
+
emptyValueComponent={emptyValueComponent}
|
|
116
116
|
readOnlyType="text"
|
|
117
117
|
readOnlyValue={value !== undefined ? value : defaultValue}
|
|
118
|
+
readOnlyNativeProps={props}
|
|
118
119
|
activeComponent={
|
|
119
120
|
/* Naked Input execution safely decoupled from Mantine's macro Input.Wrapper DOM hooks */
|
|
120
121
|
<Input
|
package/src/components/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ export * from "./Dropdown/Dropdown";
|
|
|
13
13
|
export * from "./FileInput/FileInput";
|
|
14
14
|
export * from "./FileUpload/FileUpload";
|
|
15
15
|
export * from "./Flex/Flex";
|
|
16
|
+
export * from "./FormControlLayout/FormControlLayout";
|
|
16
17
|
export * from "./Group/Group";
|
|
17
18
|
export * from "./HoverCard/HoverCard";
|
|
18
19
|
export * from "./Link/Link";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Enforces accessibility by strictly requiring at least one form of labeling:
|
|
5
|
+
* either a visual \`label\`, an \`aria-label\`, or an \`aria-labelledby\`.
|
|
6
|
+
*/
|
|
7
|
+
export type RequireAccessibleLabel<T> = T &
|
|
8
|
+
(
|
|
9
|
+
| { label: ReactNode; "aria-label"?: string; "aria-labelledby"?: string }
|
|
10
|
+
| { label?: ReactNode; "aria-label": string; "aria-labelledby"?: string }
|
|
11
|
+
| { label?: ReactNode; "aria-label"?: string; "aria-labelledby": string }
|
|
12
|
+
);
|