@recursica/mantine-adapter 0.13.0 → 0.14.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 +1304 -1059
- 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 +57 -3
- package/dist/src/components/Tooltip/Tooltip.d.ts +42 -3
- package/package.json +1 -1
- 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/Loader/LOADER_IMPLEMENTATION_NOTES.md +25 -0
- 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 +143 -0
- package/src/components/Panel/Panel.stories.tsx +205 -6
- package/src/components/Panel/Panel.tsx +143 -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,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,25 @@
|
|
|
1
|
+
# Loader Implementation Notes
|
|
2
|
+
|
|
3
|
+
## Architecture & Integration
|
|
4
|
+
|
|
5
|
+
The `Loader` component acts as a strictly tokenized wrapper bridging the Recursica UI-Kit `loader` variables to the generic Mantine `@mantine/core` `Loader` primitive.
|
|
6
|
+
|
|
7
|
+
### Key Decisions:
|
|
8
|
+
|
|
9
|
+
- **Variant Mapping:** Recursica's `variant` directly proxies to Mantine's `type` prop for `"oval" | "bars" | "dots"`.
|
|
10
|
+
- **Property Overrides Disabled:** Natively overriding specific structural variants directly on the JSX interface like `thickness` and `borderRadius` has been intentionally omitted. Component rendering relies entirely on variables exposed by the underlying UI Kit mappings tied to the size prop.
|
|
11
|
+
|
|
12
|
+
### Token Mapping:
|
|
13
|
+
|
|
14
|
+
Sizes are bound through `data-size` attributes (`sm`, `md`, `lg` parsing to target `<div data-size="small">`, etc.).
|
|
15
|
+
|
|
16
|
+
Mantine natively sets sizing dynamically at the component root and parses thickness/variants differently natively (e.g., `oval` styles its geometry strictly via CSS `border`, while `bars` and `dots` utilize specific DOM inner spans `span.dot` / `span.bar`).
|
|
17
|
+
|
|
18
|
+
#### Specific CSS Targeting Hacks Used
|
|
19
|
+
|
|
20
|
+
- `border-width` structurally styles the `thickness` configuration of the `oval` variant by resolving `--recursica_ui-kit_components_loader_variants_sizes_..._properties_thickness`.
|
|
21
|
+
- For non-oval variants, `border-radius` natively maps downwards to targeting component `span` children within the wrapper to capture `<span className="mantine-Loader-dot" />` geometries safely without polluting the flex wrapper natively.
|
|
22
|
+
|
|
23
|
+
### Unsupported Properties
|
|
24
|
+
|
|
25
|
+
- **xs and xl Sizing:** These sizes are explicitly unsupported in the Recursica standard logic (as surfaced in `filterStylingProps` and UI Kit mappings). Attempting to use them will safely default back or fallthrough statically unless defined later. See `COMPONENT_ISSUES.md`.
|
|
@@ -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
|
+
}
|
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
2
|
import { NumberInput } from "./NumberInput";
|
|
3
|
-
import { ComingSoon } from "@recursica/storybook-template";
|
|
4
3
|
|
|
5
4
|
const meta: Meta<typeof NumberInput> = {
|
|
6
|
-
title: "UI-Kit
|
|
5
|
+
title: "UI-Kit/NumberInput",
|
|
7
6
|
component: NumberInput,
|
|
8
7
|
tags: ["autodocs"],
|
|
9
|
-
argTypes: {
|
|
8
|
+
argTypes: {
|
|
9
|
+
label: { control: "text" },
|
|
10
|
+
assistiveText: { control: "text" },
|
|
11
|
+
disabled: { control: "boolean" },
|
|
12
|
+
error: { control: "boolean" },
|
|
13
|
+
readOnly: { control: "boolean" },
|
|
14
|
+
required: { control: "boolean" },
|
|
15
|
+
hideControls: { control: "boolean" },
|
|
16
|
+
formLayout: {
|
|
17
|
+
control: "select",
|
|
18
|
+
options: ["stacked", "side-by-side"],
|
|
19
|
+
},
|
|
20
|
+
labelSize: {
|
|
21
|
+
control: "select",
|
|
22
|
+
options: ["small", "default", "large"],
|
|
23
|
+
},
|
|
24
|
+
checked: { table: { disable: true } },
|
|
25
|
+
defaultChecked: { table: { disable: true } },
|
|
26
|
+
assistiveWithIcon: { table: { disable: true } },
|
|
27
|
+
labelOptionalText: { table: { disable: true } },
|
|
28
|
+
labelWithEditIcon: { table: { disable: true } },
|
|
29
|
+
onLabelEditClick: { table: { disable: true } },
|
|
30
|
+
emptyValueComponent: { table: { disable: true } },
|
|
31
|
+
},
|
|
10
32
|
};
|
|
11
33
|
|
|
12
34
|
export default meta;
|
|
@@ -14,5 +36,63 @@ export default meta;
|
|
|
14
36
|
type Story = StoryObj<typeof NumberInput>;
|
|
15
37
|
|
|
16
38
|
export const Default: Story = {
|
|
17
|
-
|
|
39
|
+
args: {
|
|
40
|
+
label: "Amount",
|
|
41
|
+
placeholder: "Enter an amount",
|
|
42
|
+
assistiveText: "Must be greater than 0",
|
|
43
|
+
defaultValue: 10,
|
|
44
|
+
min: 0,
|
|
45
|
+
max: 100,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const SideBySideLayout: Story = {
|
|
50
|
+
args: {
|
|
51
|
+
...Default.args,
|
|
52
|
+
formLayout: "side-by-side",
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const States: Story = {
|
|
57
|
+
render: () => (
|
|
58
|
+
<div
|
|
59
|
+
style={{
|
|
60
|
+
display: "flex",
|
|
61
|
+
flexDirection: "column",
|
|
62
|
+
gap: "1rem",
|
|
63
|
+
maxWidth: 400,
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
<NumberInput label="Default" placeholder="Enter a number" />
|
|
67
|
+
<NumberInput label="Disabled" placeholder="Disabled input" disabled />
|
|
68
|
+
<NumberInput label="Error" placeholder="Error state" error />
|
|
69
|
+
<NumberInput label="Read Only" value={42} readOnly />
|
|
70
|
+
<NumberInput label="Required" required />
|
|
71
|
+
</div>
|
|
72
|
+
),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const WithLeftIcon: Story = {
|
|
76
|
+
args: {
|
|
77
|
+
label: "Price",
|
|
78
|
+
placeholder: "0.00",
|
|
79
|
+
leftSection: <span>$</span>,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const WithRightIcon: Story = {
|
|
84
|
+
args: {
|
|
85
|
+
label: "Percentage",
|
|
86
|
+
placeholder: "0",
|
|
87
|
+
rightSection: <span>%</span>,
|
|
88
|
+
hideControls: true, // Typically hiding controls if rightSection is occupied
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const HiddenControls: Story = {
|
|
93
|
+
args: {
|
|
94
|
+
label: "Zip Code",
|
|
95
|
+
placeholder: "Enter zip code",
|
|
96
|
+
hideControls: true,
|
|
97
|
+
},
|
|
18
98
|
};
|