@nordmanai/nif 0.2.5 → 0.2.9

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.
Files changed (70) hide show
  1. package/dist/index.d.ts +5 -0
  2. package/dist/index.js +6915 -6376
  3. package/dist/styles.css +1 -1
  4. package/dist/ui/components/nm-alert-dialog/nm-alert-dialog.d.ts +17 -0
  5. package/dist/ui/components/nm-dialog/nm-dialog.d.ts +4 -0
  6. package/dist/ui/components/nm-drawer/nm-drawer.d.ts +18 -0
  7. package/dist/ui/components/nm-sidebar/nm-sidebar.d.ts +134 -0
  8. package/dist/ui/config/nm-appearance.d.ts +13 -1
  9. package/dist/ui/config/nm-drawer.d.ts +3 -0
  10. package/dist/ui/config/nm-sidebar.d.ts +29 -0
  11. package/dist/ui/lib/appearance/appearanceState.d.ts +2 -1
  12. package/package.json +1 -1
  13. package/registry/index.json +212 -1
  14. package/registry/ui/components/nm-ai/nm-ai.css +3 -3
  15. package/registry/ui/components/nm-alert/nm-alert.css +1 -1
  16. package/registry/ui/components/nm-alert-dialog/nm-alert-dialog.css +4 -0
  17. package/registry/ui/components/nm-alert-dialog/nm-alert-dialog.tsx +43 -0
  18. package/registry/ui/components/nm-button/nm-button.css +2 -2
  19. package/registry/ui/components/nm-button-group/nm-button-group.css +1 -1
  20. package/registry/ui/components/nm-calendar/nm-calendar.css +1 -1
  21. package/registry/ui/components/nm-card/nm-card.css +2 -2
  22. package/registry/ui/components/nm-chatbox/nm-chatbox.css +1 -1
  23. package/registry/ui/components/nm-checkbox/nm-checkbox.css +2 -2
  24. package/registry/ui/components/nm-chip/nm-chip.css +1 -1
  25. package/registry/ui/components/nm-code-block/nm-code-block.css +1 -1
  26. package/registry/ui/components/nm-collection/nm-collection.css +2 -2
  27. package/registry/ui/components/nm-color-picker/nm-color-picker.css +1 -1
  28. package/registry/ui/components/nm-combobox/nm-combobox.css +2 -2
  29. package/registry/ui/components/nm-command/nm-command.css +1 -1
  30. package/registry/ui/components/nm-composer/nm-composer.css +3 -3
  31. package/registry/ui/components/nm-date-picker/nm-date-picker.css +2 -2
  32. package/registry/ui/components/nm-dialog/nm-dialog.css +16 -1
  33. package/registry/ui/components/nm-dialog/nm-dialog.tsx +8 -0
  34. package/registry/ui/components/nm-drawer/nm-drawer.css +70 -0
  35. package/registry/ui/components/nm-drawer/nm-drawer.tsx +41 -0
  36. package/registry/ui/components/nm-dropdown/nm-dropdown.css +2 -2
  37. package/registry/ui/components/nm-dropdown-menu/nm-dropdown-menu.css +1 -1
  38. package/registry/ui/components/nm-field/nm-field.css +6 -6
  39. package/registry/ui/components/nm-hover-card/nm-hover-card.css +1 -1
  40. package/registry/ui/components/nm-input/nm-input.css +3 -3
  41. package/registry/ui/components/nm-input-group/nm-input-group.css +2 -2
  42. package/registry/ui/components/nm-message/nm-message.css +1 -1
  43. package/registry/ui/components/nm-native-select/nm-native-select.css +2 -2
  44. package/registry/ui/components/nm-popover/nm-popover.css +1 -1
  45. package/registry/ui/components/nm-prose/nm-prose.css +3 -3
  46. package/registry/ui/components/nm-questionnaire/nm-questionnaire.css +3 -3
  47. package/registry/ui/components/nm-radio-group/nm-radio-group.css +2 -2
  48. package/registry/ui/components/nm-segmented/nm-segmented.css +1 -1
  49. package/registry/ui/components/nm-select/nm-select.css +2 -2
  50. package/registry/ui/components/nm-separator/nm-separator.css +1 -1
  51. package/registry/ui/components/nm-side-panel/nm-side-panel.css +1 -1
  52. package/registry/ui/components/nm-sidebar/nm-sidebar.css +647 -0
  53. package/registry/ui/components/nm-sidebar/nm-sidebar.tsx +532 -0
  54. package/registry/ui/components/nm-spinner/nm-spinner.css +1 -1
  55. package/registry/ui/components/nm-switch/nm-switch.css +1 -1
  56. package/registry/ui/components/nm-table/nm-table.css +4 -4
  57. package/registry/ui/components/nm-tabs/nm-tabs.css +1 -1
  58. package/registry/ui/components/nm-textarea/nm-textarea.css +5 -5
  59. package/registry/ui/components/nm-toggle/nm-toggle.css +1 -1
  60. package/registry/ui/components/nordman-icon-button/nordman-icon-button.css +2 -2
  61. package/registry/ui/components/nordman-login/nordman-login.css +3 -3
  62. package/registry/ui/components/nordman-toggle/nordman-toggle.css +1 -1
  63. package/registry/ui/config/nm-appearance.ts +17 -0
  64. package/registry/ui/config/nm-drawer.ts +3 -0
  65. package/registry/ui/config/nm-sidebar.ts +37 -0
  66. package/registry/ui/lib/appearance/appearanceState.ts +8 -0
  67. package/registry/ui/lib/appearance/applyAppearance.ts +3 -1
  68. package/registry/ui/lib/appearance/deriveTokens.ts +2 -0
  69. package/registry/ui/styles/light-appearance.css +3 -3
  70. package/registry/ui/styles/tokens.css +31 -0
