@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
|
@@ -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 RecursicaDropdownProps
|
|
|
28
30
|
|
|
29
31
|
export type DropdownProps = RecursicaOverStyled<RecursicaDropdownProps>;
|
|
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 MantineSelectProps)[];
|
|
40
|
+
|
|
31
41
|
export const Dropdown = forwardRef<HTMLInputElement, DropdownProps>(
|
|
32
42
|
function Dropdown(props, ref) {
|
|
33
43
|
const {
|
|
@@ -60,46 +70,23 @@ export const Dropdown = forwardRef<HTMLInputElement, DropdownProps>(
|
|
|
60
70
|
data,
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
classNamesProp &&
|
|
83
|
-
typeof classNamesProp === "object" &&
|
|
84
|
-
!Array.isArray(classNamesProp)
|
|
85
|
-
) {
|
|
86
|
-
const o = classNamesProp as Partial<Record<string, string>>;
|
|
87
|
-
mergedClassNames.wrapper = o.wrapper
|
|
88
|
-
? `${styles.root} ${o.wrapper}`
|
|
89
|
-
: styles.root;
|
|
90
|
-
mergedClassNames.input = o.input
|
|
91
|
-
? `${styles.input} ${o.input}`
|
|
92
|
-
: styles.input;
|
|
93
|
-
mergedClassNames.section = o.section
|
|
94
|
-
? `${styles.section} ${o.section}`
|
|
95
|
-
: styles.section;
|
|
96
|
-
mergedClassNames.dropdown = o.dropdown
|
|
97
|
-
? `${styles.dropdown} ${o.dropdown}`
|
|
98
|
-
: styles.dropdown;
|
|
99
|
-
mergedClassNames.option = o.option
|
|
100
|
-
? `${styles.option} ${o.option}`
|
|
101
|
-
: styles.option;
|
|
102
|
-
}
|
|
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
|
+
dropdown: styles.dropdown,
|
|
86
|
+
option: styles.option,
|
|
87
|
+
},
|
|
88
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
89
|
+
);
|
|
103
90
|
|
|
104
91
|
const injectedStyles = {
|
|
105
92
|
...((style as React.CSSProperties) || {}),
|
|
@@ -146,6 +133,7 @@ export const Dropdown = forwardRef<HTMLInputElement, DropdownProps>(
|
|
|
146
133
|
/* Naked Select execution safely decoupled from Mantine's macro Input.Wrapper DOM hooks */
|
|
147
134
|
<MantineSelect
|
|
148
135
|
ref={ref}
|
|
136
|
+
{...(sanitizedProps as unknown as MantineSelectProps)}
|
|
149
137
|
classNames={mergedClassNames}
|
|
150
138
|
disabled={disabled}
|
|
151
139
|
value={value}
|
|
@@ -169,7 +157,6 @@ export const Dropdown = forwardRef<HTMLInputElement, DropdownProps>(
|
|
|
169
157
|
"data-error": error ? "true" : undefined,
|
|
170
158
|
},
|
|
171
159
|
}}
|
|
172
|
-
{...(sanitizedProps as unknown as MantineSelectProps)}
|
|
173
160
|
/>
|
|
174
161
|
}
|
|
175
162
|
/>
|
|
@@ -1,24 +1,3 @@
|
|
|
1
|
-
/* EXEMPTIONS:
|
|
2
|
-
- The disabled/error states' own border-size variables are ignored so the border never changes
|
|
3
|
-
thickness across states and shifts the layout — same house policy as TextField/DatePicker.
|
|
4
|
-
The flat, state-agnostic properties_border-size token below is applied uniformly instead.
|
|
5
|
-
- There is no forge-defined focus state for file-input (no `states.focus` axis, unlike its
|
|
6
|
-
disabled/error siblings) — the generic recursica_brand_states_focus_* ring is used instead,
|
|
7
|
-
same fallback TextField/DatePicker use for the same reason.
|
|
8
|
-
- properties_icon-text-gap doubles as the gap between chips: file-input has no dedicated
|
|
9
|
-
chip-gap token (unlike file-upload's properties_item-gap).
|
|
10
|
-
- The trailing clear-all affordance is now a real shared `Button` (icon-only, "text" variant)
|
|
11
|
-
rather than a bespoke span, so it gets its own real button semantics/keyboard handling —
|
|
12
|
-
same pattern as Tree's expand/collapse button. It renders through Button's own tokened
|
|
13
|
-
color states (including disabled), so file-input's own trailing-icon color tokens — which
|
|
14
|
-
have no "clear button is disabled/errored" equivalent state of their own anyway — are no
|
|
15
|
-
longer consumed here. */
|
|
16
|
-
/* recursica-ignore: --recursica_ui-kit_components_file-input_variants_states_disabled_properties_border-size */
|
|
17
|
-
/* recursica-ignore: --recursica_ui-kit_components_file-input_variants_states_error_properties_border-size */
|
|
18
|
-
/* recursica-ignore: --recursica_ui-kit_components_file-input_properties_colors_trailing-icon */
|
|
19
|
-
/* recursica-ignore: --recursica_ui-kit_components_file-input_variants_states_error_properties_colors_trailing-icon */
|
|
20
|
-
/* recursica-ignore: --recursica_ui-kit_components_file-input_variants_states_disabled_properties_colors_trailing-icon */
|
|
21
|
-
|
|
22
1
|
/* LAYOUT SPACING OVERRIDES:
|
|
23
2
|
- Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens.
|
|
24
3
|
- Also sets the --file-input-control-{max,min}-width hooks consumed inline in FileInput.tsx,
|
|
@@ -309,6 +309,7 @@ export const FileInput = forwardRef<HTMLDivElement, FileInputProps>(
|
|
|
309
309
|
>
|
|
310
310
|
<div
|
|
311
311
|
ref={ref}
|
|
312
|
+
{...restRecord}
|
|
312
313
|
className={styles.root}
|
|
313
314
|
role="button"
|
|
314
315
|
aria-label={browseLabel}
|
|
@@ -324,7 +325,6 @@ export const FileInput = forwardRef<HTMLDivElement, FileInputProps>(
|
|
|
324
325
|
onDragLeave={interactive ? handleDragLeave : undefined}
|
|
325
326
|
onDragOver={interactive ? handleDragOver : undefined}
|
|
326
327
|
onDrop={interactive ? handleDrop : undefined}
|
|
327
|
-
{...restRecord}
|
|
328
328
|
>
|
|
329
329
|
<span className={styles.leadingIcon} aria-hidden>
|
|
330
330
|
{icon ?? <UploadIcon />}
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/* EXEMPTIONS:
|
|
2
|
-
- border-style has no usable var(...) form: the Figma-exported token's value is the literal
|
|
3
|
-
string `"dashed"` (quotes included), which is not a valid CSS <line-style> keyword — the same
|
|
4
|
-
class of "structural, not tokenized" property the canonical guide already treats border-style
|
|
5
|
-
as (see .root's own HARDCODED VALUES note below and TimePicker/DatePicker's identical
|
|
6
|
-
hardcoded `border-style: solid`). Hardcoded to the keyword `dashed` instead.
|
|
7
|
-
- properties_icon-size has no equivalent: unlike TextField/DatePicker, file-upload has no
|
|
8
|
-
dedicated icon-size token. Sized to visually match the Figma reference instead (see
|
|
9
|
-
HARDCODED VALUES below). */
|
|
10
|
-
/* recursica-ignore: --recursica_ui-kit_components_file-upload_properties_border-style */
|
|
11
|
-
|
|
12
1
|
/* HARDCODED VALUES:
|
|
13
2
|
- .root: display: flex; flex-direction: column; width: 100% — structural layout, not a design
|
|
14
3
|
token concern (matches how other block-level components like Layer are laid out).
|
|
@@ -268,10 +268,10 @@ export const FileUpload = forwardRef<HTMLDivElement, FileUploadProps>(
|
|
|
268
268
|
>
|
|
269
269
|
<div
|
|
270
270
|
ref={ref}
|
|
271
|
+
{...restRecord}
|
|
271
272
|
className={styles.root}
|
|
272
273
|
data-disabled={disabled ? "true" : undefined}
|
|
273
274
|
data-error={effectiveError ? "true" : undefined}
|
|
274
|
-
{...restRecord}
|
|
275
275
|
>
|
|
276
276
|
{!readOnly && (
|
|
277
277
|
<div
|
|
@@ -5,13 +5,7 @@
|
|
|
5
5
|
and positioning (-arrowSize/2) calculations that cannot be CSS-driven. The default matches
|
|
6
6
|
the Recursica beak-size token (16px). See COMPONENT_ISSUES.md for details.
|
|
7
7
|
- All structural layout (display, position, overflow) is deferred to Mantine's native
|
|
8
|
-
behavior. We only override visual design tokens (colors, typography, spacing, borders).
|
|
9
|
-
/* EXEMPTIONS:
|
|
10
|
-
- beak-size is ignored here because Mantine's popover arrows compute their sizing and positional offsets
|
|
11
|
-
dynamically within the React rendering engine (requires inline pixel number rather than standard CSS variables).
|
|
12
|
-
The beak size is checked in JS against a fixed value of 16px. If this variable changes, the TSX components
|
|
13
|
-
need to be reviewed/re-compiled. */
|
|
14
|
-
/* recursica-ignore: --recursica_ui-kit_components_hover-card-popover_properties_beak-size = 16px */
|
|
8
|
+
behavior. We only override visual design tokens (colors, typography, spacing, borders). */
|
|
15
9
|
|
|
16
10
|
/* ======================================
|
|
17
11
|
DROPDOWN CONTAINER
|
|
@@ -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 "./HoverCard.module.css";
|
|
@@ -42,54 +43,37 @@ export type HoverCardProps = RecursicaOverStyled<
|
|
|
42
43
|
const HoverCardBase = function HoverCard({
|
|
43
44
|
overStyled = false,
|
|
44
45
|
withBeak = true,
|
|
46
|
+
position = "top", // Recursica default; Mantine defaults to "bottom". Consumers can still override.
|
|
47
|
+
// arrowSize must be a JS number prop — Mantine uses it for inline width/height
|
|
48
|
+
// and positioning offset (-arrowSize/2) calculations that cannot be CSS-driven.
|
|
49
|
+
// Default to 16 to match the Recursica beak-size token (16px). Consumers can still override.
|
|
50
|
+
arrowSize = 16,
|
|
51
|
+
withArrow,
|
|
45
52
|
...rest
|
|
46
53
|
}: HoverCardProps) {
|
|
47
54
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
55
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
48
56
|
|
|
49
57
|
// Bind CSS module classes to Mantine's internal classNames API
|
|
50
|
-
const mergedClassNames
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
classNamesProp &&
|
|
58
|
-
typeof classNamesProp === "object" &&
|
|
59
|
-
!Array.isArray(classNamesProp)
|
|
60
|
-
) {
|
|
61
|
-
const o = classNamesProp as Record<string, string>;
|
|
62
|
-
Object.keys(o).forEach((key) => {
|
|
63
|
-
if (mergedClassNames[key]) {
|
|
64
|
-
mergedClassNames[key] = `${mergedClassNames[key]} ${o[key]}`;
|
|
65
|
-
} else {
|
|
66
|
-
mergedClassNames[key] = o[key];
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// arrowSize must be a JS number prop — Mantine uses it for inline width/height
|
|
72
|
-
// and positioning offset (-arrowSize/2) calculations that cannot be CSS-driven.
|
|
73
|
-
// Default to 16 to match the Recursica beak-size token (16px).
|
|
74
|
-
const arrowSize =
|
|
75
|
-
((sanitizedProps as Record<string, unknown>).arrowSize as
|
|
76
|
-
| number
|
|
77
|
-
| undefined) ?? 16;
|
|
58
|
+
const mergedClassNames = mergeClassNames(
|
|
59
|
+
{
|
|
60
|
+
dropdown: styles.dropdown,
|
|
61
|
+
arrow: styles.arrow,
|
|
62
|
+
},
|
|
63
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
64
|
+
);
|
|
78
65
|
|
|
79
66
|
// Resolve withBeak (Recursica) vs withArrow (Mantine).
|
|
80
67
|
// withBeak takes precedence when both are provided.
|
|
81
|
-
const withArrow = (sanitizedProps as Record<string, unknown>).withArrow as
|
|
82
|
-
| boolean
|
|
83
|
-
| undefined;
|
|
84
68
|
const resolvedWithArrow = withBeak ?? withArrow;
|
|
85
69
|
|
|
86
70
|
return (
|
|
87
71
|
<MantineHoverCard
|
|
88
|
-
|
|
72
|
+
{...(sanitizedProps as unknown as MantineHoverCardProps)}
|
|
73
|
+
position={position}
|
|
89
74
|
arrowSize={arrowSize}
|
|
90
75
|
withArrow={resolvedWithArrow}
|
|
91
76
|
classNames={mergedClassNames}
|
|
92
|
-
{...(sanitizedProps as unknown as MantineHoverCardProps)}
|
|
93
77
|
/>
|
|
94
78
|
);
|
|
95
79
|
};
|
|
@@ -128,8 +112,8 @@ const HoverCardDropdown = function HoverCardDropdown({
|
|
|
128
112
|
|
|
129
113
|
return (
|
|
130
114
|
<MantineHoverCard.Dropdown
|
|
131
|
-
className={classNameProp}
|
|
132
115
|
{...(sanitizedProps as unknown as MantineHoverCardDropdownProps)}
|
|
116
|
+
className={classNameProp}
|
|
133
117
|
/>
|
|
134
118
|
);
|
|
135
119
|
};
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
/* EXEMPTIONS:
|
|
2
|
-
- layouts_stacked sizes width variables are ignored because stacked labels naturally occupy 100% width block-level
|
|
3
|
-
real estate in HTML rendering, making explicit width properties redundant. */
|
|
4
|
-
|
|
5
1
|
/* HARDCODED VALUES:
|
|
6
2
|
- display: flex helps us leverage flex 'order' to perfectly position Mantine's injected asterisk.
|
|
7
3
|
- align-items: baseline ensures text logic lines up nicely if font sizes differ slightly.
|
|
8
4
|
- margin/padding resets.
|
|
9
5
|
*/
|
|
10
|
-
/* recursica-ignore: --recursica_ui-kit_components_label_variants_layouts_stacked_variants_sizes_default_properties_width */
|
|
11
|
-
/* recursica-ignore: --recursica_ui-kit_components_label_variants_layouts_stacked_variants_sizes_small_properties_width */
|
|
12
6
|
|
|
13
7
|
.root {
|
|
14
8
|
display: flex;
|
|
@@ -2,6 +2,8 @@ import React, { forwardRef } from "react";
|
|
|
2
2
|
import { Input, type InputLabelProps } from "@mantine/core";
|
|
3
3
|
import {
|
|
4
4
|
filterStylingProps,
|
|
5
|
+
omitUnsupportedProps,
|
|
6
|
+
mergeClassNames,
|
|
5
7
|
type RecursicaOverStyled,
|
|
6
8
|
} from "../../utils/filterStylingProps";
|
|
7
9
|
import styles from "./Label.module.css";
|
|
@@ -35,28 +37,25 @@ export const Label = forwardRef<HTMLLabelElement, LabelProps>(function Label(
|
|
|
35
37
|
else if (labelOptionalText) resolvedOptionalText = labelOptionalText;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
41
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
42
|
+
const UNSUPPORTED_PROPS = [
|
|
43
|
+
"size", // Recursica controls label sizing via `labelSize` + design tokens, not Mantine's native `size`.
|
|
44
|
+
] as const satisfies readonly (keyof InputLabelProps)[];
|
|
40
45
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
47
|
+
filterStylingProps(rest, overStyled),
|
|
48
|
+
UNSUPPORTED_PROPS,
|
|
49
|
+
);
|
|
50
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
45
51
|
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
mergedClassNames.label = o.label
|
|
54
|
-
? `${styles.root} ${o.label}`
|
|
55
|
-
: styles.root;
|
|
56
|
-
mergedClassNames.required = o.required
|
|
57
|
-
? `${styles.required} ${o.required}`
|
|
58
|
-
: styles.required;
|
|
59
|
-
}
|
|
52
|
+
const mergedClassNames = mergeClassNames(
|
|
53
|
+
{
|
|
54
|
+
label: styles.root,
|
|
55
|
+
required: styles.required,
|
|
56
|
+
},
|
|
57
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
58
|
+
);
|
|
60
59
|
|
|
61
60
|
const classNameProp = restRecord.className as string | undefined;
|
|
62
61
|
const finalClass = classNameProp
|
|
@@ -66,12 +65,12 @@ export const Label = forwardRef<HTMLLabelElement, LabelProps>(function Label(
|
|
|
66
65
|
return (
|
|
67
66
|
<Input.Label
|
|
68
67
|
ref={ref}
|
|
68
|
+
{...sanitizedProps}
|
|
69
69
|
className={finalClass}
|
|
70
70
|
classNames={mergedClassNames}
|
|
71
71
|
data-size={labelSize}
|
|
72
72
|
data-alignment={resolvedAlignment}
|
|
73
73
|
required={required && !labelWithEditIcon}
|
|
74
|
-
{...sanitizedProps}
|
|
75
74
|
>
|
|
76
75
|
<span className={styles.labelText}>{children}</span>
|
|
77
76
|
{resolvedOptionalText && (
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
/*
|
|
2
|
-
- text_text-transform is ignored because links naturally inherit casing directly from text
|
|
3
|
-
children rather than requiring custom CSS transforms. */
|
|
4
|
-
/* recursica-ignore: --recursica_ui-kit_components_link_properties_text_text-transform */
|
|
5
|
-
|
|
6
|
-
/*
|
|
1
|
+
/*
|
|
7
2
|
HARDCODED VALUES:
|
|
8
3
|
- display: inline-flex; (Base layout to align icon and text correctly)
|
|
9
4
|
- align-items: center;
|
|
@@ -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 "./Link.module.css";
|
|
@@ -23,19 +24,10 @@ const _Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link(
|
|
|
23
24
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
24
25
|
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
25
26
|
|
|
26
|
-
const mergedClassNames
|
|
27
|
-
root: styles.root,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const classNamesProp = restRecord.classNames;
|
|
31
|
-
if (
|
|
32
|
-
classNamesProp &&
|
|
33
|
-
typeof classNamesProp === "object" &&
|
|
34
|
-
!Array.isArray(classNamesProp)
|
|
35
|
-
) {
|
|
36
|
-
const o = classNamesProp as Partial<Record<string, string>>;
|
|
37
|
-
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
38
|
-
}
|
|
27
|
+
const mergedClassNames = mergeClassNames(
|
|
28
|
+
{ root: styles.root },
|
|
29
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
30
|
+
);
|
|
39
31
|
|
|
40
32
|
const classNameProp = restRecord.className as string | undefined;
|
|
41
33
|
const finalClass = classNameProp
|
|
@@ -45,11 +37,11 @@ const _Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link(
|
|
|
45
37
|
return (
|
|
46
38
|
<MantineAnchor
|
|
47
39
|
ref={ref}
|
|
40
|
+
{...(sanitizedProps as Record<string, unknown>)}
|
|
48
41
|
className={finalClass}
|
|
49
42
|
classNames={mergedClassNames}
|
|
50
43
|
underline="never"
|
|
51
44
|
{...(icon ? { "data-has-icon": "" } : {})}
|
|
52
|
-
{...(sanitizedProps as Record<string, unknown>)}
|
|
53
45
|
>
|
|
54
46
|
{icon && (
|
|
55
47
|
<span className={styles.iconWrapper} aria-hidden>
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from "@mantine/core";
|
|
6
6
|
import {
|
|
7
7
|
filterStylingProps,
|
|
8
|
+
mergeClassNames,
|
|
8
9
|
type RecursicaOverStyled,
|
|
9
10
|
} from "../../utils/filterStylingProps";
|
|
10
11
|
import styles from "./Loader.module.css";
|
|
@@ -33,23 +34,14 @@ export const Loader = forwardRef<HTMLSpanElement, LoaderProps>(function Loader(
|
|
|
33
34
|
// Strip all visual override injections unless developer has specifically opted into overStyling.
|
|
34
35
|
// External layout props like margins are safely preserved.
|
|
35
36
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
37
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
36
38
|
|
|
37
|
-
const mergedClassNames
|
|
38
|
-
root: styles.root,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const classNamesProp = (sanitizedProps as Record<string, unknown>).classNames;
|
|
42
|
-
if (
|
|
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
|
-
}
|
|
39
|
+
const mergedClassNames = mergeClassNames(
|
|
40
|
+
{ root: styles.root },
|
|
41
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
42
|
+
);
|
|
50
43
|
|
|
51
|
-
const classNameProp =
|
|
52
|
-
.className as string | undefined;
|
|
44
|
+
const classNameProp = restRecord.className as string | undefined;
|
|
53
45
|
const finalClass = classNameProp
|
|
54
46
|
? `${styles.root} ${classNameProp}`
|
|
55
47
|
: styles.root;
|
|
@@ -57,10 +49,10 @@ export const Loader = forwardRef<HTMLSpanElement, LoaderProps>(function Loader(
|
|
|
57
49
|
return (
|
|
58
50
|
<MantineLoader
|
|
59
51
|
ref={ref}
|
|
52
|
+
{...sanitizedProps}
|
|
60
53
|
type={variant}
|
|
61
54
|
data-variant={variant}
|
|
62
55
|
data-size={resolvedSize}
|
|
63
|
-
{...sanitizedProps}
|
|
64
56
|
className={finalClass}
|
|
65
57
|
classNames={mergedClassNames}
|
|
66
58
|
/>
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/* EXEMPTIONS:
|
|
2
|
-
- colors_supporting-text-color (selected variant) is ignored because selected menu items do not
|
|
3
|
-
render supporting secondary text, making the selected-state override for supporting text
|
|
4
|
-
colors obsolete. */
|
|
5
|
-
/* recursica-ignore: --recursica_ui-kit_components_menu-item_variants_selection-states_selected_properties_colors_supporting-text-color */
|
|
6
|
-
|
|
7
1
|
/* HARDCODED VALUES:
|
|
8
2
|
- border-style: solid. Structural rendering rule for the dropdown border (Mantine uses Paper which may not set border natively).
|
|
9
3
|
- NOTE: overflow is intentionally NOT set on .dropdown. Mantine renders sub-menu dropdowns
|