@recursica/mantine-adapter 0.42.0 → 0.43.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 +18 -0
- package/dist/index.d.ts +93 -15
- package/dist/mantine-adapter.cjs +2 -2
- package/dist/mantine-adapter.cjs.map +1 -1
- package/dist/mantine-adapter.css +1 -1
- package/dist/mantine-adapter.js +3546 -3250
- package/dist/mantine-adapter.js.map +1 -1
- package/package.json +1 -1
- package/src/GlobalExemptions.modules.css +0 -6
- package/src/components/Accordion/Accordion.module.css +0 -8
- package/src/components/Accordion/Accordion.tsx +32 -33
- package/src/components/AssistiveElement/AssistiveElement.tsx +1 -1
- package/src/components/AutoComplete/AutoComplete.module.css +0 -7
- package/src/components/AutoComplete/AutoComplete.tsx +26 -38
- package/src/components/Avatar/Avatar.module.css +0 -8
- package/src/components/Avatar/Avatar.tsx +22 -23
- package/src/components/Badge/Badge.tsx +12 -18
- package/src/components/Breadcrumb/Breadcrumb.tsx +10 -18
- package/src/components/Button/Button.tsx +31 -30
- package/src/components/Card/Card.tsx +48 -27
- package/src/components/Checkbox/Checkbox.tsx +29 -42
- package/src/components/Checkbox/CheckboxGroup.tsx +12 -5
- package/src/components/Chip/Chip.module.css +0 -16
- package/src/components/Chip/Chip.tsx +34 -27
- package/src/components/DatePicker/DATEPICKER_IMPLEMENTATION_NOTES.md +14 -1
- package/src/components/DatePicker/DatePicker.icons.tsx +27 -0
- package/src/components/DatePicker/DatePicker.module.css +256 -7
- package/src/components/DatePicker/DatePicker.stories.tsx +0 -7
- package/src/components/DatePicker/DatePicker.tsx +68 -33
- package/src/components/DatePicker/USAGE.md +6 -2
- package/src/components/Dropdown/BareDropdown.tsx +25 -13
- package/src/components/Dropdown/Dropdown.module.css +0 -7
- package/src/components/Dropdown/Dropdown.tsx +25 -38
- package/src/components/FileInput/FileInput.module.css +0 -21
- package/src/components/FileInput/FileInput.tsx +1 -1
- package/src/components/FileUpload/FileUpload.module.css +0 -11
- package/src/components/FileUpload/FileUpload.tsx +1 -1
- package/src/components/HoverCard/HoverCard.module.css +1 -7
- package/src/components/HoverCard/HoverCard.tsx +18 -34
- package/src/components/Label/Label.module.css +0 -6
- package/src/components/Label/Label.tsx +20 -21
- package/src/components/Link/Link.module.css +1 -6
- package/src/components/Link/Link.tsx +6 -14
- package/src/components/Loader/Loader.tsx +8 -16
- package/src/components/Menu/Menu.module.css +0 -6
- package/src/components/Menu/Menu.tsx +55 -48
- package/src/components/Modal/Modal.module.css +0 -11
- package/src/components/Modal/Modal.tsx +134 -96
- package/src/components/NumberInput/NumberInput.module.css +0 -7
- package/src/components/NumberInput/NumberInput.tsx +14 -7
- package/src/components/Pagination/Pagination.module.css +0 -81
- package/src/components/Pagination/Pagination.tsx +25 -34
- package/src/components/Panel/Panel.tsx +19 -26
- package/src/components/Popover/Popover.tsx +19 -31
- package/src/components/Radio/Radio.tsx +32 -43
- package/src/components/Radio/RadioGroup.tsx +11 -4
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +1 -1
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +1 -1
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +1 -1
- package/src/components/SegmentedControl/SegmentedControl.module.css +0 -1
- package/src/components/SegmentedControl/SegmentedControl.tsx +29 -33
- package/src/components/Slider/Slider.tsx +30 -43
- package/src/components/Stepper/Stepper.tsx +20 -13
- package/src/components/Switch/Switch.tsx +45 -45
- package/src/components/Switch/SwitchGroup.tsx +11 -4
- package/src/components/Table/Table.tsx +1 -1
- package/src/components/Tabs/Tabs.tsx +13 -6
- package/src/components/Text/Text.tsx +1 -1
- package/src/components/TextArea/TextArea.module.css +0 -7
- package/src/components/TextArea/TextArea.tsx +21 -25
- package/src/components/TextField/TextField.module.css +0 -7
- package/src/components/TextField/TextField.tsx +23 -30
- package/src/components/TimePicker/TimePicker.module.css +0 -16
- package/src/components/TimePicker/TimePicker.tsx +26 -12
- package/src/components/Timeline/Timeline.module.css +0 -6
- package/src/components/Timeline/Timeline.tsx +7 -21
- package/src/components/Timeline/TimelineItem.tsx +14 -26
- package/src/components/Title/Title.tsx +12 -2
- package/src/components/Toast/Toast.module.css +0 -7
- package/src/components/Toast/Toast.tsx +32 -31
- package/src/components/Tooltip/Tooltip.module.css +0 -9
- package/src/components/Tooltip/Tooltip.tsx +18 -34
- package/src/components/TransferList/TransferList.module.css +0 -8
- package/src/components/TransferList/TransferList.tsx +1 -1
- package/src/components/Tree/Tree.tsx +8 -8
- package/src/utils/filterStylingProps.ts +4 -0
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
} from "@mantine/core";
|
|
6
6
|
import {
|
|
7
7
|
filterStylingProps,
|
|
8
|
+
omitUnsupportedProps,
|
|
9
|
+
mergeClassNames,
|
|
8
10
|
type RecursicaOverStyled,
|
|
9
11
|
} from "../../utils/filterStylingProps";
|
|
10
12
|
import styles from "./SegmentedControl.module.css";
|
|
@@ -31,31 +33,15 @@ function useSegmentedControlClassNames(restRecord: Record<string, unknown>): {
|
|
|
31
33
|
className: string;
|
|
32
34
|
classNames: Partial<Record<string, string>>;
|
|
33
35
|
} {
|
|
34
|
-
const mergedClassNames
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
classNamesProp &&
|
|
44
|
-
typeof classNamesProp === "object" &&
|
|
45
|
-
!Array.isArray(classNamesProp)
|
|
46
|
-
) {
|
|
47
|
-
const o = classNamesProp as Partial<Record<string, string>>;
|
|
48
|
-
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
49
|
-
mergedClassNames.control = o.control
|
|
50
|
-
? `${styles.control} ${o.control}`
|
|
51
|
-
: styles.control;
|
|
52
|
-
mergedClassNames.label = o.label
|
|
53
|
-
? `${styles.label} ${o.label}`
|
|
54
|
-
: styles.label;
|
|
55
|
-
mergedClassNames.indicator = o.indicator
|
|
56
|
-
? `${styles.indicator} ${o.indicator}`
|
|
57
|
-
: styles.indicator;
|
|
58
|
-
}
|
|
36
|
+
const mergedClassNames = mergeClassNames(
|
|
37
|
+
{
|
|
38
|
+
root: styles.root,
|
|
39
|
+
control: styles.control,
|
|
40
|
+
label: styles.label,
|
|
41
|
+
indicator: styles.indicator,
|
|
42
|
+
},
|
|
43
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
44
|
+
);
|
|
59
45
|
|
|
60
46
|
const classNameProp = restRecord.className as string | undefined;
|
|
61
47
|
const finalClass = classNameProp
|
|
@@ -70,26 +56,36 @@ const _SegmentedControl = forwardRef<HTMLDivElement, SegmentedControlProps>(
|
|
|
70
56
|
{ overStyled = false, orientation = "horizontal", fullWidth, ...rest },
|
|
71
57
|
ref,
|
|
72
58
|
) {
|
|
73
|
-
|
|
74
|
-
|
|
59
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
60
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
61
|
+
const UNSUPPORTED_PROPS = [
|
|
62
|
+
// SegmentedControl only supports per-item disabling via the `data` array (each item may set
|
|
63
|
+
// its own `disabled`); a top-level `disabled` is intentionally unsupported (typed as `never`
|
|
64
|
+
// in RecursicaSegmentedControlProps) because Mantine's top-level `disabled` would disable
|
|
65
|
+
// the whole control uniformly instead of per-item.
|
|
66
|
+
"disabled",
|
|
67
|
+
] as const satisfies readonly (keyof MantineSegmentedControlProps)[];
|
|
75
68
|
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
70
|
+
filterStylingProps(rest, overStyled) as Record<string, unknown>,
|
|
71
|
+
UNSUPPORTED_PROPS,
|
|
72
|
+
) as Partial<typeof rest>;
|
|
73
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
78
74
|
|
|
79
75
|
const stylingParams = useSegmentedControlClassNames(restRecord);
|
|
80
76
|
|
|
81
77
|
return (
|
|
82
78
|
<MantineSegmentedControl
|
|
83
79
|
ref={ref}
|
|
80
|
+
{...(sanitizedProps as Omit<
|
|
81
|
+
MantineSegmentedControlProps,
|
|
82
|
+
"variant" | "size"
|
|
83
|
+
>)}
|
|
84
84
|
className={stylingParams.className}
|
|
85
85
|
classNames={stylingParams.classNames}
|
|
86
86
|
orientation={orientation}
|
|
87
87
|
fullWidth={fullWidth}
|
|
88
88
|
data-orientation={orientation}
|
|
89
|
-
{...(sanitizedProps as Omit<
|
|
90
|
-
MantineSegmentedControlProps,
|
|
91
|
-
"variant" | "size"
|
|
92
|
-
>)}
|
|
93
89
|
/>
|
|
94
90
|
);
|
|
95
91
|
},
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
8
8
|
import {
|
|
9
9
|
filterStylingProps,
|
|
10
|
+
omitUnsupportedProps,
|
|
11
|
+
mergeClassNames,
|
|
10
12
|
type RecursicaOverStyled,
|
|
11
13
|
} from "../../utils/filterStylingProps";
|
|
12
14
|
import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
|
|
@@ -133,51 +135,36 @@ export const Slider = forwardRef<HTMLDivElement, SliderProps>(
|
|
|
133
135
|
setInputValue(resolvedValue.toString());
|
|
134
136
|
};
|
|
135
137
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
139
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
140
|
+
const UNSUPPORTED_PROPS = [
|
|
141
|
+
"size", // Recursica controls sizing via Slider.module.css variables, not Mantine's native size scale.
|
|
142
|
+
"variant", // Slider has a single Recursica-defined visual treatment; Mantine's variant isn't exposed.
|
|
143
|
+
"radius", // Corner radius is fixed by Recursica tokens in Slider.module.css, not caller-configurable.
|
|
144
|
+
// Not currently a real key of Mantine's SliderProps (that's an Input.Wrapper-only prop) — kept
|
|
145
|
+
// as a defensive no-op delete since it predates this consolidation and the public prop type
|
|
146
|
+
// already `Omit`s it; Recursica's own FormControlLayout/WithReadOnlyWrapper own wrapper markup.
|
|
147
|
+
"wrapperProps",
|
|
148
|
+
] as const satisfies readonly (keyof MantineSliderProps | "wrapperProps")[];
|
|
138
149
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
150
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
151
|
+
filterStylingProps(rest, overStyled) as Record<string, unknown>,
|
|
152
|
+
UNSUPPORTED_PROPS,
|
|
153
|
+
) as Partial<typeof rest>;
|
|
154
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
144
155
|
|
|
145
156
|
// Securely map core native blocks down ensuring nested CSS modules map precisely
|
|
146
|
-
const mergedClassNames
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
classNamesProp &&
|
|
158
|
-
typeof classNamesProp === "object" &&
|
|
159
|
-
!Array.isArray(classNamesProp)
|
|
160
|
-
) {
|
|
161
|
-
const o = classNamesProp as Partial<Record<string, string>>;
|
|
162
|
-
mergedClassNames.root = o.root
|
|
163
|
-
? `${styles.sliderRoot} ${o.root}`
|
|
164
|
-
: styles.sliderRoot;
|
|
165
|
-
mergedClassNames.track = o.track
|
|
166
|
-
? `${styles.sliderTrack} ${o.track}`
|
|
167
|
-
: styles.sliderTrack;
|
|
168
|
-
mergedClassNames.bar = o.bar
|
|
169
|
-
? `${styles.sliderBar} ${o.bar}`
|
|
170
|
-
: styles.sliderBar;
|
|
171
|
-
mergedClassNames.thumb = o.thumb
|
|
172
|
-
? `${styles.sliderThumb} ${o.thumb}`
|
|
173
|
-
: styles.sliderThumb;
|
|
174
|
-
mergedClassNames.mark = o.mark
|
|
175
|
-
? `${styles.sliderMark} ${o.mark}`
|
|
176
|
-
: styles.sliderMark;
|
|
177
|
-
mergedClassNames.markLabel = o.markLabel
|
|
178
|
-
? `${styles.sliderMarkLabel} ${o.markLabel}`
|
|
179
|
-
: styles.sliderMarkLabel;
|
|
180
|
-
}
|
|
157
|
+
const mergedClassNames = mergeClassNames(
|
|
158
|
+
{
|
|
159
|
+
root: styles.sliderRoot,
|
|
160
|
+
track: styles.sliderTrack,
|
|
161
|
+
bar: styles.sliderBar,
|
|
162
|
+
thumb: styles.sliderThumb,
|
|
163
|
+
mark: styles.sliderMark,
|
|
164
|
+
markLabel: styles.sliderMarkLabel,
|
|
165
|
+
},
|
|
166
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
167
|
+
);
|
|
181
168
|
|
|
182
169
|
const wrapperClass = className
|
|
183
170
|
? `${styles.layoutOverride} ${className}`
|
|
@@ -232,6 +219,7 @@ export const Slider = forwardRef<HTMLDivElement, SliderProps>(
|
|
|
232
219
|
|
|
233
220
|
<div className={styles.sliderTrackWrapper}>
|
|
234
221
|
<MantineSlider
|
|
222
|
+
{...(sanitizedProps as unknown as MantineSliderProps)}
|
|
235
223
|
classNames={mergedClassNames}
|
|
236
224
|
disabled={disabled}
|
|
237
225
|
value={resolvedValue}
|
|
@@ -241,7 +229,6 @@ export const Slider = forwardRef<HTMLDivElement, SliderProps>(
|
|
|
241
229
|
max={max}
|
|
242
230
|
step={step}
|
|
243
231
|
label={tooltipLabel}
|
|
244
|
-
{...(sanitizedProps as unknown as MantineSliderProps)}
|
|
245
232
|
/>
|
|
246
233
|
</div>
|
|
247
234
|
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "@mantine/core";
|
|
7
7
|
import {
|
|
8
8
|
filterStylingProps,
|
|
9
|
+
mergeClassNames,
|
|
9
10
|
type RecursicaOverStyled,
|
|
10
11
|
} from "../../utils/filterStylingProps";
|
|
11
12
|
import styles from "./Stepper.module.css";
|
|
@@ -30,28 +31,34 @@ const _Stepper = forwardRef<HTMLDivElement, StepperProps>(
|
|
|
30
31
|
} = props;
|
|
31
32
|
|
|
32
33
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
34
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
35
|
+
|
|
36
|
+
const mergedClassNames = mergeClassNames(
|
|
37
|
+
{
|
|
38
|
+
steps: styles.steps,
|
|
39
|
+
step: styles.step,
|
|
40
|
+
stepIcon: styles.stepIcon,
|
|
41
|
+
stepCompletedIcon: styles.stepCompletedIcon,
|
|
42
|
+
stepBody: styles.stepBody,
|
|
43
|
+
stepLabel: styles.stepLabel,
|
|
44
|
+
stepDescription: styles.stepDescription,
|
|
45
|
+
separator: styles.separator,
|
|
46
|
+
verticalSeparator: styles.verticalSeparator,
|
|
47
|
+
content: styles.content,
|
|
48
|
+
},
|
|
49
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
50
|
+
);
|
|
33
51
|
|
|
34
52
|
return (
|
|
35
53
|
<MantineStepper
|
|
36
54
|
ref={ref}
|
|
55
|
+
{...(sanitizedProps as MantineStepperProps)}
|
|
37
56
|
orientation={orientation}
|
|
38
57
|
className={`${styles.root} ${orientation === "horizontal" ? styles.horizontal : styles.vertical} ${size === "large" ? styles.large : styles.small} ${className || ""}`}
|
|
39
58
|
style={style as React.CSSProperties}
|
|
40
59
|
data-size={size}
|
|
41
60
|
data-orientation={orientation}
|
|
42
|
-
classNames={
|
|
43
|
-
steps: styles.steps,
|
|
44
|
-
step: styles.step,
|
|
45
|
-
stepIcon: styles.stepIcon,
|
|
46
|
-
stepCompletedIcon: styles.stepCompletedIcon,
|
|
47
|
-
stepBody: styles.stepBody,
|
|
48
|
-
stepLabel: styles.stepLabel,
|
|
49
|
-
stepDescription: styles.stepDescription,
|
|
50
|
-
separator: styles.separator,
|
|
51
|
-
verticalSeparator: styles.verticalSeparator,
|
|
52
|
-
content: styles.content,
|
|
53
|
-
}}
|
|
54
|
-
{...(sanitizedProps as MantineStepperProps)}
|
|
61
|
+
classNames={mergedClassNames}
|
|
55
62
|
/>
|
|
56
63
|
);
|
|
57
64
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef } from "react";
|
|
1
|
+
import { forwardRef, type CSSProperties } from "react";
|
|
2
2
|
import {
|
|
3
3
|
Switch as MantineSwitch,
|
|
4
4
|
type SwitchProps as MantineSwitchProps,
|
|
@@ -9,6 +9,10 @@ import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
filterStylingProps,
|
|
12
|
+
omitUnsupportedProps,
|
|
13
|
+
withCallerOverride,
|
|
14
|
+
mergeClassNames,
|
|
15
|
+
mergeStyles,
|
|
12
16
|
type RecursicaOverStyled,
|
|
13
17
|
} from "../../utils/filterStylingProps";
|
|
14
18
|
import {
|
|
@@ -59,50 +63,42 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
|
|
59
63
|
controlMinWidth,
|
|
60
64
|
...rest
|
|
61
65
|
} = props;
|
|
62
|
-
|
|
66
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
67
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
68
|
+
const UNSUPPORTED_PROPS = [
|
|
69
|
+
"size", // Recursica controls sizing via Switch.module.css variables, not Mantine's native size scale.
|
|
70
|
+
"color", // Colors are token-driven via Switch.module.css; Mantine's native palette isn't exposed.
|
|
71
|
+
"radius", // Corner radius is fixed by Recursica tokens in Switch.module.css, not caller-configurable.
|
|
72
|
+
"variant", // Switch has a single Recursica-defined visual treatment; Mantine's variant isn't exposed.
|
|
73
|
+
] as const satisfies readonly (keyof MantineSwitchProps)[];
|
|
74
|
+
|
|
75
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
76
|
+
filterStylingProps(rest, overStyled) as Record<string, unknown>,
|
|
77
|
+
UNSUPPORTED_PROPS,
|
|
78
|
+
) as Partial<typeof rest>;
|
|
63
79
|
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
64
80
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
) {
|
|
87
|
-
const o = classNamesProp as Partial<Record<string, string>>;
|
|
88
|
-
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
89
|
-
mergedClassNames.body = o.body ? `${styles.body} ${o.body}` : styles.body;
|
|
90
|
-
mergedClassNames.track = o.track
|
|
91
|
-
? `${styles.track} ${o.track}`
|
|
92
|
-
: styles.track;
|
|
93
|
-
mergedClassNames.thumb = o.thumb
|
|
94
|
-
? `${styles.thumb} ${o.thumb}`
|
|
95
|
-
: styles.thumb;
|
|
96
|
-
mergedClassNames.trackLabel = o.trackLabel
|
|
97
|
-
? `${styles.trackLabel} ${o.trackLabel}`
|
|
98
|
-
: styles.trackLabel;
|
|
99
|
-
mergedClassNames.labelWrapper = o.labelWrapper
|
|
100
|
-
? `${styles.labelWrapper} ${o.labelWrapper}`
|
|
101
|
-
: styles.labelWrapper;
|
|
102
|
-
mergedClassNames.label = o.label
|
|
103
|
-
? `${styles.label} ${o.label}`
|
|
104
|
-
: styles.label;
|
|
105
|
-
}
|
|
81
|
+
const mergedClassNames = mergeClassNames(
|
|
82
|
+
{
|
|
83
|
+
root: styles.root,
|
|
84
|
+
body: styles.body,
|
|
85
|
+
track: styles.track,
|
|
86
|
+
thumb: styles.thumb,
|
|
87
|
+
trackLabel: styles.trackLabel,
|
|
88
|
+
labelWrapper: styles.labelWrapper,
|
|
89
|
+
label: styles.label,
|
|
90
|
+
},
|
|
91
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// Recursica has no default per-slot inline styles here (all default styling comes from
|
|
95
|
+
// Switch.module.css above) — this only exists so a caller-supplied `styles` prop (permitted
|
|
96
|
+
// once overStyled=true clears filterStylingProps) merges in per-slot instead of needing its
|
|
97
|
+
// own passthrough path.
|
|
98
|
+
const mergedStyles = mergeStyles(
|
|
99
|
+
{} as Record<string, CSSProperties | undefined>,
|
|
100
|
+
restRecord.styles as Partial<Record<string, CSSProperties>> | undefined,
|
|
101
|
+
);
|
|
106
102
|
|
|
107
103
|
const classNameProp = restRecord.className as string | undefined;
|
|
108
104
|
const finalClass = classNameProp
|
|
@@ -147,12 +143,16 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
|
|
147
143
|
const switchNode = (
|
|
148
144
|
<MantineSwitch
|
|
149
145
|
ref={ref}
|
|
146
|
+
{...(sanitizedProps as unknown as MantineSwitchProps)}
|
|
150
147
|
className={finalClass}
|
|
151
148
|
classNames={mergedClassNames}
|
|
149
|
+
styles={mergedStyles}
|
|
152
150
|
disabled={readOnly || disabled}
|
|
153
151
|
data-disabled={readOnly || disabled || undefined}
|
|
154
|
-
thumbIcon={
|
|
155
|
-
|
|
152
|
+
thumbIcon={withCallerOverride<React.ReactNode>(
|
|
153
|
+
FinalThumbIcon,
|
|
154
|
+
thumbIcon,
|
|
155
|
+
)}
|
|
156
156
|
/>
|
|
157
157
|
);
|
|
158
158
|
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
8
8
|
import {
|
|
9
9
|
filterStylingProps,
|
|
10
|
+
omitUnsupportedProps,
|
|
10
11
|
type RecursicaOverStyled,
|
|
11
12
|
} from "../../utils/filterStylingProps";
|
|
12
13
|
import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
|
|
@@ -61,11 +62,17 @@ export const SwitchGroup = forwardRef<HTMLDivElement, SwitchGroupProps>(
|
|
|
61
62
|
defaultValue,
|
|
62
63
|
...rest
|
|
63
64
|
} = props;
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
66
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
67
|
+
const UNSUPPORTED_PROPS = [
|
|
68
|
+
"size", // Recursica controls sizing via Switch.module.css variables, not Mantine's native size scale.
|
|
69
|
+
] as const satisfies readonly (keyof MantineSwitchGroupProps)[];
|
|
66
70
|
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
72
|
+
filterStylingProps(rest, overStyled) as Record<string, unknown>,
|
|
73
|
+
UNSUPPORTED_PROPS,
|
|
74
|
+
) as Partial<typeof rest>;
|
|
75
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
69
76
|
|
|
70
77
|
return (
|
|
71
78
|
<WithReadOnlyWrapper
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from "@mantine/core";
|
|
9
9
|
import {
|
|
10
10
|
filterStylingProps,
|
|
11
|
+
mergeClassNames,
|
|
11
12
|
type RecursicaOverStyled,
|
|
12
13
|
} from "../../utils/filterStylingProps";
|
|
13
14
|
import styles from "./Tabs.module.css";
|
|
@@ -30,21 +31,27 @@ const _Tabs = forwardRef<HTMLDivElement, TabsProps>(function Tabs(props, ref) {
|
|
|
30
31
|
} = props;
|
|
31
32
|
|
|
32
33
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
34
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
35
|
+
|
|
36
|
+
const mergedClassNames = mergeClassNames(
|
|
37
|
+
{
|
|
38
|
+
list: styles.list,
|
|
39
|
+
tab: styles.tab,
|
|
40
|
+
panel: styles.panel,
|
|
41
|
+
},
|
|
42
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
43
|
+
);
|
|
33
44
|
|
|
34
45
|
return (
|
|
35
46
|
<MantineTabs
|
|
36
47
|
ref={ref}
|
|
48
|
+
{...(sanitizedProps as MantineTabsProps)}
|
|
37
49
|
variant={variant}
|
|
38
50
|
orientation={orientation}
|
|
39
51
|
className={`${styles.root} ${className || ""}`}
|
|
40
52
|
data-variant={variant}
|
|
41
53
|
data-orientation={orientation}
|
|
42
|
-
classNames={
|
|
43
|
-
list: styles.list,
|
|
44
|
-
tab: styles.tab,
|
|
45
|
-
panel: styles.panel,
|
|
46
|
-
}}
|
|
47
|
-
{...(sanitizedProps as MantineTabsProps)}
|
|
54
|
+
classNames={mergedClassNames}
|
|
48
55
|
/>
|
|
49
56
|
);
|
|
50
57
|
});
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/* EXEMPTIONS:
|
|
2
|
-
- border-size variables are ignored because a uniform 1px border is applied globally to prevent
|
|
3
|
-
unexpected layout shift or flickering during focused, disabled, or error state transitions. */
|
|
4
|
-
/* recursica-ignore: --recursica_ui-kit_components_textarea_properties_border-size */
|
|
5
|
-
/* recursica-ignore: --recursica_ui-kit_components_textarea_variants_states_disabled_properties_border-size */
|
|
6
|
-
/* recursica-ignore: --recursica_ui-kit_components_textarea_variants_states_error_properties_border-size */
|
|
7
|
-
|
|
8
1
|
/* LAYOUT SPACING OVERRIDES:
|
|
9
2
|
- Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens.
|
|
10
3
|
- Also sets the --textarea-control-{max,min}-width hooks consumed inline in TextArea.tsx, since
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
7
7
|
import {
|
|
8
8
|
filterStylingProps,
|
|
9
|
+
omitUnsupportedProps,
|
|
10
|
+
mergeClassNames,
|
|
9
11
|
type RecursicaOverStyled,
|
|
10
12
|
} from "../../utils/filterStylingProps";
|
|
11
13
|
import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
|
|
@@ -28,6 +30,14 @@ export interface RecursicaTextAreaProps
|
|
|
28
30
|
|
|
29
31
|
export type TextAreaProps = RecursicaOverStyled<RecursicaTextAreaProps>;
|
|
30
32
|
|
|
33
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
34
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
35
|
+
const UNSUPPORTED_PROPS = [
|
|
36
|
+
"size", // Recursica controls sizing via the `size` variant + design tokens, not raw dimensions.
|
|
37
|
+
"variant", // Colors/variants are token-driven; the library's native palette isn't exposed.
|
|
38
|
+
"radius", // Recursica does not expose the library's native corner-radius system.
|
|
39
|
+
] as const satisfies readonly (keyof MantineTextareaProps)[];
|
|
40
|
+
|
|
31
41
|
export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
|
|
32
42
|
function TextArea(props, ref) {
|
|
33
43
|
const {
|
|
@@ -58,34 +68,20 @@ export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
|
|
|
58
68
|
defaultValue,
|
|
59
69
|
...rest
|
|
60
70
|
} = props;
|
|
61
|
-
const sanitizedProps =
|
|
71
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
72
|
+
filterStylingProps(rest, overStyled) as Record<string, unknown>,
|
|
73
|
+
UNSUPPORTED_PROPS,
|
|
74
|
+
);
|
|
62
75
|
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
63
76
|
|
|
64
|
-
// Delete prohibited sizing hooks from bypassing variables natively
|
|
65
|
-
delete restRecord["size"];
|
|
66
|
-
delete restRecord["variant"];
|
|
67
|
-
delete restRecord["radius"];
|
|
68
|
-
|
|
69
77
|
// Securely map core native blocks down ensuring nested CSS modules map precisely
|
|
70
|
-
const mergedClassNames
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
classNamesProp &&
|
|
78
|
-
typeof classNamesProp === "object" &&
|
|
79
|
-
!Array.isArray(classNamesProp)
|
|
80
|
-
) {
|
|
81
|
-
const o = classNamesProp as Partial<Record<string, string>>;
|
|
82
|
-
mergedClassNames.wrapper = o.wrapper
|
|
83
|
-
? `${styles.root} ${o.wrapper}`
|
|
84
|
-
: styles.root;
|
|
85
|
-
mergedClassNames.input = o.input
|
|
86
|
-
? `${styles.input} ${o.input}`
|
|
87
|
-
: styles.input;
|
|
88
|
-
}
|
|
78
|
+
const mergedClassNames = mergeClassNames(
|
|
79
|
+
{
|
|
80
|
+
wrapper: styles.root, // The nested Input internal relative wrapper bounding box
|
|
81
|
+
input: styles.input,
|
|
82
|
+
},
|
|
83
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
84
|
+
);
|
|
89
85
|
|
|
90
86
|
const wrapperClass = className
|
|
91
87
|
? `${styles.layoutOverride} ${className}`
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/* EXEMPTIONS:
|
|
2
|
-
- border-size variables are ignored because a uniform 1px border is applied globally to prevent
|
|
3
|
-
unexpected layout shift or flickering during focused, disabled, or error state transitions. */
|
|
4
|
-
/* recursica-ignore: --recursica_ui-kit_components_text-field_properties_border-size */
|
|
5
|
-
/* recursica-ignore: --recursica_ui-kit_components_text-field_variants_states_disabled_properties_border-size */
|
|
6
|
-
/* recursica-ignore: --recursica_ui-kit_components_text-field_variants_states_error_properties_border-size */
|
|
7
|
-
|
|
8
1
|
/* LAYOUT SPACING OVERRIDES:
|
|
9
2
|
- Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens.
|
|
10
3
|
- Also sets the --text-field-control-{max,min}-width hooks consumed inline in TextField.tsx,
|
|
@@ -3,6 +3,8 @@ import { Input, type InputProps, type InputWrapperProps } from "@mantine/core";
|
|
|
3
3
|
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
4
4
|
import {
|
|
5
5
|
filterStylingProps,
|
|
6
|
+
omitUnsupportedProps,
|
|
7
|
+
mergeClassNames,
|
|
6
8
|
type RecursicaOverStyled,
|
|
7
9
|
} from "../../utils/filterStylingProps";
|
|
8
10
|
import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
|
|
@@ -30,6 +32,14 @@ export interface RecursicaTextFieldProps
|
|
|
30
32
|
|
|
31
33
|
export type TextFieldProps = RecursicaOverStyled<RecursicaTextFieldProps>;
|
|
32
34
|
|
|
35
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
36
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
37
|
+
const UNSUPPORTED_PROPS = [
|
|
38
|
+
"size", // Recursica controls sizing via the `size` variant + design tokens, not raw dimensions.
|
|
39
|
+
"variant", // Colors/variants are token-driven; the library's native palette isn't exposed.
|
|
40
|
+
"radius", // Recursica does not expose the library's native corner-radius system.
|
|
41
|
+
] as const satisfies readonly (keyof InputProps)[];
|
|
42
|
+
|
|
33
43
|
export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
34
44
|
function TextField(props, ref) {
|
|
35
45
|
const {
|
|
@@ -60,38 +70,21 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
60
70
|
defaultValue,
|
|
61
71
|
...rest
|
|
62
72
|
} = props;
|
|
63
|
-
const sanitizedProps =
|
|
73
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
74
|
+
filterStylingProps(rest, overStyled) as Record<string, unknown>,
|
|
75
|
+
UNSUPPORTED_PROPS,
|
|
76
|
+
);
|
|
64
77
|
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
65
78
|
|
|
66
|
-
// Delete prohibited sizing hooks from bypassing variables natively
|
|
67
|
-
delete restRecord["size"];
|
|
68
|
-
delete restRecord["variant"];
|
|
69
|
-
delete restRecord["radius"];
|
|
70
|
-
|
|
71
79
|
// Securely map core native blocks down ensuring nested CSS modules map precisely
|
|
72
|
-
const mergedClassNames
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
classNamesProp &&
|
|
81
|
-
typeof classNamesProp === "object" &&
|
|
82
|
-
!Array.isArray(classNamesProp)
|
|
83
|
-
) {
|
|
84
|
-
const o = classNamesProp as Partial<Record<string, string>>;
|
|
85
|
-
mergedClassNames.wrapper = o.wrapper
|
|
86
|
-
? `${styles.root} ${o.wrapper}`
|
|
87
|
-
: styles.root;
|
|
88
|
-
mergedClassNames.input = o.input
|
|
89
|
-
? `${styles.input} ${o.input}`
|
|
90
|
-
: styles.input;
|
|
91
|
-
mergedClassNames.section = o.section
|
|
92
|
-
? `${styles.section} ${o.section}`
|
|
93
|
-
: styles.section;
|
|
94
|
-
}
|
|
80
|
+
const mergedClassNames = mergeClassNames(
|
|
81
|
+
{
|
|
82
|
+
wrapper: styles.root, // The nested Input internal relative wrapper bounding box
|
|
83
|
+
input: styles.input,
|
|
84
|
+
section: styles.section,
|
|
85
|
+
},
|
|
86
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
87
|
+
);
|
|
95
88
|
|
|
96
89
|
const wrapperClass = className
|
|
97
90
|
? `${styles.layoutOverride} ${className}`
|
|
@@ -127,6 +120,7 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
127
120
|
/* Naked Input execution safely decoupled from Mantine's macro Input.Wrapper DOM hooks */
|
|
128
121
|
<Input
|
|
129
122
|
ref={ref}
|
|
123
|
+
{...(sanitizedProps as unknown as InputProps)}
|
|
130
124
|
classNames={mergedClassNames}
|
|
131
125
|
disabled={disabled}
|
|
132
126
|
value={value}
|
|
@@ -135,7 +129,6 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
135
129
|
"data-disabled": disabled ? "true" : undefined,
|
|
136
130
|
"data-error": error ? "true" : undefined,
|
|
137
131
|
}}
|
|
138
|
-
{...(sanitizedProps as unknown as InputProps)}
|
|
139
132
|
/>
|
|
140
133
|
}
|
|
141
134
|
/>
|