@recursica/mantine-adapter 0.53.0 → 0.55.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 +30 -0
- package/dist/index.d.ts +10 -0
- 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 +634 -617
- package/dist/mantine-adapter.js.map +1 -1
- package/package.json +5 -4
- package/src/components/Accordion/Accordion.module.css +17 -8
- package/src/components/AutoComplete/AutoComplete.module.css +9 -2
- package/src/components/Chip/Chip.module.css +18 -0
- package/src/components/DatePicker/DatePicker.module.css +9 -2
- package/src/components/Dropdown/Dropdown.module.css +9 -2
- package/src/components/FileInput/FileInput.module.css +12 -0
- package/src/components/FileUpload/FileUpload.module.css +6 -1
- package/src/components/FormControlLayout/FormControlLayout.module.css +12 -0
- package/src/components/FormControlLayout/FormControlLayout.stories.tsx +36 -0
- package/src/components/HoverCard/HoverCard.module.css +6 -1
- package/src/components/Label/Label.stories.tsx +63 -54
- package/src/components/Link/Link.module.css +5 -0
- package/src/components/Loader/Loader.animate.dom.test.tsx +82 -0
- package/src/components/Loader/Loader.module.css +10 -0
- package/src/components/Loader/Loader.stories.tsx +20 -0
- package/src/components/Loader/Loader.tsx +8 -1
- package/src/components/Modal/Modal.module.css +6 -2
- package/src/components/NumberInput/NumberInput.module.css +9 -2
- package/src/components/SegmentedControl/SegmentedControl.module.css +6 -0
- package/src/components/Table/TABLE_IMPLEMENTATION_NOTES.md +11 -0
- package/src/components/Table/Table.module.css +14 -0
- package/src/components/Table/Table.stories.tsx +1 -1
- package/src/components/Table/Table.tsx +9 -1
- package/src/components/Table/USAGE.md +4 -2
- package/src/components/TextArea/TextArea.module.css +9 -2
- package/src/components/TextField/TextField.module.css +9 -2
- package/src/components/TimePicker/TIMEPICKER_IMPLEMENTATION_NOTES.md +7 -1
- package/src/components/TimePicker/TimePicker.module.css +44 -0
- package/src/components/TimePicker/TimePicker.stories.tsx +22 -0
- package/src/components/TimePicker/TimePicker.tsx +1 -0
- package/src/components/Timeline/Timeline.module.css +5 -0
- package/src/components/Toast/Toast.module.css +8 -0
- package/src/components/Tooltip/Tooltip.module.css +9 -1
- package/src/components/TransferList/TransferList.module.css +9 -1
|
@@ -41,6 +41,11 @@ const meta: Meta<LoaderStoryArgs> = {
|
|
|
41
41
|
description:
|
|
42
42
|
"Applies a wrapping context to observe rendering logic externally",
|
|
43
43
|
},
|
|
44
|
+
animate: {
|
|
45
|
+
control: "boolean",
|
|
46
|
+
description:
|
|
47
|
+
"Freezes the CSS animation when false — deterministic, for visual regression",
|
|
48
|
+
},
|
|
44
49
|
},
|
|
45
50
|
};
|
|
46
51
|
|
|
@@ -48,6 +53,11 @@ export default meta;
|
|
|
48
53
|
|
|
49
54
|
type Story = StoryObj<LoaderStoryArgs>;
|
|
50
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Animated — excluded from visual regression (`adapter-tester.config.json`),
|
|
58
|
+
* since a moving animation diffs differently every run. See the `Static*`
|
|
59
|
+
* stories below for the deterministic, visual-regression-covered equivalents.
|
|
60
|
+
*/
|
|
51
61
|
export const Default: Story = {
|
|
52
62
|
args: {
|
|
53
63
|
variant: "oval",
|
|
@@ -62,33 +72,43 @@ export const Default: Story = {
|
|
|
62
72
|
),
|
|
63
73
|
};
|
|
64
74
|
|
|
75
|
+
/** `animate: false` freezes the spin — deterministic for visual regression. */
|
|
65
76
|
export const StaticOvalDefault: Story = {
|
|
66
77
|
args: {
|
|
67
78
|
variant: "oval",
|
|
68
79
|
size: "default",
|
|
80
|
+
animate: false,
|
|
69
81
|
},
|
|
70
82
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
71
83
|
render: ({ withLayer, layer, ...args }: any) => <Loader {...args} />,
|
|
72
84
|
};
|
|
73
85
|
|
|
86
|
+
/** `animate: false` freezes the bars — deterministic for visual regression. */
|
|
74
87
|
export const StaticBarsLarge: Story = {
|
|
75
88
|
args: {
|
|
76
89
|
variant: "bars",
|
|
77
90
|
size: "large",
|
|
91
|
+
animate: false,
|
|
78
92
|
},
|
|
79
93
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
80
94
|
render: ({ withLayer, layer, ...args }: any) => <Loader {...args} />,
|
|
81
95
|
};
|
|
82
96
|
|
|
97
|
+
/** `animate: false` freezes the dots — deterministic for visual regression. */
|
|
83
98
|
export const StaticDotsSmall: Story = {
|
|
84
99
|
args: {
|
|
85
100
|
variant: "dots",
|
|
86
101
|
size: "sm",
|
|
102
|
+
animate: false,
|
|
87
103
|
},
|
|
88
104
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
89
105
|
render: ({ withLayer, layer, ...args }: any) => <Loader {...args} />,
|
|
90
106
|
};
|
|
91
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Animated — excluded from visual regression, same as `Default`; this one
|
|
110
|
+
* additionally demonstrates rendering inside a `layer={2}` context.
|
|
111
|
+
*/
|
|
92
112
|
export const LayerTwoOval: Story = {
|
|
93
113
|
args: {
|
|
94
114
|
variant: "oval",
|
|
@@ -17,7 +17,13 @@ export type LoaderProps = RecursicaOverStyled<
|
|
|
17
17
|
>;
|
|
18
18
|
|
|
19
19
|
export const Loader = forwardRef<HTMLSpanElement, LoaderProps>(function Loader(
|
|
20
|
-
{
|
|
20
|
+
{
|
|
21
|
+
variant = "oval",
|
|
22
|
+
size = "default",
|
|
23
|
+
animate = true,
|
|
24
|
+
overStyled = false,
|
|
25
|
+
...rest
|
|
26
|
+
},
|
|
21
27
|
ref,
|
|
22
28
|
) {
|
|
23
29
|
const mapSize = {
|
|
@@ -53,6 +59,7 @@ export const Loader = forwardRef<HTMLSpanElement, LoaderProps>(function Loader(
|
|
|
53
59
|
type={variant}
|
|
54
60
|
data-variant={variant}
|
|
55
61
|
data-size={resolvedSize}
|
|
62
|
+
data-animate={animate}
|
|
56
63
|
className={finalClass}
|
|
57
64
|
classNames={mergedClassNames}
|
|
58
65
|
/>
|
|
@@ -72,7 +72,9 @@
|
|
|
72
72
|
var(
|
|
73
73
|
--recursica_ui-kit_components_modal_properties_header-footer-horizontal-padding
|
|
74
74
|
);
|
|
75
|
-
background-color:
|
|
75
|
+
background-color: var(
|
|
76
|
+
--recursica_ui-kit_components_modal_properties_colors_header-background-color
|
|
77
|
+
);
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
.title {
|
|
@@ -201,7 +203,9 @@
|
|
|
201
203
|
var(
|
|
202
204
|
--recursica_ui-kit_components_modal_properties_header-footer-horizontal-padding
|
|
203
205
|
);
|
|
204
|
-
background-color:
|
|
206
|
+
background-color: var(
|
|
207
|
+
--recursica_ui-kit_components_modal_properties_colors_footer-background-color
|
|
208
|
+
);
|
|
205
209
|
display: flex;
|
|
206
210
|
justify-content: flex-end;
|
|
207
211
|
gap: var(--recursica_ui-kit_components_modal_properties_button-gap);
|
|
@@ -35,13 +35,18 @@
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/* HARDCODED VALUES:
|
|
38
|
-
- border-width: 1px. Native geometric boundary for the input box.
|
|
39
38
|
- border-style: solid. Native structural rendering rule.
|
|
40
39
|
- outline: none. Bypassing browser focus rings to rely strictly on Recursica focus states natively.
|
|
41
40
|
- flex/layout: display: flex on the root wrapper safely encapsulating internal section rendering.
|
|
42
41
|
- Controls: Hardcoded to bypass Mantine's default borders and backgrounds on the increment/decrement arrows.
|
|
43
42
|
*/
|
|
44
43
|
|
|
44
|
+
/* EXEMPTIONS:
|
|
45
|
+
- border-size is constant across disabled/error states — only border-color changes; the
|
|
46
|
+
disabled/error border-size tokens are never applied by design. */
|
|
47
|
+
/* recursica-ignore: --recursica_ui-kit_components_number-input_variants_states_disabled_properties_border-size */
|
|
48
|
+
/* recursica-ignore: --recursica_ui-kit_components_number-input_variants_states_error_properties_border-size */
|
|
49
|
+
|
|
45
50
|
.root {
|
|
46
51
|
display: flex;
|
|
47
52
|
position: relative;
|
|
@@ -92,7 +97,9 @@
|
|
|
92
97
|
border-radius: var(
|
|
93
98
|
--recursica_ui-kit_components_number-input_properties_border-radius
|
|
94
99
|
);
|
|
95
|
-
border-width:
|
|
100
|
+
border-width: var(
|
|
101
|
+
--recursica_ui-kit_components_number-input_properties_border-size
|
|
102
|
+
);
|
|
96
103
|
border-style: solid;
|
|
97
104
|
|
|
98
105
|
/* Strict Typography Unification */
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
- Scope prefix .root to enforce Figma tokens over Mantine's inline calculation without using !important
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
/* EXEMPTIONS:
|
|
8
|
+
- The generic, non-state-specific segmented-control-item border-radius is ignored: the
|
|
9
|
+
selected/unselected state-specific border-radius tokens below already cover both states an
|
|
10
|
+
item can be in. */
|
|
11
|
+
/* recursica-ignore: --recursica_ui-kit_components_segmented-control-item_properties_item_border-radius */
|
|
12
|
+
|
|
7
13
|
.root {
|
|
8
14
|
background-color: var(
|
|
9
15
|
--recursica_ui-kit_components_segmented-control_properties_colors_background-color
|
|
@@ -56,6 +56,17 @@ recipe with a plain `Checkbox`; the only MUI product with built-in selection is
|
|
|
56
56
|
selected-row background/token state; wiring an actual checkbox column is a separate,
|
|
57
57
|
not-yet-scoped ask.
|
|
58
58
|
|
|
59
|
+
## Currency alignment on header/footer reuses the table-cell token
|
|
60
|
+
|
|
61
|
+
`--recursica_ui-kit_components_table-cell_properties_currency-style_text-align` (`right`) is the
|
|
62
|
+
only currency-style text-align token the UI Kit exports — there's no
|
|
63
|
+
`table-header_properties_currency-style_*` block at all, and the
|
|
64
|
+
`table-footer_properties_currency-style_*` block skips `text-align` specifically. `Table.module.css`
|
|
65
|
+
reuses the table-cell token for both `thead th[data-currency="true"]` and
|
|
66
|
+
`tfoot td[data-currency="true"]` so header/footer currency cells stay right-aligned in step with
|
|
67
|
+
the body. `Table.Th` gained a `variant` prop (mirroring `Table.Td`) to set `data-currency` since
|
|
68
|
+
header cells had no way to opt into this before.
|
|
69
|
+
|
|
59
70
|
## Deliberately not changed
|
|
60
71
|
|
|
61
72
|
- **No wrapper divs** — Forge wraps the table in two divs to get a scrollable bordered
|
|
@@ -218,6 +218,15 @@
|
|
|
218
218
|
);
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
/* Currency column header alignment override. No dedicated table-header currency-style token
|
|
222
|
+
exists yet, so this reuses the table-cell currency-style text-align token to match the
|
|
223
|
+
currency value cells below it. */
|
|
224
|
+
.root thead th[data-currency="true"] {
|
|
225
|
+
text-align: var(
|
|
226
|
+
--recursica_ui-kit_components_table-cell_properties_currency-style_text-align
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
221
230
|
/* Header sort icon & gap spacing helper */
|
|
222
231
|
.root thead th .sortIcon {
|
|
223
232
|
width: var(--recursica_ui-kit_components_table-header_properties_icon-size);
|
|
@@ -407,6 +416,11 @@
|
|
|
407
416
|
line-height: var(
|
|
408
417
|
--recursica_ui-kit_components_table-footer_properties_currency-style_line-height
|
|
409
418
|
);
|
|
419
|
+
/* No table-footer currency-style text-align token exists yet; reuse the table-cell one so
|
|
420
|
+
footer currency cells match the body's right alignment. */
|
|
421
|
+
text-align: var(
|
|
422
|
+
--recursica_ui-kit_components_table-cell_properties_currency-style_text-align
|
|
423
|
+
);
|
|
410
424
|
text-decoration: var(
|
|
411
425
|
--recursica_ui-kit_components_table-footer_properties_currency-style_text-decoration
|
|
412
426
|
);
|
|
@@ -114,7 +114,14 @@ export type TableThProps = RecursicaOverStyled<
|
|
|
114
114
|
|
|
115
115
|
export const TableTh = forwardRef<HTMLTableCellElement, TableThProps>(
|
|
116
116
|
function TableTh(
|
|
117
|
-
{
|
|
117
|
+
{
|
|
118
|
+
overStyled = false,
|
|
119
|
+
sorted = false,
|
|
120
|
+
disabled = false,
|
|
121
|
+
variant = "default",
|
|
122
|
+
children,
|
|
123
|
+
...rest
|
|
124
|
+
},
|
|
118
125
|
ref,
|
|
119
126
|
) {
|
|
120
127
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
@@ -124,6 +131,7 @@ export const TableTh = forwardRef<HTMLTableCellElement, TableThProps>(
|
|
|
124
131
|
{...(sanitizedProps as unknown as MantineTableThProps)}
|
|
125
132
|
data-sorted={sorted ? "true" : undefined}
|
|
126
133
|
data-disabled={disabled ? "true" : undefined}
|
|
134
|
+
data-currency={variant === "currency" ? "true" : undefined}
|
|
127
135
|
aria-sort={
|
|
128
136
|
sorted === "asc"
|
|
129
137
|
? "ascending"
|
|
@@ -43,7 +43,7 @@ export default function Demo() {
|
|
|
43
43
|
## 3. Row and Cell States
|
|
44
44
|
|
|
45
45
|
- **`Table.Tr`**: `selected` applies the selected-row background; `disabled` dims the row and applies the disabled cell colors to every cell in it.
|
|
46
|
-
- **`Table.Th`**: `sorted="asc" | "desc"` applies the sorted header style and renders the matching chevron icon; omit it (or pass `false`) for the unsorted style. `disabled` dims the header cell.
|
|
46
|
+
- **`Table.Th`**: `sorted="asc" | "desc"` applies the sorted header style and renders the matching chevron icon; omit it (or pass `false`) for the unsorted style. `disabled` dims the header cell. `variant="currency"` right-aligns the header to match a currency column's value cells.
|
|
47
47
|
- **`Table.Td`**: `variant="currency"` applies the currency text style (for numeric/monetary columns); `disabled` dims the cell.
|
|
48
48
|
|
|
49
49
|
```tsx
|
|
@@ -51,7 +51,9 @@ export default function Demo() {
|
|
|
51
51
|
<Table.Thead>
|
|
52
52
|
<Table.Tr>
|
|
53
53
|
<Table.Th>Name</Table.Th>
|
|
54
|
-
<Table.Th sorted="asc">
|
|
54
|
+
<Table.Th sorted="asc" variant="currency">
|
|
55
|
+
Balance
|
|
56
|
+
</Table.Th>
|
|
55
57
|
</Table.Tr>
|
|
56
58
|
</Table.Thead>
|
|
57
59
|
<Table.Tbody>
|
|
@@ -35,12 +35,17 @@
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/* HARDCODED VALUES:
|
|
38
|
-
- border-width: 1px. Native geometric boundary for the input box.
|
|
39
38
|
- border-style: solid. Native structural rendering rule.
|
|
40
39
|
- outline: none. Bypassing browser focus rings to rely strictly on Recursica focus states natively.
|
|
41
40
|
- flex/layout: display: flex on the root wrapper safely encapsulating internal section rendering.
|
|
42
41
|
*/
|
|
43
42
|
|
|
43
|
+
/* EXEMPTIONS:
|
|
44
|
+
- border-size is constant across disabled/error states — only border-color changes; the
|
|
45
|
+
disabled/error border-size tokens are never applied by design. */
|
|
46
|
+
/* recursica-ignore: --recursica_ui-kit_components_textarea_variants_states_disabled_properties_border-size */
|
|
47
|
+
/* recursica-ignore: --recursica_ui-kit_components_textarea_variants_states_error_properties_border-size */
|
|
48
|
+
|
|
44
49
|
.root {
|
|
45
50
|
display: flex;
|
|
46
51
|
position: relative;
|
|
@@ -78,7 +83,9 @@
|
|
|
78
83
|
border-radius: var(
|
|
79
84
|
--recursica_ui-kit_components_textarea_properties_border-radius
|
|
80
85
|
);
|
|
81
|
-
border-width:
|
|
86
|
+
border-width: var(
|
|
87
|
+
--recursica_ui-kit_components_textarea_properties_border-size
|
|
88
|
+
);
|
|
82
89
|
border-style: solid;
|
|
83
90
|
|
|
84
91
|
/* Strict Typography Unification */
|
|
@@ -35,12 +35,17 @@
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/* HARDCODED VALUES:
|
|
38
|
-
- border-width: 1px. Native geometric boundary for the input box.
|
|
39
38
|
- border-style: solid. Native structural rendering rule.
|
|
40
39
|
- outline: none. Bypassing browser focus rings to rely strictly on Recursica focus states natively.
|
|
41
40
|
- flex/layout: display: flex on the root wrapper safely encapsulating internal section rendering.
|
|
42
41
|
*/
|
|
43
42
|
|
|
43
|
+
/* EXEMPTIONS:
|
|
44
|
+
- border-size is constant across disabled/error states — only border-color changes; the
|
|
45
|
+
disabled/error border-size tokens are never applied by design. */
|
|
46
|
+
/* recursica-ignore: --recursica_ui-kit_components_text-field_variants_states_disabled_properties_border-size */
|
|
47
|
+
/* recursica-ignore: --recursica_ui-kit_components_text-field_variants_states_error_properties_border-size */
|
|
48
|
+
|
|
44
49
|
.root {
|
|
45
50
|
display: flex;
|
|
46
51
|
position: relative;
|
|
@@ -91,7 +96,9 @@
|
|
|
91
96
|
border-radius: var(
|
|
92
97
|
--recursica_ui-kit_components_text-field_properties_border-radius
|
|
93
98
|
);
|
|
94
|
-
border-width:
|
|
99
|
+
border-width: var(
|
|
100
|
+
--recursica_ui-kit_components_text-field_properties_border-size
|
|
101
|
+
);
|
|
95
102
|
border-style: solid;
|
|
96
103
|
|
|
97
104
|
/* Strict Typography Unification */
|
|
@@ -36,7 +36,7 @@ Because the AM/PM behavior is fixed, several of Mantine's `TimePicker` props are
|
|
|
36
36
|
## Design tokens
|
|
37
37
|
|
|
38
38
|
- No dedicated `min-height` token exists for `time-picker` (unlike `text-field`/`date-picker`) — `.fieldsGroup`'s explicit `height` is derived from `text_line-height` instead, which also fixes a real bug: Mantine's own field CSS sets `height: 100%` on every field to fill `.fieldsGroup`, and a percentage height only resolves against a _concrete_ parent height. Before this, `.fieldsGroup` was auto-height (padding only), so `100%` resolved to `0` — this is why the AM/PM control was invisible in early builds (verified via real headless-browser inspection, not just markup checks — a raw server-render test had missed this entirely since it doesn't compute layout).
|
|
39
|
-
- `icon-size`/`icon-color`/`icon-text-gap`/`placeholder-opacity`
|
|
39
|
+
- `icon-size`/`icon-color`/`icon-text-gap`/`placeholder-opacity` (plus the disabled/error `icon-color` variants) are wired via `leftSection` — see "Leading icon" below. Not exempted: despite an earlier note here claiming otherwise, `SpinInput` (`@mantine/dates`) renders a real `<input placeholder="--">` per hour/minute/second segment, so `::placeholder` targets it like any other input.
|
|
40
40
|
- The AM/PM `BareDropdown` draws its own border/background/padding from `Dropdown`'s own tokens via `Dropdown.module.css` — it does not reuse any `time-picker` tokens.
|
|
41
41
|
|
|
42
42
|
## Read-Only Implementation
|
|
@@ -76,6 +76,12 @@ The MUI adapter's equivalent (`mui-adapter/src/components/TimePicker/TimePicker.
|
|
|
76
76
|
|
|
77
77
|
Note: selecting AM/PM before any hour is typed is still a no-op in both adapters (`handleMeridiemChange` bails out when `hour`/`internalValue` is undefined) — that's pre-existing, shared behavior in both adapters, not something this fix touches.
|
|
78
78
|
|
|
79
|
+
## Leading icon (Matt Massey, 2026-08-30)
|
|
80
|
+
|
|
81
|
+
Added `leftSection` (`RecursicaTimePickerProps`), matching `TextField`/`AutoComplete`'s naming and convention: purely decorative, consumer-supplied, no default. Unlike `DatePicker`'s fixed `CalendarIcon`, there's no single icon that makes sense for every `TimePicker` use, so this is opt-in only.
|
|
82
|
+
|
|
83
|
+
Mantine's `TimePicker` already accepts `leftSection` (inherited from `@mantine/core`'s `__InputProps` via `InputBase`, which it renders through internally with `component: "div"` — confirmed by reading `TimePicker.mjs`/`Input.mjs` directly) — it was already passing through unstyled before this change (not blocked by `filterStylingProps`), just never mapped to a `classNames.section`/CSS, so an icon would render with no size or color. Added `section: styles.section` to the `classNames` map and the token-driven `.section`/`.section svg` rules (icon-size, icon-color, disabled/error icon-color) to actually style it.
|
|
84
|
+
|
|
79
85
|
## Visual review round 5 (Matt Massey, 2026-08-08)
|
|
80
86
|
|
|
81
87
|
- **AM/PM error-state border wasn't changing**: `BareDropdown` set `data-error`/`data-disabled` via Mantine's `wrapperProps` — which targets the _outer_ `Input.Wrapper` (the label/description/error stacking element), a different, ancestor element from the "wrapper" styles-api slot that actually carries `styles.root`'s border. `Dropdown.module.css`'s `.root[data-error]`/`[data-disabled]` rules never matched as a result. This is the exact same "two different things both called 'wrapper'" trap as the earlier `style` vs `styles.wrapper` bug. Fixed by using `attributes={{ wrapper: {...} }}` instead — the styles-api hook that actually targets the same slot as `classNames.wrapper`. **This is a shared, pre-existing bug** — the real `Dropdown.tsx` had the identical mistake, so its error/disabled states never applied a border color either; fixed there too (low-risk, purely-additive, same reasoning as the `data-selected` fix above).
|
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
/* EXEMPTIONS:
|
|
10
|
+
- border-size is constant across disabled/error states — only border-color changes; the
|
|
11
|
+
disabled/error border-size tokens are never applied by design. */
|
|
12
|
+
/* recursica-ignore: --recursica_ui-kit_components_time-picker_variants_states_disabled_properties_border-size */
|
|
13
|
+
/* recursica-ignore: --recursica_ui-kit_components_time-picker_variants_states_error_properties_border-size */
|
|
14
|
+
|
|
9
15
|
/* LAYOUT SPACING OVERRIDES:
|
|
10
16
|
- Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens. */
|
|
11
17
|
.layoutOverride {
|
|
@@ -45,6 +51,9 @@
|
|
|
45
51
|
.timeWrapper {
|
|
46
52
|
display: flex;
|
|
47
53
|
align-items: center;
|
|
54
|
+
/* Gap between the leading-icon section (when leftSection is passed) and the field itself — a
|
|
55
|
+
no-op with no icon, since gap has no effect between fewer than two flex children. */
|
|
56
|
+
gap: var(--recursica_ui-kit_components_time-picker_properties_icon-text-gap);
|
|
48
57
|
position: relative;
|
|
49
58
|
box-sizing: border-box;
|
|
50
59
|
/* min-width, not width: the `width` token was authored for a single plain input (confirmed against
|
|
@@ -117,6 +126,29 @@
|
|
|
117
126
|
);
|
|
118
127
|
}
|
|
119
128
|
|
|
129
|
+
/* Leading icon (leftSection). Only one icon-color token exists for time-picker (unlike
|
|
130
|
+
text-field's separate leading/trailing) — this field has no right-side icon slot. */
|
|
131
|
+
.section {
|
|
132
|
+
display: flex;
|
|
133
|
+
align-items: center;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.section :global(svg) {
|
|
137
|
+
width: var(--recursica_ui-kit_components_time-picker_properties_icon-size);
|
|
138
|
+
height: var(--recursica_ui-kit_components_time-picker_properties_icon-size);
|
|
139
|
+
color: var(
|
|
140
|
+
--recursica_ui-kit_components_time-picker_properties_colors_icon-color
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* SpinInput renders a real <input placeholder="--">, one per hour/minute/second segment. */
|
|
145
|
+
.timeField::placeholder {
|
|
146
|
+
opacity: var(
|
|
147
|
+
--recursica_ui-kit_components_time-picker_properties_placeholder-opacity
|
|
148
|
+
);
|
|
149
|
+
color: inherit;
|
|
150
|
+
}
|
|
151
|
+
|
|
120
152
|
.timeField {
|
|
121
153
|
font-family: var(
|
|
122
154
|
--recursica_ui-kit_components_time-picker_properties_text_font-family
|
|
@@ -202,6 +234,12 @@
|
|
|
202
234
|
) !important;
|
|
203
235
|
}
|
|
204
236
|
|
|
237
|
+
.root[data-error="true"] .section :global(svg) {
|
|
238
|
+
color: var(
|
|
239
|
+
--recursica_ui-kit_components_time-picker_variants_states_error_properties_colors_icon-color
|
|
240
|
+
) !important;
|
|
241
|
+
}
|
|
242
|
+
|
|
205
243
|
/* Disabled State Mapping (Propagated strictly down from the wrapper DOM context) */
|
|
206
244
|
.root[data-disabled="true"] .timeWrapper {
|
|
207
245
|
border-color: var(
|
|
@@ -218,3 +256,9 @@
|
|
|
218
256
|
) !important;
|
|
219
257
|
cursor: not-allowed;
|
|
220
258
|
}
|
|
259
|
+
|
|
260
|
+
.root[data-disabled="true"] .section :global(svg) {
|
|
261
|
+
color: var(
|
|
262
|
+
--recursica_ui-kit_components_time-picker_variants_states_disabled_properties_colors_icon-color
|
|
263
|
+
) !important;
|
|
264
|
+
}
|
|
@@ -101,6 +101,28 @@ export const ErrorState: Story = {
|
|
|
101
101
|
},
|
|
102
102
|
};
|
|
103
103
|
|
|
104
|
+
export const WithLeadingIcon: Story = {
|
|
105
|
+
args: {
|
|
106
|
+
label: "Meeting Time",
|
|
107
|
+
assistiveText: "Choose the start time in your local timezone.",
|
|
108
|
+
leftSection: (
|
|
109
|
+
<svg
|
|
110
|
+
width="24"
|
|
111
|
+
height="24"
|
|
112
|
+
viewBox="0 0 24 24"
|
|
113
|
+
fill="none"
|
|
114
|
+
stroke="currentColor"
|
|
115
|
+
strokeWidth="2"
|
|
116
|
+
strokeLinecap="round"
|
|
117
|
+
strokeLinejoin="round"
|
|
118
|
+
>
|
|
119
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
120
|
+
<polyline points="12 6 12 12 16 14"></polyline>
|
|
121
|
+
</svg>
|
|
122
|
+
),
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
|
|
104
126
|
export const StaticReadOnly: Story = {
|
|
105
127
|
args: {
|
|
106
128
|
label: "Static ReadOnly Review",
|
|
@@ -43,6 +43,11 @@
|
|
|
43
43
|
--recursica_ui-kit_components_timeline-bullet_variants_types_default_properties_bullet-size
|
|
44
44
|
) !important;
|
|
45
45
|
}
|
|
46
|
+
/* EXEMPTIONS:
|
|
47
|
+
- The avatar variant's own avatar-size token is ignored — sizing is deliberately pinned to
|
|
48
|
+
the default bullet-size above (not the avatar's own size) to keep the connector line
|
|
49
|
+
aligned across bullet variants; the child Avatar component governs its own visual size. */
|
|
50
|
+
/* recursica-ignore: --recursica_ui-kit_components_timeline-bullet_variants_types_avatar_properties_avatar-size */
|
|
46
51
|
|
|
47
52
|
/* Control connector lines via the item ::before pseudo-element */
|
|
48
53
|
/* Inactive connector */
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
- border-style: solid. Baseline so the per-variant border-color tokens actually render.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
/* EXEMPTIONS:
|
|
6
|
+
- elevation_layer-1/2/3 are ignored: a toast's elevation doesn't depend on the layer it's
|
|
7
|
+
summoned from — all four layer variants resolve to the same brand elevation value, so
|
|
8
|
+
layer-0 (already wired below) is the correct, layer-agnostic choice for all of them. */
|
|
9
|
+
/* recursica-ignore: --recursica_ui-kit_components_toast_properties_elevation_layer-1 */
|
|
10
|
+
/* recursica-ignore: --recursica_ui-kit_components_toast_properties_elevation_layer-2 */
|
|
11
|
+
/* recursica-ignore: --recursica_ui-kit_components_toast_properties_elevation_layer-3 */
|
|
12
|
+
|
|
5
13
|
/* ======================================
|
|
6
14
|
TOAST / NOTIFICATION ROOT
|
|
7
15
|
====================================== */
|
|
@@ -3,11 +3,19 @@
|
|
|
3
3
|
which may not set border-style natively). Same pattern as Menu / HoverCard.
|
|
4
4
|
- arrowSize defaults to 16 in Tooltip.tsx. Mantine uses arrowSize for inline width/height
|
|
5
5
|
and positioning (-arrowSize/2) calculations that cannot be CSS-driven. The default matches
|
|
6
|
-
the Recursica beak-size token (16px).
|
|
6
|
+
the Recursica beak-size token (16px).
|
|
7
|
+
- arrow inset/offset is Mantine's own default (no arrowOffset override) — same "must be a JS
|
|
8
|
+
prop, not CSS-driven" constraint as arrowSize.
|
|
7
9
|
- All structural layout (display, position, overflow) is deferred to Mantine's native
|
|
8
10
|
behavior. We only override visual design tokens (colors, typography, spacing, borders).
|
|
9
11
|
*/
|
|
10
12
|
|
|
13
|
+
/* EXEMPTIONS:
|
|
14
|
+
- beak-size/beak-inset are ignored: the arrow's size and position are Mantine's own
|
|
15
|
+
`arrowSize`/`arrowOffset` JS props, not CSS-driven — see HARDCODED VALUES above. */
|
|
16
|
+
/* recursica-ignore: --recursica_ui-kit_components_tooltip_properties_beak-size */
|
|
17
|
+
/* recursica-ignore: --recursica_ui-kit_components_tooltip_properties_beak-inset */
|
|
18
|
+
|
|
11
19
|
/* ======================================
|
|
12
20
|
TOOLTIP CONTAINER
|
|
13
21
|
====================================== */
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
- `properties_title-filter-gap` sits between each pane's header row and its search field.
|
|
5
5
|
- `properties_filter-items-gap` sits between each pane's search field and its item list. */
|
|
6
6
|
|
|
7
|
+
/* EXEMPTIONS:
|
|
8
|
+
- border-size is constant across disabled/error states — only border-color changes; the
|
|
9
|
+
disabled/error border-size tokens are never applied by design. */
|
|
10
|
+
/* recursica-ignore: --recursica_ui-kit_components_transfer-list_variants_states_disabled_properties_border-size */
|
|
11
|
+
/* recursica-ignore: --recursica_ui-kit_components_transfer-list_variants_states_error_properties_border-size */
|
|
12
|
+
|
|
7
13
|
.layoutOverride {
|
|
8
14
|
--form-control-margin-bottom: var(
|
|
9
15
|
--recursica_ui-kit_components_transfer-list_variants_layouts_stacked_properties_top-bottom-margin
|
|
@@ -41,7 +47,9 @@
|
|
|
41
47
|
var(
|
|
42
48
|
--recursica_ui-kit_components_transfer-list_properties_horizontal-padding
|
|
43
49
|
);
|
|
44
|
-
border-width:
|
|
50
|
+
border-width: var(
|
|
51
|
+
--recursica_ui-kit_components_transfer-list_properties_border-size
|
|
52
|
+
);
|
|
45
53
|
border-style: solid;
|
|
46
54
|
border-radius: var(
|
|
47
55
|
--recursica_ui-kit_components_transfer-list_properties_border-radius
|