@recursica/mantine-adapter 0.20.0 → 0.22.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 +13 -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 +1624 -1498
- package/dist/mantine-adapter.js.map +1 -1
- package/dist/src/components/AutoComplete/AutoComplete.d.ts +9 -0
- package/dist/src/components/Avatar/Avatar.d.ts +1 -1
- package/dist/src/components/Badge/Badge.d.ts +1 -1
- package/dist/src/components/Button/Button.d.ts +11 -1
- package/dist/src/components/Card/Card.d.ts +1 -1
- package/dist/src/components/Flex/Flex.d.ts +1 -1
- package/dist/src/components/Link/Link.d.ts +1 -1
- package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +6 -1
- package/dist/src/components/Text/Text.d.ts +1 -1
- package/dist/src/components/Toast/Toast.d.ts +1 -1
- package/dist/src/components/index.d.ts +1 -0
- package/package.json +5 -2
- package/src/GlobalExemptions.modules.css +13 -0
- package/src/components/AutoComplete/AUTOCOMPLETE_IMPLEMENTATION_NOTES.md +21 -0
- package/src/components/AutoComplete/AutoComplete.module.css +311 -0
- package/src/components/AutoComplete/AutoComplete.stories.tsx +187 -0
- package/src/components/AutoComplete/AutoComplete.tsx +154 -0
- package/src/components/Avatar/Avatar.module.css +40 -36
- package/src/components/Badge/Badge.module.css +4 -1
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +3 -10
- package/src/components/Button/Button.module.css +220 -57
- package/src/components/Button/Button.stories.tsx +68 -0
- package/src/components/Button/Button.tsx +42 -3
- package/src/components/Button/IMPLEMENTATION_NOTES.md +16 -0
- package/src/components/Card/Card.module.css +58 -1
- package/src/components/Card/Card.stories.tsx +4 -2
- package/src/components/Checkbox/Checkbox.module.css +74 -46
- package/src/components/Checkbox/Checkbox.stories.tsx +3 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +1 -9
- package/src/components/Chip/Chip.module.css +19 -1
- package/src/components/DatePicker/DatePicker.module.css +45 -0
- package/src/components/Dropdown/Dropdown.module.css +42 -15
- package/src/components/Dropdown/Dropdown.stories.tsx +3 -0
- package/src/components/Dropdown/Dropdown.tsx +5 -1
- package/src/components/FileInput/FileInput.module.css +50 -0
- package/src/components/FileUpload/FileUpload.module.css +43 -0
- package/src/components/FormControlLayout/FormControlLayout.module.css +12 -2
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +66 -0
- package/src/components/HoverCard/HoverCard.module.css +12 -5
- package/src/components/Label/Label.module.css +11 -3
- package/src/components/Link/Link.module.css +8 -0
- package/src/components/Menu/Menu.module.css +73 -30
- package/src/components/Modal/Modal.module.css +92 -47
- package/src/components/NumberInput/NumberInput.module.css +46 -15
- package/src/components/NumberInput/NumberInput.tsx +5 -1
- package/src/components/Pagination/Pagination.module.css +123 -41
- package/src/components/Panel/Panel.module.css +55 -3
- package/src/components/Popover/Popover.module.css +6 -4
- package/src/components/Radio/Radio.module.css +72 -59
- package/src/components/Radio/Radio.stories.tsx +3 -0
- package/src/components/Radio/RadioGroup.tsx +1 -8
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +14 -0
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +16 -1
- package/src/components/SegmentedControl/SegmentedControl.module.css +106 -41
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +1 -4
- package/src/components/SegmentedControl/SegmentedControl.tsx +18 -4
- package/src/components/Slider/Slider.module.css +89 -0
- package/src/components/Stepper/Stepper.module.css +53 -2
- package/src/components/Switch/Switch.module.css +62 -23
- package/src/components/Switch/Switch.stories.tsx +3 -0
- package/src/components/Switch/Switch.tsx +1 -0
- package/src/components/Switch/SwitchGroup.tsx +3 -10
- package/src/components/Tabs/Tabs.module.css +33 -12
- package/src/components/TextArea/TextArea.module.css +58 -120
- package/src/components/TextArea/TextArea.stories.tsx +3 -0
- package/src/components/TextArea/TextArea.tsx +7 -3
- package/src/components/TextField/TextField.module.css +46 -15
- package/src/components/TextField/TextField.tsx +5 -1
- package/src/components/TimePicker/TimePicker.module.css +44 -0
- package/src/components/Timeline/Timeline.module.css +6 -0
- package/src/components/Toast/Toast.module.css +62 -1
- package/src/components/Toast/Toast.tsx +1 -1
- package/src/components/Tooltip/Tooltip.module.css +9 -0
- package/src/components/TransferList/TransferList.module.css +41 -0
- package/src/components/index.ts +1 -0
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IMPLEMENTATION NOTES:
|
|
3
|
+
*
|
|
4
|
+
* - Icon-Only Flexbox Hack: Mantine renders a hidden `.label` span even if `children` is empty.
|
|
5
|
+
* Because we apply `flex: 1` to `.label`, this empty span grows and pushes the `leftSection` (the icon)
|
|
6
|
+
* off-center. To fix this, we apply `display: none` to the label when `data-content="icon-only"`.
|
|
7
|
+
*/
|
|
1
8
|
/* Baseline and Reset */
|
|
2
9
|
.root {
|
|
3
10
|
box-sizing: border-box;
|
|
@@ -36,15 +43,20 @@
|
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
/* Internal Mantine reset & layout logic for Truncation */
|
|
39
|
-
.root >
|
|
46
|
+
.root > *:not(.loader) {
|
|
40
47
|
min-width: 0;
|
|
41
48
|
position: relative;
|
|
42
49
|
z-index: 1;
|
|
43
50
|
}
|
|
44
51
|
|
|
52
|
+
.loader {
|
|
53
|
+
/* Mantine absolutely positions this; we just need a hook to exclude it from the child reset */
|
|
54
|
+
}
|
|
55
|
+
|
|
45
56
|
.label {
|
|
46
57
|
display: flex;
|
|
47
58
|
align-items: center;
|
|
59
|
+
justify-content: center;
|
|
48
60
|
min-width: 0;
|
|
49
61
|
flex: 1 1 0;
|
|
50
62
|
}
|
|
@@ -61,39 +73,114 @@
|
|
|
61
73
|
|
|
62
74
|
/* ==== SIZES ==== */
|
|
63
75
|
.root[data-size="default"] {
|
|
64
|
-
|
|
65
|
-
--recursica_ui-kit_components_button_variants_sizes_default_properties_border-radius
|
|
66
|
-
);
|
|
67
|
-
height: var(
|
|
68
|
-
--recursica_ui-kit_components_button_variants_sizes_default_properties_height
|
|
69
|
-
);
|
|
70
|
-
min-width: var(
|
|
71
|
-
--recursica_ui-kit_components_button_variants_sizes_default_properties_min-width
|
|
72
|
-
);
|
|
76
|
+
/* Set baseline paddings and min-width using generic tokens as baseline defaults */
|
|
73
77
|
padding: 0
|
|
74
78
|
var(
|
|
75
79
|
--recursica_ui-kit_components_button_variants_sizes_default_properties_horizontal-padding
|
|
76
80
|
);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
max-width: var(
|
|
80
|
-
--recursica_ui-kit_components_button_variants_sizes_default_properties_max-label-width
|
|
81
|
+
min-width: var(
|
|
82
|
+
--recursica_ui-kit_components_button_variants_sizes_default_properties_min-width
|
|
81
83
|
);
|
|
84
|
+
|
|
85
|
+
height: var(
|
|
86
|
+
--recursica_ui-kit_components_button_variants_sizes_default_properties_height
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
.labelText {
|
|
90
|
+
max-width: var(
|
|
91
|
+
--recursica_ui-kit_components_button_variants_sizes_default_properties_max-label-width
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.iconWrapper {
|
|
96
|
+
width: var(
|
|
97
|
+
--recursica_ui-kit_components_button_variants_sizes_default_properties_icon
|
|
98
|
+
);
|
|
99
|
+
height: var(
|
|
100
|
+
--recursica_ui-kit_components_button_variants_sizes_default_properties_icon
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.section {
|
|
105
|
+
gap: var(
|
|
106
|
+
--recursica_ui-kit_components_button_variants_sizes_default_properties_icon-text-gap
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
&[data-content="label"] {
|
|
111
|
+
border-radius: var(
|
|
112
|
+
--recursica_ui-kit_components_button_variants_content_label_variants_sizes_default_properties_border-radius
|
|
113
|
+
);
|
|
114
|
+
min-width: var(
|
|
115
|
+
--recursica_ui-kit_components_button_variants_content_label_variants_sizes_default_properties_min-width
|
|
116
|
+
);
|
|
117
|
+
padding: 0
|
|
118
|
+
var(
|
|
119
|
+
--recursica_ui-kit_components_button_variants_content_label_variants_sizes_default_properties_horizontal-padding
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
&[data-content="icon-label"] {
|
|
124
|
+
border-radius: var(
|
|
125
|
+
--recursica_ui-kit_components_button_variants_content_icon-label_variants_sizes_default_properties_border-radius
|
|
126
|
+
);
|
|
127
|
+
min-width: var(
|
|
128
|
+
--recursica_ui-kit_components_button_variants_content_icon-label_variants_sizes_default_properties_min-width
|
|
129
|
+
);
|
|
130
|
+
padding: 0
|
|
131
|
+
var(
|
|
132
|
+
--recursica_ui-kit_components_button_variants_content_icon-label_variants_sizes_default_properties_horizontal-padding
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
&[data-content="icon-only"] {
|
|
137
|
+
border-radius: var(
|
|
138
|
+
--recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_default_properties_border-radius
|
|
139
|
+
);
|
|
140
|
+
min-width: var(
|
|
141
|
+
--recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_default_properties_min-width
|
|
142
|
+
);
|
|
143
|
+
padding: 0
|
|
144
|
+
var(
|
|
145
|
+
--recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_default_properties_horizontal-padding
|
|
146
|
+
);
|
|
147
|
+
}
|
|
82
148
|
}
|
|
149
|
+
|
|
83
150
|
.root[data-size="small"] {
|
|
84
|
-
|
|
85
|
-
|
|
151
|
+
/* Set baseline paddings and min-width using generic tokens as baseline defaults */
|
|
152
|
+
padding: 0
|
|
153
|
+
var(
|
|
154
|
+
--recursica_ui-kit_components_button_variants_sizes_small_properties_horizontal-padding
|
|
155
|
+
);
|
|
156
|
+
min-width: var(
|
|
157
|
+
--recursica_ui-kit_components_button_variants_sizes_small_properties_min-width
|
|
86
158
|
);
|
|
159
|
+
|
|
87
160
|
height: var(
|
|
88
161
|
--recursica_ui-kit_components_button_variants_sizes_small_properties_height
|
|
89
162
|
);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
163
|
+
|
|
164
|
+
.labelText {
|
|
165
|
+
max-width: var(
|
|
166
|
+
--recursica_ui-kit_components_button_variants_sizes_small_properties_max-label-width
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.iconWrapper {
|
|
171
|
+
width: var(
|
|
172
|
+
--recursica_ui-kit_components_button_variants_sizes_small_properties_icon
|
|
96
173
|
);
|
|
174
|
+
height: var(
|
|
175
|
+
--recursica_ui-kit_components_button_variants_sizes_small_properties_icon
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.section {
|
|
180
|
+
gap: var(
|
|
181
|
+
--recursica_ui-kit_components_button_variants_sizes_small_properties_icon-text-gap
|
|
182
|
+
);
|
|
183
|
+
}
|
|
97
184
|
|
|
98
185
|
/* Override specific typography for small */
|
|
99
186
|
font-family: var(
|
|
@@ -114,11 +201,75 @@
|
|
|
114
201
|
--recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-weight
|
|
115
202
|
)
|
|
116
203
|
);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
204
|
+
font-style: var(
|
|
205
|
+
--recursica_ui-kit_components_button_variants_sizes_small_properties_text_font-style,
|
|
206
|
+
var(
|
|
207
|
+
--recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-style
|
|
208
|
+
)
|
|
121
209
|
);
|
|
210
|
+
letter-spacing: var(
|
|
211
|
+
--recursica_ui-kit_components_button_variants_sizes_small_properties_text_letter-spacing,
|
|
212
|
+
var(
|
|
213
|
+
--recursica_ui-kit_components_button_variants_sizes_default_properties_text_letter-spacing
|
|
214
|
+
)
|
|
215
|
+
);
|
|
216
|
+
line-height: var(
|
|
217
|
+
--recursica_ui-kit_components_button_variants_sizes_small_properties_text_line-height,
|
|
218
|
+
var(
|
|
219
|
+
--recursica_ui-kit_components_button_variants_sizes_default_properties_text_line-height
|
|
220
|
+
)
|
|
221
|
+
);
|
|
222
|
+
text-decoration: var(
|
|
223
|
+
--recursica_ui-kit_components_button_variants_sizes_small_properties_text_text-decoration,
|
|
224
|
+
var(
|
|
225
|
+
--recursica_ui-kit_components_button_variants_sizes_default_properties_text_text-decoration
|
|
226
|
+
)
|
|
227
|
+
);
|
|
228
|
+
text-transform: var(
|
|
229
|
+
--recursica_ui-kit_components_button_variants_sizes_small_properties_text_text-transform,
|
|
230
|
+
var(
|
|
231
|
+
--recursica_ui-kit_components_button_variants_sizes_default_properties_text_text-transform
|
|
232
|
+
)
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
&[data-content="label"] {
|
|
236
|
+
border-radius: var(
|
|
237
|
+
--recursica_ui-kit_components_button_variants_content_label_variants_sizes_small_properties_border-radius
|
|
238
|
+
);
|
|
239
|
+
min-width: var(
|
|
240
|
+
--recursica_ui-kit_components_button_variants_content_label_variants_sizes_small_properties_min-width
|
|
241
|
+
);
|
|
242
|
+
padding: 0
|
|
243
|
+
var(
|
|
244
|
+
--recursica_ui-kit_components_button_variants_content_label_variants_sizes_small_properties_horizontal-padding
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
&[data-content="icon-label"] {
|
|
249
|
+
border-radius: var(
|
|
250
|
+
--recursica_ui-kit_components_button_variants_content_icon-label_variants_sizes_small_properties_border-radius
|
|
251
|
+
);
|
|
252
|
+
min-width: var(
|
|
253
|
+
--recursica_ui-kit_components_button_variants_content_icon-label_variants_sizes_small_properties_min-width
|
|
254
|
+
);
|
|
255
|
+
padding: 0
|
|
256
|
+
var(
|
|
257
|
+
--recursica_ui-kit_components_button_variants_content_icon-label_variants_sizes_small_properties_horizontal-padding
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
&[data-content="icon-only"] {
|
|
262
|
+
border-radius: var(
|
|
263
|
+
--recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_small_properties_border-radius
|
|
264
|
+
);
|
|
265
|
+
min-width: var(
|
|
266
|
+
--recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_small_properties_min-width
|
|
267
|
+
);
|
|
268
|
+
padding: 0
|
|
269
|
+
var(
|
|
270
|
+
--recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_small_properties_horizontal-padding
|
|
271
|
+
);
|
|
272
|
+
}
|
|
122
273
|
}
|
|
123
274
|
|
|
124
275
|
/* Icon Resets */
|
|
@@ -133,45 +284,22 @@
|
|
|
133
284
|
height: 100%;
|
|
134
285
|
object-fit: contain;
|
|
135
286
|
}
|
|
136
|
-
.root[data-size="default"] .iconWrapper {
|
|
137
|
-
width: var(
|
|
138
|
-
--recursica_ui-kit_components_button_variants_sizes_default_properties_icon
|
|
139
|
-
);
|
|
140
|
-
height: var(
|
|
141
|
-
--recursica_ui-kit_components_button_variants_sizes_default_properties_icon
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
.root[data-size="small"] .iconWrapper {
|
|
145
|
-
width: var(
|
|
146
|
-
--recursica_ui-kit_components_button_variants_sizes_small_properties_icon
|
|
147
|
-
);
|
|
148
|
-
height: var(
|
|
149
|
-
--recursica_ui-kit_components_button_variants_sizes_small_properties_icon
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
287
|
|
|
153
288
|
.section {
|
|
154
289
|
min-width: 0;
|
|
155
290
|
}
|
|
156
|
-
.root[data-size="default"] .section {
|
|
157
|
-
gap: var(
|
|
158
|
-
--recursica_ui-kit_components_button_variants_sizes_default_properties_icon-text-gap
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
.root[data-size="small"] .section {
|
|
162
|
-
gap: var(
|
|
163
|
-
--recursica_ui-kit_components_button_variants_sizes_small_properties_icon-text-gap
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
291
|
|
|
167
292
|
/* Icon-only logic overrides */
|
|
168
|
-
.root[data-icon-only] .
|
|
293
|
+
.root[data-content="icon-only"] .label {
|
|
294
|
+
display: none;
|
|
295
|
+
}
|
|
296
|
+
.root[data-content="icon-only"] .section {
|
|
169
297
|
gap: 0;
|
|
170
298
|
}
|
|
171
|
-
.root[data-icon-only] .section[data-position="left"] {
|
|
299
|
+
.root[data-content="icon-only"] .section[data-position="left"] {
|
|
172
300
|
margin-inline-end: 0;
|
|
173
301
|
}
|
|
174
|
-
.root[data-icon-only] .section[data-position="right"] {
|
|
302
|
+
.root[data-content="icon-only"] .section[data-position="right"] {
|
|
175
303
|
margin-inline-start: 0;
|
|
176
304
|
}
|
|
177
305
|
|
|
@@ -210,13 +338,21 @@
|
|
|
210
338
|
--recursica_ui-kit_components_button_variants_sizes_small_properties_hover-color
|
|
211
339
|
);
|
|
212
340
|
}
|
|
213
|
-
.root:hover:not(:disabled)::after {
|
|
341
|
+
.root[data-size="default"]:hover:not(:disabled)::after {
|
|
214
342
|
opacity: var(
|
|
215
343
|
--recursica_ui-kit_components_button_variants_sizes_default_properties_hover-opacity,
|
|
216
344
|
0.1
|
|
217
345
|
);
|
|
218
346
|
}
|
|
219
|
-
|
|
347
|
+
.root[data-size="small"]:hover:not(:disabled)::after {
|
|
348
|
+
opacity: var(
|
|
349
|
+
--recursica_ui-kit_components_button_variants_sizes_small_properties_hover-opacity,
|
|
350
|
+
var(
|
|
351
|
+
--recursica_ui-kit_components_button_variants_sizes_default_properties_hover-opacity,
|
|
352
|
+
0.1
|
|
353
|
+
)
|
|
354
|
+
);
|
|
355
|
+
}
|
|
220
356
|
/* ==== VARIANTS ==== */
|
|
221
357
|
|
|
222
358
|
/* SOLID */
|
|
@@ -236,11 +372,20 @@
|
|
|
236
372
|
color: var(
|
|
237
373
|
--recursica_ui-kit_components_button_variants_styles_solid_properties_colors_text
|
|
238
374
|
);
|
|
375
|
+
|
|
376
|
+
.iconWrapper {
|
|
377
|
+
color: var(
|
|
378
|
+
--recursica_ui-kit_components_button_variants_styles_solid_properties_colors_icon-color
|
|
379
|
+
);
|
|
380
|
+
}
|
|
239
381
|
}
|
|
240
382
|
.root[data-variant="solid"]:hover:not(:disabled) {
|
|
241
383
|
color: var(
|
|
242
384
|
--recursica_ui-kit_components_button_variants_styles_solid_properties_colors_text-hover
|
|
243
385
|
);
|
|
386
|
+
box-shadow: var(
|
|
387
|
+
--recursica_ui-kit_components_button_variants_styles_solid_properties_hover-elevation
|
|
388
|
+
);
|
|
244
389
|
}
|
|
245
390
|
|
|
246
391
|
/* OUTLINE */
|
|
@@ -260,11 +405,20 @@
|
|
|
260
405
|
color: var(
|
|
261
406
|
--recursica_ui-kit_components_button_variants_styles_outline_properties_colors_text
|
|
262
407
|
);
|
|
408
|
+
|
|
409
|
+
.iconWrapper {
|
|
410
|
+
color: var(
|
|
411
|
+
--recursica_ui-kit_components_button_variants_styles_outline_properties_colors_icon-color
|
|
412
|
+
);
|
|
413
|
+
}
|
|
263
414
|
}
|
|
264
415
|
.root[data-variant="outline"]:hover:not(:disabled) {
|
|
265
416
|
color: var(
|
|
266
417
|
--recursica_ui-kit_components_button_variants_styles_outline_properties_colors_text-hover
|
|
267
418
|
);
|
|
419
|
+
box-shadow: var(
|
|
420
|
+
--recursica_ui-kit_components_button_variants_styles_outline_properties_hover-elevation
|
|
421
|
+
);
|
|
268
422
|
}
|
|
269
423
|
|
|
270
424
|
/* TEXT */
|
|
@@ -284,9 +438,18 @@
|
|
|
284
438
|
color: var(
|
|
285
439
|
--recursica_ui-kit_components_button_variants_styles_text_properties_colors_text
|
|
286
440
|
);
|
|
441
|
+
|
|
442
|
+
.iconWrapper {
|
|
443
|
+
color: var(
|
|
444
|
+
--recursica_ui-kit_components_button_variants_styles_text_properties_colors_icon-color
|
|
445
|
+
);
|
|
446
|
+
}
|
|
287
447
|
}
|
|
288
448
|
.root[data-variant="text"]:hover:not(:disabled) {
|
|
289
449
|
color: var(
|
|
290
450
|
--recursica_ui-kit_components_button_variants_styles_text_properties_colors_text-hover
|
|
291
451
|
);
|
|
452
|
+
box-shadow: var(
|
|
453
|
+
--recursica_ui-kit_components_button_variants_styles_text_properties_hover-elevation
|
|
454
|
+
);
|
|
292
455
|
}
|
|
@@ -10,6 +10,9 @@ const meta: Meta<ButtonStoryProps> = {
|
|
|
10
10
|
component: Button,
|
|
11
11
|
tags: ["autodocs"],
|
|
12
12
|
argTypes: {
|
|
13
|
+
disabled: {
|
|
14
|
+
control: "boolean",
|
|
15
|
+
},
|
|
13
16
|
variant: {
|
|
14
17
|
control: "select",
|
|
15
18
|
options: ["solid", "outline", "text"],
|
|
@@ -20,6 +23,30 @@ const meta: Meta<ButtonStoryProps> = {
|
|
|
20
23
|
options: ["default", "small"],
|
|
21
24
|
description: "The size of the button",
|
|
22
25
|
},
|
|
26
|
+
loading: {
|
|
27
|
+
control: "boolean",
|
|
28
|
+
description: "Sets the button to a loading state",
|
|
29
|
+
},
|
|
30
|
+
useRecursicaLoader: {
|
|
31
|
+
control: "boolean",
|
|
32
|
+
description:
|
|
33
|
+
"Use the Recursica Loader component instead of the default Mantine loader",
|
|
34
|
+
},
|
|
35
|
+
loaderVariant: {
|
|
36
|
+
control: "select",
|
|
37
|
+
options: ["oval", "bars", "dots"],
|
|
38
|
+
description: "The visual variant of the Recursica Loader",
|
|
39
|
+
},
|
|
40
|
+
loaderSize: {
|
|
41
|
+
control: "select",
|
|
42
|
+
options: [undefined, "sm", "md", "lg", "small", "default", "large"],
|
|
43
|
+
description: "The size variant for the loader",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
args: {
|
|
47
|
+
useRecursicaLoader: true,
|
|
48
|
+
loaderVariant: "oval",
|
|
49
|
+
loaderSize: undefined,
|
|
23
50
|
},
|
|
24
51
|
};
|
|
25
52
|
|
|
@@ -80,6 +107,30 @@ export const TextWithIcon: Story = {
|
|
|
80
107
|
},
|
|
81
108
|
};
|
|
82
109
|
|
|
110
|
+
export const IconOnly: Story = {
|
|
111
|
+
args: {
|
|
112
|
+
variant: "solid",
|
|
113
|
+
size: "default",
|
|
114
|
+
"aria-label": "Search",
|
|
115
|
+
icon: (
|
|
116
|
+
<svg
|
|
117
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
118
|
+
width="24"
|
|
119
|
+
height="24"
|
|
120
|
+
viewBox="0 0 24 24"
|
|
121
|
+
fill="none"
|
|
122
|
+
stroke="currentColor"
|
|
123
|
+
strokeWidth="2"
|
|
124
|
+
strokeLinecap="round"
|
|
125
|
+
strokeLinejoin="round"
|
|
126
|
+
>
|
|
127
|
+
<circle cx="11" cy="11" r="8"></circle>
|
|
128
|
+
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
|
129
|
+
</svg>
|
|
130
|
+
),
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
|
|
83
134
|
export const LayerOneSolid: Story = {
|
|
84
135
|
args: {
|
|
85
136
|
children: "Layer 1 Solid",
|
|
@@ -126,3 +177,20 @@ export const TruncatedLabel: Story = {
|
|
|
126
177
|
</div>
|
|
127
178
|
),
|
|
128
179
|
};
|
|
180
|
+
|
|
181
|
+
export const Loading: Story = {
|
|
182
|
+
args: {
|
|
183
|
+
children: "Saving Changes",
|
|
184
|
+
variant: "solid",
|
|
185
|
+
size: "default",
|
|
186
|
+
loading: true,
|
|
187
|
+
},
|
|
188
|
+
parameters: {
|
|
189
|
+
docs: {
|
|
190
|
+
description: {
|
|
191
|
+
story:
|
|
192
|
+
"When `loading={true}` is applied, the Button injects the Recursica `<Loader />` component. Per Recursica design rules, placing a Button in a loading state automatically forces the `disabled={true}` state on the underlying element. This ensures the button immediately receives the brand theme disabled opacities without relying solely on semantic logic.",
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import React, { forwardRef } from "react";
|
|
2
|
+
import { Loader } from "../Loader/Loader";
|
|
3
|
+
import type { RecursicaLoaderProps } from "../Loader/Loader";
|
|
2
4
|
import {
|
|
3
5
|
Button as MantineButton,
|
|
4
6
|
type ButtonProps as MantineButtonProps,
|
|
@@ -11,9 +13,18 @@ import {
|
|
|
11
13
|
import styles from "./Button.module.css";
|
|
12
14
|
|
|
13
15
|
export interface RecursicaButtonProps {
|
|
16
|
+
/** The visual style variant of the button */
|
|
14
17
|
variant?: "solid" | "outline" | "text";
|
|
18
|
+
/** The size of the button */
|
|
15
19
|
size?: "default" | "small";
|
|
20
|
+
/** An optional icon element to display to the left of the button text. Replaces Mantine's leftSection. */
|
|
16
21
|
icon?: React.ReactNode;
|
|
22
|
+
/** Which Recursica Loader variant to use */
|
|
23
|
+
loaderVariant?: RecursicaLoaderProps["variant"];
|
|
24
|
+
/** The size variant for the loader */
|
|
25
|
+
loaderSize?: RecursicaLoaderProps["size"];
|
|
26
|
+
/** Whether to use the Recursica loader or fallback to the Mantine loader */
|
|
27
|
+
useRecursicaLoader?: boolean;
|
|
17
28
|
}
|
|
18
29
|
|
|
19
30
|
export type ButtonProps = RecursicaOverStyled<
|
|
@@ -34,6 +45,9 @@ const _Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
|
|
|
34
45
|
icon,
|
|
35
46
|
children,
|
|
36
47
|
overStyled = false,
|
|
48
|
+
loaderVariant = "oval",
|
|
49
|
+
loaderSize,
|
|
50
|
+
useRecursicaLoader = true,
|
|
37
51
|
...rest
|
|
38
52
|
},
|
|
39
53
|
ref,
|
|
@@ -57,8 +71,15 @@ const _Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
|
|
|
57
71
|
|
|
58
72
|
const hasLeftSection = !!icon || !!restRecord["leftSection"];
|
|
59
73
|
const hasRightSection = !!restRecord["rightSection"];
|
|
60
|
-
const
|
|
61
|
-
|
|
74
|
+
const hasVisibleText = hasVisibleChildren(children);
|
|
75
|
+
const isIconOnly = (hasLeftSection || hasRightSection) && !hasVisibleText;
|
|
76
|
+
|
|
77
|
+
let contentType = "label";
|
|
78
|
+
if (isIconOnly) {
|
|
79
|
+
contentType = "icon-only";
|
|
80
|
+
} else if (hasLeftSection || hasRightSection) {
|
|
81
|
+
contentType = "icon-label";
|
|
82
|
+
}
|
|
62
83
|
|
|
63
84
|
if (
|
|
64
85
|
typeof process !== "undefined" &&
|
|
@@ -75,6 +96,7 @@ const _Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
|
|
|
75
96
|
root: styles.root,
|
|
76
97
|
section: styles.section,
|
|
77
98
|
label: styles.label,
|
|
99
|
+
loader: styles.loader,
|
|
78
100
|
};
|
|
79
101
|
|
|
80
102
|
const classNamesProp = restRecord.classNames;
|
|
@@ -94,6 +116,21 @@ const _Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
|
|
|
94
116
|
? `${styles.root} ${classNameProp}`
|
|
95
117
|
: styles.root;
|
|
96
118
|
|
|
119
|
+
const userLoaderProps = restRecord.loaderProps as
|
|
120
|
+
| Record<string, any>
|
|
121
|
+
| undefined;
|
|
122
|
+
|
|
123
|
+
const resolvedLoaderSize =
|
|
124
|
+
loaderSize ?? (size === "small" ? "small" : "default");
|
|
125
|
+
|
|
126
|
+
let mergedLoaderProps = userLoaderProps;
|
|
127
|
+
if (useRecursicaLoader) {
|
|
128
|
+
mergedLoaderProps = {
|
|
129
|
+
children: <Loader variant={loaderVariant} size={resolvedLoaderSize} />,
|
|
130
|
+
...userLoaderProps,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
97
134
|
return (
|
|
98
135
|
<MantineButton
|
|
99
136
|
ref={ref}
|
|
@@ -101,6 +138,7 @@ const _Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
|
|
|
101
138
|
classNames={mergedClassNames}
|
|
102
139
|
variant={mapVariant[variant]}
|
|
103
140
|
size={mapSize[size]}
|
|
141
|
+
loaderProps={mergedLoaderProps}
|
|
104
142
|
leftSection={
|
|
105
143
|
icon != null ? (
|
|
106
144
|
<span className={styles.iconWrapper} aria-hidden>
|
|
@@ -110,8 +148,9 @@ const _Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
|
|
|
110
148
|
}
|
|
111
149
|
data-variant={variant}
|
|
112
150
|
data-size={size}
|
|
113
|
-
|
|
151
|
+
data-content={contentType}
|
|
114
152
|
{...sanitizedProps}
|
|
153
|
+
disabled={!!restRecord.disabled || !!restRecord.loading}
|
|
115
154
|
>
|
|
116
155
|
<span className={styles.labelText}>{children}</span>
|
|
117
156
|
</MantineButton>
|
|
@@ -43,3 +43,19 @@ Mantine's `.mantine-Button-label` flex centering breaks primitive truncation log
|
|
|
43
43
|
## Disabled state: brand theme opacity (implicit)
|
|
44
44
|
|
|
45
45
|
**Decision:** The UI kit enforces global brand theme disabled opacities. The `.root:disabled` logic implicitly overrides visibility locally via `var(--recursica_brand_states_disabled)`.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Loader color contrast
|
|
50
|
+
|
|
51
|
+
**Decision:** When a Button is in a loading state, the `Recursica Loader` component is injected. The `Loader` component strictly defines its own colors and styles per variant, meaning it does not inherit the text color (`currentColor`) from the Button.
|
|
52
|
+
|
|
53
|
+
**Constraint:** This can lead to contrast issues (e.g., a blue dots loader inside a solid blue button). Design has explicitly decided not to address this at the moment. As such, developers using the `loading` prop must be aware that the loader's color is fixed by its internal tokens, not by the button's context.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Loading state enforces disabled state
|
|
58
|
+
|
|
59
|
+
**Decision:** When `loading={true}` is passed to the Button, the component explicitly forces `disabled={true}` natively on the underlying element.
|
|
60
|
+
|
|
61
|
+
**Implementation:** This ensures that loading buttons automatically inherit the brand theme disabled opacities (via the `:disabled` CSS pseudo-class) rather than relying solely on Mantine's native `data-disabled` dataset logic, which may not trigger the strict visual fade required by the Recursica design system.
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/* HARDCODED VALUES:
|
|
2
|
+
- display: flex on root
|
|
3
|
+
- flex-direction: column
|
|
4
|
+
- gap: section-gap
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
.root {
|
|
2
8
|
/* HARDCODE: Map Recursica explicitly into Mantine's variable format so internal components know the margins */
|
|
3
9
|
--card-padding: var(--recursica_ui-kit_components_card_properties_padding);
|
|
@@ -33,7 +39,32 @@
|
|
|
33
39
|
border-bottom: var(--recursica_ui-kit_components_card_properties_divider-size)
|
|
34
40
|
solid
|
|
35
41
|
var(--recursica_ui-kit_components_card_properties_colors_divider-color);
|
|
36
|
-
|
|
42
|
+
|
|
43
|
+
/* Direct Figma Typography Mapping */
|
|
44
|
+
font-family: var(
|
|
45
|
+
--recursica_ui-kit_components_card_properties_header-style_fontFamily
|
|
46
|
+
);
|
|
47
|
+
font-size: var(
|
|
48
|
+
--recursica_ui-kit_components_card_properties_header-style_fontSize
|
|
49
|
+
);
|
|
50
|
+
font-style: var(
|
|
51
|
+
--recursica_ui-kit_components_card_properties_header-style_fontStyle
|
|
52
|
+
);
|
|
53
|
+
font-weight: var(
|
|
54
|
+
--recursica_ui-kit_components_card_properties_header-style_fontWeight
|
|
55
|
+
);
|
|
56
|
+
letter-spacing: var(
|
|
57
|
+
--recursica_ui-kit_components_card_properties_header-style_letterSpacing
|
|
58
|
+
);
|
|
59
|
+
line-height: var(
|
|
60
|
+
--recursica_ui-kit_components_card_properties_header-style_lineHeight
|
|
61
|
+
);
|
|
62
|
+
text-transform: var(
|
|
63
|
+
--recursica_ui-kit_components_card_properties_header-style_textCase
|
|
64
|
+
);
|
|
65
|
+
text-decoration: var(
|
|
66
|
+
--recursica_ui-kit_components_card_properties_header-style_textDecoration
|
|
67
|
+
);
|
|
37
68
|
}
|
|
38
69
|
|
|
39
70
|
.footer {
|
|
@@ -58,4 +89,30 @@
|
|
|
58
89
|
flex-direction: column;
|
|
59
90
|
gap: var(--recursica_ui-kit_components_card_properties_vertical-gutter);
|
|
60
91
|
padding: 0;
|
|
92
|
+
|
|
93
|
+
/* Direct Figma Typography Mapping */
|
|
94
|
+
font-family: var(
|
|
95
|
+
--recursica_ui-kit_components_card_properties_content-style_fontFamily
|
|
96
|
+
);
|
|
97
|
+
font-size: var(
|
|
98
|
+
--recursica_ui-kit_components_card_properties_content-style_fontSize
|
|
99
|
+
);
|
|
100
|
+
font-style: var(
|
|
101
|
+
--recursica_ui-kit_components_card_properties_content-style_fontStyle
|
|
102
|
+
);
|
|
103
|
+
font-weight: var(
|
|
104
|
+
--recursica_ui-kit_components_card_properties_content-style_fontWeight
|
|
105
|
+
);
|
|
106
|
+
letter-spacing: var(
|
|
107
|
+
--recursica_ui-kit_components_card_properties_content-style_letterSpacing
|
|
108
|
+
);
|
|
109
|
+
line-height: var(
|
|
110
|
+
--recursica_ui-kit_components_card_properties_content-style_lineHeight
|
|
111
|
+
);
|
|
112
|
+
text-transform: var(
|
|
113
|
+
--recursica_ui-kit_components_card_properties_content-style_textCase
|
|
114
|
+
);
|
|
115
|
+
text-decoration: var(
|
|
116
|
+
--recursica_ui-kit_components_card_properties_content-style_textDecoration
|
|
117
|
+
);
|
|
61
118
|
}
|
|
@@ -37,7 +37,8 @@ export const Default: Story = {
|
|
|
37
37
|
<div
|
|
38
38
|
style={{
|
|
39
39
|
padding: "48px",
|
|
40
|
-
backgroundColor:
|
|
40
|
+
backgroundColor:
|
|
41
|
+
"var(--recursica_brand_palettes_neutral_050_color_tone)",
|
|
41
42
|
}}
|
|
42
43
|
>
|
|
43
44
|
<Layer layer={0}>
|
|
@@ -72,7 +73,8 @@ export const HeaderlessAndFooterless: Story = {
|
|
|
72
73
|
<div
|
|
73
74
|
style={{
|
|
74
75
|
padding: "48px",
|
|
75
|
-
backgroundColor:
|
|
76
|
+
backgroundColor:
|
|
77
|
+
"var(--recursica_brand_palettes_neutral_050_color_tone)",
|
|
76
78
|
}}
|
|
77
79
|
>
|
|
78
80
|
<Layer layer={0}>
|