@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.
- package/CHANGELOG.md +12 -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 +1329 -1082
- package/dist/mantine-adapter.js.map +1 -1
- package/dist/src/components/HoverCard/HoverCard.d.ts +55 -3
- package/dist/src/components/NumberInput/NumberInput.d.ts +10 -2
- package/dist/src/components/Panel/Panel.d.ts +65 -3
- package/dist/src/components/Tooltip/Tooltip.d.ts +42 -3
- package/package.json +1 -1
- package/src/components/Card/Card.module.css +1 -0
- package/src/components/Card/Card.stories.tsx +48 -58
- package/src/components/Dropdown/Dropdown.module.css +0 -3
- package/src/components/HoverCard/HOVERCARD_IMPLEMENTATION_NOTES.md +77 -0
- package/src/components/HoverCard/HoverCard.module.css +84 -0
- package/src/components/HoverCard/HoverCard.stories.tsx +160 -5
- package/src/components/HoverCard/HoverCard.tsx +153 -4
- package/src/components/NumberInput/NUMBER_INPUT_IMPLEMENTATION_NOTES.md +18 -0
- package/src/components/NumberInput/NumberInput.module.css +250 -0
- package/src/components/NumberInput/NumberInput.stories.tsx +84 -4
- package/src/components/NumberInput/NumberInput.tsx +144 -5
- package/src/components/Panel/PANEL_IMPLEMENTATION_NOTES.md +106 -0
- package/src/components/Panel/Panel.module.css +154 -0
- package/src/components/Panel/Panel.stories.tsx +216 -6
- package/src/components/Panel/Panel.tsx +153 -4
- package/src/components/TextArea/TextArea.module.css +0 -3
- package/src/components/TextField/TextField.module.css +0 -3
- package/src/components/Tooltip/TOOLTIP_IMPLEMENTATION_NOTES.md +85 -0
- package/src/components/Tooltip/Tooltip.module.css +81 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +154 -6
- 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 {
|
|
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
|
-
|
|
6
|
-
|
|
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<
|
|
93
|
+
type Story = StoryObj<HoverCardStoryArgs>;
|
|
14
94
|
|
|
15
95
|
export const Default: Story = {
|
|
16
|
-
|
|
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
|
|
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
|
-
|
|
13
|
+
// ============================================================
|
|
14
|
+
// HOVERCARD ROOT
|
|
15
|
+
// ============================================================
|
|
4
16
|
|
|
5
|
-
|
|
6
|
-
|
|
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
|
+
}
|