@recursica/mantine-adapter 0.13.1 → 0.15.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.
Files changed (32) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/mantine-adapter.cjs +1 -1
  3. package/dist/mantine-adapter.cjs.map +1 -1
  4. package/dist/mantine-adapter.css +1 -1
  5. package/dist/mantine-adapter.js +1329 -1082
  6. package/dist/mantine-adapter.js.map +1 -1
  7. package/dist/src/components/HoverCard/HoverCard.d.ts +55 -3
  8. package/dist/src/components/NumberInput/NumberInput.d.ts +10 -2
  9. package/dist/src/components/Panel/Panel.d.ts +65 -3
  10. package/dist/src/components/Tooltip/Tooltip.d.ts +42 -3
  11. package/package.json +1 -1
  12. package/src/components/Card/Card.module.css +1 -0
  13. package/src/components/Card/Card.stories.tsx +48 -58
  14. package/src/components/Dropdown/Dropdown.module.css +0 -3
  15. package/src/components/HoverCard/HOVERCARD_IMPLEMENTATION_NOTES.md +77 -0
  16. package/src/components/HoverCard/HoverCard.module.css +84 -0
  17. package/src/components/HoverCard/HoverCard.stories.tsx +160 -5
  18. package/src/components/HoverCard/HoverCard.tsx +153 -4
  19. package/src/components/NumberInput/NUMBER_INPUT_IMPLEMENTATION_NOTES.md +18 -0
  20. package/src/components/NumberInput/NumberInput.module.css +250 -0
  21. package/src/components/NumberInput/NumberInput.stories.tsx +84 -4
  22. package/src/components/NumberInput/NumberInput.tsx +144 -5
  23. package/src/components/Panel/PANEL_IMPLEMENTATION_NOTES.md +106 -0
  24. package/src/components/Panel/Panel.module.css +154 -0
  25. package/src/components/Panel/Panel.stories.tsx +216 -6
  26. package/src/components/Panel/Panel.tsx +153 -4
  27. package/src/components/TextArea/TextArea.module.css +0 -3
  28. package/src/components/TextField/TextField.module.css +0 -3
  29. package/src/components/Tooltip/TOOLTIP_IMPLEMENTATION_NOTES.md +85 -0
  30. package/src/components/Tooltip/Tooltip.module.css +81 -0
  31. package/src/components/Tooltip/Tooltip.stories.tsx +154 -6
  32. package/src/components/Tooltip/Tooltip.tsx +114 -4
@@ -1,17 +1,172 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
2
  import { HoverCard } from "./HoverCard";
3
- import { ComingSoon } from "@recursica/storybook-template";
3
+ import { Button } from "../Button";
4
+ import { Text } from "../Text/Text";
5
+ import { Group } from "../Group/Group";
6
+ import { Stack } from "../Stack/Stack";
7
+ import { Avatar } from "../Avatar";
4
8
 
