@recursica/mantine-adapter 0.42.1 → 0.44.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 +17 -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 +3534 -3266
- package/dist/mantine-adapter.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Accordion/Accordion.tsx +32 -33
- package/src/components/AssistiveElement/AssistiveElement.tsx +1 -1
- package/src/components/AutoComplete/AutoComplete.tsx +26 -38
- package/src/components/Avatar/Avatar.tsx +22 -23
- package/src/components/Badge/Badge.tsx +12 -18
- package/src/components/Breadcrumb/Breadcrumb.module.css +2 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +0 -6
- package/src/components/Breadcrumb/Breadcrumb.tsx +25 -17
- 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.tsx +34 -27
- package/src/components/DatePicker/DatePicker.tsx +46 -47
- package/src/components/Dropdown/BareDropdown.tsx +25 -13
- package/src/components/Dropdown/DROPDOWN_IMPLEMENTATION_NOTES.md +2 -0
- package/src/components/Dropdown/Dropdown.module.css +61 -4
- package/src/components/Dropdown/Dropdown.stories.tsx +21 -0
- package/src/components/Dropdown/Dropdown.tsx +41 -37
- package/src/components/Dropdown/USAGE.md +1 -0
- package/src/components/FileInput/FileInput.tsx +1 -1
- package/src/components/FileUpload/FileUpload.tsx +1 -1
- package/src/components/HoverCard/HoverCard.tsx +18 -34
- package/src/components/Label/Label.tsx +20 -21
- package/src/components/Link/Link.tsx +6 -14
- package/src/components/Loader/Loader.tsx +8 -16
- package/src/components/Menu/Menu.stories.tsx +9 -1
- package/src/components/Menu/Menu.tsx +55 -48
- package/src/components/Modal/Modal.tsx +134 -96
- package/src/components/NumberInput/NumberInput.tsx +14 -7
- 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.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.tsx +21 -25
- package/src/components/TextField/TextField.tsx +23 -30
- package/src/components/TimePicker/TimePicker.tsx +26 -12
- 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.tsx +32 -31
- package/src/components/Tooltip/Tooltip.tsx +18 -34
- package/src/components/TransferList/TransferList.tsx +1 -1
- package/src/components/Tree/Tree.tsx +8 -8
- package/src/utils/filterStylingProps.ts +4 -0
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
} from "@mantine/core";
|
|
10
10
|
import {
|
|
11
11
|
filterStylingProps,
|
|
12
|
+
withCallerOverride,
|
|
13
|
+
mergeClassNames,
|
|
12
14
|
type RecursicaOverStyled,
|
|
13
15
|
} from "../../utils/filterStylingProps";
|
|
14
16
|
import styles from "./Pagination.module.css";
|
|
@@ -42,25 +44,14 @@ function usePaginationClassNames(restRecord: Record<string, unknown>): {
|
|
|
42
44
|
className: string;
|
|
43
45
|
classNames: Partial<Record<string, string>>;
|
|
44
46
|
} {
|
|
45
|
-
const mergedClassNames
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
classNamesProp &&
|
|
54
|
-
typeof classNamesProp === "object" &&
|
|
55
|
-
!Array.isArray(classNamesProp)
|
|
56
|
-
) {
|
|
57
|
-
const o = classNamesProp as Partial<Record<string, string>>;
|
|
58
|
-
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
59
|
-
mergedClassNames.control = o.control
|
|
60
|
-
? `${styles.control} ${o.control}`
|
|
61
|
-
: styles.control;
|
|
62
|
-
mergedClassNames.dots = o.dots ? `${styles.dots} ${o.dots}` : styles.dots;
|
|
63
|
-
}
|
|
47
|
+
const mergedClassNames = mergeClassNames(
|
|
48
|
+
{
|
|
49
|
+
root: styles.root,
|
|
50
|
+
control: styles.control,
|
|
51
|
+
dots: styles.dots,
|
|
52
|
+
},
|
|
53
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
54
|
+
);
|
|
64
55
|
|
|
65
56
|
const classNameProp = restRecord.className as string | undefined;
|
|
66
57
|
const finalClass = classNameProp
|
|
@@ -80,9 +71,9 @@ const _PaginationRoot = forwardRef<HTMLDivElement, PaginationRootProps>(
|
|
|
80
71
|
return (
|
|
81
72
|
<MantinePagination.Root
|
|
82
73
|
ref={ref}
|
|
74
|
+
{...(sanitizedProps as MantinePaginationRootProps)}
|
|
83
75
|
className={stylingParams.className}
|
|
84
76
|
classNames={stylingParams.classNames}
|
|
85
|
-
{...(sanitizedProps as MantinePaginationRootProps)}
|
|
86
77
|
/>
|
|
87
78
|
);
|
|
88
79
|
},
|
|
@@ -97,13 +88,13 @@ const _PaginationNext = forwardRef<
|
|
|
97
88
|
ref,
|
|
98
89
|
) {
|
|
99
90
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
100
|
-
const
|
|
91
|
+
const computedIcon = withLabel ? NextWithLabel : undefined;
|
|
101
92
|
return (
|
|
102
93
|
<MantinePagination.Next
|
|
103
94
|
ref={ref}
|
|
104
|
-
data-variant="text"
|
|
105
|
-
icon={renderIcon as any}
|
|
106
95
|
{...sanitizedProps}
|
|
96
|
+
data-variant="text"
|
|
97
|
+
icon={withCallerOverride(computedIcon, icon) as any}
|
|
107
98
|
/>
|
|
108
99
|
);
|
|
109
100
|
});
|
|
@@ -117,13 +108,13 @@ const _PaginationPrevious = forwardRef<
|
|
|
117
108
|
ref,
|
|
118
109
|
) {
|
|
119
110
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
120
|
-
const
|
|
111
|
+
const computedIcon = withLabel ? PrevWithLabel : undefined;
|
|
121
112
|
return (
|
|
122
113
|
<MantinePagination.Previous
|
|
123
114
|
ref={ref}
|
|
124
|
-
data-variant="text"
|
|
125
|
-
icon={renderIcon as any}
|
|
126
115
|
{...sanitizedProps}
|
|
116
|
+
data-variant="text"
|
|
117
|
+
icon={withCallerOverride(computedIcon, icon) as any}
|
|
127
118
|
/>
|
|
128
119
|
);
|
|
129
120
|
});
|
|
@@ -137,13 +128,13 @@ const _PaginationFirst = forwardRef<
|
|
|
137
128
|
ref,
|
|
138
129
|
) {
|
|
139
130
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
140
|
-
const
|
|
131
|
+
const computedIcon = withLabel ? FirstWithLabel : undefined;
|
|
141
132
|
return (
|
|
142
133
|
<MantinePagination.First
|
|
143
134
|
ref={ref}
|
|
144
|
-
data-variant="text"
|
|
145
|
-
icon={renderIcon as any}
|
|
146
135
|
{...sanitizedProps}
|
|
136
|
+
data-variant="text"
|
|
137
|
+
icon={withCallerOverride(computedIcon, icon) as any}
|
|
147
138
|
/>
|
|
148
139
|
);
|
|
149
140
|
});
|
|
@@ -157,13 +148,13 @@ const _PaginationLast = forwardRef<
|
|
|
157
148
|
ref,
|
|
158
149
|
) {
|
|
159
150
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
160
|
-
const
|
|
151
|
+
const computedIcon = withLabel ? LastWithLabel : undefined;
|
|
161
152
|
return (
|
|
162
153
|
<MantinePagination.Last
|
|
163
154
|
ref={ref}
|
|
164
|
-
data-variant="text"
|
|
165
|
-
icon={renderIcon as any}
|
|
166
155
|
{...sanitizedProps}
|
|
156
|
+
data-variant="text"
|
|
157
|
+
icon={withCallerOverride(computedIcon, icon) as any}
|
|
167
158
|
/>
|
|
168
159
|
);
|
|
169
160
|
});
|
|
@@ -201,11 +192,11 @@ const _Pagination = forwardRef<HTMLDivElement, PaginationProps>(
|
|
|
201
192
|
return (
|
|
202
193
|
<MantinePagination
|
|
203
194
|
ref={ref}
|
|
195
|
+
{...labelsIcons}
|
|
196
|
+
{...(sanitizedProps as MantinePaginationProps)}
|
|
204
197
|
className={stylingParams.className}
|
|
205
198
|
classNames={stylingParams.classNames}
|
|
206
199
|
getControlProps={mergedGetControlProps}
|
|
207
|
-
{...labelsIcons}
|
|
208
|
-
{...(sanitizedProps as MantinePaginationProps)}
|
|
209
200
|
/>
|
|
210
201
|
);
|
|
211
202
|
},
|
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
} from "@mantine/core";
|
|
13
13
|
import {
|
|
14
14
|
filterStylingProps,
|
|
15
|
+
mergeClassNames,
|
|
16
|
+
withCallerOverride,
|
|
15
17
|
type RecursicaOverStyled,
|
|
16
18
|
} from "../../utils/filterStylingProps";
|
|
17
19
|
import styles from "./Panel.module.css";
|
|
@@ -68,38 +70,29 @@ const PanelBase = function Panel({
|
|
|
68
70
|
...rest
|
|
69
71
|
}: PanelProps) {
|
|
70
72
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
73
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
71
74
|
|
|
72
75
|
// Bind CSS module classes to Mantine's internal classNames API
|
|
73
|
-
const mergedClassNames
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
classNamesProp &&
|
|
84
|
-
typeof classNamesProp === "object" &&
|
|
85
|
-
!Array.isArray(classNamesProp)
|
|
86
|
-
) {
|
|
87
|
-
const o = classNamesProp as Record<string, string>;
|
|
88
|
-
Object.keys(o).forEach((key) => {
|
|
89
|
-
if (mergedClassNames[key]) {
|
|
90
|
-
mergedClassNames[key] = `${mergedClassNames[key]} ${o[key]}`;
|
|
91
|
-
} else {
|
|
92
|
-
mergedClassNames[key] = o[key];
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
}
|
|
76
|
+
const mergedClassNames = mergeClassNames(
|
|
77
|
+
{
|
|
78
|
+
content: styles.content,
|
|
79
|
+
header: styles.header,
|
|
80
|
+
title: wrapHeaderText ? styles.titleTruncate : styles.title,
|
|
81
|
+
body: styles.body,
|
|
82
|
+
inner: styles.inner,
|
|
83
|
+
},
|
|
84
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
85
|
+
);
|
|
96
86
|
|
|
97
87
|
return (
|
|
98
88
|
<MantineDrawer
|
|
89
|
+
{...(sanitizedProps as unknown as MantineDrawerProps)}
|
|
99
90
|
position={placement} /* Recursica default: right; Mantine default: left */
|
|
100
91
|
keepMounted={keepMounted}
|
|
101
|
-
closeOnClickOutside={
|
|
102
|
-
|
|
92
|
+
closeOnClickOutside={withCallerOverride(
|
|
93
|
+
Boolean(rest.opened),
|
|
94
|
+
rest.closeOnClickOutside,
|
|
95
|
+
)}
|
|
103
96
|
classNames={mergedClassNames}
|
|
104
97
|
/>
|
|
105
98
|
);
|
|
@@ -130,7 +123,7 @@ export const PanelFooter = forwardRef<HTMLDivElement, PanelFooterProps>(
|
|
|
130
123
|
? `${styles.footer} ${classNameProp}`
|
|
131
124
|
: styles.footer;
|
|
132
125
|
|
|
133
|
-
return <div ref={ref} className={finalClassName}
|
|
126
|
+
return <div ref={ref} {...sanitizedProps} className={finalClassName} />;
|
|
134
127
|
},
|
|
135
128
|
);
|
|
136
129
|
PanelFooter.displayName = "PanelFooter";
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
} from "@mantine/core";
|
|
7
7
|
import {
|
|
8
8
|
filterStylingProps,
|
|
9
|
+
mergeClassNames,
|
|
10
|
+
withCallerOverride,
|
|
9
11
|
type RecursicaOverStyled,
|
|
10
12
|
} from "../../utils/filterStylingProps";
|
|
11
13
|
import styles from "./Popover.module.css";
|
|
@@ -47,54 +49,40 @@ export type PopoverProps = Omit<
|
|
|
47
49
|
const PopoverBase = function Popover({
|
|
48
50
|
overStyled = false,
|
|
49
51
|
withBeak = true,
|
|
52
|
+
position = "top", // Recursica default; Mantine defaults to "bottom"
|
|
50
53
|
...rest
|
|
51
54
|
}: PopoverProps) {
|
|
52
55
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
56
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
53
57
|
|
|
54
58
|
// Bind CSS module classes to Mantine's internal classNames API
|
|
55
|
-
const mergedClassNames
|
|
56
|
-
dropdown: styles.dropdown,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const classNamesProp = (sanitizedProps as Record<string, unknown>).classNames;
|
|
61
|
-
if (
|
|
62
|
-
classNamesProp &&
|
|
63
|
-
typeof classNamesProp === "object" &&
|
|
64
|
-
!Array.isArray(classNamesProp)
|
|
65
|
-
) {
|
|
66
|
-
const o = classNamesProp as Record<string, string>;
|
|
67
|
-
Object.keys(o).forEach((key) => {
|
|
68
|
-
if (mergedClassNames[key]) {
|
|
69
|
-
mergedClassNames[key] = `${mergedClassNames[key]} ${o[key]}`;
|
|
70
|
-
} else {
|
|
71
|
-
mergedClassNames[key] = o[key];
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
}
|
|
59
|
+
const mergedClassNames = mergeClassNames(
|
|
60
|
+
{ dropdown: styles.dropdown, arrow: styles.arrow },
|
|
61
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
62
|
+
);
|
|
75
63
|
|
|
76
64
|
// arrowSize must be a JS number prop — Mantine uses it for inline width/height
|
|
77
65
|
// and positioning offset (-arrowSize/2) calculations that cannot be CSS-driven.
|
|
78
66
|
// Default to 16 to match the Recursica beak-size token (16px).
|
|
79
|
-
const arrowSize =
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
67
|
+
const arrowSize = withCallerOverride<number>(
|
|
68
|
+
16,
|
|
69
|
+
restRecord.arrowSize as number | undefined,
|
|
70
|
+
);
|
|
83
71
|
|
|
84
72
|
// Resolve withBeak (Recursica) vs withArrow (Mantine).
|
|
85
73
|
// withBeak takes precedence when both are provided.
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
| undefined
|
|
89
|
-
|
|
74
|
+
const resolvedWithArrow = withCallerOverride<boolean | undefined>(
|
|
75
|
+
withBeak,
|
|
76
|
+
restRecord.withArrow as boolean | undefined,
|
|
77
|
+
);
|
|
90
78
|
|
|
91
79
|
return (
|
|
92
80
|
<MantinePopover
|
|
93
|
-
|
|
81
|
+
{...(sanitizedProps as unknown as MantinePopoverProps)}
|
|
82
|
+
position={position}
|
|
94
83
|
arrowSize={arrowSize}
|
|
95
84
|
withArrow={resolvedWithArrow}
|
|
96
85
|
classNames={mergedClassNames}
|
|
97
|
-
{...(sanitizedProps as unknown as MantinePopoverProps)}
|
|
98
86
|
/>
|
|
99
87
|
);
|
|
100
88
|
};
|
|
@@ -133,8 +121,8 @@ const PopoverDropdown = function PopoverDropdown({
|
|
|
133
121
|
|
|
134
122
|
return (
|
|
135
123
|
<MantinePopover.Dropdown
|
|
136
|
-
className={classNameProp}
|
|
137
124
|
{...(sanitizedProps as unknown as MantinePopoverDropdownProps)}
|
|
125
|
+
className={classNameProp}
|
|
138
126
|
/>
|
|
139
127
|
);
|
|
140
128
|
};
|
|
@@ -7,6 +7,9 @@ import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
|
7
7
|
import { RadioGroup } from "./RadioGroup";
|
|
8
8
|
import {
|
|
9
9
|
filterStylingProps,
|
|
10
|
+
omitUnsupportedProps,
|
|
11
|
+
withCallerOverride,
|
|
12
|
+
mergeClassNames,
|
|
10
13
|
type RecursicaOverStyled,
|
|
11
14
|
} from "../../utils/filterStylingProps";
|
|
12
15
|
import {
|
|
@@ -64,55 +67,41 @@ export const Radio = forwardRef<HTMLInputElement, RadioProps>(
|
|
|
64
67
|
readOnly,
|
|
65
68
|
readOnlyComponent,
|
|
66
69
|
disabled,
|
|
70
|
+
icon,
|
|
67
71
|
formLayout,
|
|
68
72
|
labelSize,
|
|
69
73
|
controlMaxWidth,
|
|
70
74
|
controlMinWidth,
|
|
71
75
|
...rest
|
|
72
76
|
} = props;
|
|
73
|
-
|
|
77
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
78
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
79
|
+
const UNSUPPORTED_PROPS = [
|
|
80
|
+
"size", // Recursica controls sizing via Radio.module.css variables, not Mantine's native size scale.
|
|
81
|
+
"color", // Colors are token-driven via Radio.module.css; Mantine's native palette isn't exposed.
|
|
82
|
+
"radius", // Corner radius is fixed by Recursica tokens in Radio.module.css, not caller-configurable.
|
|
83
|
+
"variant", // Radio has a single Recursica-defined visual treatment; Mantine's variant isn't exposed.
|
|
84
|
+
"iconColor", // Icon color is token-driven via Radio.module.css, not a native Mantine override.
|
|
85
|
+
] as const satisfies readonly (keyof MantineRadioProps)[];
|
|
86
|
+
|
|
87
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
88
|
+
filterStylingProps(rest, overStyled) as Record<string, unknown>,
|
|
89
|
+
UNSUPPORTED_PROPS,
|
|
90
|
+
) as Partial<typeof rest>;
|
|
74
91
|
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
75
92
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
icon: styles.icon,
|
|
89
|
-
labelWrapper: styles.labelWrapper,
|
|
90
|
-
label: styles.label,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const classNamesProp = restRecord.classNames;
|
|
94
|
-
if (
|
|
95
|
-
classNamesProp &&
|
|
96
|
-
typeof classNamesProp === "object" &&
|
|
97
|
-
!Array.isArray(classNamesProp)
|
|
98
|
-
) {
|
|
99
|
-
const o = classNamesProp as Partial<Record<string, string>>;
|
|
100
|
-
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
101
|
-
mergedClassNames.body = o.body ? `${styles.body} ${o.body}` : styles.body;
|
|
102
|
-
mergedClassNames.inner = o.inner
|
|
103
|
-
? `${styles.inner} ${o.inner}`
|
|
104
|
-
: styles.inner;
|
|
105
|
-
mergedClassNames.radio = o.radio
|
|
106
|
-
? `${styles.radio} ${o.radio}`
|
|
107
|
-
: styles.radio;
|
|
108
|
-
mergedClassNames.icon = o.icon ? `${styles.icon} ${o.icon}` : styles.icon;
|
|
109
|
-
mergedClassNames.labelWrapper = o.labelWrapper
|
|
110
|
-
? `${styles.labelWrapper} ${o.labelWrapper}`
|
|
111
|
-
: styles.labelWrapper;
|
|
112
|
-
mergedClassNames.label = o.label
|
|
113
|
-
? `${styles.label} ${o.label}`
|
|
114
|
-
: styles.label;
|
|
115
|
-
}
|
|
93
|
+
const mergedClassNames = mergeClassNames(
|
|
94
|
+
{
|
|
95
|
+
root: styles.root,
|
|
96
|
+
body: styles.body,
|
|
97
|
+
inner: styles.inner,
|
|
98
|
+
radio: styles.radio,
|
|
99
|
+
icon: styles.icon,
|
|
100
|
+
labelWrapper: styles.labelWrapper,
|
|
101
|
+
label: styles.label,
|
|
102
|
+
},
|
|
103
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
104
|
+
);
|
|
116
105
|
|
|
117
106
|
const classNameProp = restRecord.className as string | undefined;
|
|
118
107
|
const finalClass = classNameProp
|
|
@@ -150,11 +139,11 @@ export const Radio = forwardRef<HTMLInputElement, RadioProps>(
|
|
|
150
139
|
const radioNode = (
|
|
151
140
|
<MantineRadio
|
|
152
141
|
ref={ref}
|
|
153
|
-
|
|
142
|
+
{...(sanitizedProps as unknown as MantineRadioProps)}
|
|
143
|
+
icon={withCallerOverride<MantineRadioProps["icon"]>(RadioIcon, icon)}
|
|
154
144
|
className={finalClass}
|
|
155
145
|
classNames={mergedClassNames}
|
|
156
146
|
disabled={readOnly || disabled}
|
|
157
|
-
{...(sanitizedProps as unknown as MantineRadioProps)}
|
|
158
147
|
/>
|
|
159
148
|
);
|
|
160
149
|
|
|
@@ -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 RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
|
|
|
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 Radio.module.css variables, not Mantine's native size scale.
|
|
69
|
+
] as const satisfies readonly (keyof MantineRadioGroupProps)[];
|
|
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
|
|
@@ -100,10 +100,10 @@ export const ReadOnlyField = forwardRef<HTMLDivElement, ReadOnlyFieldProps>(
|
|
|
100
100
|
return (
|
|
101
101
|
<FormControlWrapper
|
|
102
102
|
ref={ref}
|
|
103
|
+
{...(sanitizedProps as any)}
|
|
103
104
|
overStyled={overStyled as true}
|
|
104
105
|
className={wrapperClass}
|
|
105
106
|
style={style}
|
|
106
|
-
{...(sanitizedProps as any)}
|
|
107
107
|
>
|
|
108
108
|
{content}
|
|
109
109
|
</FormControlWrapper>
|
|
@@ -27,12 +27,12 @@ export const ReadOnlyTextField: React.FC<ReadOnlyTextFieldProps> = ({
|
|
|
27
27
|
return (
|
|
28
28
|
<Box
|
|
29
29
|
component="p"
|
|
30
|
+
{...sanitizedProps}
|
|
30
31
|
className={
|
|
31
32
|
classNameProp
|
|
32
33
|
? `${styles.textField} ${classNameProp}`
|
|
33
34
|
: styles.textField
|
|
34
35
|
}
|
|
35
|
-
{...sanitizedProps}
|
|
36
36
|
>
|
|
37
37
|
{value != null
|
|
38
38
|
? React.isValidElement(value)
|
|
@@ -67,12 +67,12 @@ export const WithReadOnlyWrapper = forwardRef<
|
|
|
67
67
|
return (
|
|
68
68
|
<ReadOnlyField
|
|
69
69
|
ref={ref}
|
|
70
|
+
{...wrapperProps}
|
|
70
71
|
type={readOnlyType}
|
|
71
72
|
value={readOnlyValue}
|
|
72
73
|
emptyValueComponent={emptyValueComponent}
|
|
73
74
|
onLabelEditClick={onLabelEditClick}
|
|
74
75
|
overStyled={overStyled as true}
|
|
75
|
-
{...wrapperProps}
|
|
76
76
|
/>
|
|
77
77
|
);
|
|
78
78
|
}
|
|
@@ -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
|
|