@nonoun/native-dashboard 0.4.3 → 0.4.5

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.
@@ -1,6 +1,6 @@
1
1
  @layer ui {
2
2
 
3
- :where(native-dashboard):not(:defined),
3
+ :where(native-app):not(:defined),
4
4
  :where(n-sidebar-item):not(:defined),
5
5
  :where(n-sidebar-nav):not(:defined),
6
6
  :where(n-sidebar-group):not(:defined),
@@ -8,14 +8,14 @@
8
8
  :where(n-sidebar-nav-item):not(:defined) { visibility: hidden; }
9
9
 
10
10
  /* ╭──────────────────────────────────────────────────────────╮
11
- │ native-dashboard
11
+ │ native-app
12
12
  │ Full-page layout: collapsible/resizable sidebar aside │
13
13
  │ + content column (breadcrumb, canvas, body, chat). │
14
14
  ╰──────────────────────────────────────────────────────────╯ */
15
15
 
16
16
  /* ── Outer Layout ── */
17
17
 
18
- :where(native-dashboard) {
18
+ :where(native-app) {
19
19
  display: flex;
20
20
  height: 100dvh;
21
21
  }
@@ -23,7 +23,7 @@
23
23
  /* WHY: Reserve sidebar width before JS builds the DOM — prevents layout shift.
24
24
  Collapsed state is read synchronously in the constructor so CSS matches immediately.
25
25
  Replaced by the real aside once [data-ready] is set. */
26
- :where(native-dashboard):not([data-ready]):not([collapsed])::before {
26
+ :where(native-app):not([data-ready]):not([collapsed])::before {
27
27
  content: '';
28
28
  width: var(--n-sidebar-width);
29
29
  flex-shrink: 0;
@@ -31,7 +31,7 @@
31
31
  border-right: 1px solid var(--n-border-muted);
32
32
  }
33
33
 
34
- :where(native-dashboard):not([data-ready])[collapsed]::before {
34
+ :where(native-app):not([data-ready])[collapsed]::before {
35
35
  content: '';
36
36
  width: 48px;
37
37
  flex-shrink: 0;
@@ -42,7 +42,7 @@
42
42
  /* ── Content Column ── */
43
43
  /* WHY: Everything except the aside forms a flex column. */
44
44
 
45
- :where(native-dashboard) > :where(:not([slot])) {
45
+ :where(native-app) > :where(:not([slot])) {
46
46
  flex: 1 1 0%;
47
47
  min-width: 0;
48
48
  min-height: 0;
@@ -56,7 +56,7 @@
56
56
  ensures content behind the sidebar never bleeds through. The aside is also
57
57
  the containing block for absolute header/footer overlays. */
58
58
 
59
- :where(native-dashboard) > :where([slot="sidebar"]) {
59
+ :where(native-app) > :where([slot="sidebar"]) {
60
60
  --n-sidebar-header-height: 0px;
61
61
  --n-sidebar-footer-height: 0px;
62
62
 
@@ -75,7 +75,7 @@
75
75
  }
76
76
 
77
77
  /* WHY: Disable width transition while dragging — it fights the pointer. */
78
- :where(native-dashboard) > :where([slot="sidebar"][resizing]) {
78
+ :where(native-app) > :where([slot="sidebar"][resizing]) {
79
79
  transition: none;
80
80
  }
81
81
 
@@ -84,14 +84,14 @@
84
84
  [collapsed] drives the aside to 48px which triggers @container sidebar queries
85
85
  in this file and in child component CSS. */
86
86
 
87
- :where(native-dashboard)[collapsed] > :where([slot="sidebar"]) {
87
+ :where(native-app)[collapsed] > :where([slot="sidebar"]) {
88
88
  width: 48px;
89
89
  min-width: 48px;
90
90
  }
91
91
 
92
92
  /* ── Resize Handle ── */
93
93
 
94
- :where(native-dashboard) :where(.layout-resize-handle) {
94
+ :where(native-app) :where(.layout-resize-handle) {
95
95
  position: absolute;
96
96
  top: 0;
97
97
  right: 0;
@@ -101,18 +101,130 @@
101
101
  z-index: 1;
102
102
  }
103
103
 
104
- :where(native-dashboard) :where(.layout-resize-handle):hover,
105
- :where(native-dashboard) > :where([slot="sidebar"][resizing]) :where(.layout-resize-handle) {
104
+ :where(native-app) :where(.layout-resize-handle):hover,
105
+ :where(native-app) > :where([slot="sidebar"][resizing]) :where(.layout-resize-handle) {
106
106
  background: var(--n-border-muted);
107
107
  }
108
108
 
109
109
  /* WHY: When collapsed to icon rail, the sidebar edge meets content — drop left padding. */
110
110
 
111
- :where(native-dashboard)[collapsed] :where(n-dashboard-canvas) {
111
+ :where(native-app)[collapsed] :where(n-dashboard-canvas) {
112
112
  padding-inline-start: 0;
113
113
  }
114
114
 
115
- :where(native-dashboard)[collapsed] :where(n-dashboard-breadcrumb) {
115
+ :where(native-app)[collapsed] :where(n-dashboard-breadcrumb) {
116
+ padding-inline-start: 0;
117
+ }
118
+
119
+ /* ── Semantic layout selectors ── */
120
+ /* WHY: Semantic HTML alternatives to n-dashboard-breadcrumb, n-dashboard-canvas,
121
+ n-dashboard-panel. Both old and new selectors work simultaneously.
122
+ Layout: native-app > section > nav (breadcrumb) + section.content > main */
123
+
124
+ /* Breadcrumb bar — <nav> direct child of the content column */
125
+ :where(native-app) > :where(:not([slot])) > :where(nav) {
126
+ display: grid;
127
+ grid-template-columns: 1fr;
128
+ align-items: center;
129
+ min-height: var(--n-sidebar-item-height);
130
+ gap: calc(var(--n-space) * 2);
131
+ padding-block: var(--n-space);
132
+ padding-inline: calc(var(--n-space-k) * var(--n-space));
133
+ flex-shrink: 0;
134
+ min-width: 0;
135
+ }
136
+
137
+ /* Breadcrumb adaptive grid — leading + trailing */
138
+ :where(native-app) > :where(:not([slot])) > :where(nav):has(> :first-child + * + aside) {
139
+ grid-template-columns: auto 1fr auto;
140
+ }
141
+
142
+ /* Breadcrumb — leading only */
143
+ :where(native-app) > :where(:not([slot])) > :where(nav):has(> :first-child + *):not(:has(> aside)) {
144
+ grid-template-columns: auto 1fr;
145
+ }
146
+
147
+ /* Breadcrumb — trailing only */
148
+ :where(native-app) > :where(:not([slot])) > :where(nav):has(> aside):not(:has(> :first-child + * + aside)) {
149
+ grid-template-columns: 1fr auto;
150
+ }
151
+
152
+ /* Trailing actions in breadcrumb */
153
+ :where(native-app) > :where(:not([slot])) > :where(nav) > :where(aside) {
154
+ display: flex;
155
+ align-items: center;
156
+ gap: calc(var(--n-space) * 2);
157
+ }
158
+
159
+ /* Canvas — content area (main + aside panels) */
160
+ :where(native-app) :where(section.content) {
161
+ display: flex;
162
+ flex: 1;
163
+ min-height: 0;
164
+ gap: calc(var(--n-space-k) * var(--n-space));
165
+ padding: 0 calc(var(--n-space-k) * var(--n-space)) calc(var(--n-space-k) * var(--n-space));
166
+ }
167
+
168
+ /* Main content panel */
169
+ :where(native-app) :where(section.content) > :where(main) {
170
+ --n-ground: var(--n-panel);
171
+
172
+ flex: 1;
173
+ min-width: 0;
174
+ overflow-y: auto;
175
+ scrollbar-width: none;
176
+ display: flex;
177
+ flex-direction: column;
178
+ background: var(--n-ground);
179
+ border-radius: var(--n-radius);
180
+ }
181
+
182
+ :where(native-app) :where(section.content) > :where(main)[show-scrollbar] {
183
+ scrollbar-width: thin;
184
+ }
185
+
186
+ /* Semantic sub-containers inside main */
187
+ :where(native-app) :where(section.content) > :where(main):has(> header, > footer) {
188
+ overflow: hidden;
189
+ }
190
+
191
+ :where(native-app) :where(section.content) > :where(main):has(> header, > footer) > :where(section) {
192
+ flex: 1 1 0%;
193
+ min-height: 0;
194
+ overflow-y: auto;
195
+ scrollbar-width: none;
196
+ display: flex;
197
+ flex-direction: column;
198
+ }
199
+
200
+ :where(native-app) :where(section.content) > :where(main) > :where(header) {
201
+ flex: none;
202
+ border-bottom: 1px solid var(--n-border-muted);
203
+ background: var(--n-ground);
204
+ z-index: 1;
205
+ }
206
+
207
+ :where(native-app) :where(section.content) > :where(main) > :where(footer) {
208
+ flex: none;
209
+ border-top: 1px solid var(--n-border-muted);
210
+ background: var(--n-ground);
211
+ }
212
+
213
+ /* Content max-width centering (same as app-panel.css semantic selectors) */
214
+ :where(native-app) :where(section.content) > :where(main) > :where(header) > *,
215
+ :where(native-app) :where(section.content) > :where(main) > :where(section) > *,
216
+ :where(native-app) :where(section.content) > :where(main) > :where(footer) > * {
217
+ max-width: var(--n-dashboard-panel-content-max-width, none);
218
+ width: 100%;
219
+ margin-inline: auto;
220
+ }
221
+
222
+ /* Collapsed padding — semantic selectors */
223
+ :where(native-app)[collapsed] :where(section.content) {
224
+ padding-inline-start: 0;
225
+ }
226
+
227
+ :where(native-app)[collapsed] > :where(:not([slot])) > :where(nav) {
116
228
  padding-inline-start: 0;
117
229
  }
118
230
 
@@ -538,11 +650,11 @@
538
650
  width: var(--n-icon-size);
539
651
  height: var(--n-icon-size);
540
652
 
541
- mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z' fill='currentColor'/%3E%3C/svg%3E");
653
+ mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z' fill='currentColor'/%3E%3C/svg%3E");
542
654
  mask-size: contain;
543
655
  mask-repeat: no-repeat;
544
656
  mask-position: center;
545
- -webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z' fill='currentColor'/%3E%3C/svg%3E");
657
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z' fill='currentColor'/%3E%3C/svg%3E");
546
658
  -webkit-mask-size: contain;
547
659
  -webkit-mask-repeat: no-repeat;
548
660
  -webkit-mask-position: center;
@@ -553,9 +665,9 @@
553
665
  transform var(--n-duration) var(--n-easing);
554
666
  }
555
667
 
556
- /* Chevron rotates when open */
668
+ /* Caret rotates 90° clockwise when open */
557
669
  :where(n-sidebar-group) > :where(details[open]) > :where(summary)::after {
558
- transform: rotate(180deg);
670
+ transform: rotate(90deg);
559
671
  }
560
672
 
561
673
  /* ── Selected group — has a child with aria-current ── */
@@ -655,10 +767,36 @@
655
767
  position-area: inline-end span-block-end;
656
768
  }
657
769
 
770
+ /* ── Sidebar Section Label ── */
771
+ /* WHY: Standalone uppercase category header between sidebar groups.
772
+ Not collapsible (no <details>/<summary>). Hides in collapsed icon rail. */
773
+
774
+ :where(n-sidebar-section-label) {
775
+ display: block;
776
+ padding-block: var(--n-space);
777
+ padding-inline: calc(var(--n-space-k) * var(--n-space));
778
+ font-size: calc(var(--n-font-size) * 0.75);
779
+ font-weight: 600;
780
+ letter-spacing: 0.06em;
781
+ text-transform: uppercase;
782
+ color: var(--n-ink-muted);
783
+ user-select: none;
784
+ cursor: default;
785
+ }
786
+
787
+ :where(n-sidebar-section-label):not(:first-child) {
788
+ margin-block-start: calc(var(--n-space) * 4);
789
+ }
790
+
658
791
  /* ── Container Query: Collapsed Sidebar (nav) ── */
659
792
 
660
793
  @container sidebar (max-width: 80px) {
661
794
 
795
+ /* Section labels hide in collapsed icon rail */
796
+ :where(n-sidebar-section-label) {
797
+ display: none;
798
+ }
799
+
662
800
  /* Nav items hide entirely — only group headers (with icons) remain. */
663
801
  :where(n-sidebar-nav-item) {
664
802
  display: none;
@@ -772,6 +910,19 @@
772
910
  gap: calc(var(--n-space) * 2);
773
911
  }
774
912
 
913
+ /* ── Semantic slot selectors ── */
914
+ /* WHY: <aside> as trailing slot alternative to [slot="trailing"]. */
915
+
916
+ :where(n-dashboard-breadcrumb):has(> :first-child + * + aside) {
917
+ grid-template-columns: auto 1fr auto;
918
+ }
919
+
920
+ :where(n-dashboard-breadcrumb) > :where(aside) {
921
+ display: flex;
922
+ align-items: center;
923
+ gap: calc(var(--n-space) * 2);
924
+ }
925
+
775
926
  }
776
927
 
777
928
  @layer ui {
@@ -316,5 +316,5 @@ var f = class extends r {
316
316
  this.#t = !1, this.#e?.syncPopover(!1);
317
317
  };
318
318
  };
319
- s("n-sidebar-nav-item", p), s("n-sidebar-group-header", h), s("n-sidebar-group", m), s("n-sidebar-nav", f), s("n-sidebar-item", _), s("native-dashboard", g), s("n-listbox", t), s("n-option", n);
319
+ s("n-sidebar-nav-item", p), s("n-sidebar-group-header", h), s("n-sidebar-group", m), s("n-sidebar-nav", f), s("n-sidebar-item", _), s("native-app", g), s("n-listbox", t), s("n-option", n);
320
320
  export { g as NSidebar, m as NSidebarGroup, h as NSidebarGroupHeader, _ as NSidebarItem, f as NSidebarNav, p as NSidebarNavItem };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nonoun/native-dashboard",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "Dashboard layout and navigation components for @nonoun/native-ui",
5
5
  "license": "MIT",
6
6
  "type": "module",