nexus-shared 2.0.0 → 3.0.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 +262 -0
- package/README.md +122 -25
- package/dist/Client.Index.d.ts +11 -0
- package/dist/Client.Index.js +11 -0
- package/dist/Components/Chats/Chat.d.ts +28 -0
- package/dist/Components/Chats/Chat.js +19 -0
- package/dist/Components/Chats/ChatButton.d.ts +26 -0
- package/dist/Components/Chats/ChatButton.js +41 -0
- package/dist/Components/Chats/ChatComposer.d.ts +41 -0
- package/dist/Components/Chats/ChatComposer.js +177 -0
- package/dist/Components/Chats/ChatConversations.d.ts +35 -0
- package/dist/Components/Chats/ChatConversations.js +38 -0
- package/dist/Components/Chats/ChatPanel.d.ts +66 -0
- package/dist/Components/Chats/ChatPanel.js +94 -0
- package/dist/Components/Chats/ChatParts.d.ts +87 -0
- package/dist/Components/Chats/ChatParts.js +100 -0
- package/dist/Components/Chats/ChatThread.d.ts +22 -0
- package/dist/Components/Chats/ChatThread.js +96 -0
- package/dist/Components/Documents/Menu.js +24 -20
- package/dist/Components/Documents/SplitButton.js +5 -3
- package/dist/Components/Documents/TabButtons.d.ts +24 -6
- package/dist/Components/Documents/TabButtons.js +23 -4
- package/dist/Components/Forms/ApiForm.d.ts +6 -4
- package/dist/Components/Forms/ApiForm.js +15 -14
- package/dist/Components/Forms/Crud.js +202 -50
- package/dist/Components/Forms/ExcelImport.d.ts +42 -0
- package/dist/Components/Forms/ExcelImport.js +190 -0
- package/dist/Components/Forms/Form.js +5 -1
- package/dist/Components/Inputs/DateTimePicker.js +2 -1
- package/dist/Components/Inputs/GroupForm.js +4 -2
- package/dist/Components/Inputs/InputRenderer.d.ts +2 -0
- package/dist/Components/Inputs/InputRenderer.js +1 -1
- package/dist/Components/Inputs/ReadOnlyNotice.js +2 -1
- package/dist/Components/Inputs/RowsInput.d.ts +12 -1
- package/dist/Components/Inputs/RowsInput.js +53 -4
- package/dist/Components/Inputs/TabularForm.d.ts +7 -3
- package/dist/Components/Inputs/TabularForm.js +85 -20
- package/dist/Components/Inputs/TimePicker.js +2 -1
- package/dist/Components/Layouts/ThemeSwitcher.d.ts +2 -2
- package/dist/Components/Layouts/ThemeSwitcher.js +35 -15
- package/dist/Components/Viewers/DataTable.js +88 -34
- package/dist/Components/Viewers/DataTableColumns.d.ts +28 -0
- package/dist/Components/Viewers/DataTableColumns.js +243 -0
- package/dist/Components/Viewers/DataTableParts.d.ts +6 -2
- package/dist/Components/Viewers/DataTableParts.js +21 -9
- package/dist/Helpers/ApiClient.d.ts +22 -0
- package/dist/Helpers/ApiClient.js +4 -1
- package/dist/Helpers/ApiFormHelpers.d.ts +27 -4
- package/dist/Helpers/ApiFormHelpers.js +73 -9
- package/dist/Helpers/ApiModules.d.ts +0 -4
- package/dist/Helpers/ApiModules.js +1 -0
- package/dist/Helpers/ApiResponses.d.ts +14 -4
- package/dist/Helpers/ApiResponses.js +116 -25
- package/dist/Helpers/ApiRoutes.d.ts +0 -10
- package/dist/Helpers/ApiRoutes.js +2 -10
- package/dist/Helpers/ChatBackend.d.ts +134 -0
- package/dist/Helpers/ChatBackend.js +332 -0
- package/dist/Helpers/ChatHelpers.d.ts +189 -0
- package/dist/Helpers/ChatHelpers.js +486 -0
- package/dist/Helpers/ChatHooks.d.ts +81 -0
- package/dist/Helpers/ChatHooks.js +175 -0
- package/dist/Helpers/ChatStore.d.ts +132 -0
- package/dist/Helpers/ChatStore.js +394 -0
- package/dist/Helpers/ChatSummaries.d.ts +39 -0
- package/dist/Helpers/ChatSummaries.js +118 -0
- package/dist/Helpers/CrudBackend.d.ts +47 -5
- package/dist/Helpers/CrudBackend.js +99 -4
- package/dist/Helpers/CrudHelpers.d.ts +39 -4
- package/dist/Helpers/CrudHelpers.js +76 -11
- package/dist/Helpers/ExcelBackend.d.ts +106 -0
- package/dist/Helpers/ExcelBackend.js +290 -0
- package/dist/Helpers/ExcelHelpers.d.ts +98 -0
- package/dist/Helpers/ExcelHelpers.js +302 -0
- package/dist/Helpers/FormStore.d.ts +2 -0
- package/dist/Helpers/FormStore.js +19 -1
- package/dist/Helpers/MessageBuilder.js +0 -2
- package/dist/Helpers/PopoverHelpers.d.ts +31 -6
- package/dist/Helpers/PopoverHelpers.js +116 -12
- package/dist/Helpers/RowsStore.d.ts +7 -1
- package/dist/Helpers/RowsStore.js +22 -0
- package/dist/Helpers/TableColumns.d.ts +7 -0
- package/dist/Helpers/TableColumns.js +41 -13
- package/dist/Helpers/TableHelpers.d.ts +9 -1
- package/dist/Helpers/TableHelpers.js +20 -0
- package/dist/Interfaces/ApiInterfaces.d.ts +29 -4
- package/dist/Interfaces/ApiInterfaces.js +16 -10
- package/dist/Interfaces/ChatInterfaces.d.ts +240 -0
- package/dist/Interfaces/ChatInterfaces.js +1 -0
- package/dist/Interfaces/CrudInterfaces.d.ts +73 -12
- package/dist/Interfaces/ExcelInterfaces.d.ts +215 -0
- package/dist/Interfaces/ExcelInterfaces.js +45 -0
- package/dist/Interfaces/FormInterfaces.d.ts +52 -2
- package/dist/Interfaces/MessageInterfaces.d.ts +1 -1
- package/dist/Interfaces/TableInterfaces.d.ts +62 -2
- package/dist/Services/BrowserApi.d.ts +18 -1
- package/dist/Services/BrowserApi.js +18 -0
- package/dist/Services/ChatApi.d.ts +37 -0
- package/dist/Services/ChatApi.js +98 -0
- package/dist/Services/ExcelApi.d.ts +46 -0
- package/dist/Services/ExcelApi.js +196 -0
- package/dist/Services/ServerApi.d.ts +6 -1
- package/dist/Services/ServerApi.js +3 -0
- package/dist/Shared.Index.d.ts +8 -0
- package/dist/Shared.Index.js +8 -0
- package/package.json +6 -3
- package/src/Styles/Nexus.Button.css +2 -0
- package/src/Styles/Nexus.Chat.css +1489 -0
- package/src/Styles/Nexus.Crud.css +77 -0
- package/src/Styles/Nexus.Excel.css +370 -0
- package/src/Styles/Nexus.Form.css +23 -0
- package/src/Styles/Nexus.Index.css +2 -0
- package/src/Styles/Nexus.Menu.css +12 -2
- package/src/Styles/Nexus.Rows.css +78 -48
- package/src/Styles/Nexus.Tab.Buttons.css +55 -0
- package/src/Styles/Nexus.Table.css +286 -4
- package/src/Styles/Nexus.Theme.Picker.css +75 -2
|
@@ -57,8 +57,13 @@
|
|
|
57
57
|
*/
|
|
58
58
|
.nx-tabular {
|
|
59
59
|
--nx-tabular-row: calc(var(--nx-control-md) + 1px);
|
|
60
|
-
--nx-tabular-
|
|
60
|
+
--nx-tabular-menu: 22px;
|
|
61
61
|
--nx-tabular-line: var(--nx-border);
|
|
62
|
+
/*
|
|
63
|
+
* The sheet keeps the strong edge. Making it the plain border to answer "boxes inside boxes" put the frame below
|
|
64
|
+
* the edge of every input box beside it, in all seven themes light and dark, which the library asserts against
|
|
65
|
+
* (`tabular-form.cjs`, "frame edge"): the outermost edge of a control cannot be fainter than the ones inside it.
|
|
66
|
+
*/
|
|
62
67
|
--nx-tabular-frame: var(--nx-border-strong);
|
|
63
68
|
--nx-tabular-bg: var(--nx-surface);
|
|
64
69
|
--nx-tabular-head: color-mix(in oklab, var(--nx-text) 4%, var(--nx-surface));
|
|
@@ -68,12 +73,12 @@
|
|
|
68
73
|
|
|
69
74
|
.nx-tabular--sm {
|
|
70
75
|
--nx-tabular-row: calc(var(--nx-control-sm) + 1px);
|
|
71
|
-
--nx-tabular-
|
|
76
|
+
--nx-tabular-menu: 20px;
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
.nx-tabular--lg {
|
|
75
80
|
--nx-tabular-row: calc(var(--nx-control-lg) + 1px);
|
|
76
|
-
--nx-tabular-
|
|
81
|
+
--nx-tabular-menu: 24px;
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
.nx-tabular[data-problem] {
|
|
@@ -89,7 +94,7 @@
|
|
|
89
94
|
box-shadow: var(--nx-shadow-sm);
|
|
90
95
|
outline: none;
|
|
91
96
|
/* A focused cell scrolls clear of the header and the fixed columns. */
|
|
92
|
-
scroll-padding: var(--nx-tabular-row) var(--nx-tabular-
|
|
97
|
+
scroll-padding: var(--nx-tabular-row) 0 0 var(--nx-tabular-num, 48px);
|
|
93
98
|
scrollbar-width: thin;
|
|
94
99
|
scrollbar-color: color-mix(in oklab, var(--nx-text-subtle) 75%, transparent) transparent;
|
|
95
100
|
transition: border-color var(--nx-duration);
|
|
@@ -106,6 +111,12 @@
|
|
|
106
111
|
.nx-tabular__row {
|
|
107
112
|
display: grid;
|
|
108
113
|
grid-template-columns: var(--nx-tabular-columns);
|
|
114
|
+
/*
|
|
115
|
+
* One track, exactly the row's height. Without it the track is sized by the tallest cell, so a single
|
|
116
|
+
* textarea of two lines made every cell of its row 20px too tall and drew them over the rows below: the row
|
|
117
|
+
* looked taller than its neighbours, and its focus ring and its edges bled out of it.
|
|
118
|
+
*/
|
|
119
|
+
grid-template-rows: minmax(0, 1fr);
|
|
109
120
|
height: var(--nx-tabular-row);
|
|
110
121
|
border-bottom: 1px solid var(--nx-tabular-line);
|
|
111
122
|
background: var(--nx-tabular-bg);
|
|
@@ -163,9 +174,24 @@
|
|
|
163
174
|
display: flex;
|
|
164
175
|
align-items: stretch;
|
|
165
176
|
min-width: 0;
|
|
177
|
+
/* Nothing a cell holds is drawn past its own edges: the ring, the invalid edge and the tint all stop here. */
|
|
178
|
+
min-height: 0;
|
|
179
|
+
overflow: hidden;
|
|
166
180
|
border-left: 1px solid var(--nx-tabular-line);
|
|
167
181
|
}
|
|
168
182
|
|
|
183
|
+
/*
|
|
184
|
+
* A textarea scrolls inside its cell instead of making the cell taller. Its own `rows` would size the row, and
|
|
185
|
+
* its resize grip would let one cell break the alignment of its row: in a grid where every other cell keeps the
|
|
186
|
+
* line, that grip is a handle for making the table wrong, eighteen of them down one column.
|
|
187
|
+
*/
|
|
188
|
+
.nx-tabular__cell textarea.nx-field__control {
|
|
189
|
+
height: 100%;
|
|
190
|
+
min-height: 0;
|
|
191
|
+
/* Two classes: the multi-line rule in Nexus.Input.css is two, and one would lose to it in the same layer. */
|
|
192
|
+
resize: none;
|
|
193
|
+
}
|
|
194
|
+
|
|
169
195
|
.nx-tabular__cell > * {
|
|
170
196
|
flex: 1 1 auto;
|
|
171
197
|
min-width: 0;
|
|
@@ -227,10 +253,33 @@
|
|
|
227
253
|
margin: 0;
|
|
228
254
|
}
|
|
229
255
|
|
|
230
|
-
|
|
256
|
+
/*
|
|
257
|
+
* A generated cell wears the read-only tint and no lock: the column header carries one lock for the whole
|
|
258
|
+
* column, and the cell still says why under the table when it is used. One fact, said once, not once a row.
|
|
259
|
+
*/
|
|
260
|
+
.nx-tabular__cell .nx-field__lock {
|
|
261
|
+
display: none;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.nx-tabular__cell--check:has([data-readonly]) {
|
|
231
265
|
background: var(--nx-tabular-readonly);
|
|
232
266
|
}
|
|
233
267
|
|
|
268
|
+
.nx-tabular__head-cell[data-nx-locked] {
|
|
269
|
+
color: var(--nx-text-muted);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.nx-tabular__head-lock {
|
|
273
|
+
width: 13px;
|
|
274
|
+
height: 13px;
|
|
275
|
+
margin-left: auto;
|
|
276
|
+
color: var(--nx-text-muted);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.nx-tabular__head-cell.nx-tabular__cell--number .nx-tabular__head-lock {
|
|
280
|
+
margin-left: 4px;
|
|
281
|
+
}
|
|
282
|
+
|
|
234
283
|
.nx-tabular__cell .nx-choices {
|
|
235
284
|
display: flex;
|
|
236
285
|
align-items: center;
|
|
@@ -244,14 +293,19 @@
|
|
|
244
293
|
overflow: hidden;
|
|
245
294
|
}
|
|
246
295
|
|
|
247
|
-
/*
|
|
296
|
+
/*
|
|
297
|
+
* Row numbers, fixed at the start, with the row's menu beside them. Both have their own place and neither
|
|
298
|
+
* moves: a menu that takes the number's place on hover makes the numbering look broken and the grid unstable.
|
|
299
|
+
*/
|
|
248
300
|
.nx-tabular__num {
|
|
249
301
|
position: sticky;
|
|
250
302
|
left: 0;
|
|
251
303
|
z-index: 1;
|
|
252
|
-
display:
|
|
304
|
+
display: grid;
|
|
305
|
+
grid-template-columns: minmax(0, 1fr) var(--nx-tabular-menu);
|
|
253
306
|
align-items: center;
|
|
254
|
-
|
|
307
|
+
gap: 2px;
|
|
308
|
+
padding-left: 6px;
|
|
255
309
|
border-right: 1px solid var(--nx-tabular-line);
|
|
256
310
|
background: inherit;
|
|
257
311
|
color: var(--nx-text-muted);
|
|
@@ -264,6 +318,11 @@
|
|
|
264
318
|
font-weight: 600;
|
|
265
319
|
}
|
|
266
320
|
|
|
321
|
+
/* Right-aligned, so 9 and 10 line up under one another and the menu is always the same distance away. */
|
|
322
|
+
.nx-tabular__num-text {
|
|
323
|
+
text-align: end;
|
|
324
|
+
}
|
|
325
|
+
|
|
267
326
|
.nx-tabular__num + .nx-tabular__cell,
|
|
268
327
|
.nx-tabular__num + .nx-tabular__head-cell {
|
|
269
328
|
border-left: 0;
|
|
@@ -272,26 +331,24 @@
|
|
|
272
331
|
.nx-tabular__num-button {
|
|
273
332
|
display: grid;
|
|
274
333
|
place-items: center;
|
|
275
|
-
width:
|
|
276
|
-
height: calc(
|
|
334
|
+
width: var(--nx-tabular-menu);
|
|
335
|
+
height: calc(var(--nx-tabular-row) - 8px);
|
|
277
336
|
padding: 0;
|
|
278
337
|
border: 0;
|
|
279
338
|
border-radius: var(--nx-radius-sm);
|
|
280
339
|
background: none;
|
|
281
|
-
|
|
340
|
+
/* Muted, like the numbers beside it, so the column reads as one thing; it is the row's only control now. */
|
|
341
|
+
color: var(--nx-text-muted);
|
|
282
342
|
font: inherit;
|
|
283
343
|
cursor: pointer;
|
|
344
|
+
transition:
|
|
345
|
+
background-color var(--nx-duration),
|
|
346
|
+
color var(--nx-duration);
|
|
284
347
|
}
|
|
285
348
|
|
|
286
|
-
.nx-tabular__num-button
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
.nx-tabular__num-icon {
|
|
292
|
-
width: 16px;
|
|
293
|
-
height: 16px;
|
|
294
|
-
opacity: 0;
|
|
349
|
+
.nx-tabular__num-button .nx-icon {
|
|
350
|
+
width: 15px;
|
|
351
|
+
height: 15px;
|
|
295
352
|
}
|
|
296
353
|
|
|
297
354
|
.nx-tabular__num-button:is(:hover, :focus-visible, [aria-expanded="true"]) {
|
|
@@ -299,16 +356,6 @@
|
|
|
299
356
|
color: var(--nx-text);
|
|
300
357
|
}
|
|
301
358
|
|
|
302
|
-
.nx-tabular__row:hover .nx-tabular__num-icon,
|
|
303
|
-
.nx-tabular__num-button:is(:focus-visible, [aria-expanded="true"]) .nx-tabular__num-icon {
|
|
304
|
-
opacity: 1;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
.nx-tabular__row:hover .nx-tabular__num-button .nx-tabular__num-text,
|
|
308
|
-
.nx-tabular__num-button:is(:focus-visible, [aria-expanded="true"]) .nx-tabular__num-text {
|
|
309
|
-
opacity: 0;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
359
|
.nx-tabular__num-button:focus-visible {
|
|
313
360
|
outline: 2px solid var(--nx-primary);
|
|
314
361
|
outline-offset: -2px;
|
|
@@ -321,23 +368,6 @@
|
|
|
321
368
|
font-weight: 600;
|
|
322
369
|
}
|
|
323
370
|
|
|
324
|
-
/* Remove buttons, fixed at the end. */
|
|
325
|
-
.nx-tabular__end {
|
|
326
|
-
position: sticky;
|
|
327
|
-
right: 0;
|
|
328
|
-
z-index: 1;
|
|
329
|
-
display: flex;
|
|
330
|
-
align-items: center;
|
|
331
|
-
justify-content: center;
|
|
332
|
-
border-left: 1px solid var(--nx-tabular-line);
|
|
333
|
-
background: inherit;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
.nx-tabular__remove.nx-btn {
|
|
337
|
-
width: calc(var(--nx-tabular-row) - 9px);
|
|
338
|
-
height: calc(var(--nx-tabular-row) - 9px);
|
|
339
|
-
color: var(--nx-text-muted);
|
|
340
|
-
}
|
|
341
371
|
|
|
342
372
|
.nx-tabular__row--empty {
|
|
343
373
|
display: block;
|
|
@@ -557,7 +587,7 @@
|
|
|
557
587
|
|
|
558
588
|
@media (prefers-reduced-motion: reduce) {
|
|
559
589
|
.nx-tabular__viewport,
|
|
560
|
-
.nx-tabular__num-button
|
|
590
|
+
.nx-tabular__num-button,
|
|
561
591
|
.nx-group-form__toggle,
|
|
562
592
|
.nx-group-form__chevron {
|
|
563
593
|
transition: none;
|
|
@@ -219,6 +219,55 @@
|
|
|
219
219
|
text-overflow: ellipsis;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
/*
|
|
223
|
+
* multiple: several at once. There is no single place for a sliding indicator, so every chosen option is raised on
|
|
224
|
+
* its own, exactly as the one choice's indicator is, and an option that is not chosen sits flat on the track. The
|
|
225
|
+
* options wrap onto more rows when they do not fit, each row as tall as a one-row track's options, so a picker of
|
|
226
|
+
* 26 letters is one track of several rows rather than a line that runs off a phone. A one-character option is
|
|
227
|
+
* square, so a row of letters lines up.
|
|
228
|
+
*/
|
|
229
|
+
.nx-tabs--multiple {
|
|
230
|
+
--nx-tabs-option-height: calc(var(--nx-tabs-height) - 2 * var(--nx-tabs-pad) - 2px);
|
|
231
|
+
|
|
232
|
+
display: inline-flex;
|
|
233
|
+
flex-wrap: wrap;
|
|
234
|
+
gap: 2px;
|
|
235
|
+
max-width: 100%;
|
|
236
|
+
height: auto;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.nx-tabs--multiple.nx-tabs--block {
|
|
240
|
+
display: flex;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.nx-tabs--multiple .nx-tabs__option {
|
|
244
|
+
flex: 0 0 auto;
|
|
245
|
+
min-width: var(--nx-tabs-option-height);
|
|
246
|
+
height: var(--nx-tabs-option-height);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/* A chosen option can be unchosen, so it keeps the pointer, and it keeps its raised look under the pointer too. */
|
|
250
|
+
.nx-tabs--multiple .nx-tabs__option:has(:checked) {
|
|
251
|
+
background: var(--nx-tabs-indicator);
|
|
252
|
+
box-shadow:
|
|
253
|
+
inset 0 0 0 1px var(--nx-tabs-indicator-border),
|
|
254
|
+
var(--nx-tabs-indicator-shadow);
|
|
255
|
+
cursor: pointer;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.nx-tabs--multiple .nx-tabs__option:has(:checked):has(:focus-visible) {
|
|
259
|
+
box-shadow:
|
|
260
|
+
inset 0 0 0 1px var(--nx-tabs-indicator-border),
|
|
261
|
+
var(--nx-focus-ring);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* A finger needs more than a small button's 22px: on a touch screen every option is a medium control's height, square at the least. */
|
|
265
|
+
@media (pointer: coarse) {
|
|
266
|
+
.nx-tabs--multiple {
|
|
267
|
+
--nx-tabs-option-height: var(--nx-control-md);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
222
271
|
/*
|
|
223
272
|
* design="list": a vertical list of rows, for settings pages and side panels. There is no track: rows sit on the
|
|
224
273
|
* panel, the selected row is tinted (darker in light mode, lighter in dark mode) and marked by a bar at its start,
|
|
@@ -280,6 +329,11 @@
|
|
|
280
329
|
background: var(--nx-tabs-list-selected);
|
|
281
330
|
}
|
|
282
331
|
|
|
332
|
+
/* A list of several choices: a chosen row can be unchosen, so it keeps the pointer. */
|
|
333
|
+
.nx-tabs--list:not([role="radiogroup"]) .nx-tabs__option:has(:checked) {
|
|
334
|
+
cursor: pointer;
|
|
335
|
+
}
|
|
336
|
+
|
|
283
337
|
.nx-tabs--list .nx-tabs__option:has(:checked)::before {
|
|
284
338
|
opacity: 1;
|
|
285
339
|
transform: none;
|
|
@@ -356,6 +410,7 @@
|
|
|
356
410
|
|
|
357
411
|
@media (prefers-reduced-motion: reduce) {
|
|
358
412
|
.nx-tabs__indicator,
|
|
413
|
+
.nx-tabs--multiple .nx-tabs__option,
|
|
359
414
|
.nx-tabs--labels-selected :is(.nx-tabs__option, .nx-tabs__label),
|
|
360
415
|
.nx-tabs--list .nx-tabs__option::before {
|
|
361
416
|
transition: none;
|
|
@@ -13,6 +13,12 @@
|
|
|
13
13
|
--nx-table-flash: color-mix(in oklab, var(--nx-success) 18%, var(--nx-surface));
|
|
14
14
|
--nx-table-line: var(--nx-border);
|
|
15
15
|
--nx-table-head-h: 40px;
|
|
16
|
+
/* The band of group headings above the columns' own, when any column names a group. */
|
|
17
|
+
--nx-table-group-h: 30px;
|
|
18
|
+
/* How many rows the header has: 1, or 2 while a band stands above the headings (`data-head-rows`). */
|
|
19
|
+
--nx-table-head-rows: 1;
|
|
20
|
+
/* The whole header, which the loading bar and the selection bar are measured from. */
|
|
21
|
+
--nx-table-head-all: calc(var(--nx-table-head-h) + (var(--nx-table-head-rows) - 1) * var(--nx-table-group-h));
|
|
16
22
|
--nx-table-row-h: 44px;
|
|
17
23
|
--nx-table-pad-x: 12px;
|
|
18
24
|
--nx-table-select-w: 44px;
|
|
@@ -27,8 +33,13 @@
|
|
|
27
33
|
color: var(--nx-text);
|
|
28
34
|
}
|
|
29
35
|
|
|
36
|
+
.nx-table[data-head-rows="2"] {
|
|
37
|
+
--nx-table-head-rows: 2;
|
|
38
|
+
}
|
|
39
|
+
|
|
30
40
|
.nx-table--sm {
|
|
31
41
|
--nx-table-head-h: 34px;
|
|
42
|
+
--nx-table-group-h: 26px;
|
|
32
43
|
--nx-table-row-h: 36px;
|
|
33
44
|
--nx-table-pad-x: 10px;
|
|
34
45
|
--nx-table-select-w: 38px;
|
|
@@ -103,6 +114,30 @@
|
|
|
103
114
|
}
|
|
104
115
|
}
|
|
105
116
|
|
|
117
|
+
/*
|
|
118
|
+
* `fill`: the table takes the height it is given instead of growing with its rows. The bar and the footer keep their
|
|
119
|
+
* own height, the frame takes the rest, and the rows scroll inside it. Nothing below the table moves when a page
|
|
120
|
+
* holds fewer rows, and the page behind it never gains a scrollbar.
|
|
121
|
+
*/
|
|
122
|
+
.nx-table--fill {
|
|
123
|
+
height: 100%;
|
|
124
|
+
min-height: 0;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.nx-table--fill > .nx-table__frame {
|
|
128
|
+
display: flex;
|
|
129
|
+
flex: 1 1 auto;
|
|
130
|
+
flex-direction: column;
|
|
131
|
+
min-height: 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.nx-table--fill .nx-table__scroll {
|
|
135
|
+
flex: 1 1 auto;
|
|
136
|
+
min-height: 0;
|
|
137
|
+
/* The room for the scrollbar is kept, so the headings do not shift the moment the rows need one. */
|
|
138
|
+
scrollbar-gutter: stable;
|
|
139
|
+
}
|
|
140
|
+
|
|
106
141
|
/* The frame. */
|
|
107
142
|
.nx-table__frame {
|
|
108
143
|
position: relative;
|
|
@@ -157,6 +192,11 @@
|
|
|
157
192
|
--nx-row-bg: var(--nx-table-hover);
|
|
158
193
|
}
|
|
159
194
|
|
|
195
|
+
/* A row a click opens says so under the pointer. Only the pointer changes: nothing in the row moves on hover. */
|
|
196
|
+
.nx-table__row[data-open] {
|
|
197
|
+
cursor: pointer;
|
|
198
|
+
}
|
|
199
|
+
|
|
160
200
|
.nx-table__row[data-selected] {
|
|
161
201
|
--nx-row-bg: var(--nx-table-selected);
|
|
162
202
|
}
|
|
@@ -303,14 +343,15 @@
|
|
|
303
343
|
}
|
|
304
344
|
|
|
305
345
|
.nx-table__row:hover > .nx-table__cell--index[data-swap] > .nx-table__check,
|
|
306
|
-
|
|
346
|
+
/* The heading's own cell may stand in the band row, so the whole header counts as hovering it. */
|
|
347
|
+
.nx-table__thead:hover .nx-table__cell--index[data-swap] > .nx-table__check,
|
|
307
348
|
.nx-table__cell--index[data-swap]:focus-within > .nx-table__check,
|
|
308
349
|
.nx-table[data-selecting] .nx-table__cell--index[data-swap] > .nx-table__check {
|
|
309
350
|
opacity: 1;
|
|
310
351
|
}
|
|
311
352
|
|
|
312
353
|
.nx-table__row:hover > .nx-table__cell--index[data-swap] > .nx-table__number,
|
|
313
|
-
.nx-
|
|
354
|
+
.nx-table__thead:hover .nx-table__cell--index[data-swap] > .nx-table__number,
|
|
314
355
|
.nx-table__cell--index[data-swap]:focus-within > .nx-table__number,
|
|
315
356
|
.nx-table[data-selecting] .nx-table__cell--index[data-swap] > .nx-table__number {
|
|
316
357
|
opacity: 0;
|
|
@@ -462,6 +503,42 @@
|
|
|
462
503
|
padding: 0;
|
|
463
504
|
}
|
|
464
505
|
|
|
506
|
+
/*
|
|
507
|
+
* Columns in bands: a group's heading spans the columns next to each other that name it, and the columns with no
|
|
508
|
+
* group keep one heading as tall as both rows. Both rows stay while the rows scroll, the band on top.
|
|
509
|
+
*/
|
|
510
|
+
.nx-table__head--leaves > .nx-table__heading {
|
|
511
|
+
top: var(--nx-table-group-h);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.nx-table__heading--group {
|
|
515
|
+
height: var(--nx-table-group-h);
|
|
516
|
+
border-bottom: 0;
|
|
517
|
+
text-align: center;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/* The line under a band stops short of its edges, so two bands beside each other read as two, not as one rule. */
|
|
521
|
+
.nx-table__heading--group::after {
|
|
522
|
+
content: "";
|
|
523
|
+
position: absolute;
|
|
524
|
+
right: var(--nx-table-pad-x);
|
|
525
|
+
bottom: 0;
|
|
526
|
+
left: var(--nx-table-pad-x);
|
|
527
|
+
height: 1px;
|
|
528
|
+
background: var(--nx-table-line);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
.nx-table__group {
|
|
532
|
+
display: block;
|
|
533
|
+
overflow: hidden;
|
|
534
|
+
color: var(--nx-text);
|
|
535
|
+
font-size: var(--nx-text-xs);
|
|
536
|
+
font-weight: 700;
|
|
537
|
+
letter-spacing: 0.04em;
|
|
538
|
+
text-overflow: ellipsis;
|
|
539
|
+
text-transform: uppercase;
|
|
540
|
+
}
|
|
541
|
+
|
|
465
542
|
.nx-table__heading-inner {
|
|
466
543
|
display: flex;
|
|
467
544
|
align-items: center;
|
|
@@ -775,7 +852,7 @@
|
|
|
775
852
|
/* A thin bar under the header while a load runs with rows on screen. The rows dim only if it takes a moment. */
|
|
776
853
|
.nx-table__progress {
|
|
777
854
|
position: absolute;
|
|
778
|
-
top: calc(var(--nx-table-head-
|
|
855
|
+
top: calc(var(--nx-table-head-all) - 1px);
|
|
779
856
|
right: 0;
|
|
780
857
|
left: 0;
|
|
781
858
|
z-index: 4;
|
|
@@ -827,7 +904,7 @@
|
|
|
827
904
|
display: flex;
|
|
828
905
|
align-items: center;
|
|
829
906
|
gap: var(--nx-space-2);
|
|
830
|
-
height: calc(var(--nx-table-head-
|
|
907
|
+
height: calc(var(--nx-table-head-all) - 1px);
|
|
831
908
|
padding: 0 var(--nx-space-2) 0 2px;
|
|
832
909
|
background: var(--nx-table-selected);
|
|
833
910
|
}
|
|
@@ -1011,4 +1088,209 @@
|
|
|
1011
1088
|
opacity: 0.6;
|
|
1012
1089
|
}
|
|
1013
1090
|
}
|
|
1091
|
+
|
|
1092
|
+
/*
|
|
1093
|
+
* The Columns panel: a checkbox per column and a handle to drag it into another place. It shares the .nx-popover
|
|
1094
|
+
* panel with the menu, and holds a list rather than actions, so a click inside it never closes it.
|
|
1095
|
+
*/
|
|
1096
|
+
.nx-columns {
|
|
1097
|
+
--nx-columns-row-h: 32px;
|
|
1098
|
+
position: fixed;
|
|
1099
|
+
inset: auto;
|
|
1100
|
+
min-width: 232px;
|
|
1101
|
+
max-width: min(320px, calc(100% - 16px));
|
|
1102
|
+
max-height: calc(100vh - 16px);
|
|
1103
|
+
padding: var(--nx-space-2);
|
|
1104
|
+
outline: none;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
.nx-columns--sm {
|
|
1108
|
+
--nx-columns-row-h: 28px;
|
|
1109
|
+
font-size: var(--nx-text-sm);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
/* A shut popover is hidden by the browser, so the panel takes its layout only while it is open. */
|
|
1113
|
+
.nx-columns:popover-open {
|
|
1114
|
+
display: flex;
|
|
1115
|
+
flex-direction: column;
|
|
1116
|
+
animation: nx-menu-in 120ms ease-out;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
.nx-columns__head {
|
|
1120
|
+
display: flex;
|
|
1121
|
+
align-items: baseline;
|
|
1122
|
+
justify-content: space-between;
|
|
1123
|
+
gap: var(--nx-space-3);
|
|
1124
|
+
padding: 2px var(--nx-space-2) 6px;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
.nx-columns__title {
|
|
1128
|
+
font-weight: 600;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
.nx-columns__count {
|
|
1132
|
+
color: var(--nx-text-muted);
|
|
1133
|
+
font-size: var(--nx-text-xs);
|
|
1134
|
+
font-variant-numeric: tabular-nums;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
.nx-columns__list {
|
|
1138
|
+
display: flex;
|
|
1139
|
+
flex: 1 1 auto;
|
|
1140
|
+
flex-direction: column;
|
|
1141
|
+
min-height: 0;
|
|
1142
|
+
margin: 0;
|
|
1143
|
+
padding: 0;
|
|
1144
|
+
overflow: hidden auto;
|
|
1145
|
+
overscroll-behavior: contain;
|
|
1146
|
+
list-style: none;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
.nx-columns__row {
|
|
1150
|
+
display: flex;
|
|
1151
|
+
align-items: center;
|
|
1152
|
+
gap: 6px;
|
|
1153
|
+
min-height: var(--nx-columns-row-h);
|
|
1154
|
+
padding: 0 var(--nx-space-2) 0 2px;
|
|
1155
|
+
border: 1px solid transparent;
|
|
1156
|
+
border-radius: var(--nx-radius);
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
.nx-columns__row:hover {
|
|
1160
|
+
background: var(--nx-surface-hover);
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
/* The row being dragged stays in place and goes quiet; a line shows where it would land. */
|
|
1164
|
+
.nx-columns__row[data-held] {
|
|
1165
|
+
background: var(--nx-surface-hover);
|
|
1166
|
+
opacity: 0.6;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
.nx-columns__row[data-drop] {
|
|
1170
|
+
border-color: var(--nx-primary);
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
/* A band: its own line, with the columns under it indented along a line that says where the band ends. */
|
|
1174
|
+
.nx-columns__row--band {
|
|
1175
|
+
display: block;
|
|
1176
|
+
padding: 0;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
.nx-columns__row--band:hover {
|
|
1180
|
+
background: none;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
.nx-columns__band {
|
|
1184
|
+
display: flex;
|
|
1185
|
+
align-items: center;
|
|
1186
|
+
gap: 6px;
|
|
1187
|
+
min-height: var(--nx-columns-row-h);
|
|
1188
|
+
padding: 0 var(--nx-space-2) 0 2px;
|
|
1189
|
+
border-radius: var(--nx-radius);
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
.nx-columns__band:hover {
|
|
1193
|
+
background: var(--nx-surface-hover);
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
.nx-columns__band .nx-columns__label {
|
|
1197
|
+
font-weight: 600;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
.nx-columns__band-count {
|
|
1201
|
+
flex: none;
|
|
1202
|
+
color: var(--nx-text-subtle);
|
|
1203
|
+
font-size: var(--nx-text-xs);
|
|
1204
|
+
font-variant-numeric: tabular-nums;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
.nx-columns__children {
|
|
1208
|
+
margin: 0 0 2px 13px;
|
|
1209
|
+
padding: 0 0 0 9px;
|
|
1210
|
+
border-left: 1px solid var(--nx-border);
|
|
1211
|
+
list-style: none;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
/* A column whose band is hidden stays readable but plainly off. */
|
|
1215
|
+
.nx-columns__row--child:has(input:disabled) .nx-columns__label {
|
|
1216
|
+
color: var(--nx-text-subtle);
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
.nx-columns__handle {
|
|
1220
|
+
display: inline-flex;
|
|
1221
|
+
flex: none;
|
|
1222
|
+
align-items: center;
|
|
1223
|
+
justify-content: center;
|
|
1224
|
+
width: 20px;
|
|
1225
|
+
height: var(--nx-columns-row-h);
|
|
1226
|
+
padding: 0;
|
|
1227
|
+
border: 0;
|
|
1228
|
+
border-radius: var(--nx-radius-sm);
|
|
1229
|
+
background: none;
|
|
1230
|
+
color: var(--nx-text-subtle);
|
|
1231
|
+
cursor: grab;
|
|
1232
|
+
touch-action: none;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
.nx-columns__handle:hover {
|
|
1236
|
+
color: var(--nx-text);
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
.nx-columns__handle:focus-visible {
|
|
1240
|
+
outline: none;
|
|
1241
|
+
box-shadow: var(--nx-focus-ring);
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
.nx-columns[data-dragging] .nx-columns__handle {
|
|
1245
|
+
cursor: grabbing;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
.nx-columns__handle--fixed {
|
|
1249
|
+
cursor: default;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
.nx-columns__choice {
|
|
1253
|
+
flex: 1 1 auto;
|
|
1254
|
+
min-width: 0;
|
|
1255
|
+
padding: 2px 0;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
.nx-columns__label {
|
|
1259
|
+
overflow: hidden;
|
|
1260
|
+
text-overflow: ellipsis;
|
|
1261
|
+
white-space: nowrap;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
.nx-columns__pin {
|
|
1265
|
+
display: inline-flex;
|
|
1266
|
+
flex: none;
|
|
1267
|
+
color: var(--nx-text-subtle);
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
.nx-columns__pin .nx-icon {
|
|
1271
|
+
width: 14px;
|
|
1272
|
+
height: 14px;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
.nx-columns__note {
|
|
1276
|
+
margin: 6px 0 0;
|
|
1277
|
+
padding: 0 var(--nx-space-2);
|
|
1278
|
+
color: var(--nx-text-muted);
|
|
1279
|
+
font-size: var(--nx-text-xs);
|
|
1280
|
+
line-height: 1.4;
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
.nx-columns__foot {
|
|
1284
|
+
display: flex;
|
|
1285
|
+
justify-content: flex-end;
|
|
1286
|
+
margin-top: var(--nx-space-2);
|
|
1287
|
+
padding-top: var(--nx-space-2);
|
|
1288
|
+
border-top: 1px solid var(--nx-border);
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1292
|
+
.nx-columns:popover-open {
|
|
1293
|
+
animation: none;
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1014
1296
|
}
|