@aquera/nile-elements 2.0.10 → 2.0.12
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/README.md +6 -0
- package/demo/app-shell.html +852 -0
- package/demo/nxtgen-classes.css +2 -2
- package/demo/nxtgen-properties.css +2 -2
- package/demo/nxtgen-utilities.css +2 -2
- package/demo/nxtgen.css +2 -2
- package/demo/utilities.css +2 -2
- package/demo/variables.css +2 -2
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.js +595 -302
- package/dist/internal/app-shell-utility-control-styles.cjs.js +2 -0
- package/dist/internal/app-shell-utility-control-styles.cjs.js.map +1 -0
- package/dist/internal/app-shell-utility-control-styles.esm.js +16 -0
- package/dist/nile-app-shell/index.cjs.js +1 -1
- package/dist/nile-app-shell/index.esm.js +1 -1
- package/dist/nile-app-shell/nile-app-shell.cjs.js +1 -1
- package/dist/nile-app-shell/nile-app-shell.cjs.js.map +1 -1
- package/dist/nile-app-shell/nile-app-shell.css.cjs.js +1 -1
- package/dist/nile-app-shell/nile-app-shell.css.cjs.js.map +1 -1
- package/dist/nile-app-shell/nile-app-shell.css.esm.js +277 -96
- package/dist/nile-app-shell/nile-app-shell.esm.js +67 -11
- package/dist/nile-app-shell/shell-controller.cjs.js.map +1 -1
- package/dist/nile-app-shell-main/nile-app-shell-main.cjs.js.map +1 -1
- package/dist/nile-app-shell-nav-toggle/index.cjs.js +1 -1
- package/dist/nile-app-shell-nav-toggle/index.esm.js +1 -1
- package/dist/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.cjs.js +1 -1
- package/dist/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.cjs.js.map +1 -1
- package/dist/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.css.cjs.js +1 -1
- package/dist/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.css.cjs.js.map +1 -1
- package/dist/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.css.esm.js +7 -3
- package/dist/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.esm.js +3 -3
- package/dist/nile-app-shell-panel/index.cjs.js +1 -1
- package/dist/nile-app-shell-panel/index.esm.js +1 -1
- package/dist/nile-app-shell-panel/nile-app-shell-panel.cjs.js +1 -1
- package/dist/nile-app-shell-panel/nile-app-shell-panel.cjs.js.map +1 -1
- package/dist/nile-app-shell-panel/nile-app-shell-panel.css.cjs.js +1 -1
- package/dist/nile-app-shell-panel/nile-app-shell-panel.css.cjs.js.map +1 -1
- package/dist/nile-app-shell-panel/nile-app-shell-panel.css.esm.js +32 -8
- package/dist/nile-app-shell-panel/nile-app-shell-panel.esm.js +18 -5
- package/dist/nile-app-shell-side-nav/nile-app-shell-side-nav.cjs.js.map +1 -1
- package/dist/nile-app-shell-side-nav/nile-app-shell-side-nav.css.cjs.js.map +1 -1
- package/dist/src/internal/app-shell-utility-control-styles.d.ts +12 -0
- package/dist/src/internal/app-shell-utility-control-styles.js +29 -0
- package/dist/src/internal/app-shell-utility-control-styles.js.map +1 -0
- package/dist/src/nile-app-shell/nile-app-shell-regions.test.d.ts +3 -0
- package/dist/src/nile-app-shell/nile-app-shell-regions.test.js +210 -0
- package/dist/src/nile-app-shell/nile-app-shell-regions.test.js.map +1 -1
- package/dist/src/nile-app-shell/nile-app-shell.css.d.ts +1 -9
- package/dist/src/nile-app-shell/nile-app-shell.css.js +277 -103
- package/dist/src/nile-app-shell/nile-app-shell.css.js.map +1 -1
- package/dist/src/nile-app-shell/nile-app-shell.d.ts +90 -122
- package/dist/src/nile-app-shell/nile-app-shell.js +235 -144
- package/dist/src/nile-app-shell/nile-app-shell.js.map +1 -1
- package/dist/src/nile-app-shell/nile-app-shell.test.d.ts +4 -0
- package/dist/src/nile-app-shell/nile-app-shell.test.js +1116 -29
- package/dist/src/nile-app-shell/nile-app-shell.test.js.map +1 -1
- package/dist/src/nile-app-shell/shell-controller.d.ts +1 -8
- package/dist/src/nile-app-shell/shell-controller.js +2 -14
- package/dist/src/nile-app-shell/shell-controller.js.map +1 -1
- package/dist/src/nile-app-shell-main/nile-app-shell-main.d.ts +2 -6
- package/dist/src/nile-app-shell-main/nile-app-shell-main.js +2 -6
- package/dist/src/nile-app-shell-main/nile-app-shell-main.js.map +1 -1
- package/dist/src/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.css.d.ts +1 -4
- package/dist/src/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.css.js +7 -5
- package/dist/src/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.css.js.map +1 -1
- package/dist/src/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.d.ts +4 -8
- package/dist/src/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.js +5 -6
- package/dist/src/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.js.map +1 -1
- package/dist/src/nile-app-shell-panel/nile-app-shell-panel.css.js +31 -6
- package/dist/src/nile-app-shell-panel/nile-app-shell-panel.css.js.map +1 -1
- package/dist/src/nile-app-shell-panel/nile-app-shell-panel.d.ts +18 -13
- package/dist/src/nile-app-shell-panel/nile-app-shell-panel.js +45 -16
- package/dist/src/nile-app-shell-panel/nile-app-shell-panel.js.map +1 -1
- package/dist/src/nile-app-shell-side-nav/nile-app-shell-side-nav.css.d.ts +1 -4
- package/dist/src/nile-app-shell-side-nav/nile-app-shell-side-nav.css.js +1 -4
- package/dist/src/nile-app-shell-side-nav/nile-app-shell-side-nav.css.js.map +1 -1
- package/dist/src/nile-app-shell-side-nav/nile-app-shell-side-nav.d.ts +4 -12
- package/dist/src/nile-app-shell-side-nav/nile-app-shell-side-nav.js +4 -12
- package/dist/src/nile-app-shell-side-nav/nile-app-shell-side-nav.js.map +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/version.cjs.js +1 -1
- package/dist/version.cjs.js.map +1 -1
- package/dist/version.esm.js +1 -1
- package/package.json +1 -1
- package/plop-templates/lit/lit.test.ts.hbs +22 -0
- package/plop-templates/lit/lit.ts.hbs +10 -5
- package/plopfile.js +12 -0
- package/src/internal/app-shell-utility-control-styles.ts +30 -0
- package/src/nile-app-shell/nile-app-shell-regions.test.ts +252 -0
- package/src/nile-app-shell/nile-app-shell.css.ts +277 -103
- package/src/nile-app-shell/nile-app-shell.test.ts +1363 -29
- package/src/nile-app-shell/nile-app-shell.ts +249 -149
- package/src/nile-app-shell/shell-controller.ts +2 -14
- package/src/nile-app-shell-main/nile-app-shell-main.ts +2 -6
- package/src/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.css.ts +7 -5
- package/src/nile-app-shell-nav-toggle/nile-app-shell-nav-toggle.ts +7 -11
- package/src/nile-app-shell-panel/nile-app-shell-panel.css.ts +31 -6
- package/src/nile-app-shell-panel/nile-app-shell-panel.ts +44 -16
- package/src/nile-app-shell-side-nav/nile-app-shell-side-nav.css.ts +1 -4
- package/src/nile-app-shell-side-nav/nile-app-shell-side-nav.ts +4 -12
- package/vscode-html-custom-data.json +85 -18
|
@@ -1,16 +1,26 @@
|
|
|
1
|
-
import{css as e}from"lit";const
|
|
1
|
+
import{css as e}from"lit";import{u as n}from"../internal/app-shell-utility-control-styles.esm.js";const a=e`
|
|
2
2
|
:host {
|
|
3
|
-
/* Geometry
|
|
4
|
-
|
|
5
|
-
--nile-app-shell-side-nav-width:
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
/* Geometry: design tokens where one exists, bare pixels where none does. */
|
|
4
|
+
/* The nav track mirrors nile-side-bar's own width expressions (enterprise 240/70, NxtGen 296/68); keep in step with nile-side-bar.css.ts. */
|
|
5
|
+
--nile-app-shell-side-nav-width: var(
|
|
6
|
+
--nile-width-240px,
|
|
7
|
+
var(--ng-spacing-296, 240px)
|
|
8
|
+
);
|
|
9
|
+
--nile-app-shell-side-nav-rail-width: var(
|
|
10
|
+
--nile-width-70px,
|
|
11
|
+
var(--ng-spacing-68, 70px)
|
|
12
|
+
);
|
|
13
|
+
--nile-app-shell-gutter: var(--nile-spacing-xs, var(--ng-spacing-xs));
|
|
8
14
|
--nile-app-shell-content-padding: var(
|
|
9
15
|
--nile-spacing-3xl,
|
|
10
16
|
var(--ng-spacing-3xl)
|
|
11
17
|
);
|
|
12
|
-
--nile-app-shell-top-bar-height:
|
|
13
|
-
|
|
18
|
+
--nile-app-shell-top-bar-height: 68px;
|
|
19
|
+
/* The panel header keeps its own height, distinct from the page header. */
|
|
20
|
+
--nile-app-shell-panel-header-height: 56px;
|
|
21
|
+
--nile-app-shell-tabs-height: 33px;
|
|
22
|
+
/* The leading app icon is its own 20px size, not the 32px utility box. */
|
|
23
|
+
--nile-app-shell-app-icon-size: 20px;
|
|
14
24
|
--nile-app-shell-panel-width: 480px;
|
|
15
25
|
--nile-app-shell-panel-min-width: 360px;
|
|
16
26
|
--nile-app-shell-aside-width: 320px;
|
|
@@ -18,9 +28,10 @@ import{css as e}from"lit";const n=e`
|
|
|
18
28
|
--nile-app-shell-content-min-width: 640px;
|
|
19
29
|
--nile-app-shell-min-width: 768px;
|
|
20
30
|
--nile-app-shell-centered-width: 824px;
|
|
31
|
+
/* Both tokens are 32px; the literal is the floor with no theme sheet loaded. */
|
|
21
32
|
--nile-app-shell-utility-size: var(
|
|
22
33
|
--nile-spacing-4xl,
|
|
23
|
-
var(--ng-spacing-4xl)
|
|
34
|
+
var(--ng-spacing-4xl, 32px)
|
|
24
35
|
);
|
|
25
36
|
--nile-app-shell-radius: var(--nile-radius-xl, var(--ng-radius-2xl));
|
|
26
37
|
--nile-app-shell-duration: var(
|
|
@@ -60,8 +71,7 @@ import{css as e}from"lit";const n=e`
|
|
|
60
71
|
height: 100dvh;
|
|
61
72
|
}
|
|
62
73
|
|
|
63
|
-
/* Effective rail state
|
|
64
|
-
forced rail at narrow widths. */
|
|
74
|
+
/* Effective rail state: the user's preference, or a forced rail when narrow. */
|
|
65
75
|
:host([rail]) {
|
|
66
76
|
--_side-nav-track: var(--nile-app-shell-side-nav-rail-width);
|
|
67
77
|
}
|
|
@@ -70,10 +80,19 @@ import{css as e}from"lit";const n=e`
|
|
|
70
80
|
--_side-nav-track: 0px;
|
|
71
81
|
}
|
|
72
82
|
|
|
83
|
+
/* The Description axis: a present description adds the 8px its second line occupies. */
|
|
84
|
+
:host([has-description]) {
|
|
85
|
+
--nile-app-shell-top-bar-height: 76px;
|
|
86
|
+
}
|
|
87
|
+
|
|
73
88
|
/* The top bar compresses before the content does. */
|
|
74
89
|
@media (max-height: 600px) {
|
|
75
90
|
:host {
|
|
76
|
-
--nile-app-shell-top-bar-height:
|
|
91
|
+
--nile-app-shell-top-bar-height: 56px;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
:host([has-description]) {
|
|
95
|
+
--nile-app-shell-top-bar-height: 64px;
|
|
77
96
|
}
|
|
78
97
|
}
|
|
79
98
|
|
|
@@ -101,13 +120,12 @@ import{css as e}from"lit";const n=e`
|
|
|
101
120
|
display: none;
|
|
102
121
|
}
|
|
103
122
|
|
|
104
|
-
/*
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
*/
|
|
123
|
+
/* A slotted sidebar fills the shell-owned track and drops its own surface and edge; set --nile-app-shell-side-nav-bg to restore one. */
|
|
124
|
+
/* width is deliberately not !important: the 100% lets a raw <nav> or nile-app-shell-side-nav fill the track, while a slotted
|
|
125
|
+
nile-side-bar sizes itself from the same tokens the track reads (see the :host geometry block). Tests 21/22 in
|
|
126
|
+
nile-app-shell-regions.test.ts lock the two together; change both or neither. */
|
|
109
127
|
::slotted([slot='side-nav']) {
|
|
110
|
-
width: 100
|
|
128
|
+
width: 100%;
|
|
111
129
|
height: 100%;
|
|
112
130
|
background: var(--nile-app-shell-side-nav-bg, transparent) !important;
|
|
113
131
|
border-right: var(--nile-app-shell-side-nav-border, 0) !important;
|
|
@@ -122,19 +140,19 @@ import{css as e}from"lit";const n=e`
|
|
|
122
140
|
min-width: 0;
|
|
123
141
|
gap: var(--nile-app-shell-gutter);
|
|
124
142
|
padding: var(--nile-app-shell-gutter);
|
|
143
|
+
/* Flush against the nav track; the gutter insets the other three sides. */
|
|
144
|
+
padding-inline-start: 0;
|
|
125
145
|
box-sizing: border-box;
|
|
126
146
|
}
|
|
127
147
|
|
|
148
|
+
/* With no nav track there is nothing to sit flush against, so the start edge takes the gutter too. */
|
|
149
|
+
:host(:not([has-side-nav])) .content-section {
|
|
150
|
+
padding-inline-start: var(--nile-app-shell-gutter);
|
|
151
|
+
}
|
|
152
|
+
|
|
128
153
|
.container {
|
|
129
154
|
box-sizing: border-box;
|
|
130
|
-
/*
|
|
131
|
-
* The floor is the flex basis, not a min-width: a hard min-width cannot
|
|
132
|
-
* yield, so the row overflows and :host's overflow:hidden clips the
|
|
133
|
-
* regions after it. As a basis the container holds the floor while there
|
|
134
|
-
* is room and gives way when there is not. The shell keeps a docked panel
|
|
135
|
-
* off the row until it fits (see _dockRequirement), so the give-way path
|
|
136
|
-
* is the last resort, not the usual one.
|
|
137
|
-
*/
|
|
155
|
+
/* The floor is the flex basis, not a min-width, so the container yields instead of overflowing the clipped row. */
|
|
138
156
|
flex: 1 1 var(--nile-app-shell-content-min-width);
|
|
139
157
|
display: flex;
|
|
140
158
|
flex-direction: column;
|
|
@@ -142,24 +160,15 @@ import{css as e}from"lit";const n=e`
|
|
|
142
160
|
overflow: hidden;
|
|
143
161
|
background: var(--nile-colors-white-base, var(--ng-colors-bg-secondary));
|
|
144
162
|
border: var(--nile-border-width-1, var(--ng-border-width-1)) solid
|
|
145
|
-
var(--nile-colors-neutral-
|
|
163
|
+
var(--nile-colors-neutral-500, var(--ng-colors-border-primary));
|
|
146
164
|
border-radius: var(--nile-app-shell-radius);
|
|
147
165
|
box-shadow: var(--nile-box-shadow-none, var(--ng-shadow-none));
|
|
148
|
-
/*
|
|
149
|
-
* The container — not the viewport — is the sizing context for page
|
|
150
|
-
* content. See the content-container note below for querying it.
|
|
151
|
-
*/
|
|
166
|
+
/* The container, not the viewport, is the sizing context for page content. */
|
|
152
167
|
container-type: inline-size;
|
|
153
168
|
container-name: nile-content;
|
|
154
169
|
}
|
|
155
170
|
|
|
156
|
-
/*
|
|
157
|
-
* Container queries cannot cross a shadow boundary: a rule in the page's
|
|
158
|
-
* stylesheet cannot see a container declared in here. The
|
|
159
|
-
* content-container attribute moves the context onto the slotted page root instead, so page CSS can
|
|
160
|
-
* write an @container nile-content query. It brings layout containment with
|
|
161
|
-
* it, so it is opt-in.
|
|
162
|
-
*/
|
|
171
|
+
/* content-container moves the size query context onto the slotted page root so page CSS can query nile-content; opt-in as it brings containment. */
|
|
163
172
|
:host([content-container]) slot:not([name])::slotted(*) {
|
|
164
173
|
container-type: inline-size;
|
|
165
174
|
container-name: nile-content;
|
|
@@ -183,12 +192,7 @@ import{css as e}from"lit";const n=e`
|
|
|
183
192
|
padding-inline: var(--nile-app-shell-content-padding);
|
|
184
193
|
}
|
|
185
194
|
|
|
186
|
-
/*
|
|
187
|
-
page body; spanning the shell it carries the container's edge instead. */
|
|
188
|
-
.container > .top-bar {
|
|
189
|
-
border-bottom: var(--nile-border-width-1, var(--ng-border-width-1)) solid
|
|
190
|
-
var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
|
|
191
|
-
}
|
|
195
|
+
/* The header bar draws no bottom rule in any variant; the only divider comes from the tab rail (see .tabs). */
|
|
192
196
|
|
|
193
197
|
.shell-top-bar {
|
|
194
198
|
grid-area: top-bar;
|
|
@@ -212,32 +216,171 @@ import{css as e}from"lit";const n=e`
|
|
|
212
216
|
flex: 1 1 auto;
|
|
213
217
|
}
|
|
214
218
|
|
|
215
|
-
|
|
219
|
+
/* The title block: the back arrow, then the stack (app icon, heading and badge, with the description under them); renders before the top-bar slot. */
|
|
220
|
+
.title-area {
|
|
221
|
+
display: flex;
|
|
222
|
+
/* Top-aligned, not centred: the back arrow belongs to the title's row, not the title-plus-description stack. */
|
|
223
|
+
align-items: flex-start;
|
|
224
|
+
/* Figma's Title Area gap: 16px from the arrow to the stack. */
|
|
225
|
+
gap: var(--nile-spacing-xl, var(--ng-spacing-xl));
|
|
226
|
+
min-width: 0;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/* The back arrow's line box: exactly the page title's line height, centring the arrow on the title row. */
|
|
230
|
+
.back-line {
|
|
231
|
+
flex: 0 0 auto;
|
|
232
|
+
display: inline-flex;
|
|
233
|
+
align-items: center;
|
|
234
|
+
min-height: var(--nile-line-height-medium, var(--ng-line-height-text-md));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.title-stack {
|
|
238
|
+
display: flex;
|
|
239
|
+
flex-direction: column;
|
|
240
|
+
justify-content: center;
|
|
241
|
+
gap: var(--nile-spacing-xxs, var(--ng-spacing-xxs));
|
|
242
|
+
min-width: 0;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.title-row {
|
|
216
246
|
display: flex;
|
|
217
247
|
align-items: center;
|
|
218
248
|
gap: var(--nile-spacing-md, var(--ng-spacing-md));
|
|
249
|
+
min-width: 0;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.page-title {
|
|
253
|
+
margin: 0;
|
|
254
|
+
min-width: 0;
|
|
255
|
+
font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
|
|
256
|
+
font-size: var(--nile-type-scale-3, var(--ng-font-size-text-md));
|
|
257
|
+
line-height: var(--nile-line-height-medium, var(--ng-line-height-text-md));
|
|
258
|
+
font-weight: var(--nile-font-weight-medium, var(--ng-font-weight-semibold));
|
|
259
|
+
color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
|
|
260
|
+
white-space: nowrap;
|
|
261
|
+
overflow: hidden;
|
|
262
|
+
text-overflow: ellipsis;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.description {
|
|
266
|
+
margin: 0;
|
|
267
|
+
min-width: 0;
|
|
268
|
+
font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
|
|
269
|
+
font-size: var(--nile-type-scale-1, var(--ng-font-size-text-xs));
|
|
270
|
+
line-height: var(--nile-line-height-xsmall, var(--ng-line-height-text-xs));
|
|
271
|
+
font-weight: var(--nile-font-weight-regular, var(--ng-font-weight-regular));
|
|
272
|
+
color: var(--nile-colors-dark-500, var(--ng-colors-text-quaternary-500));
|
|
273
|
+
white-space: nowrap;
|
|
274
|
+
overflow: hidden;
|
|
275
|
+
text-overflow: ellipsis;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/* The badge sits on the title row and never shrinks the title away; each surface token pairs a Nile name with its NxtGen equivalent. */
|
|
279
|
+
.badge {
|
|
280
|
+
flex: 0 0 auto;
|
|
281
|
+
display: inline-flex;
|
|
282
|
+
align-items: center;
|
|
283
|
+
padding-inline: var(--nile-spacing-md, var(--ng-spacing-md));
|
|
284
|
+
padding-block: var(--nile-spacing-xxs, var(--ng-spacing-xxs));
|
|
285
|
+
border: var(--nile-border-width-1, var(--ng-border-width-1)) solid
|
|
286
|
+
var(
|
|
287
|
+
--nile-colors-neutral-400,
|
|
288
|
+
var(--ng-componentcolors-utility-gray-200)
|
|
289
|
+
);
|
|
290
|
+
border-radius: var(--nile-radius-full, var(--ng-radius-full));
|
|
291
|
+
background: var(
|
|
292
|
+
--nile-colors-neutral-100,
|
|
293
|
+
var(--ng-componentcolors-utility-gray-50)
|
|
294
|
+
);
|
|
295
|
+
color: var(
|
|
296
|
+
--nile-colors-dark-500,
|
|
297
|
+
var(--ng-componentcolors-utility-gray-700)
|
|
298
|
+
);
|
|
299
|
+
font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
|
|
300
|
+
font-size: var(--nile-type-scale-1, var(--ng-font-size-text-xs));
|
|
301
|
+
line-height: var(--nile-line-height-xsmall, var(--ng-line-height-text-xs));
|
|
302
|
+
font-weight: var(--nile-font-weight-medium, var(--ng-font-weight-medium));
|
|
303
|
+
white-space: nowrap;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/* headerBack: an icon-only native button, so the aria-label names it directly; the shell owns no history, so pressing it only emits nile-click { value: 'back' }. */
|
|
307
|
+
.back {
|
|
308
|
+
flex: 0 0 auto;
|
|
309
|
+
display: inline-flex;
|
|
310
|
+
align-items: center;
|
|
311
|
+
margin: 0;
|
|
312
|
+
padding: 0;
|
|
313
|
+
border: 0;
|
|
314
|
+
background: none;
|
|
315
|
+
cursor: pointer;
|
|
316
|
+
color: var(--nile-colors-dark-500, var(--ng-colors-fg-quaternary-400));
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.back:hover {
|
|
320
|
+
color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* App icon: a 20px block at the start of the title row, so the description lines up under it; shown whenever the app-icon slot has content. */
|
|
324
|
+
.app-icon {
|
|
325
|
+
position: relative;
|
|
326
|
+
flex: 0 0 auto;
|
|
327
|
+
display: inline-flex;
|
|
328
|
+
align-items: center;
|
|
329
|
+
justify-content: center;
|
|
330
|
+
width: var(--nile-app-shell-app-icon-size);
|
|
331
|
+
height: var(--nile-app-shell-app-icon-size);
|
|
332
|
+
border-radius: var(--nile-radius-sm, var(--ng-radius-sm));
|
|
333
|
+
overflow: hidden;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/* The slotted mark fills the wrapper edge to edge, clipped to the box. */
|
|
337
|
+
.app-icon slot::slotted(*) {
|
|
338
|
+
width: 100%;
|
|
339
|
+
height: 100%;
|
|
340
|
+
display: block;
|
|
341
|
+
object-fit: cover;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/* The wrapper takes no fill; the rim is a white-12% gradient drawn as a masked ::before, with literal mask fallbacks for the nxtgen-only tokens. */
|
|
345
|
+
.app-icon::before {
|
|
346
|
+
content: '';
|
|
347
|
+
position: absolute;
|
|
348
|
+
inset: 0;
|
|
349
|
+
border-radius: inherit;
|
|
350
|
+
pointer-events: none;
|
|
351
|
+
z-index: 1;
|
|
352
|
+
background: linear-gradient(
|
|
353
|
+
180deg,
|
|
354
|
+
rgb(255 255 255 / 12%) 0%,
|
|
355
|
+
rgb(255 255 255 / 0%) 100%
|
|
356
|
+
);
|
|
357
|
+
mask: var(
|
|
358
|
+
--ng-mask-rim,
|
|
359
|
+
linear-gradient(#000 0 0) content-box,
|
|
360
|
+
linear-gradient(#000 0 0)
|
|
361
|
+
);
|
|
362
|
+
mask-composite: var(--ng-mask-composite-exclude, exclude);
|
|
363
|
+
padding: 1.4px;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
:host(:not([has-app-icon])) .app-icon {
|
|
367
|
+
display: none;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/* Figma's Header Bar gap: 16px between every header action, the divider and Ask. */
|
|
371
|
+
.top-bar-actions {
|
|
372
|
+
display: flex;
|
|
373
|
+
align-items: center;
|
|
374
|
+
gap: var(--nile-spacing-xl, var(--ng-spacing-xl));
|
|
219
375
|
margin-inline-start: auto;
|
|
220
376
|
}
|
|
221
377
|
|
|
222
|
-
/*
|
|
223
|
-
* An empty flex item still takes the row's gap before it, which pulls the
|
|
224
|
-
* bar's content 16px short of the padding edge and leaves a sliver of bare
|
|
225
|
-
* container at the end of the header. Nothing in the group, no box.
|
|
226
|
-
*/
|
|
378
|
+
/* Hidden when empty, so an empty group's gap does not pull the bar's content short of the padding edge. */
|
|
227
379
|
:host(:not([has-top-bar-actions]):not([has-ask])) .top-bar-actions {
|
|
228
380
|
display: none;
|
|
229
381
|
}
|
|
230
382
|
|
|
231
|
-
/*
|
|
232
|
-
* The Ask button. The one control in the bar the shell renders itself: it
|
|
233
|
-
* turns on the panel being mounted and it calls openPanel(), neither of
|
|
234
|
-
* which slotted markup can reach.
|
|
235
|
-
*
|
|
236
|
-
* It is a stock <nile-button variant="primary">: the shell sets no surface,
|
|
237
|
-
* radius, height or type of its own, so the button's appearance — and its
|
|
238
|
-
* focus ring, hover, disabled and loading states — stays the component's.
|
|
239
|
-
* The only rule here is the flex behaviour it needs as a top-bar item.
|
|
240
|
-
*/
|
|
383
|
+
/* The Ask button: a stock <nile-button variant="secondary"> the shell renders itself; the only rule here is its flex behaviour as a top-bar item. */
|
|
241
384
|
.ask {
|
|
242
385
|
flex: 0 0 auto;
|
|
243
386
|
}
|
|
@@ -254,37 +397,38 @@ import{css as e}from"lit";const n=e`
|
|
|
254
397
|
height: 16px;
|
|
255
398
|
}
|
|
256
399
|
|
|
400
|
+
/* 10px after the 32px circle is 16px after the 20px glyph (6px overhang + 10), Figma's toggle-to-divider gap. */
|
|
257
401
|
.nav-toggle-group {
|
|
258
402
|
display: flex;
|
|
259
403
|
align-items: center;
|
|
260
|
-
gap: var(--nile-spacing-
|
|
404
|
+
gap: var(--nile-spacing-md-alt, var(--ng-spacing-md-alt));
|
|
261
405
|
}
|
|
262
406
|
|
|
263
|
-
/*
|
|
264
|
-
* Lands the 24px glyph box, not nile-button's 38px circle, on the
|
|
265
|
-
* container's 24px origin: (38 - 24) / 2 = 7.
|
|
266
|
-
*/
|
|
407
|
+
/* Lands the 20px glyph box, not the 32px utility circle, on the 24px origin: (32 - 20) / 2 = 6. */
|
|
267
408
|
.nav-toggle {
|
|
268
|
-
margin-inline-start: -
|
|
409
|
+
margin-inline-start: -6px;
|
|
269
410
|
}
|
|
270
411
|
|
|
412
|
+
/* Figma's Divider Line: a 16px 1px stroke that takes no layout width, so the items on both sides sit a clean 16px from it. Used after the nav toggle and, as ask-rule, before Ask. */
|
|
271
413
|
.rule {
|
|
272
414
|
flex: 0 0 auto;
|
|
273
415
|
width: var(--nile-border-width-1, var(--ng-border-width-1));
|
|
274
|
-
|
|
416
|
+
margin-inline-end: calc(-1 * var(--nile-border-width-1, var(--ng-border-width-1)));
|
|
417
|
+
height: 16px;
|
|
275
418
|
background: var(
|
|
276
419
|
--nile-colors-neutral-400,
|
|
277
420
|
var(--ng-colors-border-secondary)
|
|
278
421
|
);
|
|
279
422
|
}
|
|
280
423
|
|
|
424
|
+
/* ------------------------------------------------------- utility controls */
|
|
425
|
+
|
|
426
|
+
/* The shell's own icon controls (nav toggle, panel back and close): the shared utility-control recipe. */
|
|
427
|
+
${n}
|
|
428
|
+
|
|
281
429
|
/* --------------------------------------------------------------- tab strip */
|
|
282
430
|
|
|
283
|
-
/*
|
|
284
|
-
* Hoisted out of the scroller so it never scrolls away. It sits flush under
|
|
285
|
-
* the top bar — the header carries no bottom rule of its own, so the two read
|
|
286
|
-
* as one block of chrome, with the single rule living at the strip's bottom.
|
|
287
|
-
*/
|
|
431
|
+
/* Hoisted out of the scroller so it never scrolls away; sits flush under the top bar and carries the header block's single bottom rule. */
|
|
288
432
|
.tabs {
|
|
289
433
|
box-sizing: border-box;
|
|
290
434
|
flex: 0 0 auto;
|
|
@@ -292,6 +436,7 @@ import{css as e}from"lit";const n=e`
|
|
|
292
436
|
align-items: stretch;
|
|
293
437
|
gap: var(--nile-spacing-xs, var(--ng-spacing-xs));
|
|
294
438
|
min-width: 0;
|
|
439
|
+
/* A floor, not a fixed box: the strip is as tall as the row it holds plus its rule. */
|
|
295
440
|
min-height: var(--nile-app-shell-tabs-height);
|
|
296
441
|
padding-inline: var(--nile-app-shell-content-padding);
|
|
297
442
|
/* The strip carries the rule for the whole header block. */
|
|
@@ -301,14 +446,43 @@ import{css as e}from"lit";const n=e`
|
|
|
301
446
|
scrollbar-width: none;
|
|
302
447
|
}
|
|
303
448
|
|
|
449
|
+
/* The header tab's 0/4/12/4 padding composes the 32px row; the 12px bottom gives the active indicator its band, set via the group's public padding hook. */
|
|
450
|
+
::slotted([slot='tabs']) {
|
|
451
|
+
--nile-nav-tab-padding: var(--nile-spacing-none, var(--ng-spacing-none))
|
|
452
|
+
var(--nile-spacing-xs, var(--ng-spacing-xs))
|
|
453
|
+
var(--nile-spacing-lg, var(--ng-spacing-lg))
|
|
454
|
+
var(--nile-spacing-xs, var(--ng-spacing-xs));
|
|
455
|
+
}
|
|
456
|
+
|
|
304
457
|
.tabs::-webkit-scrollbar {
|
|
305
458
|
display: none;
|
|
306
459
|
}
|
|
307
460
|
|
|
308
|
-
:host(:not([has-tabs])) .tabs
|
|
461
|
+
:host(:not([has-tabs])) .tabs,
|
|
462
|
+
:host([notabs]) .tabs {
|
|
309
463
|
display: none;
|
|
310
464
|
}
|
|
311
465
|
|
|
466
|
+
/* A slotted nile-nav-tab-group drops its own track (--track-width:0 on the host) and is bottom-aligned so its indicator sits on the region's single rule. */
|
|
467
|
+
/* Scoped to the group, not the slot, so bare tab controls are not stretched to an equal share of the strip. */
|
|
468
|
+
::slotted(nile-nav-tab-group[slot='tabs']) {
|
|
469
|
+
--track-width: 0px;
|
|
470
|
+
/*
|
|
471
|
+
* The active indicator (Figma: fg-brand-primary-alt) is NOT set here: the top placement hard-codes
|
|
472
|
+
* var(--nile-colors-primary-600, var(--ng-colors-text-brand-secondary-700)) inside nile-nav-tab-group's shadow tree, and
|
|
473
|
+
* remapping either token from here would also recolour nile-nav-tab's focus ring and focus label. Known limitation (spec A-7).
|
|
474
|
+
*/
|
|
475
|
+
/*
|
|
476
|
+
* The inactive label: nile-nav-tab paints it var(--nile-colors-dark-500, var(--ng-colors-text-secondary-700)), so the strip
|
|
477
|
+
* points the NxtGen fallback at text-quaternary-500. Enterprise defines --nile-colors-dark-500 and is untouched. Inside an
|
|
478
|
+
* underline group nothing else reads text-secondary-700 (only the group's other variants and side placements do).
|
|
479
|
+
*/
|
|
480
|
+
--ng-colors-text-secondary-700: var(--ng-colors-text-quaternary-500);
|
|
481
|
+
flex: 1 1 auto;
|
|
482
|
+
min-width: 0;
|
|
483
|
+
align-self: flex-end;
|
|
484
|
+
}
|
|
485
|
+
|
|
312
486
|
/* ------------------------------------------------------------------- main */
|
|
313
487
|
|
|
314
488
|
.main {
|
|
@@ -318,7 +492,9 @@ import{css as e}from"lit";const n=e`
|
|
|
318
492
|
flex-direction: column;
|
|
319
493
|
min-height: 0;
|
|
320
494
|
overflow: auto;
|
|
495
|
+
/* Top and sides only: the page runs to the container's bottom edge. */
|
|
321
496
|
padding: var(--nile-app-shell-content-padding);
|
|
497
|
+
padding-block-end: 0;
|
|
322
498
|
}
|
|
323
499
|
|
|
324
500
|
.main:focus {
|
|
@@ -336,13 +512,7 @@ import{css as e}from"lit";const n=e`
|
|
|
336
512
|
|
|
337
513
|
/* Centred when short, scrolls from the top when tall. */
|
|
338
514
|
:host([content-align='centered']) .main-inner {
|
|
339
|
-
/*
|
|
340
|
-
* width:100% + max-width leaves free space for the auto inline margins to
|
|
341
|
-
* split; dropping the width would let the auto margins cancel the flex
|
|
342
|
-
* stretch and shrink-wrap the column to its widest child. The block margins
|
|
343
|
-
* centre it while it is short and compute to 0 once it is taller, so a tall
|
|
344
|
-
* page scrolls from the top rather than clipping.
|
|
345
|
-
*/
|
|
515
|
+
/* width:100% + max-width leaves space for the auto margins to centre it while short, and scroll from the top when tall. */
|
|
346
516
|
width: 100%;
|
|
347
517
|
max-width: var(--nile-app-shell-centered-width);
|
|
348
518
|
margin: auto;
|
|
@@ -352,8 +522,7 @@ import{css as e}from"lit";const n=e`
|
|
|
352
522
|
|
|
353
523
|
.aside {
|
|
354
524
|
box-sizing: border-box;
|
|
355
|
-
/* Gives before the page does, down to its own floor
|
|
356
|
-
the panel does: the page is the last region to be asked for room. */
|
|
525
|
+
/* Gives before the page does, down to its own floor. */
|
|
357
526
|
flex: 0 1 var(--nile-app-shell-aside-width);
|
|
358
527
|
min-width: var(--nile-app-shell-aside-min-width);
|
|
359
528
|
display: flex;
|
|
@@ -375,13 +544,7 @@ import{css as e}from"lit";const n=e`
|
|
|
375
544
|
|
|
376
545
|
.panel {
|
|
377
546
|
box-sizing: border-box;
|
|
378
|
-
/*
|
|
379
|
-
* The panel pushes the page, it never covers it, so it has to be able to
|
|
380
|
-
* give a little: full width while the row can afford it, then shrinking to
|
|
381
|
-
* its min. Here the floor can be a real min-width — the container's floor
|
|
382
|
-
* is a flex basis that yields all the way, so the row still cannot
|
|
383
|
-
* overflow into :host's clip once the panel stops giving.
|
|
384
|
-
*/
|
|
547
|
+
/* The panel pushes the page rather than covering it: full width while the row affords it, shrinking to a real min-width floor. */
|
|
385
548
|
flex: 0 1 var(--nile-app-shell-panel-width);
|
|
386
549
|
width: var(--nile-app-shell-panel-width);
|
|
387
550
|
min-width: var(--nile-app-shell-panel-min-width);
|
|
@@ -435,13 +598,28 @@ import{css as e}from"lit";const n=e`
|
|
|
435
598
|
flex: 0 0 auto;
|
|
436
599
|
display: flex;
|
|
437
600
|
align-items: center;
|
|
438
|
-
gap: var(--nile-spacing-
|
|
439
|
-
height: var(--nile-app-shell-
|
|
440
|
-
padding-inline: var(--nile-spacing-
|
|
601
|
+
gap: var(--nile-spacing-md, var(--ng-spacing-md));
|
|
602
|
+
height: var(--nile-app-shell-panel-header-height);
|
|
603
|
+
padding-inline: var(--nile-spacing-3xl, var(--ng-spacing-3xl));
|
|
441
604
|
border-bottom: var(--nile-border-width-1, var(--ng-border-width-1)) solid
|
|
442
605
|
var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
|
|
443
606
|
}
|
|
444
607
|
|
|
608
|
+
/* The back control for a panel sub-view; stands where the brand mark does in the root view. */
|
|
609
|
+
.panel-back {
|
|
610
|
+
flex: 0 0 auto;
|
|
611
|
+
margin-inline-start: -6px;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/* Mirrors the back control's offset on the end edge: the 20px glyph, not the 32px circle, lands on the padding line. */
|
|
615
|
+
.panel-close {
|
|
616
|
+
margin-inline-end: -6px;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
:host([panelback]) .panel-mark {
|
|
620
|
+
display: none;
|
|
621
|
+
}
|
|
622
|
+
|
|
445
623
|
.panel-heading {
|
|
446
624
|
display: flex;
|
|
447
625
|
align-items: center;
|
|
@@ -466,7 +644,9 @@ import{css as e}from"lit";const n=e`
|
|
|
466
644
|
|
|
467
645
|
.panel-title {
|
|
468
646
|
margin: 0;
|
|
469
|
-
|
|
647
|
+
/* Figma's Assistant Title: Text lg/Semibold, 18/28 on NxtGen. Enterprise keeps --nile-type-scale-3, and it defines no --ng-* tokens, so the line-height declaration is invalid there and the title inherits its line height exactly as before. */
|
|
648
|
+
font-size: var(--nile-type-scale-3, var(--ng-font-size-text-lg));
|
|
649
|
+
line-height: var(--ng-line-height-text-lg);
|
|
470
650
|
font-weight: var(
|
|
471
651
|
--nile-font-weight-semi-bold,
|
|
472
652
|
var(--ng-font-weight-semibold)
|
|
@@ -488,7 +668,8 @@ import{css as e}from"lit";const n=e`
|
|
|
488
668
|
flex: 1 1 auto;
|
|
489
669
|
min-height: 0;
|
|
490
670
|
overflow: auto;
|
|
491
|
-
|
|
671
|
+
/* 16 under the header, 24 on the sides and bottom. */
|
|
672
|
+
padding: var(--nile-spacing-xl, var(--ng-spacing-xl)) var(--nile-spacing-3xl, var(--ng-spacing-3xl)) var(--nile-spacing-3xl, var(--ng-spacing-3xl));
|
|
492
673
|
display: flex;
|
|
493
674
|
flex-direction: column;
|
|
494
675
|
gap: var(--nile-spacing-xl, var(--ng-spacing-xl));
|
|
@@ -496,7 +677,7 @@ import{css as e}from"lit";const n=e`
|
|
|
496
677
|
|
|
497
678
|
.panel-footer {
|
|
498
679
|
flex: 0 0 auto;
|
|
499
|
-
padding: var(--nile-spacing-xl, var(--ng-spacing-xl));
|
|
680
|
+
padding: var(--nile-spacing-xl, var(--ng-spacing-xl)) var(--nile-spacing-3xl, var(--ng-spacing-3xl)) var(--nile-spacing-3xl, var(--ng-spacing-3xl));
|
|
500
681
|
border-top: var(--nile-border-width-1, var(--ng-border-width-1)) solid
|
|
501
682
|
var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
|
|
502
683
|
}
|
|
@@ -551,4 +732,4 @@ import{css as e}from"lit";const n=e`
|
|
|
551
732
|
transition: none;
|
|
552
733
|
}
|
|
553
734
|
}
|
|
554
|
-
`;export{
|
|
735
|
+
`;export{a as s};
|