nexus-shared 3.0.0 → 3.2.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 +442 -0
- package/README.md +1123 -1000
- package/dist/Client.Index.d.ts +6 -0
- package/dist/Client.Index.js +6 -0
- package/dist/Components/Chats/ChatParts.d.ts +2 -2
- package/dist/Components/Chats/ChatParts.js +3 -7
- package/dist/Components/Chats/ChatThread.js +3 -3
- package/dist/Components/Documents/Button.d.ts +6 -1
- package/dist/Components/Documents/Button.js +2 -2
- package/dist/Components/Documents/Menu.js +21 -9
- package/dist/Components/Documents/SplitButton.d.ts +3 -1
- package/dist/Components/Documents/SplitButton.js +7 -5
- package/dist/Components/Documents/TabButtons.d.ts +5 -2
- package/dist/Components/Documents/TabButtons.js +2 -2
- package/dist/Components/Forms/ApiForm.d.ts +1 -1
- package/dist/Components/Forms/ApiForm.js +1 -1
- package/dist/Components/Forms/Crud.js +486 -206
- package/dist/Components/Forms/CrudHistory.d.ts +66 -0
- package/dist/Components/Forms/CrudHistory.js +140 -0
- package/dist/Components/Forms/CrudParts.d.ts +5 -1
- package/dist/Components/Forms/CrudParts.js +38 -5
- package/dist/Components/Forms/ExcelImport.d.ts +23 -7
- package/dist/Components/Forms/ExcelImport.js +189 -60
- package/dist/Components/Forms/Form.js +9 -14
- package/dist/Components/Forms/SubmitForm.d.ts +11 -2
- package/dist/Components/Forms/SubmitForm.js +23 -12
- package/dist/Components/Inputs/CodeBox.d.ts +69 -0
- package/dist/Components/Inputs/CodeBox.js +316 -0
- package/dist/Components/Inputs/DatePicker.js +4 -1
- package/dist/Components/Inputs/DateRangePicker.js +4 -1
- package/dist/Components/Inputs/DateTimePicker.js +4 -1
- package/dist/Components/Inputs/Dropdown.js +4 -1
- package/dist/Components/Inputs/DropdownParts.d.ts +1 -1
- package/dist/Components/Inputs/DropdownParts.js +4 -6
- package/dist/Components/Inputs/InputRenderer.js +3 -0
- package/dist/Components/Inputs/NumberBox.js +26 -2
- package/dist/Components/Inputs/RowsInput.js +2 -2
- package/dist/Components/Inputs/Slider.js +4 -1
- package/dist/Components/Inputs/TabularForm.js +42 -10
- package/dist/Components/Inputs/TextArea.js +4 -1
- package/dist/Components/Inputs/TextBox.js +4 -1
- package/dist/Components/Inputs/TimePanel.js +4 -3
- package/dist/Components/Inputs/TimePicker.js +4 -1
- package/dist/Components/Inputs/TreeView.d.ts +55 -5
- package/dist/Components/Inputs/TreeView.js +372 -23
- package/dist/Components/Layouts/Popup.js +1 -4
- package/dist/Components/Layouts/ThemePicker.d.ts +21 -3
- package/dist/Components/Layouts/ThemePicker.js +89 -6
- package/dist/Components/Layouts/ThemeScript.d.ts +4 -2
- package/dist/Components/Layouts/ThemeScript.js +4 -2
- package/dist/Components/Layouts/ThemeSwitcher.d.ts +6 -3
- package/dist/Components/Layouts/ThemeSwitcher.js +9 -8
- package/dist/Components/Viewers/Avatar.d.ts +21 -0
- package/dist/Components/Viewers/Avatar.js +21 -0
- package/dist/Components/Viewers/DataTable.js +252 -62
- package/dist/Components/Viewers/DataTableColumns.d.ts +7 -3
- package/dist/Components/Viewers/DataTableColumns.js +25 -68
- package/dist/Components/Viewers/DataTableFilters.d.ts +21 -0
- package/dist/Components/Viewers/DataTableFilters.js +68 -0
- package/dist/Components/Viewers/DataTableParts.d.ts +28 -10
- package/dist/Components/Viewers/DataTableParts.js +42 -13
- package/dist/Helpers/AnimationHelpers.d.ts +11 -0
- package/dist/Helpers/AnimationHelpers.js +20 -2
- package/dist/Helpers/ApiModules.d.ts +3 -34
- package/dist/Helpers/ApiModules.js +3 -3
- package/dist/Helpers/ApiRoutes.d.ts +68 -26
- package/dist/Helpers/ApiRoutes.js +31 -27
- package/dist/Helpers/ArrayHelpers.d.ts +0 -0
- package/dist/Helpers/ArrayHelpers.js +2 -0
- package/dist/Helpers/CodeHelpers.d.ts +97 -0
- package/dist/Helpers/CodeHelpers.js +332 -0
- package/dist/Helpers/CrudBackend.d.ts +101 -8
- package/dist/Helpers/CrudBackend.js +172 -11
- package/dist/Helpers/CrudColumns.d.ts +51 -0
- package/dist/Helpers/CrudColumns.js +69 -0
- package/dist/Helpers/CrudHelpers.d.ts +50 -5
- package/dist/Helpers/CrudHelpers.js +109 -12
- package/dist/Helpers/ExcelBackend.d.ts +3 -3
- package/dist/Helpers/ExcelBackend.js +8 -2
- package/dist/Helpers/ExcelHelpers.d.ts +36 -8
- package/dist/Helpers/ExcelHelpers.js +55 -13
- package/dist/Helpers/FormStore.d.ts +9 -5
- package/dist/Helpers/FormStore.js +25 -5
- package/dist/Helpers/InputParamsHelpers.js +8 -0
- package/dist/Helpers/MessageBuilder.js +3 -0
- package/dist/Helpers/NexusHelpers.d.ts +0 -0
- package/dist/Helpers/NexusHelpers.js +1 -0
- package/dist/Helpers/NumberHelpers.d.ts +7 -1
- package/dist/Helpers/NumberHelpers.js +41 -3
- package/dist/Helpers/PopoverHelpers.d.ts +17 -5
- package/dist/Helpers/PopoverHelpers.js +52 -17
- package/dist/Helpers/PopoverHooks.d.ts +24 -0
- package/dist/Helpers/PopoverHooks.js +62 -0
- package/dist/Helpers/RequestCache.d.ts +35 -0
- package/dist/Helpers/RequestCache.js +113 -0
- package/dist/Helpers/RowsStore.d.ts +7 -2
- package/dist/Helpers/RowsStore.js +15 -3
- package/dist/Helpers/TableFilters.d.ts +25 -0
- package/dist/Helpers/TableFilters.js +162 -0
- package/dist/Helpers/TableHelpers.d.ts +7 -4
- package/dist/Helpers/TableHelpers.js +15 -6
- package/dist/Helpers/TableJoins.d.ts +70 -0
- package/dist/Helpers/TableJoins.js +250 -0
- package/dist/Helpers/TableStore.d.ts +16 -3
- package/dist/Helpers/TableStore.js +25 -5
- package/dist/Helpers/ThemeHelpers.d.ts +21 -4
- package/dist/Helpers/ThemeHelpers.js +46 -9
- package/dist/Helpers/TreeStore.d.ts +225 -11
- package/dist/Helpers/TreeStore.js +683 -90
- package/dist/Helpers/UserPreferences.d.ts +22 -0
- package/dist/Helpers/UserPreferences.js +116 -0
- package/dist/Interfaces/CrudInterfaces.d.ts +67 -10
- package/dist/Interfaces/ExcelInterfaces.d.ts +12 -0
- package/dist/Interfaces/FormInterfaces.d.ts +37 -6
- package/dist/Interfaces/InputInterfaces.d.ts +24 -0
- package/dist/Interfaces/MessageInterfaces.d.ts +1 -1
- package/dist/Interfaces/PreferenceInterfaces.d.ts +51 -0
- package/dist/Interfaces/PreferenceInterfaces.js +25 -0
- package/dist/Interfaces/TableInterfaces.d.ts +145 -16
- package/dist/Interfaces/ThemeInterfaces.d.ts +25 -0
- package/dist/Interfaces/ThemeInterfaces.js +15 -0
- package/dist/Services/ApiProxy.d.ts +36 -1
- package/dist/Services/ApiProxy.js +182 -52
- package/dist/Services/ApiProxyRules.d.ts +203 -0
- package/dist/Services/ApiProxyRules.js +426 -0
- package/dist/Services/ExcelApi.d.ts +3 -1
- package/dist/Services/ExcelApi.js +1 -1
- package/dist/Services/JoinSources.d.ts +48 -0
- package/dist/Services/JoinSources.js +74 -0
- package/dist/Services/ServerApi.d.ts +13 -2
- package/dist/Services/ServerApi.js +8 -3
- package/dist/Services/ThemeService.d.ts +18 -2
- package/dist/Services/ThemeService.js +80 -16
- package/dist/Shared.Index.d.ts +6 -0
- package/dist/Shared.Index.js +6 -0
- package/package.json +4 -2
- package/src/Styles/Nexus.Avatar.css +79 -0
- package/src/Styles/Nexus.Base.css +51 -4
- package/src/Styles/Nexus.Button.css +27 -0
- package/src/Styles/Nexus.Calendar.css +4 -6
- package/src/Styles/Nexus.Chat.css +5 -51
- package/src/Styles/Nexus.Choice.css +4 -6
- package/src/Styles/Nexus.Crud.css +16 -9
- package/src/Styles/Nexus.Dropdown.css +12 -61
- package/src/Styles/Nexus.Editor.css +4 -6
- package/src/Styles/Nexus.Excel.css +34 -15
- package/src/Styles/Nexus.Form.css +25 -67
- package/src/Styles/Nexus.Index.css +1 -0
- package/src/Styles/Nexus.Input.css +794 -637
- package/src/Styles/Nexus.Markdown.css +0 -28
- package/src/Styles/Nexus.Menu.css +8 -30
- package/src/Styles/Nexus.Popup.css +22 -29
- package/src/Styles/Nexus.RichText.css +2 -32
- package/src/Styles/Nexus.Rows.css +51 -10
- package/src/Styles/Nexus.Slider.css +3 -5
- package/src/Styles/Nexus.Tab.Buttons.css +20 -7
- package/src/Styles/Nexus.Table.css +1387 -1296
- package/src/Styles/Nexus.Theme.Picker.css +342 -232
- package/src/Styles/Nexus.Time.css +9 -12
- package/src/Styles/Nexus.Toast.css +6 -8
- package/src/Styles/Nexus.Tokens.css +17 -0
- package/src/Styles/Nexus.Tree.css +76 -11
|
@@ -1,637 +1,794 @@
|
|
|
1
|
-
@layer nexus.components {
|
|
2
|
-
/*
|
|
3
|
-
* Field: the frame of every input. Label, a box holding icons, the control, and buttons, then a hint or error line.
|
|
4
|
-
* Sizes, designs, and states only change the --nx-field-* variables below; the rules after them read those.
|
|
5
|
-
*/
|
|
6
|
-
.nx-field {
|
|
7
|
-
--nx-field-base: var(--nx-control-md);
|
|
8
|
-
--nx-field-extra: 0px;
|
|
9
|
-
--nx-field-height: calc(var(--nx-field-base) + var(--nx-field-extra));
|
|
10
|
-
--nx-field-pad-x: 10px;
|
|
11
|
-
--nx-field-pad-y: 7px;
|
|
12
|
-
--nx-field-font: var(--nx-text-md);
|
|
13
|
-
--nx-field-label-font: var(--nx-text-sm);
|
|
14
|
-
--nx-field-icon: 16px;
|
|
15
|
-
--nx-field-bg: var(--nx-surface);
|
|
16
|
-
--nx-field-border: var(--nx-border-strong);
|
|
17
|
-
--nx-field-border-hover: color-mix(in oklab, var(--nx-border-strong), var(--nx-text) 22%);
|
|
18
|
-
--nx-field-accent: var(--nx-primary);
|
|
19
|
-
--nx-field-ring: var(--nx-focus-ring);
|
|
20
|
-
--nx-field-label-color: var(--nx-text-muted);
|
|
21
|
-
--nx-field-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
--nx-field-
|
|
31
|
-
--nx-field-pad-
|
|
32
|
-
--nx-field-
|
|
33
|
-
--nx-field-font: var(--nx-text-
|
|
34
|
-
--nx-field-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
--nx-field-
|
|
40
|
-
--nx-field-pad-
|
|
41
|
-
--nx-field-
|
|
42
|
-
--nx-field-font: var(--nx-text-
|
|
43
|
-
--nx-field-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
--nx-field-border: var(--nx-danger);
|
|
54
|
-
--nx-field-
|
|
55
|
-
--nx-field-
|
|
56
|
-
--nx-field-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
--nx-field-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
font-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
border:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
width:
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
border:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
.nx-field__control::-webkit-search-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
.nx-field__control::-ms-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
.nx-
|
|
178
|
-
.nx-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
padding-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
.nx-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
align-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
padding-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
padding-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
border:
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
outline: 2px
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
border:
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
font-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
font-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
--nx-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
.nx-field--multiline .nx-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
padding-top: calc(var(--nx-field-pad-y) +
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
.nx-field--multiline.nx-field--inbox:is([data-raised], :focus-within, :has(.nx-field__control:not(:placeholder-shown))) .nx-
|
|
608
|
-
padding-top: calc(var(--nx-field-pad-y) + var(--nx-field-inbox-pad) - 4px +
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
1
|
+
@layer nexus.components {
|
|
2
|
+
/*
|
|
3
|
+
* Field: the frame of every input. Label, a box holding icons, the control, and buttons, then a hint or error line.
|
|
4
|
+
* Sizes, designs, and states only change the --nx-field-* variables below; the rules after them read those.
|
|
5
|
+
*/
|
|
6
|
+
.nx-field {
|
|
7
|
+
--nx-field-base: var(--nx-control-md);
|
|
8
|
+
--nx-field-extra: 0px;
|
|
9
|
+
--nx-field-height: calc(var(--nx-field-base) + var(--nx-field-extra));
|
|
10
|
+
--nx-field-pad-x: 10px;
|
|
11
|
+
--nx-field-pad-y: 7px;
|
|
12
|
+
--nx-field-font: var(--nx-text-md);
|
|
13
|
+
--nx-field-label-font: var(--nx-text-sm);
|
|
14
|
+
--nx-field-icon: 16px;
|
|
15
|
+
--nx-field-bg: var(--nx-surface);
|
|
16
|
+
--nx-field-border: var(--nx-border-strong);
|
|
17
|
+
--nx-field-border-hover: color-mix(in oklab, var(--nx-border-strong), var(--nx-text) 22%);
|
|
18
|
+
--nx-field-accent: var(--nx-primary);
|
|
19
|
+
--nx-field-ring: var(--nx-focus-ring);
|
|
20
|
+
--nx-field-label-color: var(--nx-text-muted);
|
|
21
|
+
--nx-field-grip: color-mix(in oklab, var(--nx-text-subtle) 75%, transparent);
|
|
22
|
+
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
min-width: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.nx-field--sm {
|
|
29
|
+
--nx-field-base: var(--nx-control-sm);
|
|
30
|
+
--nx-field-pad-x: var(--nx-space-2);
|
|
31
|
+
--nx-field-pad-y: 4px;
|
|
32
|
+
--nx-field-font: var(--nx-text-sm);
|
|
33
|
+
--nx-field-label-font: var(--nx-text-xs);
|
|
34
|
+
--nx-field-icon: 14px;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.nx-field--lg {
|
|
38
|
+
--nx-field-base: var(--nx-control-lg);
|
|
39
|
+
--nx-field-pad-x: var(--nx-space-3);
|
|
40
|
+
--nx-field-pad-y: 9px;
|
|
41
|
+
--nx-field-font: var(--nx-text-lg);
|
|
42
|
+
--nx-field-label-font: var(--nx-text-md);
|
|
43
|
+
--nx-field-icon: 18px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* States */
|
|
47
|
+
.nx-field:focus-within {
|
|
48
|
+
--nx-field-label-color: var(--nx-field-accent);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.nx-field[data-invalid] {
|
|
52
|
+
--nx-field-border: var(--nx-danger);
|
|
53
|
+
--nx-field-border-hover: var(--nx-danger);
|
|
54
|
+
--nx-field-accent: var(--nx-danger);
|
|
55
|
+
--nx-field-ring: 0 0 0 3px color-mix(in oklab, var(--nx-danger) 30%, transparent);
|
|
56
|
+
--nx-field-label-color: var(--nx-danger);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* Read-only and disabled boxes sit lower than the panel: lighter gray in light mode, the page color in dark mode. */
|
|
60
|
+
.nx-field:is([data-readonly], [data-disabled]) {
|
|
61
|
+
--nx-field-bg: light-dark(var(--nx-surface-2), var(--nx-bg));
|
|
62
|
+
--nx-field-border-hover: var(--nx-field-border);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.nx-field:is([data-readonly], [data-disabled]) .nx-field__box {
|
|
66
|
+
box-shadow: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.nx-field[data-disabled] {
|
|
70
|
+
opacity: 0.6;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.nx-field[data-disabled] :is(.nx-field__label, .nx-field__box, .nx-field__control) {
|
|
74
|
+
cursor: not-allowed;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Label above the box */
|
|
78
|
+
.nx-field__label {
|
|
79
|
+
color: var(--nx-text);
|
|
80
|
+
font-size: var(--nx-field-label-font);
|
|
81
|
+
font-weight: 500;
|
|
82
|
+
line-height: 1.3;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.nx-field--standard > .nx-field__label {
|
|
86
|
+
align-self: flex-start;
|
|
87
|
+
margin-bottom: 6px;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.nx-field__required {
|
|
91
|
+
margin-left: 3px;
|
|
92
|
+
color: var(--nx-danger);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Box */
|
|
96
|
+
.nx-field__box {
|
|
97
|
+
position: relative;
|
|
98
|
+
display: flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
min-height: var(--nx-field-height);
|
|
101
|
+
border: 1px solid var(--nx-field-border);
|
|
102
|
+
border-radius: var(--nx-radius);
|
|
103
|
+
background: var(--nx-field-bg);
|
|
104
|
+
box-shadow: var(--nx-shadow-sm);
|
|
105
|
+
font-size: var(--nx-field-font);
|
|
106
|
+
transition:
|
|
107
|
+
border-color var(--nx-duration),
|
|
108
|
+
box-shadow var(--nx-duration);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.nx-field__box:hover {
|
|
112
|
+
border-color: var(--nx-field-border-hover);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.nx-field__box:focus-within {
|
|
116
|
+
border-color: var(--nx-field-accent);
|
|
117
|
+
box-shadow: var(--nx-field-ring);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.nx-field__control {
|
|
121
|
+
flex: 1 1 auto;
|
|
122
|
+
align-self: stretch;
|
|
123
|
+
width: 100%;
|
|
124
|
+
min-width: 0;
|
|
125
|
+
margin: 0;
|
|
126
|
+
padding: 0 var(--nx-field-pad-x);
|
|
127
|
+
border: 0;
|
|
128
|
+
border-radius: inherit;
|
|
129
|
+
outline: none;
|
|
130
|
+
background: transparent;
|
|
131
|
+
color: var(--nx-text);
|
|
132
|
+
font-size: var(--nx-field-font);
|
|
133
|
+
line-height: 1.4;
|
|
134
|
+
text-overflow: ellipsis;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Numbers line up digit under digit. */
|
|
138
|
+
.nx-field__control--number {
|
|
139
|
+
font-variant-numeric: tabular-nums;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.nx-field__control::placeholder {
|
|
143
|
+
color: var(--nx-text-subtle);
|
|
144
|
+
opacity: 1;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* Browser extras that the field replaces with its own buttons. */
|
|
148
|
+
.nx-field__control::-webkit-search-cancel-button,
|
|
149
|
+
.nx-field__control::-webkit-search-decoration {
|
|
150
|
+
appearance: none;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.nx-field__control::-ms-reveal,
|
|
154
|
+
.nx-field__control::-ms-clear {
|
|
155
|
+
display: none;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/* Autofilled values keep the field's own colors. */
|
|
159
|
+
.nx-field__control:is(:autofill, :-webkit-autofill) {
|
|
160
|
+
-webkit-text-fill-color: var(--nx-text);
|
|
161
|
+
caret-color: var(--nx-text);
|
|
162
|
+
box-shadow: 0 0 0 100px var(--nx-field-bg) inset;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* Icons */
|
|
166
|
+
.nx-field__icon {
|
|
167
|
+
display: flex;
|
|
168
|
+
align-items: center;
|
|
169
|
+
flex-shrink: 0;
|
|
170
|
+
padding-left: var(--nx-field-pad-x);
|
|
171
|
+
color: var(--nx-text-subtle);
|
|
172
|
+
pointer-events: none;
|
|
173
|
+
transition: color var(--nx-duration);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.nx-field__icon .nx-icon,
|
|
177
|
+
.nx-field__action .nx-icon,
|
|
178
|
+
.nx-field__lock .nx-icon {
|
|
179
|
+
width: var(--nx-field-icon);
|
|
180
|
+
height: var(--nx-field-icon);
|
|
181
|
+
vertical-align: 0;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.nx-field__icon--end {
|
|
185
|
+
padding-right: var(--nx-field-pad-x);
|
|
186
|
+
padding-left: 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.nx-field__box:focus-within .nx-field__icon,
|
|
190
|
+
.nx-field[data-invalid] .nx-field__icon {
|
|
191
|
+
color: var(--nx-field-accent);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.nx-field__icon:not(.nx-field__icon--end) + .nx-field__control {
|
|
195
|
+
padding-left: var(--nx-space-2);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.nx-field__control:has(~ .nx-field__actions, ~ .nx-field__icon--end) {
|
|
199
|
+
padding-right: var(--nx-space-1);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* Text before and after the value: a currency, a unit, a domain. Muted, so the value reads first. */
|
|
203
|
+
.nx-field__affix {
|
|
204
|
+
display: flex;
|
|
205
|
+
align-items: center;
|
|
206
|
+
align-self: stretch;
|
|
207
|
+
flex-shrink: 0;
|
|
208
|
+
padding-left: var(--nx-field-pad-x);
|
|
209
|
+
color: var(--nx-text-muted);
|
|
210
|
+
line-height: 1.4;
|
|
211
|
+
white-space: nowrap;
|
|
212
|
+
user-select: none;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.nx-field__affix--end {
|
|
216
|
+
padding-right: var(--nx-field-pad-x);
|
|
217
|
+
padding-left: 0;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.nx-field__icon:not(.nx-field__icon--end) + .nx-field__affix {
|
|
221
|
+
padding-left: var(--nx-space-2);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.nx-field__affix:not(.nx-field__affix--end) + .nx-field__control {
|
|
225
|
+
padding-left: 6px;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.nx-field__control:has(~ .nx-field__affix--end) {
|
|
229
|
+
padding-right: 6px;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.nx-field__affix--end:has(~ .nx-field__actions, ~ .nx-field__icon--end) {
|
|
233
|
+
padding-right: var(--nx-space-1);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* Buttons inside the box: clear, show password, − and + */
|
|
237
|
+
.nx-field__actions {
|
|
238
|
+
display: flex;
|
|
239
|
+
align-items: center;
|
|
240
|
+
flex-shrink: 0;
|
|
241
|
+
gap: 2px;
|
|
242
|
+
padding-right: 4px;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.nx-field__actions--start {
|
|
246
|
+
padding-right: 0;
|
|
247
|
+
padding-left: 4px;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.nx-field__actions + .nx-field__icon--end {
|
|
251
|
+
padding-left: var(--nx-space-1);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.nx-field__action {
|
|
255
|
+
display: grid;
|
|
256
|
+
place-items: center;
|
|
257
|
+
width: calc(var(--nx-field-base) - 10px);
|
|
258
|
+
height: calc(var(--nx-field-base) - 10px);
|
|
259
|
+
padding: 0;
|
|
260
|
+
border: 0;
|
|
261
|
+
border-radius: var(--nx-radius-sm);
|
|
262
|
+
background: none;
|
|
263
|
+
color: var(--nx-text-subtle);
|
|
264
|
+
cursor: pointer;
|
|
265
|
+
transition:
|
|
266
|
+
background-color var(--nx-duration),
|
|
267
|
+
color var(--nx-duration);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.nx-field__action:hover:not(:disabled, [aria-disabled="true"]) {
|
|
271
|
+
background: var(--nx-surface-hover);
|
|
272
|
+
color: var(--nx-text);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.nx-field__action:focus-visible {
|
|
276
|
+
outline: 2px solid var(--nx-primary);
|
|
277
|
+
outline-offset: -2px;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.nx-field__action[aria-pressed="true"] {
|
|
281
|
+
color: var(--nx-field-accent);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.nx-field__action:disabled {
|
|
285
|
+
cursor: not-allowed;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* − and +: stronger than the clear button, since they are the main way to change the value by pointer. */
|
|
289
|
+
.nx-field__action--step {
|
|
290
|
+
color: var(--nx-text-muted);
|
|
291
|
+
touch-action: manipulation;
|
|
292
|
+
user-select: none;
|
|
293
|
+
-webkit-touch-callout: none;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/* At a limit: dimmed, and the press does nothing. Not `disabled`, which would lose the pointer while it is held. */
|
|
297
|
+
.nx-field__action[aria-disabled="true"] {
|
|
298
|
+
opacity: 0.4;
|
|
299
|
+
cursor: default;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/* Split stepper: − before and + after a centered value, as in a guest or quantity picker. */
|
|
303
|
+
.nx-field--split .nx-field__control {
|
|
304
|
+
padding-inline: var(--nx-space-1);
|
|
305
|
+
text-align: center;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/*
|
|
309
|
+
* Read-only lock: at the end of the box, where a button that no longer works would be (a date picker's calendar, a
|
|
310
|
+
* number box's − and +), so a click that does nothing does not look like a bug. Muted rather than subtle, since it
|
|
311
|
+
* is the only sign of the state: at least 3:1 on the box in every theme. On an attempt to change the field it turns
|
|
312
|
+
* to the text color and nudges.
|
|
313
|
+
*/
|
|
314
|
+
.nx-field__lock {
|
|
315
|
+
display: grid;
|
|
316
|
+
place-items: center;
|
|
317
|
+
width: calc(var(--nx-field-base) - 10px);
|
|
318
|
+
height: calc(var(--nx-field-base) - 10px);
|
|
319
|
+
color: var(--nx-text-muted);
|
|
320
|
+
cursor: default;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* After the label of a field without a box: a checkbox, a switch, a choice group, a slider. Sized to the label text. */
|
|
324
|
+
.nx-field__lock--label {
|
|
325
|
+
display: inline-block;
|
|
326
|
+
width: auto;
|
|
327
|
+
height: auto;
|
|
328
|
+
margin-left: 0.35em;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.nx-field__lock--label .nx-icon {
|
|
332
|
+
width: 1em;
|
|
333
|
+
height: 1em;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.nx-field__lock[data-nudge] {
|
|
337
|
+
color: var(--nx-text);
|
|
338
|
+
animation: nx-field-nudge 320ms ease-in-out;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
@keyframes nx-field-nudge {
|
|
342
|
+
20%,
|
|
343
|
+
60% {
|
|
344
|
+
transform: translateX(-2px);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
40%,
|
|
348
|
+
80% {
|
|
349
|
+
transform: translateX(2px);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/* The note under a read-only box, in the top layer and placed by the component. Inverted, like a tooltip. */
|
|
354
|
+
.nx-field-notice {
|
|
355
|
+
position: fixed;
|
|
356
|
+
inset: auto;
|
|
357
|
+
display: flex;
|
|
358
|
+
align-items: center;
|
|
359
|
+
gap: 6px;
|
|
360
|
+
max-width: min(320px, calc(100vw - 16px));
|
|
361
|
+
margin: 0;
|
|
362
|
+
padding: 6px 10px 6px 8px;
|
|
363
|
+
overflow: visible;
|
|
364
|
+
border: 0;
|
|
365
|
+
border-radius: var(--nx-radius);
|
|
366
|
+
background: var(--nx-text);
|
|
367
|
+
color: var(--nx-surface);
|
|
368
|
+
box-shadow: var(--nx-shadow);
|
|
369
|
+
font-size: var(--nx-text-xs);
|
|
370
|
+
font-weight: 500;
|
|
371
|
+
line-height: 1.35;
|
|
372
|
+
pointer-events: none;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.nx-field-notice:popover-open {
|
|
376
|
+
animation: nx-field-notice-in 120ms ease-out;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
@keyframes nx-field-notice-in {
|
|
380
|
+
from {
|
|
381
|
+
opacity: 0;
|
|
382
|
+
transform: translateY(-4px);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.nx-field-notice .nx-icon {
|
|
387
|
+
flex-shrink: 0;
|
|
388
|
+
width: 14px;
|
|
389
|
+
height: 14px;
|
|
390
|
+
vertical-align: 0;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/* Nothing to clear in an empty field. The control always has a placeholder, so :placeholder-shown means empty. */
|
|
394
|
+
.nx-field__box:has(.nx-field__control:placeholder-shown) .nx-field__action--clear {
|
|
395
|
+
display: none;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/* Hint, error, and count under the box */
|
|
399
|
+
.nx-field__footer {
|
|
400
|
+
display: flex;
|
|
401
|
+
align-items: flex-start;
|
|
402
|
+
gap: var(--nx-space-3);
|
|
403
|
+
margin-top: 5px;
|
|
404
|
+
font-size: var(--nx-text-xs);
|
|
405
|
+
line-height: 1.35;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.nx-field__message {
|
|
409
|
+
display: flex;
|
|
410
|
+
gap: 5px;
|
|
411
|
+
min-width: 0;
|
|
412
|
+
margin: 0;
|
|
413
|
+
color: var(--nx-text-muted);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.nx-field__message .nx-icon {
|
|
417
|
+
flex-shrink: 0;
|
|
418
|
+
width: 1.35em;
|
|
419
|
+
height: 1.35em;
|
|
420
|
+
vertical-align: 0;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
.nx-field__message--error {
|
|
424
|
+
color: var(--nx-danger);
|
|
425
|
+
font-weight: 500;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.nx-field__aside {
|
|
429
|
+
margin-left: auto;
|
|
430
|
+
color: var(--nx-text-muted);
|
|
431
|
+
font-variant-numeric: tabular-nums;
|
|
432
|
+
white-space: nowrap;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/* Outlined and inbox: the label rests inside the box like a placeholder and rises on focus or once there is a value. */
|
|
436
|
+
:is(.nx-field--outlined, .nx-field--inbox) .nx-field__label {
|
|
437
|
+
position: absolute;
|
|
438
|
+
z-index: 1;
|
|
439
|
+
top: 50%;
|
|
440
|
+
left: var(--nx-field-pad-x);
|
|
441
|
+
max-width: calc(100% - 2 * var(--nx-field-pad-x));
|
|
442
|
+
overflow: hidden;
|
|
443
|
+
color: var(--nx-field-label-color);
|
|
444
|
+
font-size: var(--nx-field-font);
|
|
445
|
+
font-weight: 400;
|
|
446
|
+
line-height: 1.2;
|
|
447
|
+
text-overflow: ellipsis;
|
|
448
|
+
white-space: nowrap;
|
|
449
|
+
transform: translateY(-50%);
|
|
450
|
+
pointer-events: none;
|
|
451
|
+
transition:
|
|
452
|
+
top var(--nx-duration),
|
|
453
|
+
left var(--nx-duration),
|
|
454
|
+
font-size var(--nx-duration),
|
|
455
|
+
color var(--nx-duration),
|
|
456
|
+
transform var(--nx-duration);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/* After a start icon, the resting label lines up with the text. */
|
|
460
|
+
.nx-field__icon:not(.nx-field__icon--end) ~ .nx-field__label {
|
|
461
|
+
left: calc(var(--nx-field-pad-x) + var(--nx-field-icon) + var(--nx-space-2));
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/* On a multi-line box, the resting label sits on the first line. */
|
|
465
|
+
.nx-field--multiline .nx-field__label {
|
|
466
|
+
top: calc(var(--nx-field-pad-y) + var(--nx-field-font) * 0.7);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/*
|
|
470
|
+
* Outlined: the raised label sits on the top border, centred on its inner edge, and opens a gap in it: behind the
|
|
471
|
+
* label the field's colour runs from the box's top edge down, and never above it, where it shows on any panel whose
|
|
472
|
+
* colour is not the field's (a read-only box, a dark popover). No CSS length finds that edge at every scale: a 1px
|
|
473
|
+
* border is one device pixel thick at 125% and two at 200%. So the backing is placed by the same length the label is
|
|
474
|
+
* lifted by (half its 1.2 line height: the two cancel, and it starts on the border's inner edge), and its 1px outline
|
|
475
|
+
* covers the border, because the browser snaps an outline exactly as it snaps a border. The label's overflow keeps
|
|
476
|
+
* the outline's sides and foot inside it. A gradient on the label instead was half a pixel off at most scales from 67%
|
|
477
|
+
* to 300%: the field's colour a row above the box, or a hairline of border through the gap.
|
|
478
|
+
*/
|
|
479
|
+
.nx-field--outlined:is([data-raised], :focus-within, :has(.nx-field__control:not(:placeholder-shown))) .nx-field__label {
|
|
480
|
+
top: -0.6em;
|
|
481
|
+
left: calc(var(--nx-field-pad-x) - 4px);
|
|
482
|
+
padding: 0 4px;
|
|
483
|
+
font-size: var(--nx-text-xs);
|
|
484
|
+
font-weight: 500;
|
|
485
|
+
transform: none;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.nx-field--outlined:is([data-raised], :focus-within, :has(.nx-field__control:not(:placeholder-shown))) .nx-field__label::before {
|
|
489
|
+
content: "";
|
|
490
|
+
position: absolute;
|
|
491
|
+
z-index: -1;
|
|
492
|
+
inset: 0.6em 0 0;
|
|
493
|
+
outline: 1px solid var(--nx-field-bg);
|
|
494
|
+
background: var(--nx-field-bg);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/* Forced colours would paint that outline in the text's colour; the browser's backplate behind the text opens the gap. */
|
|
498
|
+
@media (forced-colors: active) {
|
|
499
|
+
.nx-field--outlined .nx-field__label::before {
|
|
500
|
+
display: none;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/*
|
|
505
|
+
* Outlined, with focus: the border thickens to 2px instead of taking the ring. A ring lies outside the box, past the
|
|
506
|
+
* label's backing, so it ran on behind the label; this edge lies on the border and a pixel inside it, where the
|
|
507
|
+
* backing opens the same gap in it. One 2px outline over the border, not a second pixel beside it, which showed a
|
|
508
|
+
* seam at 150%; and an outline, so it is drawn over the control (an autofilled one is opaque) and under the label.
|
|
509
|
+
*/
|
|
510
|
+
.nx-field--outlined:not([data-readonly], [data-disabled]) .nx-field__box:focus-within {
|
|
511
|
+
outline: 2px solid var(--nx-field-accent);
|
|
512
|
+
outline-offset: -2px;
|
|
513
|
+
box-shadow: var(--nx-shadow-sm);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/* Inbox: a taller box with the raised label inside its top edge. */
|
|
517
|
+
.nx-field--inbox {
|
|
518
|
+
--nx-field-extra: 12px;
|
|
519
|
+
--nx-field-inbox-pad: 17px;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
.nx-field--inbox.nx-field--sm {
|
|
523
|
+
--nx-field-inbox-pad: 15px;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
.nx-field--inbox.nx-field--lg {
|
|
527
|
+
--nx-field-inbox-pad: 19px;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
.nx-field--inbox .nx-field__control {
|
|
531
|
+
padding-top: var(--nx-field-inbox-pad);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/*
|
|
535
|
+
* Beside the value: while the label rests in the middle, icons, text, and buttons line up with it. Once the label
|
|
536
|
+
* rises, the value sits low in the box, and they move down to its line. Buttons move halfway, so their hover
|
|
537
|
+
* background keeps clear of the border.
|
|
538
|
+
*/
|
|
539
|
+
.nx-field--inbox :is(.nx-field__icon, .nx-field__affix, .nx-field__actions) {
|
|
540
|
+
align-self: stretch;
|
|
541
|
+
transition: padding-top var(--nx-duration);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
.nx-field--inbox:is([data-raised], :focus-within, :has(.nx-field__control:not(:placeholder-shown))) :is(.nx-field__icon, .nx-field__affix) {
|
|
545
|
+
padding-top: var(--nx-field-inbox-pad);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
.nx-field--inbox:is([data-raised], :focus-within, :has(.nx-field__control:not(:placeholder-shown))) .nx-field__actions {
|
|
549
|
+
padding-top: calc(var(--nx-field-inbox-pad) / 2);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
.nx-field--inbox:is([data-raised], :focus-within, :has(.nx-field__control:not(:placeholder-shown))) .nx-field__label {
|
|
553
|
+
top: 5px;
|
|
554
|
+
font-size: var(--nx-text-xs);
|
|
555
|
+
font-weight: 500;
|
|
556
|
+
transform: none;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/*
|
|
560
|
+
* Split stepper: the label sits centered over the centered value, between − and +.
|
|
561
|
+
* It must come after the raised-label rule above: both have the same specificity, so the later one wins.
|
|
562
|
+
*/
|
|
563
|
+
.nx-field--inbox.nx-field--split[data-raised] .nx-field__label {
|
|
564
|
+
left: 50%;
|
|
565
|
+
max-width: calc(100% - 2 * var(--nx-field-base));
|
|
566
|
+
transform: translateX(-50%);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/* Multi-line */
|
|
570
|
+
.nx-field--multiline .nx-field__box {
|
|
571
|
+
align-items: stretch;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.nx-field--multiline .nx-field__control {
|
|
575
|
+
padding: var(--nx-field-pad-y) var(--nx-field-pad-x);
|
|
576
|
+
font-family: inherit;
|
|
577
|
+
resize: vertical;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/* Buttons and the read-only lock sit at the top end, centered on the first line (line height 1.4). */
|
|
581
|
+
.nx-field--multiline .nx-field__actions {
|
|
582
|
+
align-items: flex-start;
|
|
583
|
+
padding-top: calc(var(--nx-field-pad-y) + 0.7em - (var(--nx-field-base) - 10px) / 2);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/* The browser's own resize grip ignores the theme (white lines in dark mode): draw two grip lines instead. */
|
|
587
|
+
.nx-field--multiline .nx-field__control::-webkit-resizer {
|
|
588
|
+
background: linear-gradient(
|
|
589
|
+
135deg,
|
|
590
|
+
transparent 0 48%,
|
|
591
|
+
var(--nx-field-grip) 48% 56%,
|
|
592
|
+
transparent 56% 70%,
|
|
593
|
+
var(--nx-field-grip) 70% 78%,
|
|
594
|
+
transparent 78%
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
.nx-field--multiline.nx-field--inbox .nx-field__control {
|
|
599
|
+
padding-top: calc(var(--nx-field-pad-y) + var(--nx-field-inbox-pad) - 4px);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
.nx-field--multiline .nx-field__icon {
|
|
603
|
+
align-items: flex-start;
|
|
604
|
+
padding-top: calc(var(--nx-field-pad-y) + (1.4em - var(--nx-field-icon)) / 2);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
.nx-field--multiline.nx-field--inbox:is([data-raised], :focus-within, :has(.nx-field__control:not(:placeholder-shown))) .nx-field__icon {
|
|
608
|
+
padding-top: calc(var(--nx-field-pad-y) + var(--nx-field-inbox-pad) - 4px + (1.4em - var(--nx-field-icon)) / 2);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
.nx-field--multiline.nx-field--inbox:is([data-raised], :focus-within, :has(.nx-field__control:not(:placeholder-shown))) .nx-field__actions {
|
|
612
|
+
padding-top: calc(var(--nx-field-pad-y) + var(--nx-field-inbox-pad) - 4px + 0.7em - (var(--nx-field-base) - 10px) / 2);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/* Grows with its text between --nx-field-rows and --nx-field-max-rows lines. */
|
|
616
|
+
.nx-field__control--auto {
|
|
617
|
+
field-sizing: content;
|
|
618
|
+
min-height: calc(var(--nx-field-rows, 3) * 1lh + 2 * var(--nx-field-pad-y));
|
|
619
|
+
max-height: calc(var(--nx-field-max-rows, 12) * 1lh + 2 * var(--nx-field-pad-y));
|
|
620
|
+
resize: none;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
@supports not (field-sizing: content) {
|
|
624
|
+
.nx-field__control--auto {
|
|
625
|
+
max-height: none;
|
|
626
|
+
resize: vertical;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/*
|
|
631
|
+
* Code box: a box per character, drawn from one input that lies over them unseen. The boxes wear the field's own
|
|
632
|
+
* variables, so sizes, states, densities, and themes come with them; the field's single frame steps aside.
|
|
633
|
+
*/
|
|
634
|
+
.nx-field--code .nx-field__box,
|
|
635
|
+
.nx-field--code .nx-field__box:focus-within {
|
|
636
|
+
min-height: 0;
|
|
637
|
+
border: 0;
|
|
638
|
+
background: none;
|
|
639
|
+
box-shadow: none;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
.nx-code {
|
|
643
|
+
position: relative;
|
|
644
|
+
display: flex;
|
|
645
|
+
min-width: 0;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
.nx-code[data-block] {
|
|
649
|
+
flex: 1 1 auto;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/* On a phone the gaps and the characters scale with the screen, so an SSN's nine boxes fit a 390px screen. */
|
|
653
|
+
.nx-code__slots,
|
|
654
|
+
.nx-code__group {
|
|
655
|
+
display: flex;
|
|
656
|
+
align-items: center;
|
|
657
|
+
gap: min(var(--nx-space-2), 1.2vw);
|
|
658
|
+
min-width: 0;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
.nx-code[data-block] :is(.nx-code__slots, .nx-code__group) {
|
|
662
|
+
flex: 1 1 auto;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
.nx-code__separator {
|
|
666
|
+
flex: none;
|
|
667
|
+
color: var(--nx-text-muted);
|
|
668
|
+
font-size: var(--nx-field-font);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/*
|
|
672
|
+
* A box is a little taller than the field's line and about as wide; its character is larger than the field's text.
|
|
673
|
+
* Boxes shrink alike rather than spill out of their field: a code too long for its room is cramped, never cut off.
|
|
674
|
+
*/
|
|
675
|
+
.nx-code__slot {
|
|
676
|
+
position: relative;
|
|
677
|
+
display: grid;
|
|
678
|
+
flex: 0 1 calc(var(--nx-field-height) + var(--nx-space-1));
|
|
679
|
+
place-items: center;
|
|
680
|
+
min-width: 0;
|
|
681
|
+
height: calc(var(--nx-field-height) + var(--nx-space-3));
|
|
682
|
+
border: 1px solid var(--nx-field-border);
|
|
683
|
+
border-radius: var(--nx-radius);
|
|
684
|
+
background: var(--nx-field-bg);
|
|
685
|
+
box-shadow: var(--nx-shadow-sm);
|
|
686
|
+
color: var(--nx-text);
|
|
687
|
+
font-size: min(calc(var(--nx-field-font) * 1.4), 5vw);
|
|
688
|
+
font-variant-numeric: tabular-nums;
|
|
689
|
+
font-weight: 600;
|
|
690
|
+
line-height: 1;
|
|
691
|
+
transition:
|
|
692
|
+
border-color var(--nx-duration),
|
|
693
|
+
box-shadow var(--nx-duration),
|
|
694
|
+
background-color var(--nx-duration);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/*
|
|
698
|
+
* Without `block` the rows around the boxes are as wide as their content, and Chromium counts each box's width there,
|
|
699
|
+
* not its flex-basis: with a basis alone an empty box was its 2px border and a filled one its character. A width
|
|
700
|
+
* gives each box its size; `min-width: 0` still lets them shrink alike on a narrow screen.
|
|
701
|
+
*/
|
|
702
|
+
.nx-code:not([data-block]) .nx-code__slot {
|
|
703
|
+
width: calc(var(--nx-field-height) + var(--nx-space-1));
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
.nx-code[data-block] .nx-code__slot {
|
|
707
|
+
flex: 1 1 0;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
.nx-code:hover .nx-code__slot {
|
|
711
|
+
border-color: var(--nx-field-border-hover);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
.nx-code__slot[data-active] {
|
|
715
|
+
border-color: var(--nx-field-accent);
|
|
716
|
+
box-shadow: var(--nx-field-ring);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
.nx-code__slot[data-selected] {
|
|
720
|
+
background: color-mix(in oklab, var(--nx-field-accent) 14%, var(--nx-field-bg));
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
.nx-code__slot:empty::before {
|
|
724
|
+
content: attr(data-placeholder);
|
|
725
|
+
color: var(--nx-text-subtle);
|
|
726
|
+
font-weight: 400;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/* The caret in an empty box, blinking as a text caret does. */
|
|
730
|
+
.nx-code__slot[data-caret]::after {
|
|
731
|
+
content: "";
|
|
732
|
+
position: absolute;
|
|
733
|
+
width: 2px;
|
|
734
|
+
height: 45%;
|
|
735
|
+
border-radius: 1px;
|
|
736
|
+
background: var(--nx-text);
|
|
737
|
+
animation: nx-code-caret 1s step-end infinite;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
@keyframes nx-code-caret {
|
|
741
|
+
50% {
|
|
742
|
+
opacity: 0;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
.nx-field:is([data-readonly], [data-disabled]) .nx-code__slot {
|
|
747
|
+
box-shadow: none;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
/* The input that holds the code lies over the boxes, never seen. At 16px a phone does not zoom in on focus. */
|
|
751
|
+
.nx-code__input {
|
|
752
|
+
position: absolute;
|
|
753
|
+
inset: 0;
|
|
754
|
+
width: 100%;
|
|
755
|
+
margin: 0;
|
|
756
|
+
padding: 0;
|
|
757
|
+
border: 0;
|
|
758
|
+
outline: none;
|
|
759
|
+
background: transparent;
|
|
760
|
+
color: transparent;
|
|
761
|
+
caret-color: transparent;
|
|
762
|
+
font-size: 16px;
|
|
763
|
+
cursor: text;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
.nx-code__input::selection {
|
|
767
|
+
background: transparent;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/* An offered code fills the input without its yellow: the boxes show it. */
|
|
771
|
+
.nx-code__input:is(:autofill, :-webkit-autofill) {
|
|
772
|
+
-webkit-text-fill-color: transparent;
|
|
773
|
+
transition: background-color 600000s;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
.nx-code__input:disabled {
|
|
777
|
+
cursor: not-allowed;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
[data-nx-motion="reduce"] .nx-field__label,
|
|
781
|
+
[data-nx-motion="reduce"] .nx-field--inbox :is(.nx-field__icon, .nx-field__affix, .nx-field__actions),
|
|
782
|
+
[data-nx-motion="reduce"] .nx-code__slot {
|
|
783
|
+
transition: none;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
[data-nx-motion="reduce"] .nx-code__slot[data-caret]::after {
|
|
787
|
+
animation: none;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
[data-nx-motion="reduce"] .nx-field__lock[data-nudge],
|
|
791
|
+
[data-nx-motion="reduce"] .nx-field-notice:popover-open {
|
|
792
|
+
animation: none;
|
|
793
|
+
}
|
|
794
|
+
}
|