@recursica/mantine-adapter 0.6.0 → 0.7.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/.storybook/commonArgTypes.ts +148 -0
- package/CHANGELOG.md +69 -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 +660 -586
- package/dist/mantine-adapter.js.map +1 -1
- package/dist/src/components/Checkbox/CheckboxGroup.d.ts +1 -1
- package/dist/src/components/Chip/Chip.d.ts +14 -2
- package/package.json +5 -2
- package/src/OverStyling.stories.tsx +174 -0
- package/src/Version.stories.tsx +56 -0
- package/src/components/Accordion/ACCORDION_IMPLEMENTATION_NOTES.md +48 -0
- package/src/components/Accordion/Accordion.module.css +261 -0
- package/src/components/Accordion/Accordion.stories.tsx +145 -0
- package/src/components/Accordion/Accordion.tsx +200 -0
- package/src/components/Accordion/index.ts +1 -0
- package/src/components/AssistiveElement/AssistiveElement.module.css +111 -0
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +73 -0
- package/src/components/AssistiveElement/AssistiveElement.tsx +91 -0
- package/src/components/Avatar/AVATAR_IMPLEMENTATION_NOTES.md +24 -0
- package/src/components/Avatar/Avatar.module.css +340 -0
- package/src/components/Avatar/Avatar.stories.tsx +102 -0
- package/src/components/Avatar/Avatar.tsx +100 -0
- package/src/components/Avatar/index.ts +1 -0
- package/src/components/Badge/BADGE_IMPLEMENTATION_NOTES.md +18 -0
- package/src/components/Badge/Badge.module.css +124 -0
- package/src/components/Badge/Badge.stories.tsx +77 -0
- package/src/components/Badge/Badge.tsx +66 -0
- package/src/components/Breadcrumb/BREADCRUMB_IMPLEMENTATION_NOTES.md +14 -0
- package/src/components/Breadcrumb/Breadcrumb.module.css +26 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +77 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +64 -0
- package/src/components/Button/Button.module.css +275 -0
- package/src/components/Button/Button.stories.tsx +105 -0
- package/src/components/Button/Button.tsx +122 -0
- package/src/components/Button/IMPLEMENTATION_NOTES.md +45 -0
- package/src/components/Button/index.ts +1 -0
- package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +10 -0
- package/src/components/Card/Card.module.css +60 -0
- package/src/components/Card/Card.stories.tsx +141 -0
- package/src/components/Card/Card.tsx +176 -0
- package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +25 -0
- package/src/components/Checkbox/Checkbox.module.css +204 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +73 -0
- package/src/components/Checkbox/Checkbox.tsx +111 -0
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +138 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +140 -0
- package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +35 -0
- package/src/components/Chip/Chip.module.css +218 -0
- package/src/components/Chip/Chip.stories.tsx +115 -0
- package/src/components/Chip/Chip.tsx +143 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +22 -0
- package/src/components/DatePicker/DatePicker.tsx +7 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +22 -0
- package/src/components/Dropdown/Dropdown.tsx +7 -0
- package/src/components/FileInput/FileInput.stories.tsx +22 -0
- package/src/components/FileInput/FileInput.tsx +7 -0
- package/src/components/FileUpload/FileUpload.stories.tsx +22 -0
- package/src/components/FileUpload/FileUpload.tsx +7 -0
- package/src/components/FormControlWrapper/FORMCONTROLWRAPPER_IMPLEMENTATION_NOTES.md +32 -0
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +46 -0
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +116 -0
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +170 -0
- package/src/components/HoverCard/HoverCard.stories.tsx +17 -0
- package/src/components/HoverCard/HoverCard.tsx +7 -0
- package/src/components/Label/LABEL_IMPLEMENTATION_NOTES.md +48 -0
- package/src/components/Label/Label.module.css +177 -0
- package/src/components/Label/Label.stories.tsx +123 -0
- package/src/components/Label/Label.tsx +132 -0
- package/src/components/Label/index.ts +1 -0
- package/src/components/Link/Link.stories.tsx +17 -0
- package/src/components/Link/Link.tsx +7 -0
- package/src/components/Loader/Loader.stories.tsx +17 -0
- package/src/components/Loader/Loader.tsx +7 -0
- package/src/components/Menu/Menu.stories.tsx +17 -0
- package/src/components/Menu/Menu.tsx +7 -0
- package/src/components/Modal/Modal.stories.tsx +17 -0
- package/src/components/Modal/Modal.tsx +7 -0
- package/src/components/NumberInput/NumberInput.stories.tsx +22 -0
- package/src/components/NumberInput/NumberInput.tsx +7 -0
- package/src/components/Pagination/Pagination.stories.tsx +17 -0
- package/src/components/Pagination/Pagination.tsx +7 -0
- package/src/components/Panel/Panel.stories.tsx +17 -0
- package/src/components/Panel/Panel.tsx +7 -0
- package/src/components/Popover/Popover.stories.tsx +17 -0
- package/src/components/Popover/Popover.tsx +7 -0
- package/src/components/Radio/Radio.stories.tsx +22 -0
- package/src/components/Radio/Radio.tsx +7 -0
- package/src/components/ReadOnlyField/READ_ONLY_FIELD_IMPLEMENTATION_NOTES.md +15 -0
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +49 -0
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +120 -0
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +75 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +46 -0
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +85 -0
- package/src/components/ReadOnlyField/index.ts +3 -0
- package/src/components/Search/Search.stories.tsx +17 -0
- package/src/components/Search/Search.tsx +7 -0
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +22 -0
- package/src/components/SegmentedControl/SegmentedControl.tsx +7 -0
- package/src/components/Slider/Slider.stories.tsx +22 -0
- package/src/components/Slider/Slider.tsx +7 -0
- package/src/components/Stepper/Stepper.stories.tsx +17 -0
- package/src/components/Stepper/Stepper.tsx +7 -0
- package/src/components/Switch/Switch.stories.tsx +22 -0
- package/src/components/Switch/Switch.tsx +7 -0
- package/src/components/Table/Table.stories.tsx +17 -0
- package/src/components/Table/Table.tsx +7 -0
- package/src/components/Tabs/Tabs.stories.tsx +17 -0
- package/src/components/Tabs/Tabs.tsx +7 -0
- package/src/components/Text/Text.stories.tsx +88 -0
- package/src/components/Text/Text.tsx +54 -0
- package/src/components/TextArea/TextArea.stories.tsx +22 -0
- package/src/components/TextArea/TextArea.tsx +7 -0
- package/src/components/TextField/TEXTFIELD_IMPLEMENTATION_NOTES.md +19 -0
- package/src/components/TextField/TextField.module.css +225 -0
- package/src/components/TextField/TextField.stories.tsx +162 -0
- package/src/components/TextField/TextField.tsx +138 -0
- package/src/components/TimePicker/TimePicker.stories.tsx +22 -0
- package/src/components/TimePicker/TimePicker.tsx +7 -0
- package/src/components/Timeline/Timeline.stories.tsx +17 -0
- package/src/components/Timeline/Timeline.tsx +7 -0
- package/src/components/Title/Title.stories.tsx +63 -0
- package/src/components/Title/Title.tsx +45 -0
- package/src/components/Toast/Toast.stories.tsx +17 -0
- package/src/components/Toast/Toast.tsx +7 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +17 -0
- package/src/components/Tooltip/Tooltip.tsx +7 -0
- package/src/components/TransferList/TransferList.stories.tsx +17 -0
- package/src/components/TransferList/TransferList.tsx +7 -0
- package/src/components/index.ts +39 -0
- package/src/env.d.ts +7 -0
- package/src/index.ts +3 -0
- package/src/types/index.ts +9 -0
- package/src/types/mantine.d.ts +7 -0
- package/src/types/scss-modules.d.ts +9 -0
- package/src/utils/ColorSchemeWrapper.tsx +27 -0
- package/src/utils/copyToClipboard.ts +36 -0
- package/src/utils/filterStylingProps.ts +139 -0
- package/src/utils/index.ts +1 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { TextArea } from "./TextArea";
|
|
3
|
+
import { ComingSoon } from "@recursica/storybook-template";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof TextArea> = {
|
|
6
|
+
title: "UI-Kit/🚧 TextArea",
|
|
7
|
+
component: TextArea,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
argTypes: {
|
|
10
|
+
disabled: {
|
|
11
|
+
control: "boolean",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default meta;
|
|
17
|
+
|
|
18
|
+
type Story = StoryObj<typeof TextArea>;
|
|
19
|
+
|
|
20
|
+
export const Default: Story = {
|
|
21
|
+
render: () => <ComingSoon componentName="TextArea" />,
|
|
22
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# TextField Implementation Notes
|
|
2
|
+
|
|
3
|
+
## Architectural philosophy
|
|
4
|
+
|
|
5
|
+
The `TextField` primitive intentionally ignores Mantine's built-in `<TextInput>` structure in favor of directly binding against `<Input>`.
|
|
6
|
+
|
|
7
|
+
### 1. Bypassing `Input.Wrapper`
|
|
8
|
+
|
|
9
|
+
Because `<TextInput>` inherently renders Mantine's `Input.Wrapper` underneath the hood, utilizing it natively double-wraps our layouts causing massive DOM bloat and margin collapsing errors. By leveraging the completely naked `<Input>` primitive natively natively alongside `FormControlWrapper`, we retain full logical control of where the `label` maps, avoiding dual label conflicts or mis-aligned asterisks securely.
|
|
10
|
+
|
|
11
|
+
### 2. State Hooks (`wrapperProps`)
|
|
12
|
+
|
|
13
|
+
Because we target `<Input>`, all dynamic UI modifiers (`disabled`, `error`, etc) must strictly be applied to the `.root` CSS module to correctly style the internal `<input>` boxes AND the nested `.[data-position]` icon sections simultaneously.
|
|
14
|
+
|
|
15
|
+
To accomplish this safely without spilling random pseudo-variables onto the input parameters, we exclusively use Mantine's `<Input wrapperProps={{...}}>` block natively locking `.root[data-error]` to correctly map Recursica UI variable hooks without breaking the DOM hierarchy natively.
|
|
16
|
+
|
|
17
|
+
### 3. Component Definition Intersections
|
|
18
|
+
|
|
19
|
+
To strictly acquire native HTML typings, `TextField.tsx` explicitly extracts `React.ComponentPropsWithoutRef<"input">`. However, to prevent Typescript strict union collisions with overlapping Mantine definitions over functional `style` components and custom mappings natively, we meticulously omit (`Pick<InputWrapperProps, ...>`) explicit base elements to guarantee that strictly Recursica styles traverse the array flawlessly.
|
|
@@ -0,0 +1,225 @@
|
|
|
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
|
+
*/
|
|
7
|
+
|
|
8
|
+
.root {
|
|
9
|
+
display: flex;
|
|
10
|
+
position: relative;
|
|
11
|
+
width: 100%;
|
|
12
|
+
min-height: var(
|
|
13
|
+
--recursica_ui-kit_components_text-field_properties_min-height
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
/* Override Mantine native Input variables governing section spacing padding mathematics safely */
|
|
17
|
+
--input-left-section-size: calc(
|
|
18
|
+
var(--recursica_ui-kit_components_text-field_properties_icon-size) +
|
|
19
|
+
(
|
|
20
|
+
var(
|
|
21
|
+
--recursica_ui-kit_components_text-field_properties_horizontal-padding
|
|
22
|
+
) *
|
|
23
|
+
2
|
|
24
|
+
)
|
|
25
|
+
);
|
|
26
|
+
--input-right-section-size: calc(
|
|
27
|
+
var(--recursica_ui-kit_components_text-field_properties_icon-size) +
|
|
28
|
+
(
|
|
29
|
+
var(
|
|
30
|
+
--recursica_ui-kit_components_text-field_properties_horizontal-padding
|
|
31
|
+
) *
|
|
32
|
+
2
|
|
33
|
+
)
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.input {
|
|
38
|
+
/* Structural Overrides */
|
|
39
|
+
width: 100%;
|
|
40
|
+
box-sizing: border-box;
|
|
41
|
+
margin: 0;
|
|
42
|
+
|
|
43
|
+
/* Box Geometry */
|
|
44
|
+
min-height: var(
|
|
45
|
+
--recursica_ui-kit_components_text-field_properties_min-height
|
|
46
|
+
);
|
|
47
|
+
padding-top: var(
|
|
48
|
+
--recursica_ui-kit_components_text-field_properties_vertical-padding
|
|
49
|
+
);
|
|
50
|
+
padding-bottom: var(
|
|
51
|
+
--recursica_ui-kit_components_text-field_properties_vertical-padding
|
|
52
|
+
);
|
|
53
|
+
padding-left: var(
|
|
54
|
+
--recursica_ui-kit_components_text-field_properties_horizontal-padding
|
|
55
|
+
);
|
|
56
|
+
padding-right: var(
|
|
57
|
+
--recursica_ui-kit_components_text-field_properties_horizontal-padding
|
|
58
|
+
);
|
|
59
|
+
border-radius: var(
|
|
60
|
+
--recursica_ui-kit_components_text-field_properties_border-radius
|
|
61
|
+
);
|
|
62
|
+
border-width: 1px;
|
|
63
|
+
border-style: solid;
|
|
64
|
+
|
|
65
|
+
/* Strict Typography Unification */
|
|
66
|
+
font-family: var(
|
|
67
|
+
--recursica_ui-kit_components_text-field_properties_text_font-family
|
|
68
|
+
);
|
|
69
|
+
font-size: var(
|
|
70
|
+
--recursica_ui-kit_components_text-field_properties_text_font-size
|
|
71
|
+
);
|
|
72
|
+
font-style: var(
|
|
73
|
+
--recursica_ui-kit_components_text-field_properties_text_font-style
|
|
74
|
+
);
|
|
75
|
+
font-weight: var(
|
|
76
|
+
--recursica_ui-kit_components_text-field_properties_text_font-weight
|
|
77
|
+
);
|
|
78
|
+
letter-spacing: var(
|
|
79
|
+
--recursica_ui-kit_components_text-field_properties_text_letter-spacing
|
|
80
|
+
);
|
|
81
|
+
line-height: var(
|
|
82
|
+
--recursica_ui-kit_components_text-field_properties_text_line-height
|
|
83
|
+
);
|
|
84
|
+
text-decoration: var(
|
|
85
|
+
--recursica_ui-kit_components_text-field_properties_text_text-decoration
|
|
86
|
+
);
|
|
87
|
+
text-transform: var(
|
|
88
|
+
--recursica_ui-kit_components_text-field_properties_text_text-transform
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
/* Base State Default Execution */
|
|
92
|
+
background-color: var(
|
|
93
|
+
--recursica_ui-kit_components_text-field_variants_states_default_properties_colors_background
|
|
94
|
+
);
|
|
95
|
+
border-color: var(
|
|
96
|
+
--recursica_ui-kit_components_text-field_variants_states_default_properties_colors_border-color
|
|
97
|
+
);
|
|
98
|
+
color: var(
|
|
99
|
+
--recursica_ui-kit_components_text-field_variants_states_default_properties_colors_text
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
outline: none;
|
|
103
|
+
transition:
|
|
104
|
+
border-color 0.15s ease,
|
|
105
|
+
background-color 0.15s ease;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.input::placeholder {
|
|
109
|
+
opacity: var(
|
|
110
|
+
--recursica_ui-kit_components_text-field_properties_placeholder-opacity
|
|
111
|
+
);
|
|
112
|
+
color: inherit;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Dynamic Padding Overrides */
|
|
116
|
+
.root[data-with-left-section] .input {
|
|
117
|
+
padding-left: var(--input-left-section-size);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.root[data-with-right-section] .input {
|
|
121
|
+
padding-right: var(--input-right-section-size);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* Flexible End-Caps (Icons, actions) */
|
|
125
|
+
.section {
|
|
126
|
+
display: flex;
|
|
127
|
+
align-items: center;
|
|
128
|
+
justify-content: center;
|
|
129
|
+
height: 100%;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.section :global(svg) {
|
|
133
|
+
width: var(--recursica_ui-kit_components_text-field_properties_icon-size);
|
|
134
|
+
height: var(--recursica_ui-kit_components_text-field_properties_icon-size);
|
|
135
|
+
color: var(
|
|
136
|
+
--recursica_ui-kit_components_text-field_variants_states_default_properties_colors_leading-icon
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.section[data-position="right"] :global(svg) {
|
|
141
|
+
color: var(
|
|
142
|
+
--recursica_ui-kit_components_text-field_variants_states_default_properties_colors_trailing-icon
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* -------------------------------------
|
|
147
|
+
STATE CASCADE ARCHITECTURE
|
|
148
|
+
-------------------------------------- */
|
|
149
|
+
|
|
150
|
+
/* Focus State Mapping (Triggered internally via browser pseudo-pseudo-class) */
|
|
151
|
+
.input:focus-within,
|
|
152
|
+
.input:focus {
|
|
153
|
+
border-color: var(
|
|
154
|
+
--recursica_ui-kit_components_text-field_variants_states_focus_properties_colors_border-color
|
|
155
|
+
);
|
|
156
|
+
background-color: var(
|
|
157
|
+
--recursica_ui-kit_components_text-field_variants_states_focus_properties_colors_background
|
|
158
|
+
);
|
|
159
|
+
color: var(
|
|
160
|
+
--recursica_ui-kit_components_text-field_variants_states_focus_properties_colors_text
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.root:focus-within .section[data-position="left"] :global(svg) {
|
|
165
|
+
color: var(
|
|
166
|
+
--recursica_ui-kit_components_text-field_variants_states_focus_properties_colors_leading-icon
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.root:focus-within .section[data-position="right"] :global(svg) {
|
|
171
|
+
color: var(
|
|
172
|
+
--recursica_ui-kit_components_text-field_variants_states_focus_properties_colors_trailing-icon
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* Error State Mapping (Propagated strictly down from the wrapper DOM context) */
|
|
177
|
+
.root[data-error] .input {
|
|
178
|
+
border-color: var(
|
|
179
|
+
--recursica_ui-kit_components_text-field_variants_states_error_properties_colors_border-color
|
|
180
|
+
) !important;
|
|
181
|
+
background-color: var(
|
|
182
|
+
--recursica_ui-kit_components_text-field_variants_states_error_properties_colors_background
|
|
183
|
+
) !important;
|
|
184
|
+
color: var(
|
|
185
|
+
--recursica_ui-kit_components_text-field_variants_states_error_properties_colors_text
|
|
186
|
+
) !important;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.root[data-error] .section[data-position="left"] :global(svg) {
|
|
190
|
+
color: var(
|
|
191
|
+
--recursica_ui-kit_components_text-field_variants_states_error_properties_colors_leading-icon
|
|
192
|
+
) !important;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.root[data-error] .section[data-position="right"] :global(svg) {
|
|
196
|
+
color: var(
|
|
197
|
+
--recursica_ui-kit_components_text-field_variants_states_error_properties_colors_trailing-icon
|
|
198
|
+
) !important;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* Disabled State Mapping (Propagated strictly down from the wrapper DOM context) */
|
|
202
|
+
.root[data-disabled] .input {
|
|
203
|
+
border-color: var(
|
|
204
|
+
--recursica_ui-kit_components_text-field_variants_states_disabled_properties_colors_border-color
|
|
205
|
+
) !important;
|
|
206
|
+
background-color: var(
|
|
207
|
+
--recursica_ui-kit_components_text-field_variants_states_disabled_properties_colors_background
|
|
208
|
+
) !important;
|
|
209
|
+
color: var(
|
|
210
|
+
--recursica_ui-kit_components_text-field_variants_states_disabled_properties_colors_text
|
|
211
|
+
) !important;
|
|
212
|
+
cursor: not-allowed;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.root[data-disabled] .section[data-position="left"] :global(svg) {
|
|
216
|
+
color: var(
|
|
217
|
+
--recursica_ui-kit_components_text-field_variants_states_disabled_properties_colors_leading-icon
|
|
218
|
+
) !important;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.root[data-disabled] .section[data-position="right"] :global(svg) {
|
|
222
|
+
color: var(
|
|
223
|
+
--recursica_ui-kit_components_text-field_variants_states_disabled_properties_colors_trailing-icon
|
|
224
|
+
) !important;
|
|
225
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { TextField } from "./TextField";
|
|
3
|
+
import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
|
|
4
|
+
const meta: Meta<typeof TextField> = {
|
|
5
|
+
title: "UI-Kit/TextField",
|
|
6
|
+
component: TextField,
|
|
7
|
+
tags: ["autodocs"],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: `
|
|
12
|
+
The \`TextField\` primitive functions as a universal text entry input natively integrated directly into the unified \`FormControlWrapper\` architecture.
|
|
13
|
+
|
|
14
|
+
### Architectural Decoupling
|
|
15
|
+
Recursica forcibly overrides the internal Mantine \`Input.Wrapper\` defaults injecting an untamed \`<Input>\` layout primitive perfectly mapped back into our rigid design systems. State modifiers (e.g. Focus, Errors) hook flawlessly back onto our CSS module mapping variable colors strictly accurately.
|
|
16
|
+
|
|
17
|
+
### Examples
|
|
18
|
+
Always structure horizontal architectures via the generic \`formLayout\` parameter.
|
|
19
|
+
\`\`\`tsx
|
|
20
|
+
<TextField
|
|
21
|
+
label="Primary Network Socket"
|
|
22
|
+
assistiveText="Ensure connections resolve seamlessly."
|
|
23
|
+
formLayout="stacked"
|
|
24
|
+
/>
|
|
25
|
+
\`\`\`
|
|
26
|
+
`,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
argTypes: {
|
|
31
|
+
...formControlArgTypes,
|
|
32
|
+
disabled: {
|
|
33
|
+
control: "boolean",
|
|
34
|
+
description:
|
|
35
|
+
"Maps the formal disabled variable states structurally to the input core.",
|
|
36
|
+
},
|
|
37
|
+
error: {
|
|
38
|
+
control: "text",
|
|
39
|
+
description:
|
|
40
|
+
"Applies the strict error string boundary rendering invalid structures seamlessly.",
|
|
41
|
+
},
|
|
42
|
+
required: {
|
|
43
|
+
control: "boolean",
|
|
44
|
+
},
|
|
45
|
+
label: {
|
|
46
|
+
control: "text",
|
|
47
|
+
},
|
|
48
|
+
assistiveText: {
|
|
49
|
+
control: "text",
|
|
50
|
+
},
|
|
51
|
+
readOnly: {
|
|
52
|
+
control: "boolean",
|
|
53
|
+
description:
|
|
54
|
+
"Toggles structural read-only data presentation explicitly blocking standard component bindings.",
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default meta;
|
|
60
|
+
|
|
61
|
+
type Story = StoryObj<typeof TextField>;
|
|
62
|
+
|
|
63
|
+
export const Default: Story = {
|
|
64
|
+
args: {
|
|
65
|
+
disabled: false,
|
|
66
|
+
label: "Authentication Token",
|
|
67
|
+
placeholder: "Enter validation hash...",
|
|
68
|
+
assistiveText:
|
|
69
|
+
"Tokens are stored identically locally and strictly ephemeral.",
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const FormsSideBySide: Story = {
|
|
74
|
+
args: {
|
|
75
|
+
label: "Distributed Access Control",
|
|
76
|
+
placeholder: "admin@node.local",
|
|
77
|
+
assistiveText:
|
|
78
|
+
"Specify the exact cluster administrative credentials enforcing strict domain policies. This violently long string tests native textual wrapping safely mapping alongside inputs.",
|
|
79
|
+
formLayout: "side-by-side",
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const WithLeadingIcon: Story = {
|
|
84
|
+
args: {
|
|
85
|
+
label: "Search Global Context",
|
|
86
|
+
placeholder: "Search for repositories...",
|
|
87
|
+
leftSection: (
|
|
88
|
+
<svg
|
|
89
|
+
width="24"
|
|
90
|
+
height="24"
|
|
91
|
+
viewBox="0 0 24 24"
|
|
92
|
+
fill="none"
|
|
93
|
+
stroke="currentColor"
|
|
94
|
+
strokeWidth="2"
|
|
95
|
+
strokeLinecap="round"
|
|
96
|
+
strokeLinejoin="round"
|
|
97
|
+
>
|
|
98
|
+
<circle cx="11" cy="11" r="8"></circle>
|
|
99
|
+
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
|
100
|
+
</svg>
|
|
101
|
+
),
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const WithTrailingIcon: Story = {
|
|
106
|
+
args: {
|
|
107
|
+
label: "Validation URL",
|
|
108
|
+
placeholder: "https://recursica.dev",
|
|
109
|
+
rightSection: (
|
|
110
|
+
<svg
|
|
111
|
+
width="24"
|
|
112
|
+
height="24"
|
|
113
|
+
viewBox="0 0 24 24"
|
|
114
|
+
fill="none"
|
|
115
|
+
stroke="currentColor"
|
|
116
|
+
strokeWidth="2"
|
|
117
|
+
strokeLinecap="round"
|
|
118
|
+
strokeLinejoin="round"
|
|
119
|
+
>
|
|
120
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
121
|
+
</svg>
|
|
122
|
+
),
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export const Disabled: Story = {
|
|
127
|
+
args: {
|
|
128
|
+
label: "Disabled Deployment Node",
|
|
129
|
+
placeholder: "Disabled primitive map...",
|
|
130
|
+
disabled: true,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const ErrorState: Story = {
|
|
135
|
+
args: {
|
|
136
|
+
label: "Cluster Failure",
|
|
137
|
+
placeholder: "Failing component instance...",
|
|
138
|
+
defaultValue: "Invalid Execution Plan",
|
|
139
|
+
error:
|
|
140
|
+
"Critical runtime node disconnect detected traversing DOM architecture.",
|
|
141
|
+
required: true,
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export const StaticReadOnly: Story = {
|
|
146
|
+
args: {
|
|
147
|
+
label: "Static ReadOnly Review",
|
|
148
|
+
placeholder: "Ignored...",
|
|
149
|
+
value: "Explicitly Uneditable Bound Output",
|
|
150
|
+
readOnly: true,
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export const EditableReadOnly: Story = {
|
|
155
|
+
args: {
|
|
156
|
+
label: "Editable ReadOnly Review",
|
|
157
|
+
placeholder: "Ignored until active...",
|
|
158
|
+
defaultValue: "Waiting for Edit Execution",
|
|
159
|
+
readOnly: true,
|
|
160
|
+
labelWithEditIcon: true,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import React, { forwardRef } from "react";
|
|
2
|
+
import { Input, type InputProps, type InputWrapperProps } from "@mantine/core";
|
|
3
|
+
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
4
|
+
import {
|
|
5
|
+
filterStylingProps,
|
|
6
|
+
type RecursicaOverStyled,
|
|
7
|
+
} from "../../utils/filterStylingProps";
|
|
8
|
+
import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
|
|
9
|
+
import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
|
|
10
|
+
import styles from "./TextField.module.css";
|
|
11
|
+
|
|
12
|
+
export interface RecursicaTextFieldProps
|
|
13
|
+
extends Omit<InputProps, "size" | "variant" | "radius" | "wrapperProps">,
|
|
14
|
+
Pick<
|
|
15
|
+
InputWrapperProps,
|
|
16
|
+
"label" | "error" | "required" | "withAsterisk" | "id"
|
|
17
|
+
>,
|
|
18
|
+
Omit<
|
|
19
|
+
React.ComponentPropsWithoutRef<"input">,
|
|
20
|
+
"size" | "style" | "className" | "id"
|
|
21
|
+
>,
|
|
22
|
+
Omit<
|
|
23
|
+
RecursicaFormControlWrapperProps,
|
|
24
|
+
"controlMaxWidth" | "controlMinWidth"
|
|
25
|
+
>,
|
|
26
|
+
ReadOnlyControlProps {}
|
|
27
|
+
|
|
28
|
+
export type TextFieldProps = RecursicaOverStyled<RecursicaTextFieldProps>;
|
|
29
|
+
|
|
30
|
+
export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
31
|
+
function TextField(
|
|
32
|
+
{
|
|
33
|
+
overStyled = false,
|
|
34
|
+
formLayout = "stacked",
|
|
35
|
+
|
|
36
|
+
// Label & Wrapper Maps
|
|
37
|
+
labelSize,
|
|
38
|
+
labelAlignment,
|
|
39
|
+
labelOptionalText,
|
|
40
|
+
labelWithEditIcon,
|
|
41
|
+
onLabelEditClick,
|
|
42
|
+
|
|
43
|
+
label,
|
|
44
|
+
assistiveText,
|
|
45
|
+
assistiveWithIcon,
|
|
46
|
+
error,
|
|
47
|
+
required,
|
|
48
|
+
withAsterisk,
|
|
49
|
+
id,
|
|
50
|
+
className,
|
|
51
|
+
style,
|
|
52
|
+
disabled,
|
|
53
|
+
readOnly,
|
|
54
|
+
readOnlyComponent,
|
|
55
|
+
value,
|
|
56
|
+
defaultValue,
|
|
57
|
+
...rest
|
|
58
|
+
},
|
|
59
|
+
ref,
|
|
60
|
+
) {
|
|
61
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
62
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
63
|
+
|
|
64
|
+
// Delete prohibited sizing hooks from bypassing variables natively
|
|
65
|
+
delete restRecord["size"];
|
|
66
|
+
delete restRecord["variant"];
|
|
67
|
+
delete restRecord["radius"];
|
|
68
|
+
|
|
69
|
+
// Securely map core native blocks down ensuring nested CSS modules map precisely
|
|
70
|
+
const mergedClassNames: Partial<Record<string, string>> = {
|
|
71
|
+
wrapper: styles.root, // The nested Input internal relative wrapper bounding box
|
|
72
|
+
input: styles.input,
|
|
73
|
+
section: styles.section,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const classNamesProp = restRecord.classNames;
|
|
77
|
+
if (
|
|
78
|
+
classNamesProp &&
|
|
79
|
+
typeof classNamesProp === "object" &&
|
|
80
|
+
!Array.isArray(classNamesProp)
|
|
81
|
+
) {
|
|
82
|
+
const o = classNamesProp as Partial<Record<string, string>>;
|
|
83
|
+
mergedClassNames.wrapper = o.wrapper
|
|
84
|
+
? `${styles.root} ${o.wrapper}`
|
|
85
|
+
: styles.root;
|
|
86
|
+
mergedClassNames.input = o.input
|
|
87
|
+
? `${styles.input} ${o.input}`
|
|
88
|
+
: styles.input;
|
|
89
|
+
mergedClassNames.section = o.section
|
|
90
|
+
? `${styles.section} ${o.section}`
|
|
91
|
+
: styles.section;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<WithReadOnlyWrapper
|
|
96
|
+
className={className}
|
|
97
|
+
style={style as React.CSSProperties}
|
|
98
|
+
controlMaxWidth="var(--recursica_ui-kit_components_text-field_properties_max-width)"
|
|
99
|
+
controlMinWidth="var(--recursica_ui-kit_components_text-field_properties_min-width)"
|
|
100
|
+
overStyled={overStyled as true}
|
|
101
|
+
formLayout={formLayout}
|
|
102
|
+
labelSize={labelSize}
|
|
103
|
+
labelAlignment={labelAlignment}
|
|
104
|
+
labelOptionalText={labelOptionalText}
|
|
105
|
+
labelWithEditIcon={labelWithEditIcon}
|
|
106
|
+
onLabelEditClick={onLabelEditClick}
|
|
107
|
+
label={label}
|
|
108
|
+
assistiveText={assistiveText}
|
|
109
|
+
assistiveWithIcon={assistiveWithIcon}
|
|
110
|
+
error={error}
|
|
111
|
+
required={required}
|
|
112
|
+
withAsterisk={withAsterisk}
|
|
113
|
+
id={id}
|
|
114
|
+
readOnly={readOnly}
|
|
115
|
+
readOnlyComponent={readOnlyComponent}
|
|
116
|
+
readOnlyType="text"
|
|
117
|
+
readOnlyValue={value !== undefined ? value : defaultValue}
|
|
118
|
+
activeComponent={
|
|
119
|
+
/* Naked Input execution safely decoupled from Mantine's macro Input.Wrapper DOM hooks */
|
|
120
|
+
<Input
|
|
121
|
+
ref={ref}
|
|
122
|
+
classNames={mergedClassNames}
|
|
123
|
+
disabled={disabled}
|
|
124
|
+
value={value}
|
|
125
|
+
defaultValue={defaultValue}
|
|
126
|
+
wrapperProps={{
|
|
127
|
+
"data-disabled": disabled ? "true" : undefined,
|
|
128
|
+
"data-error": error ? "true" : undefined,
|
|
129
|
+
}}
|
|
130
|
+
{...(sanitizedProps as unknown as InputProps)}
|
|
131
|
+
/>
|
|
132
|
+
}
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
},
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
TextField.displayName = "TextField";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { TimePicker } from "./TimePicker";
|
|
3
|
+
import { ComingSoon } from "@recursica/storybook-template";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof TimePicker> = {
|
|
6
|
+
title: "UI-Kit/🚧 TimePicker",
|
|
7
|
+
component: TimePicker,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
argTypes: {
|
|
10
|
+
disabled: {
|
|
11
|
+
control: "boolean",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default meta;
|
|
17
|
+
|
|
18
|
+
type Story = StoryObj<typeof TimePicker>;
|
|
19
|
+
|
|
20
|
+
export const Default: Story = {
|
|
21
|
+
render: () => <ComingSoon componentName="TimePicker" />,
|
|
22
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Timeline } from "./Timeline";
|
|
3
|
+
import { ComingSoon } from "@recursica/storybook-template";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Timeline> = {
|
|
6
|
+
title: "UI-Kit/🚧 Timeline",
|
|
7
|
+
component: Timeline,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
|
|
13
|
+
type Story = StoryObj<typeof Timeline>;
|
|
14
|
+
|
|
15
|
+
export const Default: Story = {
|
|
16
|
+
render: () => <ComingSoon componentName="Timeline" />,
|
|
17
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Title } from "./Title";
|
|
3
|
+
import { Layer } from "@recursica/adapter-common";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Title> = {
|
|
6
|
+
title: "UI-Kit/Title",
|
|
7
|
+
component: Title,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
parameters: {
|
|
10
|
+
docs: {
|
|
11
|
+
description: {
|
|
12
|
+
component:
|
|
13
|
+
"The semantic `<Title>` abstraction intrinsically links pure `h1-h6` tag generation with exact Recursica design boundaries to preserve SEO and screen reader trees uniformly globally.",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
argTypes: {
|
|
18
|
+
order: {
|
|
19
|
+
control: "select",
|
|
20
|
+
options: [1, 2, 3, 4, 5, 6],
|
|
21
|
+
description:
|
|
22
|
+
"Controls the `h` tag and the resultant typographical weighting natively mapped to Recursica.",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default meta;
|
|
28
|
+
|
|
29
|
+
type Story = StoryObj<typeof Title>;
|
|
30
|
+
|
|
31
|
+
export const Default: Story = {
|
|
32
|
+
args: {
|
|
33
|
+
order: 1,
|
|
34
|
+
children: "Semantic H1 Document Boundary",
|
|
35
|
+
},
|
|
36
|
+
render: ({ ...args }) => (
|
|
37
|
+
<Layer layer={0} style={{ padding: "48px" }}>
|
|
38
|
+
<Title {...args} />
|
|
39
|
+
</Layer>
|
|
40
|
+
),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const StaticVariations: Story = {
|
|
44
|
+
args: {},
|
|
45
|
+
render: () => (
|
|
46
|
+
<Layer
|
|
47
|
+
layer={0}
|
|
48
|
+
style={{
|
|
49
|
+
padding: "48px",
|
|
50
|
+
display: "flex",
|
|
51
|
+
flexDirection: "column",
|
|
52
|
+
gap: "24px",
|
|
53
|
+
}}
|
|
54
|
+
>
|
|
55
|
+
<Title order={1}>H1 Title</Title>
|
|
56
|
+
<Title order={2}>H2 Title</Title>
|
|
57
|
+
<Title order={3}>H3 Title</Title>
|
|
58
|
+
<Title order={4}>H4 Title</Title>
|
|
59
|
+
<Title order={5}>H5 Title</Title>
|
|
60
|
+
<Title order={6}>H6 Title</Title>
|
|
61
|
+
</Layer>
|
|
62
|
+
),
|
|
63
|
+
};
|