@@ -0,0 +1,647 @@
1
+ /* The provider holds the sidebar and the main area side by side. */
2
+ .nm-sidebar-provider {
3
+ --nm-sidebar-width: var(--nm-width-sidebar);
4
+ --nm-sidebar-width-icon: var(--nm-width-sidebar-icon);
5
+ position: relative;
6
+ box-sizing: border-box;
7
+ display: flex;
8
+ width: 100%;
9
+ min-height: 100%;
10
+ min-width: 0;
11
+ overflow: hidden;
12
+ background: var(--nm-canvas);
13
+ color: var(--nm-fg);
14
+ font-family: var(--nm-font);
15
+ font-size: var(--nm-type-ui);
16
+ }
17
+ /* A fixed height frames the provider as a card: a sidebar shown inside a page. */
18
+ .nm-sidebar-provider[data-height='sm'],
19
+ .nm-sidebar-provider[data-height='lg'] {
20
+ min-height: 0;
21
+ border: var(--nm-rule) solid var(--nm-border-strong);
22
+ border-radius: var(--nm-radius-lg);
23
+ }
24
+ .nm-sidebar-provider[data-height='sm'] {
25
+ height: var(--nm-height-sidebar-sm);
26
+ }
27
+ .nm-sidebar-provider[data-height='lg'] {
28
+ height: var(--nm-height-sidebar-lg);
29
+ }
30
+
31
+ /* The sidebar: a column that takes its width from the provider and gives it up when collapsed. */
32
+ .nm-sidebar {
33
+ position: relative;
34
+ box-sizing: border-box;
35
+ display: flex;
36
+ flex: 0 0 auto;
37
+ flex-direction: column;
38
+ width: var(--nm-sidebar-width);
39
+ min-height: 0;
40
+ overflow: hidden;
41
+ color: var(--nm-fg);
42
+ background: var(--nm-raised);
43
+ transition:
44
+ width var(--reveal) var(--ease),
45
+ padding var(--reveal) var(--ease);
46
+ }
47
+ .nm-sidebar[data-side='right'] {
48
+ order: 1;
49
+ }
50
+ .nm-sidebar[data-variant='sidebar'][data-side='left'] {
51
+ border-inline-end: var(--nm-rule) solid var(--nm-border-divider);
52
+ }
53
+ .nm-sidebar[data-variant='sidebar'][data-side='right'] {
54
+ border-inline-start: var(--nm-rule) solid var(--nm-border-divider);
55
+ }
56
+ .nm-sidebar[data-collapsible='offcanvas'] {
57
+ width: 0;
58
+ border-width: 0;
59
+ }
60
+ .nm-sidebar[data-collapsible='icon'],
61
+ .nm-sidebar[data-collapsible='toggle'] {
62
+ width: var(--nm-sidebar-width-icon);
63
+ }
64
+
65
+ /* The inner column keeps its width while the outer one closes, so nothing reflows on the way out. */
66
+ .nm-sidebar__inner {
67
+ box-sizing: border-box;
68
+ display: flex;
69
+ flex: 1;
70
+ flex-direction: column;
71
+ width: 100%;
72
+ min-width: 0;
73
+ min-height: 0;
74
+ }
75
+ .nm-sidebar[data-collapsible='offcanvas'] .nm-sidebar__inner {
76
+ width: var(--nm-sidebar-width);
77
+ }
78
+
79
+ /* Peek: the collapsed sidebar shown in full over the main area while the pointer rests on it or on the toggle.
80
+ The column keeps its collapsed width in the flow, and the inner panel floats out over the page. */
81
+ .nm-sidebar[data-peek] {
82
+ overflow: visible;
83
+ z-index: 1;
84
+ }
85
+ .nm-sidebar[data-mode='offcanvas'][data-peek] {
86
+ width: 0;
87
+ border-width: 0;
88
+ }
89
+ .nm-sidebar[data-mode='icon'][data-peek],
90
+ .nm-sidebar[data-mode='toggle'][data-peek] {
91
+ width: var(--nm-sidebar-width-icon);
92
+ }
93
+ .nm-sidebar[data-peek] .nm-sidebar__inner {
94
+ position: absolute;
95
+ inset-block: 0;
96
+ inset-inline-start: 0;
97
+ width: var(--nm-sidebar-width);
98
+ border-inline-end: var(--nm-rule) solid var(--nm-border-strong);
99
+ background: var(--nm-raised);
100
+ }
101
+ .nm-sidebar[data-side='right'][data-peek] .nm-sidebar__inner {
102
+ inset-inline-start: auto;
103
+ inset-inline-end: 0;
104
+ border-inline-end: 0;
105
+ border-inline-start: var(--nm-rule) solid var(--nm-border-strong);
106
+ }
107
+ .nm-sidebar[data-variant='floating'][data-peek] .nm-sidebar__inner,
108
+ .nm-sidebar[data-variant='inset'][data-peek] .nm-sidebar__inner {
109
+ inset-block: var(--nm-space-8);
110
+ inset-inline-start: var(--nm-space-8);
111
+ border: var(--nm-rule) solid var(--nm-border-strong);
112
+ border-radius: var(--nm-radius-lg);
113
+ }
114
+ .nm-sidebar[data-variant='floating'][data-side='right'][data-peek] .nm-sidebar__inner,
115
+ .nm-sidebar[data-variant='inset'][data-side='right'][data-peek] .nm-sidebar__inner {
116
+ inset-inline-start: auto;
117
+ inset-inline-end: var(--nm-space-8);
118
+ }
119
+
120
+ /* Floating: a raised card inside a margin. Inset: the sidebar is on the canvas and the main area is the card. */
121
+ .nm-sidebar[data-variant='floating'],
122
+ .nm-sidebar[data-variant='inset'] {
123
+ padding: var(--nm-space-8);
124
+ background: var(--nm-canvas);
125
+ }
126
+ .nm-sidebar[data-variant='floating'][data-side='left'],
127
+ .nm-sidebar[data-variant='inset'][data-side='left'] {
128
+ padding-inline-end: 0;
129
+ }
130
+ .nm-sidebar[data-variant='floating'][data-side='right'],
131
+ .nm-sidebar[data-variant='inset'][data-side='right'] {
132
+ padding-inline-start: 0;
133
+ }
134
+ .nm-sidebar[data-variant='floating'] .nm-sidebar__inner {
135
+ border: var(--nm-rule) solid var(--nm-border-strong);
136
+ border-radius: var(--nm-radius-lg);
137
+ background: var(--nm-raised);
138
+ }
139
+ .nm-sidebar[data-variant='floating'][data-collapsible='offcanvas'],
140
+ .nm-sidebar[data-variant='inset'][data-collapsible='offcanvas'],
141
+ .nm-sidebar[data-variant='floating'][data-mode='offcanvas'][data-peek],
142
+ .nm-sidebar[data-variant='inset'][data-mode='offcanvas'][data-peek] {
143
+ padding-inline: 0;
144
+ }
145
+
146
+ /* On a phone the sidebar is a drawer over the page: the NIF Drawer at the sidebar's phone width. */
147
+ .nm-sidebar__sheet {
148
+ --nm-width-drawer: var(--nm-width-sidebar-mobile);
149
+ }
150
+
151
+ /* The main area. With the inset variant it is the raised card. */
152
+ .nm-sidebar__inset {
153
+ position: relative;
154
+ box-sizing: border-box;
155
+ display: flex;
156
+ flex: 1;
157
+ flex-direction: column;
158
+ min-width: 0;
159
+ min-height: 0;
160
+ background: var(--nm-canvas);
161
+ }
162
+ .nm-sidebar[data-variant='inset'] ~ .nm-sidebar__inset {
163
+ margin: var(--nm-space-8);
164
+ overflow: hidden;
165
+ border-radius: var(--nm-radius-lg);
166
+ background: var(--nm-raised);
167
+ }
168
+
169
+ /* The button that toggles the sidebar: the quiet NIF icon button, kept in place in a bar or a header. */
170
+ .nm-sidebar__trigger {
171
+ flex-shrink: 0;
172
+ }
173
+ /* A header with the toggle in it is a row: the brand or switcher, then the toggle at the end. */
174
+ .nm-sidebar__header:has(> .nm-sidebar__trigger) {
175
+ flex-direction: row;
176
+ align-items: center;
177
+ }
178
+ .nm-sidebar__header:has(> .nm-sidebar__trigger) > :not(.nm-sidebar__trigger) {
179
+ flex: 1 1 auto;
180
+ min-width: 0;
181
+ }
182
+ .nm-sidebar[data-side='right'] .nm-sidebar__header:has(> .nm-sidebar__trigger) {
183
+ flex-direction: row-reverse;
184
+ }
185
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__header:has(> .nm-sidebar__trigger) {
186
+ flex-direction: column;
187
+ }
188
+
189
+ /* The thin strip on the edge that toggles the sidebar. A line appears on hover. */
190
+ .nm-sidebar__rail {
191
+ position: absolute;
192
+ inset-block: 0;
193
+ inset-inline-end: calc(var(--nm-space-8) * -1);
194
+ z-index: 1;
195
+ width: var(--nm-space-16);
196
+ padding: 0;
197
+ border: 0;
198
+ background: transparent;
199
+ cursor: w-resize;
200
+ outline: none;
201
+ }
202
+ .nm-sidebar[data-side='right'] .nm-sidebar__rail {
203
+ inset-inline-end: auto;
204
+ inset-inline-start: calc(var(--nm-space-8) * -1);
205
+ cursor: e-resize;
206
+ }
207
+ .nm-sidebar[data-state='collapsed'] .nm-sidebar__rail {
208
+ cursor: e-resize;
209
+ }
210
+ .nm-sidebar[data-state='collapsed'][data-side='right'] .nm-sidebar__rail {
211
+ cursor: w-resize;
212
+ }
213
+ .nm-sidebar__rail::after {
214
+ content: '';
215
+ position: absolute;
216
+ inset-block: 0;
217
+ left: 50%;
218
+ width: var(--nm-rule);
219
+ background: var(--nm-line-strong);
220
+ opacity: 0;
221
+ transition: opacity var(--reveal) var(--ease);
222
+ }
223
+ .nm-sidebar__rail:hover::after {
224
+ opacity: 1;
225
+ }
226
+
227
+ /* Header and footer stay put. The content between them scrolls. */
228
+ .nm-sidebar__header,
229
+ .nm-sidebar__footer {
230
+ display: flex;
231
+ flex-shrink: 0;
232
+ flex-direction: column;
233
+ gap: var(--nm-space-8);
234
+ padding: var(--nm-space-8);
235
+ }
236
+ .nm-sidebar__content {
237
+ display: flex;
238
+ flex: 1;
239
+ flex-direction: column;
240
+ min-height: 0;
241
+ overflow: hidden auto;
242
+ scrollbar-width: thin;
243
+ scrollbar-color: var(--nm-line-strong) transparent;
244
+ }
245
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__content {
246
+ overflow: hidden;
247
+ }
248
+ .nm-sidebar__separator {
249
+ width: auto;
250
+ margin-inline: var(--nm-space-8);
251
+ }
252
+ .nm-sidebar__input {
253
+ height: var(--control-h);
254
+ background: var(--nm-panel);
255
+ border-color: transparent;
256
+ }
257
+
258
+ /* A group: label, optional action, then its rows. */
259
+ .nm-sidebar__group {
260
+ position: relative;
261
+ display: flex;
262
+ flex-direction: column;
263
+ min-width: 0;
264
+ padding: var(--nm-space-8);
265
+ }
266
+ .nm-sidebar__group-label {
267
+ display: flex;
268
+ flex-shrink: 0;
269
+ align-items: center;
270
+ gap: var(--nm-space-8);
271
+ box-sizing: border-box;
272
+ height: var(--control-h);
273
+ padding: 0 var(--nm-icon-pad);
274
+ border-radius: var(--nm-control-r);
275
+ color: var(--nm-fg-subtle);
276
+ font-size: var(--nm-type-ui-sm);
277
+ font-weight: var(--nm-weight-medium);
278
+ line-height: var(--nm-leading-tight);
279
+ letter-spacing: var(--nm-track);
280
+ white-space: nowrap;
281
+ outline: none;
282
+ }
283
+ .nm-sidebar__group-label .nm-icon {
284
+ flex-shrink: 0;
285
+ width: var(--nm-icon-sm);
286
+ height: var(--nm-icon-sm);
287
+ }
288
+ /* Actions are the NIF small icon button, quiet. A tighter pad fits them inside a row. */
289
+ .nm-sidebar__group-action,
290
+ .nm-sidebar__menu-action {
291
+ --nm-icon-pad: var(--nm-space-6);
292
+ position: absolute;
293
+ inset-inline-end: var(--nm-space-4);
294
+ color: var(--nm-fg-subtle);
295
+ }
296
+ .nm-sidebar__group-action {
297
+ top: calc(var(--nm-space-8) + (var(--control-h) - var(--nm-icon-button) - var(--nm-space-6) * 2) / 2);
298
+ inset-inline-end: var(--nm-space-12);
299
+ }
300
+ .nm-sidebar__group-content {
301
+ width: 100%;
302
+ min-width: 0;
303
+ }
304
+
305
+ /* The menu is a plain list. */
306
+ .nm-sidebar__menu,
307
+ .nm-sidebar__menu-sub {
308
+ display: flex;
309
+ flex-direction: column;
310
+ gap: var(--nm-space-2);
311
+ width: 100%;
312
+ min-width: 0;
313
+ margin: 0;
314
+ padding: 0;
315
+ list-style: none;
316
+ }
317
+ .nm-sidebar__menu-item,
318
+ .nm-sidebar__menu-sub-item {
319
+ position: relative;
320
+ min-width: 0;
321
+ }
322
+
323
+ /* A row: an icon and a label. Quiet at rest, filled on hover, filled and firm when active. */
324
+ .nm-sidebar__menu-button {
325
+ display: flex;
326
+ align-items: center;
327
+ gap: var(--nm-space-8);
328
+ box-sizing: border-box;
329
+ width: 100%;
330
+ height: var(--control-h);
331
+ padding: 0 var(--nm-icon-pad);
332
+ border: var(--nm-rule) solid transparent;
333
+ border-radius: var(--nm-control-r);
334
+ background: transparent;
335
+ color: var(--nm-fg);
336
+ font: inherit;
337
+ font-size: var(--nm-type-ui);
338
+ font-weight: var(--nm-weight-regular);
339
+ line-height: var(--nm-leading-tight);
340
+ text-align: start;
341
+ text-decoration: none;
342
+ white-space: nowrap;
343
+ overflow: hidden;
344
+ cursor: pointer;
345
+ outline: none;
346
+ transition:
347
+ background-color var(--reveal) var(--ease),
348
+ color var(--reveal) var(--ease);
349
+ }
350
+ .nm-sidebar__menu-button > span:not(.nm-avatar) {
351
+ min-width: 0;
352
+ flex: 1 1 auto;
353
+ overflow: hidden;
354
+ text-overflow: ellipsis;
355
+ }
356
+ .nm-sidebar__menu-button > .nm-icon {
357
+ flex-shrink: 0;
358
+ width: var(--nm-icon-button);
359
+ height: var(--nm-icon-button);
360
+ color: var(--nm-fg-muted);
361
+ transition: color var(--reveal) var(--ease);
362
+ }
363
+ /* An avatar in a row: the NIF Avatar, on the strong line so it stays a disc when the row fills on hover or when active. */
364
+ .nm-sidebar__menu-button > .nm-avatar {
365
+ flex-shrink: 0;
366
+ background: var(--nm-line-strong);
367
+ color: var(--nm-fg);
368
+ }
369
+ .nm-sidebar__menu-button:hover,
370
+ .nm-sidebar__menu-button:focus-visible,
371
+ .nm-sidebar__menu-button[data-popup-open] {
372
+ background: var(--nm-line);
373
+ color: var(--nm-fg);
374
+ }
375
+ .nm-sidebar__menu-button:hover > .nm-icon,
376
+ .nm-sidebar__menu-button:focus-visible > .nm-icon,
377
+ .nm-sidebar__menu-button[data-active] > .nm-icon {
378
+ color: var(--nm-fg);
379
+ }
380
+ .nm-sidebar__menu-button:focus-visible {
381
+ outline: var(--nm-rule) solid var(--focus);
382
+ outline-offset: calc(var(--nm-rule) * -1);
383
+ }
384
+ .nm-sidebar__menu-button[data-active] {
385
+ background: var(--nm-panel);
386
+ color: var(--nm-fg);
387
+ font-weight: var(--nm-weight-medium);
388
+ }
389
+ .nm-sidebar__menu-button:disabled,
390
+ .nm-sidebar__menu-button[aria-disabled='true'] {
391
+ pointer-events: none;
392
+ opacity: var(--control-disabled-opacity);
393
+ }
394
+ .nm-sidebar__menu-button[data-variant='outline'] {
395
+ border-color: var(--nm-border-strong);
396
+ background: var(--nm-raised);
397
+ }
398
+ .nm-sidebar__menu-button[data-variant='outline']:hover,
399
+ .nm-sidebar__menu-button[data-variant='outline'][data-active] {
400
+ background: var(--nm-panel);
401
+ }
402
+ .nm-sidebar__menu-button[data-size='sm'] {
403
+ height: var(--control-h-sm);
404
+ font-size: var(--nm-type-ui-sm);
405
+ }
406
+ .nm-sidebar__menu-button[data-size='lg'] {
407
+ height: var(--control-h-lg);
408
+ }
409
+ /* A large row with two lines of text, such as the person in the footer. */
410
+ .nm-sidebar__menu-button > .nm-sidebar__text {
411
+ display: flex;
412
+ flex: 1 1 auto;
413
+ flex-direction: column;
414
+ gap: var(--nm-space-2);
415
+ min-width: 0;
416
+ line-height: var(--nm-leading-tight);
417
+ }
418
+ .nm-sidebar__text > span {
419
+ display: block;
420
+ overflow: hidden;
421
+ text-overflow: ellipsis;
422
+ white-space: nowrap;
423
+ }
424
+ .nm-sidebar__text > span + span {
425
+ color: var(--nm-fg-subtle);
426
+ font-size: var(--nm-type-ui-sm);
427
+ font-weight: var(--nm-weight-regular);
428
+ }
429
+ /* A row with a badge or an action leaves room for it. */
430
+ .nm-sidebar__menu-item:has(> .nm-sidebar__menu-badge) > .nm-sidebar__menu-button,
431
+ .nm-sidebar__menu-item:has(> .nm-sidebar__menu-action) > .nm-sidebar__menu-button {
432
+ padding-inline-end: var(--nm-icon-control);
433
+ }
434
+
435
+ /* The chevron of a row that opens. It points right when closed and down when open. */
436
+ .nm-sidebar__chevron {
437
+ flex-shrink: 0;
438
+ margin-inline-start: auto;
439
+ width: var(--nm-icon-sm);
440
+ height: var(--nm-icon-sm);
441
+ color: var(--nm-fg-subtle);
442
+ transform: rotate(-90deg);
443
+ transition: transform var(--reveal) var(--ease);
444
+ }
445
+ [aria-expanded='true'] > .nm-sidebar__chevron,
446
+ [data-panel-open] > .nm-sidebar__chevron,
447
+ [data-open] > .nm-sidebar__chevron,
448
+ .nm-sidebar__chevron[data-menu] {
449
+ transform: none;
450
+ }
451
+
452
+ /* The action at the end of a row sits over the row's end, centred on its height. */
453
+ .nm-sidebar__menu-action {
454
+ /* Centred by arithmetic, not a transform: the motion button owns transform. */
455
+ top: calc(50% - (var(--nm-icon-button) + var(--nm-space-6) * 2) / 2);
456
+ transition:
457
+ opacity var(--reveal) var(--ease),
458
+ background-color var(--reveal) var(--ease);
459
+ }
460
+ .nm-sidebar__menu-action[data-show-on-hover] {
461
+ opacity: 0;
462
+ }
463
+ .nm-sidebar__menu-item:hover > .nm-sidebar__menu-action[data-show-on-hover],
464
+ .nm-sidebar__menu-item:focus-within > .nm-sidebar__menu-action[data-show-on-hover],
465
+ .nm-sidebar__menu-item:has(> [data-active]) > .nm-sidebar__menu-action[data-show-on-hover],
466
+ .nm-sidebar__menu-action[data-show-on-hover][data-popup-open],
467
+ .nm-sidebar__menu-action[data-show-on-hover][aria-expanded='true'] {
468
+ opacity: 1;
469
+ }
470
+
471
+ /* A count at the end of a row: the NIF Chip, small, quiet until the row is hovered or active. */
472
+ .nm-sidebar__menu-badge {
473
+ position: absolute;
474
+ top: 50%;
475
+ inset-inline-end: var(--nm-icon-pad);
476
+ background: transparent;
477
+ color: var(--nm-fg-subtle);
478
+ font-variant-numeric: tabular-nums;
479
+ pointer-events: none;
480
+ user-select: none;
481
+ transform: translateY(-50%);
482
+ }
483
+ .nm-sidebar__menu-item:hover > .nm-sidebar__menu-badge,
484
+ .nm-sidebar__menu-item:has(> [data-active]) > .nm-sidebar__menu-badge {
485
+ color: var(--nm-fg);
486
+ }
487
+
488
+ /* A row's shape while it loads. */
489
+ .nm-sidebar__menu-skeleton {
490
+ display: flex;
491
+ align-items: center;
492
+ gap: var(--nm-space-8);
493
+ box-sizing: border-box;
494
+ height: var(--control-h);
495
+ padding: 0 var(--nm-icon-pad);
496
+ }
497
+ .nm-sidebar__menu-skeleton-icon {
498
+ flex-shrink: 0;
499
+ width: var(--nm-icon-button);
500
+ height: var(--nm-icon-button);
501
+ border-radius: var(--nm-radius-sm);
502
+ }
503
+ .nm-sidebar__menu-skeleton-text {
504
+ flex: 1 1 auto;
505
+ max-width: var(--nm-sidebar-skeleton-width, 100%);
506
+ height: var(--nm-space-12);
507
+ border-radius: var(--nm-radius-sm);
508
+ }
509
+
510
+ /* Rows under a row. A line runs down from the parent's icon, and the rows sit after it. */
511
+ .nm-sidebar__menu-sub {
512
+ box-sizing: border-box;
513
+ width: auto;
514
+ margin-inline-start: calc(var(--nm-icon-pad) + var(--nm-icon-button) / 2);
515
+ padding-inline-start: calc(var(--nm-icon-pad) + var(--nm-icon-button) / 2);
516
+ padding-block: var(--nm-space-2);
517
+ border-inline-start: var(--nm-rule) solid var(--nm-border);
518
+ }
519
+ .nm-sidebar__menu-sub-button {
520
+ display: flex;
521
+ align-items: center;
522
+ gap: var(--nm-space-8);
523
+ box-sizing: border-box;
524
+ width: 100%;
525
+ height: var(--control-h);
526
+ padding: 0 var(--nm-icon-pad);
527
+ border: 0;
528
+ border-radius: var(--nm-control-r);
529
+ background: transparent;
530
+ color: var(--nm-fg-muted);
531
+ font: inherit;
532
+ font-size: var(--nm-type-ui);
533
+ font-weight: var(--nm-weight-regular);
534
+ line-height: var(--nm-leading-tight);
535
+ text-align: start;
536
+ text-decoration: none;
537
+ white-space: nowrap;
538
+ overflow: hidden;
539
+ cursor: pointer;
540
+ outline: none;
541
+ transition:
542
+ background-color var(--reveal) var(--ease),
543
+ color var(--reveal) var(--ease);
544
+ }
545
+ .nm-sidebar__menu-sub-button > span {
546
+ min-width: 0;
547
+ overflow: hidden;
548
+ text-overflow: ellipsis;
549
+ }
550
+ .nm-sidebar__menu-sub-button > .nm-icon {
551
+ flex-shrink: 0;
552
+ width: var(--nm-icon-sm);
553
+ height: var(--nm-icon-sm);
554
+ color: var(--nm-fg-subtle);
555
+ }
556
+ .nm-sidebar__menu-sub-button:hover,
557
+ .nm-sidebar__menu-sub-button:focus-visible {
558
+ background: var(--nm-line);
559
+ color: var(--nm-fg);
560
+ }
561
+ .nm-sidebar__menu-sub-button:focus-visible {
562
+ outline: var(--nm-rule) solid var(--focus);
563
+ outline-offset: calc(var(--nm-rule) * -1);
564
+ }
565
+ .nm-sidebar__menu-sub-button[data-active] {
566
+ background: var(--nm-panel);
567
+ color: var(--nm-fg);
568
+ font-weight: var(--nm-weight-medium);
569
+ }
570
+ .nm-sidebar__menu-sub-button[data-size='sm'] {
571
+ height: var(--control-h-sm);
572
+ font-size: var(--nm-type-ui-sm);
573
+ }
574
+ .nm-sidebar__menu-sub-button:disabled,
575
+ .nm-sidebar__menu-sub-button[aria-disabled='true'] {
576
+ pointer-events: none;
577
+ opacity: var(--control-disabled-opacity);
578
+ }
579
+
580
+ /* Collapsed to icons: every row is a square with its icon in the middle. Labels, badges, actions and sub rows go. */
581
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__header,
582
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__footer,
583
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__group {
584
+ align-items: center;
585
+ }
586
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__group-label,
587
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__group-action,
588
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__menu-badge,
589
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__menu-action,
590
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__menu-sub,
591
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__input,
592
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__chevron,
593
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__menu-skeleton-text,
594
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__menu-button:not(:has(.nm-icon, .nm-avatar)) {
595
+ display: none;
596
+ }
597
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__menu-button {
598
+ width: var(--control-h);
599
+ height: var(--control-h);
600
+ padding: 0;
601
+ justify-content: center;
602
+ }
603
+ /* The label leaves the view but stays in the accessibility tree, so the row keeps its name. */
604
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__menu-button > span:not(.nm-avatar),
605
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__menu-button > .nm-sidebar__text {
606
+ position: absolute;
607
+ width: var(--nm-rule);
608
+ height: var(--nm-rule);
609
+ margin: calc(var(--nm-rule) * -1);
610
+ padding: 0;
611
+ overflow: hidden;
612
+ clip-path: inset(50%);
613
+ white-space: nowrap;
614
+ border: 0;
615
+ }
616
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__menu-button[data-size='lg'] {
617
+ width: var(--control-h-lg);
618
+ height: var(--control-h-lg);
619
+ }
620
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__menu-button[data-size='sm'] {
621
+ width: var(--control-h-sm);
622
+ height: var(--control-h-sm);
623
+ }
624
+ .nm-sidebar[data-collapsible='icon'] .nm-sidebar__menu-skeleton {
625
+ width: var(--control-h);
626
+ padding: 0;
627
+ justify-content: center;
628
+ }
629
+
630
+ /* Collapsed to the toggle: only the toggle in the header remains, centred in the narrow column. */
631
+ .nm-sidebar[data-collapsible='toggle'] .nm-sidebar__inner > :not(.nm-sidebar__header),
632
+ .nm-sidebar[data-collapsible='toggle'] .nm-sidebar__header > :not(.nm-sidebar__trigger) {
633
+ display: none;
634
+ }
635
+ .nm-sidebar[data-collapsible='toggle'] .nm-sidebar__header {
636
+ align-items: center;
637
+ justify-content: center;
638
+ }
639
+
640
+ @media (prefers-reduced-motion: reduce) {
641
+ .nm-sidebar,
642
+ .nm-sidebar__menu-button,
643
+ .nm-sidebar__chevron,
644
+ .nm-sidebar__menu-action {
645
+ transition: none;
646
+ }
647
+ }