@recursica/mantine-adapter 0.47.0 → 0.48.1
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 +9 -4
- 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 +1633 -1559
- package/dist/mantine-adapter.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Accordion/Accordion.module.css +11 -0
- package/src/components/AutoComplete/AutoComplete.module.css +10 -0
- package/src/components/Button/Button.module.css +10 -0
- package/src/components/Card/Card.stories.tsx +2 -4
- package/src/components/Chip/Chip.module.css +9 -0
- package/src/components/DatePicker/DatePicker.module.css +16 -0
- package/src/components/Dropdown/Dropdown.module.css +10 -0
- package/src/components/FileInput/FILEINPUT_IMPLEMENTATION_NOTES.md +4 -1
- package/src/components/FileInput/FileInput.module.css +17 -0
- package/src/components/FileUpload/FileUpload.module.css +6 -0
- package/src/components/Link/Link.module.css +5 -0
- package/src/components/Menu/Menu.module.css +6 -0
- package/src/components/NumberInput/NumberInput.module.css +8 -0
- package/src/components/Pagination/Pagination.module.css +7 -0
- package/src/components/Slider/IMPLEMENTATION_NOTES.md +22 -2
- package/src/components/Slider/Slider.module.css +36 -2
- package/src/components/Slider/Slider.stories.tsx +65 -0
- package/src/components/Slider/Slider.tsx +149 -42
- package/src/components/Slider/USAGE.md +15 -1
- package/src/components/Switch/Switch.module.css +8 -0
- package/src/components/Table/Table.module.css +6 -0
- package/src/components/Tabs/Tabs.module.css +7 -0
- package/src/components/TextArea/TextArea.module.css +8 -0
- package/src/components/TextField/TextField.module.css +8 -0
- package/src/components/TimePicker/TimePicker.module.css +8 -0
- package/src/components/Tree/IMPLEMENTATION_NOTES.md +3 -0
- package/src/components/Tree/Tree.module.css +11 -0
- package/src/components/Tree/Tree.tsx +11 -6
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"url": "git+https://github.com/borderux/recursica.git",
|
|
14
14
|
"directory": "packages/mantine-adapter"
|
|
15
15
|
},
|
|
16
|
-
"version": "0.
|
|
16
|
+
"version": "0.48.1",
|
|
17
17
|
"type": "module",
|
|
18
18
|
"main": "./dist/mantine-adapter.cjs",
|
|
19
19
|
"module": "./dist/mantine-adapter.js",
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"vitest": "^3.2.4"
|
|
95
95
|
},
|
|
96
96
|
"dependencies": {
|
|
97
|
-
"@recursica/adapter-common": "^0.
|
|
97
|
+
"@recursica/adapter-common": "^0.23.0",
|
|
98
98
|
"@recursica/official-release": "^2.8.0"
|
|
99
99
|
},
|
|
100
100
|
"peerDependencies": {
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_disabled
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_focus_blur
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_focus_border-size
|
|
6
|
+
* recursica-allow-brand: --recursica_brand_states_focus_color
|
|
7
|
+
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
8
|
+
* recursica-allow-brand: --recursica_brand_states_hover_color
|
|
9
|
+
* recursica-allow-brand: --recursica_brand_states_hover_opacity
|
|
10
|
+
*/
|
|
11
|
+
|
|
1
12
|
/* ==== ACCORDION CONTAINER ==== */
|
|
2
13
|
.root {
|
|
3
14
|
box-sizing: border-box;
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_focus_blur
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_focus_border-size
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_focus_color
|
|
6
|
+
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
7
|
+
* recursica-allow-brand: --recursica_brand_states_hover_color
|
|
8
|
+
* recursica-allow-brand: --recursica_brand_states_hover_opacity
|
|
9
|
+
*/
|
|
10
|
+
|
|
1
11
|
/* LAYOUT SPACING OVERRIDES:
|
|
2
12
|
- Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens.
|
|
3
13
|
- Also sets the --autocomplete-control-{max,min}-width hooks consumed inline in AutoComplete.tsx,
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_focus_blur
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_focus_border-size
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_focus_color
|
|
6
|
+
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
7
|
+
* recursica-allow-brand: --recursica_brand_states_hover_color
|
|
8
|
+
* recursica-allow-brand: --recursica_brand_states_hover_opacity
|
|
9
|
+
*/
|
|
10
|
+
|
|
1
11
|
/**
|
|
2
12
|
* IMPLEMENTATION NOTES:
|
|
3
13
|
*
|
|
@@ -37,8 +37,7 @@ export const Default: Story = {
|
|
|
37
37
|
<div
|
|
38
38
|
style={{
|
|
39
39
|
padding: "48px",
|
|
40
|
-
backgroundColor:
|
|
41
|
-
"var(--recursica_brand_palettes_neutral_050_color_tone)",
|
|
40
|
+
backgroundColor: "#e9ecef",
|
|
42
41
|
}}
|
|
43
42
|
>
|
|
44
43
|
<Layer layer={0}>
|
|
@@ -73,8 +72,7 @@ export const HeaderlessAndFooterless: Story = {
|
|
|
73
72
|
<div
|
|
74
73
|
style={{
|
|
75
74
|
padding: "48px",
|
|
76
|
-
backgroundColor:
|
|
77
|
-
"var(--recursica_brand_palettes_neutral_050_color_tone)",
|
|
75
|
+
backgroundColor: "#e9ecef",
|
|
78
76
|
}}
|
|
79
77
|
>
|
|
80
78
|
<Layer layer={0}>
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_disabled
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_focus_blur
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_focus_border-size
|
|
6
|
+
* recursica-allow-brand: --recursica_brand_states_focus_color
|
|
7
|
+
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
/* HARDCODED VALUES
|
|
2
11
|
border-style: solid; (Baseline reset)
|
|
3
12
|
box-sizing: border-box; (Baseline reset)
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* No ui-kit_components_date-picker radius token exists for the calendar day cells; reuses the brand default border-radius.
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_dimensions_border-radii_default
|
|
4
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_disabled
|
|
6
|
+
* recursica-allow-brand: --recursica_brand_states_focus_blur
|
|
7
|
+
* recursica-allow-brand: --recursica_brand_states_focus_border-size
|
|
8
|
+
* recursica-allow-brand: --recursica_brand_states_focus_color
|
|
9
|
+
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
10
|
+
* recursica-allow-brand: --recursica_brand_states_hover_color
|
|
11
|
+
* recursica-allow-brand: --recursica_brand_states_hover_opacity
|
|
12
|
+
* No ui-kit_components_date-picker in-range token exists; the generic overlay tint fills the range-selection band (see inline comment above .day[data-in-range]).
|
|
13
|
+
* recursica-allow-brand: --recursica_brand_states_overlay_color
|
|
14
|
+
* recursica-allow-brand: --recursica_brand_states_overlay_opacity
|
|
15
|
+
*/
|
|
16
|
+
|
|
1
17
|
/* LAYOUT SPACING OVERRIDES:
|
|
2
18
|
- Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens. */
|
|
3
19
|
.layoutOverride {
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_focus_blur
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_focus_border-size
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_focus_color
|
|
6
|
+
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
7
|
+
* recursica-allow-brand: --recursica_brand_states_hover_color
|
|
8
|
+
* recursica-allow-brand: --recursica_brand_states_hover_opacity
|
|
9
|
+
*/
|
|
10
|
+
|
|
1
11
|
/* LAYOUT SPACING OVERRIDES:
|
|
2
12
|
- Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens.
|
|
3
13
|
- Also sets the --dropdown-control-{max,min}-width hooks consumed inline in Dropdown.tsx, since
|
|
@@ -136,7 +136,10 @@ roving group, _then_ the trailing clear button as its own stop.
|
|
|
136
136
|
wraps onto multiple lines below the dropzone — `FileInput` is a fixed single-line, `min-height`d
|
|
137
137
|
control, so wrapping would grow it vertically. Enough chips to overflow the control's own width
|
|
138
138
|
scroll horizontally within it instead (mouse wheel/trackpad or a native scrollbar), same tradeoff
|
|
139
|
-
already made for `.value`'s ellipsis truncation.
|
|
139
|
+
already made for `.value`'s ellipsis truncation. The native scrollbar itself is hidden
|
|
140
|
+
(`scrollbar-width: none`, `-ms-overflow-style: none`, `::-webkit-scrollbar { display: none }`) —
|
|
141
|
+
the control's `min-height` isn't tall enough to host a visible horizontal scrollbar without
|
|
142
|
+
clipping the chips, and scrolling (wheel/trackpad/drag) still works with it hidden.
|
|
140
143
|
|
|
141
144
|
## Read-only vs disabled
|
|
142
145
|
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_focus_blur
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_focus_border-size
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_focus_color
|
|
6
|
+
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
7
|
+
* recursica-allow-brand: --recursica_brand_states_hover_color
|
|
8
|
+
* recursica-allow-brand: --recursica_brand_states_hover_opacity
|
|
9
|
+
*/
|
|
10
|
+
|
|
1
11
|
/* LAYOUT SPACING OVERRIDES:
|
|
2
12
|
- Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens.
|
|
3
13
|
- Also sets the --file-input-control-{max,min}-width hooks consumed inline in FileInput.tsx,
|
|
@@ -178,6 +188,13 @@
|
|
|
178
188
|
overflow-x: auto;
|
|
179
189
|
overflow-y: hidden;
|
|
180
190
|
gap: var(--recursica_ui-kit_components_file-input_properties_icon-text-gap);
|
|
191
|
+
/* HARDCODE: scrollbar stays functional (still scrolls via wheel/trackpad/drag) but hidden —
|
|
192
|
+
the control isn't tall enough to host a visible scrollbar without clipping the chips. */
|
|
193
|
+
scrollbar-width: none; /* Firefox */
|
|
194
|
+
-ms-overflow-style: none; /* legacy Edge */
|
|
195
|
+
}
|
|
196
|
+
.chipRow::-webkit-scrollbar {
|
|
197
|
+
display: none; /* Chrome, Safari */
|
|
181
198
|
}
|
|
182
199
|
|
|
183
200
|
.chipWrapper {
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_hover_color
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_hover_opacity
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
/* HARDCODED VALUES:
|
|
2
8
|
- .root: display: flex; flex-direction: column; width: 100% — structural layout, not a design
|
|
3
9
|
token concern (matches how other block-level components like Layer are laid out).
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Only source for link hover-underline; no per-component token exists (see IMPLEMENTATION_NOTES.md).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_link_decoration
|
|
4
|
+
*/
|
|
5
|
+
|
|
1
6
|
/*
|
|
2
7
|
HARDCODED VALUES:
|
|
3
8
|
- display: inline-flex; (Base layout to align icon and text correctly)
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_hover_color
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_hover_opacity
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
/* HARDCODED VALUES:
|
|
2
8
|
- border-style: solid. Structural rendering rule for the dropdown border (Mantine uses Paper which may not set border natively).
|
|
3
9
|
- NOTE: overflow is intentionally NOT set on .dropdown. Mantine renders sub-menu dropdowns
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_focus_blur
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_focus_border-size
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_focus_color
|
|
6
|
+
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
/* LAYOUT SPACING OVERRIDES:
|
|
2
10
|
- Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens.
|
|
3
11
|
- Also sets the --number-input-control-{max,min}-width hooks consumed inline in NumberInput.tsx,
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_disabled
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_hover_color
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_hover_opacity
|
|
6
|
+
*/
|
|
7
|
+
|
|
1
8
|
.root {
|
|
2
9
|
display: flex;
|
|
3
10
|
align-items: center;
|
|
@@ -67,6 +67,26 @@ This document contains specific design decisions, architectural constraints, and
|
|
|
67
67
|
- `minLabel`/`maxLabel` (new `adapter-common` props) override the `.minMaxGuide` text at either end of the track, falling back to the numeric `min`/`max`.
|
|
68
68
|
- `trailingIcon` (new `adapter-common` prop) renders a second icon on the opposite side of the track from the existing `icon`, reusing the same `.iconWrapper` styling (disabled/error/focus states already target `.iconWrapper` generically, so no new CSS was needed).
|
|
69
69
|
|
|
70
|
-
## 8.
|
|
70
|
+
## 8. Dual-Thumb / Range Support
|
|
71
71
|
|
|
72
|
-
**Decision:**
|
|
72
|
+
**Decision:** Previously requested and declined (see git history for this section) as no use case needed it; reopened with a full spec and implemented. `value`/`defaultValue`/`onChange`/`onChangeEnd` are now typed `number | [number, number]` in `@recursica/adapter-common`'s `RecursicaSliderProps`.
|
|
73
|
+
**Implementation:**
|
|
74
|
+
|
|
75
|
+
- `isRange = Array.isArray(resolvedValue)` picks which underlying Mantine component to render: single-thumb `Slider` (unchanged) or two-thumb `RangeSlider` — Mantine ships these as two separate components (unlike raw MUI, which renders two thumbs off a single `Slider` given a tuple `value`), so this is a real component swap, not just a type/prop change. Both share the same `SliderStylesNames` shape, so `mergedClassNames` (root/track/bar/thumb/mark/markLabel) applies unchanged to either.
|
|
76
|
+
- Internal state (`internalValue`, `resolvedValue`, `inputValue`) generalized from `number` to `number | [number, number]`; range-mode input handlers (`handleLowerInputChange`/`handleUpperInputChange`) clamp each thumb against the other's current value (not the shared `min`/`max`) so the two inputs can't cross.
|
|
77
|
+
- `SliderReadOnlyValue` and the floating `.currentValue` display both render `"lower – upper"` for a range value, running each side through `tooltipLabel` independently when it's a formatter.
|
|
78
|
+
- DOM order in range mode (input → leading icon → min label → track → max label → trailing icon → input) mirrors Forge's own Material/Carbon range layouts — see §9 below.
|
|
79
|
+
- Not carried over: Mantine `RangeSlider`'s own `minRange`/`maxRange`/`pushOnOverlap`/`thumbFromLabel`/`thumbToLabel` pass through via the existing unsanitized `...rest` spread if a caller sets them directly; no adapter-level default is applied (e.g. Mantine's own `minRange` default of `10` is left as-is).
|
|
80
|
+
|
|
81
|
+
## 9. Trailing Icon Order Relative to the Input Field
|
|
82
|
+
|
|
83
|
+
**Decision:** `trailingIcon` previously rendered after the numeric input (`... max label, input, trailing icon`), reversed from Forge's Material/Carbon kits, which always render the trailing icon directly after the max label and before the input.
|
|
84
|
+
**Implementation:** Moved `{trailingIconEl}` before the `showInput` input block in the single-value layout; the range layout was built with this order from the start (input → icon → min label → track → max label → trailing icon → input).
|
|
85
|
+
|
|
86
|
+
## 10. Marks Rendering Off Mantine Defaults Instead of Recursica Tokens
|
|
87
|
+
|
|
88
|
+
**Decision:** §3 claimed marks were "fully styles-mapped back to our scoped variables" — not quite true. Mantine's `markWrapper` style slot (the zero-height, top-anchored positioning wrapper around each mark dot + label) was never mapped in `mergedClassNames`, and `markLabel`'s vertical position was never overridden, so both stayed on raw Mantine defaults.
|
|
89
|
+
**Implementation:**
|
|
90
|
+
|
|
91
|
+
- `markWrapper` is anchored to Mantine's own `top: 0` (the track's top edge), with the mark dot inside it unpositioned. Mantine's own dot has no size override so it happens to fill the track height exactly by default; our `step-indicator-width` token is independent of track height, so the dot rendered small and flush to the top instead of centered. Added `markWrapper: styles.sliderMarkWrapper` to `mergedClassNames`, with `.sliderMarkWrapper { top: 50%; }`, and changed `.sliderMark`'s transform from `translateX(-50%)` to `translate(-50%, -50%)` to center the dot on that midpoint.
|
|
92
|
+
- `.sliderMarkLabel` never overrode `transform`, so its vertical offset stayed Mantine's own `calc(var(--mantine-spacing-xs) / 2)` — an unbound theme default, not a recursica token. Replaced the vertical term with `--recursica_ui-kit_globals_form_properties_label-field-gap-vertical` (the same token the mui-adapter's markLabel already uses), keeping the horizontal term (`-50% + var(--slider-size) / 2`, Mantine's own mark-offset compensation) unchanged.
|
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_focus_blur
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_focus_border-size
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_focus_color
|
|
6
|
+
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
/*
|
|
2
10
|
* HARDCODED VALUES:
|
|
3
11
|
* - display: flex; align-items: center; width: 100%; (Standard CSS flexbox layouts for bidirectional components)
|
|
4
12
|
* - flex-grow: 1; flex-shrink: 0; (Layout control structures)
|
|
5
|
-
* - transform:
|
|
13
|
+
* - transform: translate(-50%, -50%); (custom step-mark centering offset — see .sliderMarkWrapper
|
|
14
|
+
* / .sliderMark below; not inherited from Mantine, which centers marks via its own
|
|
15
|
+
* --slider-size variable that our step-indicator-width token doesn't participate in)
|
|
16
|
+
* - top: 50%; on .sliderMarkWrapper (re-anchors Mantine's zero-height mark wrapper to the
|
|
17
|
+
* track's vertical midpoint instead of its top edge)
|
|
6
18
|
* - outline: none; border-style: solid; (Standard focus reset and border outlines)
|
|
7
19
|
* - Focus ring on thumb/icon/input: the token schema no longer provides per-component focus
|
|
8
20
|
* colors for these (only `active` covers track/step-indicator-color). We apply the generic
|
|
@@ -109,6 +121,18 @@
|
|
|
109
121
|
var(--recursica_brand_states_focus_color);
|
|
110
122
|
}
|
|
111
123
|
|
|
124
|
+
/*
|
|
125
|
+
* Mantine positions the mark dot inside a zero-height `markWrapper` anchored to the track's
|
|
126
|
+
* top edge, relying on the dot's height matching Mantine's own `--slider-size` to land centered.
|
|
127
|
+
* Our step-indicator-width token is independent of that, so without an explicit vertical
|
|
128
|
+
* transform the dot sits flush to the track's top instead of centered. `sliderMarkWrapper`
|
|
129
|
+
* moves the anchor to the track's vertical midpoint; `translate(-50%, -50%)` below centers the
|
|
130
|
+
* dot on that midpoint (in addition to the pre-existing horizontal centering).
|
|
131
|
+
*/
|
|
132
|
+
.sliderMarkWrapper {
|
|
133
|
+
top: 50%;
|
|
134
|
+
}
|
|
135
|
+
|
|
112
136
|
.sliderMark {
|
|
113
137
|
box-sizing: border-box;
|
|
114
138
|
width: var(
|
|
@@ -123,7 +147,7 @@
|
|
|
123
147
|
background-color: var(
|
|
124
148
|
--recursica_ui-kit_components_slider_properties_colors_step-indicator-color
|
|
125
149
|
);
|
|
126
|
-
transform:
|
|
150
|
+
transform: translate(-50%, -50%);
|
|
127
151
|
border: none;
|
|
128
152
|
}
|
|
129
153
|
|
|
@@ -139,8 +163,18 @@
|
|
|
139
163
|
* Mantine's default markLabel has no dedicated recursica token; it renders with Mantine's own
|
|
140
164
|
* theme grey instead of inheriting the container text color. Reusing the min-max-label
|
|
141
165
|
* typography tokens and inheriting color keeps this visually consistent with the min/max guides.
|
|
166
|
+
*
|
|
167
|
+
* The vertical gap between mark and label is also Mantine's own default (half of
|
|
168
|
+
* --mantine-spacing-xs, unbound to any recursica token) unless overridden here. The transform's
|
|
169
|
+
* horizontal term (`-50% + var(--slider-size) / 2`) is Mantine's own mark-offset compensation
|
|
170
|
+
* and is left untouched; only the vertical term is replaced with the same label-field gap token
|
|
171
|
+
* the mui-adapter's markLabel already uses, for cross-adapter consistency.
|
|
142
172
|
*/
|
|
143
173
|
.sliderMarkLabel {
|
|
174
|
+
transform: translate(
|
|
175
|
+
calc(-50% + var(--slider-size) / 2),
|
|
176
|
+
var(--recursica_ui-kit_globals_form_properties_label-field-gap-vertical)
|
|
177
|
+
);
|
|
144
178
|
color: inherit;
|
|
145
179
|
|
|
146
180
|
font-family: var(
|
|
@@ -190,6 +190,71 @@ export const WithIconsAndLabels: Story = {
|
|
|
190
190
|
},
|
|
191
191
|
};
|
|
192
192
|
|
|
193
|
+
export const RangeMode: Story = {
|
|
194
|
+
args: {
|
|
195
|
+
label: "Price Range",
|
|
196
|
+
assistiveText: "Pass a [number, number] tuple to render two thumbs.",
|
|
197
|
+
defaultValue: [20, 80],
|
|
198
|
+
min: 0,
|
|
199
|
+
max: 100,
|
|
200
|
+
showMinMaxLabels: true,
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
export const RangeModeWithInputs: Story = {
|
|
205
|
+
args: {
|
|
206
|
+
...RangeMode.args,
|
|
207
|
+
showInput: true,
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
export const RangeModeWithIconsAndInputs: Story = {
|
|
212
|
+
args: {
|
|
213
|
+
label: "Price Range",
|
|
214
|
+
assistiveText:
|
|
215
|
+
"Full range usage: leading/trailing icons, min/max label overrides, and both bound inputs.",
|
|
216
|
+
defaultValue: [20, 80],
|
|
217
|
+
min: 0,
|
|
218
|
+
max: 100,
|
|
219
|
+
showInput: true,
|
|
220
|
+
minLabel: "$0",
|
|
221
|
+
maxLabel: "$100",
|
|
222
|
+
tooltipLabel: (value: number) => `$${value}`,
|
|
223
|
+
icon: (
|
|
224
|
+
<svg
|
|
225
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
226
|
+
width="16"
|
|
227
|
+
height="16"
|
|
228
|
+
viewBox="0 0 24 24"
|
|
229
|
+
fill="none"
|
|
230
|
+
stroke="currentColor"
|
|
231
|
+
strokeWidth="2"
|
|
232
|
+
strokeLinecap="round"
|
|
233
|
+
strokeLinejoin="round"
|
|
234
|
+
>
|
|
235
|
+
<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon>
|
|
236
|
+
</svg>
|
|
237
|
+
),
|
|
238
|
+
trailingIcon: (
|
|
239
|
+
<svg
|
|
240
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
241
|
+
width="16"
|
|
242
|
+
height="16"
|
|
243
|
+
viewBox="0 0 24 24"
|
|
244
|
+
fill="none"
|
|
245
|
+
stroke="currentColor"
|
|
246
|
+
strokeWidth="2"
|
|
247
|
+
strokeLinecap="round"
|
|
248
|
+
strokeLinejoin="round"
|
|
249
|
+
>
|
|
250
|
+
<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon>
|
|
251
|
+
<path d="M15.54 8.46a5 5 0 0 1 0 7.07"></path>
|
|
252
|
+
<path d="M19.07 4.93a10 10 0 0 1 0 14.14"></path>
|
|
253
|
+
</svg>
|
|
254
|
+
),
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
|
|
193
258
|
export const FormLayouts: Story = {
|
|
194
259
|
render: () => (
|
|
195
260
|
<div
|