5
- const meta: Meta<typeof HoverCard> = {
6
- title: "UI-Kit/🚧 HoverCard",
9
+ /**
10
+ * HoverCard story axes:
11
+ * - position: dropdown alignment relative to target
12
+ * - withArrow: arrow indicator on the dropdown
13
+ * - openDelay / closeDelay: hover timing controls
14
+ * - content variations: plain text, rich content (avatar + text + actions)
15
+ * - layer: tested via the global Layer decorator (withLayer/layer args)
16
+ */
17
+
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ type HoverCardStoryArgs = Record<string, any>;
20
+
21
+ const meta: Meta = {
22
+ title: "UI-Kit/HoverCard",
7
23
  component: HoverCard,
8
24
  tags: ["autodocs"],
25
+ argTypes: {
26
+ position: {
27
+ control: "select",
28
+ options: [
29
+ "bottom",
30
+ "bottom-start",
31
+ "bottom-end",
32
+ "top",
33
+ "top-start",
34
+ "top-end",
35
+ "left",
36
+ "left-start",
37
+ "left-end",
38
+ "right",
39
+ "right-start",
40
+ "right-end",
41
+ ],
42
+ description: "The position of the dropdown relative to the target.",
43
+ },
44
+ withBeak: {
45
+ control: "boolean",
46
+ description:
47
+ "Whether to display a beak (arrow) pointing to the target. Recursica equivalent of Mantine's withArrow.",
48
+ },
49
+ offset: {
50
+ control: "number",
51
+ description:
52
+ "Distance in px between the dropdown and the target element.",
53
+ },
54
+ openDelay: {
55
+ control: "number",
56
+ description: "Delay in ms before the dropdown opens on hover.",
57
+ },
58
+ closeDelay: {
59
+ control: "number",
60
+ description: "Delay in ms before the dropdown closes when hover ends.",
61
+ },
62
+ disabled: {
63
+ control: "boolean",
64
+ description: "If set, the hover card dropdown will not be rendered.",
65
+ },
66
+ },
67
+ parameters: {
68
+ layout: "centered",
69
+ docs: {
70
+ description: {
71
+ component: `
72
+ The \`HoverCard\` component displays a popover-style dropdown when the user hovers over a target element. It wraps Mantine's composable \`HoverCard\` while enforcing strict Recursica design token styling.
73
+
74
+ ### Composable API
75
+
76
+ HoverCard uses a dot-notation composition pattern:
77
+ - \`<HoverCard>\` — Root container managing open/close state on hover
78
+ - \`<HoverCard.Target>\` — Wrapper for the trigger element (must be a single element supporting ref)
79
+ - \`<HoverCard.Dropdown>\` — The popup panel displaying content on hover
80
+
81
+ ### Key Behaviors
82
+ - The dropdown opens when the user hovers over the target and closes when they move away
83
+ - \`openDelay\` and \`closeDelay\` control the timing of open/close transitions
84
+ - The dropdown stays open while the user hovers over it, allowing interaction with its content
85
+ `,
86
+ },
87
+ },
88
+ },
9
89
  };
10
90
 
11
91
  export default meta;
12
92
 
13
- type Story = StoryObj<typeof HoverCard>;
93
+ type Story = StoryObj<HoverCardStoryArgs>;
14
94
 
15
95
  export const Default: Story = {
16
- render: () => <ComingSoon componentName="HoverCard" />,
96
+ args: {
97
+ position: "top",
98
+ withBeak: true,
99
+ offset: 5,
100
+ openDelay: 0,
101
+ closeDelay: 150,
102
+ },
103
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
104
+ render: ({ withLayer, layer, ...args }: HoverCardStoryArgs) => {
105
+ return (
106
+ <HoverCard {...args}>
107
+ <HoverCard.Target>
108
+ <Button variant="solid">Hover me</Button>
109
+ </HoverCard.Target>
110
+
111
+ <HoverCard.Dropdown>
112
+ <Text>
113
+ This is a hover card with informational content that appears when
114
+ you hover over the target element.
115
+ </Text>
116
+ </HoverCard.Dropdown>
117
+ </HoverCard>
118
+ );
119
+ },
120
+ };
121
+
122
+ export const WithoutBeak: Story = {
123
+ args: {
124
+ position: "top",
125
+ withBeak: false,
126
+ offset: 5,
127
+ },
128
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
129
+ render: ({ withLayer, layer, ...args }: HoverCardStoryArgs) => {
130
+ return (
131
+ <HoverCard {...args}>
132
+ <HoverCard.Target>
133
+ <Button variant="outline">Without Beak</Button>
134
+ </HoverCard.Target>
135
+
136
+ <HoverCard.Dropdown>
137
+ <Text>
138
+ This hover card has the beak disabled, showing a clean dropdown
139
+ without the pointing indicator.
140
+ </Text>
141
+ </HoverCard.Dropdown>
142
+ </HoverCard>
143
+ );
144
+ },
145
+ };
146
+
147
+ export const RichContent: Story = {
148
+ args: {
149
+ position: "top",
150
+ offset: 5,
151
+ },
152
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
153
+ render: ({ withLayer, layer, ...args }: HoverCardStoryArgs) => {
154
+ return (
155
+ <HoverCard {...args}>
156
+ <HoverCard.Target>
157
+ <Button variant="solid">User Profile</Button>
158
+ </HoverCard.Target>
159
+
160
+ <HoverCard.Dropdown>
161
+ <Group>
162
+ <Avatar src={null} alt="User avatar" />
163
+ <Stack>
164
+ <Text>Jane Doe</Text>
165
+ <Text>Software Engineer at Recursica</Text>
166
+ </Stack>
167
+ </Group>
168
+ </HoverCard.Dropdown>
169
+ </HoverCard>
170
+ );
171
+ },
17
172
  };
@@ -1,7 +1,156 @@
1
- import React from "react";
1
+ import {
2
+ HoverCard as MantineHoverCard,
3
+ type HoverCardProps as MantineHoverCardProps,
4
+ type HoverCardTargetProps as MantineHoverCardTargetProps,
5
+ type HoverCardDropdownProps as MantineHoverCardDropdownProps,
6
+ } from "@mantine/core";
7
+ import {
8
+ filterStylingProps,
9
+ type RecursicaOverStyled,
10
+ } from "../../utils/filterStylingProps";
11
+ import styles from "./HoverCard.module.css";
2
12
 
3
- export type HoverCardProps = React.HTMLAttributes<HTMLDivElement>;
13
+ // ============================================================
14
+ // HOVERCARD ROOT
15
+ // ============================================================
4
16
 
5
- export const HoverCard: React.FC<HoverCardProps> = (props) => {
6
- return <div {...props}>HoverCard</div>;
17
+ /**
18
+ * Recursica-specific props for HoverCard.
19
+ */
20
+ export interface RecursicaHoverCardProps {
21
+ /**
22
+ * Whether to display a beak (arrow) pointing from the dropdown to the target.
23
+ * This is the Recursica equivalent of Mantine's `withArrow`.
24
+ * When both `withBeak` and `withArrow` are provided, `withBeak` takes precedence.
25
+ */
26
+ withBeak?: boolean;
27
+ }
28
+
29
+ /**
30
+ * Recursica HoverCard component wrapping Mantine's composable HoverCard.
31
+ *
32
+ * Displays a dropdown panel when the user hovers over a target element.
33
+ * Uses the composable dot-notation pattern:
34
+ * ```tsx
35
+ * <HoverCard withBeak>
36
+ * <HoverCard.Target>
37
+ * <Button>Hover me</Button>
38
+ * </HoverCard.Target>
39
+ * <HoverCard.Dropdown>
40
+ * Content displayed on hover
41
+ * </HoverCard.Dropdown>
42
+ * </HoverCard>
43
+ * ```
44
+ */
45
+ export type HoverCardProps = RecursicaOverStyled<
46
+ MantineHoverCardProps & RecursicaHoverCardProps
47
+ >;
48
+
49
+ const HoverCardBase = function HoverCard({
50
+ overStyled = false,
51
+ withBeak = true,
52
+ ...rest
53
+ }: HoverCardProps) {
54
+ const sanitizedProps = filterStylingProps(rest, overStyled);
55
+
56
+ // Bind CSS module classes to Mantine's internal classNames API
57
+ const mergedClassNames: Partial<Record<string, string>> = {
58
+ dropdown: styles.dropdown,
59
+ arrow: styles.arrow,
60
+ };
61
+
62
+ const classNamesProp = (sanitizedProps as Record<string, unknown>).classNames;
63
+ if (
64
+ classNamesProp &&
65
+ typeof classNamesProp === "object" &&
66
+ !Array.isArray(classNamesProp)
67
+ ) {
68
+ const o = classNamesProp as Record<string, string>;
69
+ Object.keys(o).forEach((key) => {
70
+ if (mergedClassNames[key]) {
71
+ mergedClassNames[key] = `${mergedClassNames[key]} ${o[key]}`;
72
+ } else {
73
+ mergedClassNames[key] = o[key];
74
+ }
75
+ });
76
+ }
77
+
78
+ // arrowSize must be a JS number prop — Mantine uses it for inline width/height
79
+ // and positioning offset (-arrowSize/2) calculations that cannot be CSS-driven.
80
+ // Default to 16 to match the Recursica beak-size token (16px).
81
+ const arrowSize =
82
+ ((sanitizedProps as Record<string, unknown>).arrowSize as
83
+ | number
84
+ | undefined) ?? 16;
85
+
86
+ // Resolve withBeak (Recursica) vs withArrow (Mantine).
87
+ // withBeak takes precedence when both are provided.
88
+ const withArrow = (sanitizedProps as Record<string, unknown>).withArrow as
89
+ | boolean
90
+ | undefined;
91
+ const resolvedWithArrow = withBeak ?? withArrow;
92
+
93
+ return (
94
+ <MantineHoverCard
95
+ position="top" /* Recursica default; Mantine defaults to "bottom" */
96
+ arrowSize={arrowSize}
97
+ withArrow={resolvedWithArrow}
98
+ classNames={mergedClassNames}
99
+ {...(sanitizedProps as unknown as MantineHoverCardProps)}
100
+ />
101
+ );
102
+ };
103
+ HoverCardBase.displayName = "HoverCard";
104
+
105
+ // ============================================================
106
+ // HOVERCARD TARGET
107
+ // ============================================================
108
+
109
+ /**
110
+ * Wrapper for the element that triggers the hover card.
111
+ * Requires a single child element that supports ref forwarding.
112
+ */
113
+ export type HoverCardTargetProps = MantineHoverCardTargetProps;
114
+
115
+ const HoverCardTarget = function HoverCardTarget(props: HoverCardTargetProps) {
116
+ return <MantineHoverCard.Target {...props} />;
117
+ };
118
+ HoverCardTarget.displayName = "HoverCardTarget";
119
+
120
+ // ============================================================
121
+ // HOVERCARD DROPDOWN
122
+ // ============================================================
123
+
124
+ /** The dropdown panel displayed when hovering over the target. */
125
+ export type HoverCardDropdownProps =
126
+ RecursicaOverStyled<MantineHoverCardDropdownProps>;
127
+
128
+ const HoverCardDropdown = function HoverCardDropdown({
129
+ overStyled = false,
130
+ ...rest
131
+ }: HoverCardDropdownProps) {
132
+ const sanitizedProps = filterStylingProps(rest, overStyled);
133
+ const classNameProp = (sanitizedProps as Record<string, unknown>)
134
+ .className as string | undefined;
135
+
136
+ return (
137
+ <MantineHoverCard.Dropdown
138
+ className={classNameProp}
139
+ {...(sanitizedProps as unknown as MantineHoverCardDropdownProps)}
140
+ />
141
+ );
7
142
  };
143
+ HoverCardDropdown.displayName = "HoverCardDropdown";
144
+
145
+ // ============================================================
146
+ // DOT NOTATION EXPORT
147
+ // ============================================================
148
+
149
+ type HoverCardComponent = typeof HoverCardBase & {
150
+ Target: typeof HoverCardTarget;
151
+ Dropdown: typeof HoverCardDropdown;
152
+ };
153
+
154
+ export const HoverCard = HoverCardBase as HoverCardComponent;
155
+ HoverCard.Target = HoverCardTarget;
156
+ HoverCard.Dropdown = HoverCardDropdown;
@@ -0,0 +1,18 @@
1
+ # NumberInput Implementation Notes
2
+
3
+ This document contains specific design decisions, architectural constraints, and hacks required to bridge the Recursica design system with Mantine's underlying `NumberInput` primitive.
4
+
5
+ ## 1. Native Macro Wrapper Bypass
6
+
7
+ **Decision:** The `<NumberInput>` component explicitly bypasses Mantine's native `Input.Wrapper` DOM injections.
8
+ **Implementation:** We pass `label={undefined}`, `description={undefined}`, and `error={undefined}` directly into the primitive `<MantineNumberInput>`. All visual form control geometry is delegated exclusively to our unified `<FormControlWrapper>`, ensuring 100% token adherence for label spacing and assistive text styling without duplicate DOM rendering.
9
+
10
+ ## 2. Right Section & Controls Override
11
+
12
+ **Decision:** Passing a `rightSection` element will natively remove the increment/decrement arrow controls.
13
+ **Implementation:** Mantine inherently renders its stepper controls inside the `rightSection` DOM slot. Providing a custom right-aligned icon or text element intentionally overwrites this slot. If a layout strictly requires both a custom right-aligned element and the stepper controls simultaneously, the integrator must manually rebuild the arrows using Mantine's `handlersRef` within a custom right-section wrapper.
14
+
15
+ ## 3. Controls Styling
16
+
17
+ **Decision:** The increment/decrement control arrows rely partially on native Mantine CSS inheritance.
18
+ **Implementation:** The current Recursica design system tokens do not provide explicit UI styling parameters (`background`, `border`, `hover` states) for the inner number-input arrows. We have explicitly removed Mantine's default borders to cleanly nest them inside the unified input box, and mapped the icon colors to the generic `trailing-icon` token variable, but further visual configurations currently fall back to Mantine defaults.
@@ -0,0 +1,250 @@
1
+ /* HARDCODED VALUES:
2
+ - border-width: 1px. Native geometric boundary for the input box.
3
+ - border-style: solid. Native structural rendering rule.
4
+ - outline: none. Bypassing browser focus rings to rely strictly on Recursica focus states natively.
5
+ - flex/layout: display: flex on the root wrapper safely encapsulating internal section rendering.
6
+ - Controls: Hardcoded to bypass Mantine's default borders and backgrounds on the increment/decrement arrows.
7
+ */
8
+
9
+ .root {
10
+ display: flex;
11
+ position: relative;
12
+ width: 100%;
13
+ min-height: var(
14
+ --recursica_ui-kit_components_number-input_properties_min-height
15
+ );
16
+
17
+ /* Override Mantine native Input variables governing section spacing padding mathematics safely */
18
+ --input-left-section-size: calc(
19
+ var(--recursica_ui-kit_components_number-input_properties_icon-size) +
20
+ (
21
+ var(
22
+ --recursica_ui-kit_components_number-input_properties_horizontal-padding
23
+ ) *
24
+ 2
25
+ )
26
+ );
27
+ --input-right-section-size: calc(
28
+ var(--recursica_ui-kit_components_number-input_properties_icon-size) +
29
+ (
30
+ var(
31
+ --recursica_ui-kit_components_number-input_properties_horizontal-padding
32
+ ) *
33
+ 2
34
+ )
35
+ );
36
+ }
37
+
38
+ .input {
39
+ /* Structural Overrides */
40
+ width: 100%;
41
+ box-sizing: border-box;
42
+ margin: 0;
43
+
44
+ /* Box Geometry */
45
+ min-height: var(
46
+ --recursica_ui-kit_components_number-input_properties_min-height
47
+ );
48
+ padding-top: var(
49
+ --recursica_ui-kit_components_number-input_properties_vertical-padding
50
+ );
51
+ padding-bottom: var(
52
+ --recursica_ui-kit_components_number-input_properties_vertical-padding
53
+ );
54
+ padding-left: var(
55
+ --recursica_ui-kit_components_number-input_properties_horizontal-padding
56
+ );
57
+ padding-right: var(
58
+ --recursica_ui-kit_components_number-input_properties_horizontal-padding
59
+ );
60
+ border-radius: var(
61
+ --recursica_ui-kit_components_number-input_properties_border-radius
62
+ );
63
+ border-width: 1px;
64
+ border-style: solid;
65
+
66
+ /* Strict Typography Unification */
67
+ font-family: var(
68
+ --recursica_ui-kit_components_number-input_properties_text_font-family
69
+ );
70
+ font-size: var(
71
+ --recursica_ui-kit_components_number-input_properties_text_font-size
72
+ );
73
+ font-style: var(
74
+ --recursica_ui-kit_components_number-input_properties_text_font-style
75
+ );
76
+ font-weight: var(
77
+ --recursica_ui-kit_components_number-input_properties_text_font-weight
78
+ );
79
+ letter-spacing: var(
80
+ --recursica_ui-kit_components_number-input_properties_text_letter-spacing
81
+ );
82
+ line-height: var(
83
+ --recursica_ui-kit_components_number-input_properties_text_line-height
84
+ );
85
+ text-decoration: var(
86
+ --recursica_ui-kit_components_number-input_properties_text_text-decoration
87
+ );
88
+ text-transform: var(
89
+ --recursica_ui-kit_components_number-input_properties_text_text-transform
90
+ );
91
+
92
+ /* Base State Default Execution */
93
+ background-color: var(
94
+ --recursica_ui-kit_components_number-input_variants_states_default_properties_colors_background
95
+ );
96
+ border-color: var(
97
+ --recursica_ui-kit_components_number-input_variants_states_default_properties_colors_border-color
98
+ );
99
+ color: var(
100
+ --recursica_ui-kit_components_number-input_variants_states_default_properties_colors_text
101
+ );
102
+
103
+ outline: none;
104
+ }
105
+
106
+ .input::placeholder {
107
+ opacity: var(
108
+ --recursica_ui-kit_components_number-input_properties_placeholder-opacity
109
+ );
110
+ color: inherit;
111
+ }
112
+
113
+ /* Dynamic Padding Overrides */
114
+ .root[data-with-left-section] .input {
115
+ padding-left: var(--input-left-section-size);
116
+ }
117
+
118
+ .root[data-with-right-section] .input {
119
+ padding-right: var(--input-right-section-size);
120
+ }
121
+
122
+ /* Flexible End-Caps (Icons, actions) */
123
+ .section {
124
+ display: flex;
125
+ align-items: center;
126
+ justify-content: center;
127
+ height: 100%;
128
+ }
129
+
130
+ .section :global(svg) {
131
+ width: var(--recursica_ui-kit_components_number-input_properties_icon-size);
132
+ height: var(--recursica_ui-kit_components_number-input_properties_icon-size);
133
+ color: var(
134
+ --recursica_ui-kit_components_number-input_variants_states_default_properties_colors_leading-icon
135
+ );
136
+ }
137
+
138
+ .section[data-position="right"] :global(svg) {
139
+ color: var(
140
+ --recursica_ui-kit_components_number-input_variants_states_default_properties_colors_trailing-icon
141
+ );
142
+ }
143
+
144
+ /* -------------------------------------
145
+ CONTROLS (Mantine Specific Up/Down Arrows)
146
+ -------------------------------------- */
147
+
148
+ .controls {
149
+ /* Adjust right padding so controls do not overlap borders */
150
+ padding-right: var(
151
+ --recursica_ui-kit_components_number-input_properties_horizontal-padding
152
+ );
153
+ }
154
+
155
+ .control {
156
+ /* Override Mantine borders for the inner controls */
157
+ border: none;
158
+ background: transparent;
159
+ color: var(
160
+ --recursica_ui-kit_components_number-input_variants_states_default_properties_colors_trailing-icon
161
+ );
162
+ }
163
+
164
+ .control:hover {
165
+ background: transparent;
166
+ }
167
+
168
+ /* -------------------------------------
169
+ STATE CASCADE ARCHITECTURE
170
+ -------------------------------------- */
171
+
172
+ /* Focus State Mapping (Triggered internally via browser pseudo-pseudo-class) */
173
+ .input:focus-within,
174
+ .input:focus {
175
+ border-color: var(
176
+ --recursica_ui-kit_components_number-input_variants_states_focus_properties_colors_border-color
177
+ );
178
+ background-color: var(
179
+ --recursica_ui-kit_components_number-input_variants_states_focus_properties_colors_background
180
+ );
181
+ color: var(
182
+ --recursica_ui-kit_components_number-input_variants_states_focus_properties_colors_text
183
+ );
184
+ }
185
+
186
+ .root:focus-within .section[data-position="left"] :global(svg) {
187
+ color: var(
188
+ --recursica_ui-kit_components_number-input_variants_states_focus_properties_colors_leading-icon
189
+ );
190
+ }
191
+
192
+ .root:focus-within .section[data-position="right"] :global(svg),
193
+ .root:focus-within .control {
194
+ color: var(
195
+ --recursica_ui-kit_components_number-input_variants_states_focus_properties_colors_trailing-icon
196
+ );
197
+ }
198
+
199
+ /* Error State Mapping (Propagated strictly down from the wrapper DOM context) */
200
+ .root[data-error] .input {
201
+ border-color: var(
202
+ --recursica_ui-kit_components_number-input_variants_states_error_properties_colors_border-color
203
+ ) !important;
204
+ background-color: var(
205
+ --recursica_ui-kit_components_number-input_variants_states_error_properties_colors_background
206
+ ) !important;
207
+ color: var(
208
+ --recursica_ui-kit_components_number-input_variants_states_error_properties_colors_text
209
+ ) !important;
210
+ }
211
+
212
+ .root[data-error] .section[data-position="left"] :global(svg) {
213
+ color: var(
214
+ --recursica_ui-kit_components_number-input_variants_states_error_properties_colors_leading-icon
215
+ ) !important;
216
+ }
217
+
218
+ .root[data-error] .section[data-position="right"] :global(svg),
219
+ .root[data-error] .control {
220
+ color: var(
221
+ --recursica_ui-kit_components_number-input_variants_states_error_properties_colors_trailing-icon
222
+ ) !important;
223
+ }
224
+
225
+ /* Disabled State Mapping (Propagated strictly down from the wrapper DOM context) */
226
+ .root[data-disabled] .input {
227
+ border-color: var(
228
+ --recursica_ui-kit_components_number-input_variants_states_disabled_properties_colors_border-color
229
+ ) !important;
230
+ background-color: var(
231
+ --recursica_ui-kit_components_number-input_variants_states_disabled_properties_colors_background
232
+ ) !important;
233
+ color: var(
234
+ --recursica_ui-kit_components_number-input_variants_states_disabled_properties_colors_text
235
+ ) !important;
236
+ cursor: not-allowed;
237
+ }
238
+
239
+ .root[data-disabled] .section[data-position="left"] :global(svg) {
240
+ color: var(
241
+ --recursica_ui-kit_components_number-input_variants_states_disabled_properties_colors_leading-icon
242
+ ) !important;
243
+ }
244
+
245
+ .root[data-disabled] .section[data-position="right"] :global(svg),
246
+ .root[data-disabled] .control {
247
+ color: var(
248
+ --recursica_ui-kit_components_number-input_variants_states_disabled_properties_colors_trailing-icon
249
+ ) !important;
250
+ }