@sken-ds/primitives 0.3.7 → 0.4.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/dist/index.js +7 -7
- package/dist/ix-bridge.css +20 -20
- package/dist/sken-button.js.map +1 -1
- package/dist/sken-checkbox.js.map +1 -1
- package/dist/sken-combobox.js +65 -56
- package/dist/sken-combobox.js.map +1 -1
- package/dist/{sken-datatable-BtR-NwRN.js → sken-datatable-ChDjB_T_.js} +7 -9
- package/dist/{sken-datatable-BtR-NwRN.js.map → sken-datatable-ChDjB_T_.js.map} +1 -1
- package/dist/sken-datatable.js +1 -1
- package/dist/sken-date-picker.js.map +1 -1
- package/dist/{sken-dialog-hRtML2jW.js → sken-dialog-BvRZxwSk.js} +33 -18
- package/dist/sken-dialog-BvRZxwSk.js.map +1 -0
- package/dist/sken-dialog.js +1 -1
- package/dist/sken-filter-chip.js +16 -10
- package/dist/sken-filter-chip.js.map +1 -1
- package/dist/sken-input.js.map +1 -1
- package/dist/sken-layout-region.js.map +1 -1
- package/dist/sken-layout.js +163 -86
- package/dist/sken-layout.js.map +1 -1
- package/dist/sken-number-input.js +32 -42
- package/dist/sken-number-input.js.map +1 -1
- package/dist/sken-switch.js.map +1 -1
- package/dist/sken-textarea.js.map +1 -1
- package/package.json +2 -2
- package/dist/sken-dialog-hRtML2jW.js.map +0 -1
package/dist/sken-layout.js
CHANGED
|
@@ -2,22 +2,34 @@ import { t as e } from "./decorate-D4FKzyDw.js";
|
|
|
2
2
|
import "./sken-layout-region.js";
|
|
3
3
|
import { LitElement as t, css as n, html as r, unsafeCSS as i } from "lit";
|
|
4
4
|
import { customElement as a, property as o } from "lit/decorators.js";
|
|
5
|
+
import { SkenLayoutVariantRoles as s } from "@sken-ds/contracts";
|
|
5
6
|
//#region src/components/sken-layout.ts
|
|
6
|
-
var
|
|
7
|
+
var c = {
|
|
7
8
|
sm: "12rem",
|
|
8
9
|
md: "16rem",
|
|
9
10
|
lg: "20rem"
|
|
10
|
-
},
|
|
11
|
+
}, l = {
|
|
12
|
+
topbar: "var(--sken-card)",
|
|
13
|
+
"primary-nav": "var(--sken-background)",
|
|
14
|
+
sidebar: "var(--sken-muted)",
|
|
15
|
+
content: "var(--sken-background)",
|
|
16
|
+
footer: "var(--sken-muted)"
|
|
17
|
+
}, u = class extends t {
|
|
11
18
|
constructor(...e) {
|
|
12
|
-
super(...e), this.variant = "header-content", this.topbarMode = "fixed", this.sidebarPosition = "start", this.sidebarSize = "md";
|
|
19
|
+
super(...e), this.variant = "header-content", this.topbarMode = "fixed", this.sidebarPosition = "start", this.sidebarSize = "md", this.density = "none";
|
|
20
|
+
}
|
|
21
|
+
get #e() {
|
|
22
|
+
return s[this.variant];
|
|
23
|
+
}
|
|
24
|
+
get #t() {
|
|
25
|
+
return this.#e.includes("sidebar");
|
|
13
26
|
}
|
|
14
27
|
static {
|
|
15
28
|
this.styles = n`
|
|
16
29
|
/* ── The host ────────────────────────────────────────────────
|
|
17
|
-
The host owns the page-level grid. The
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
projects the consumer's regions into the grid cells. */
|
|
30
|
+
The host owns the page-level grid. The topbar / primary-nav
|
|
31
|
+
/ footer sit in their own rows; the body is a sub-grid that
|
|
32
|
+
holds the sidebar (when present) and the content. */
|
|
21
33
|
:host {
|
|
22
34
|
display: grid;
|
|
23
35
|
block-size: 100dvh;
|
|
@@ -31,13 +43,40 @@ var s = {
|
|
|
31
43
|
font-family: var(--sken-family-sans, system-ui, sans-serif);
|
|
32
44
|
}
|
|
33
45
|
|
|
46
|
+
/* ── Per-cell grid items ─────────────────────────────────────
|
|
47
|
+
Each named slot sits inside a wrapper element that is the
|
|
48
|
+
actual grid item. The wrapper's class matches the role
|
|
49
|
+
(topbar, primary-nav, body, footer). The variant rules
|
|
50
|
+
below assign the right 'grid-area' to each role. The
|
|
51
|
+
'display: contents' <sken-layout-region> is projected
|
|
52
|
+
through the named <slot> and inherits the wrapper's
|
|
53
|
+
background, border, and padding. */
|
|
54
|
+
.topbar {
|
|
55
|
+
grid-area: topbar;
|
|
56
|
+
background: var(
|
|
57
|
+
--sken-layout-region-topbar-background,
|
|
58
|
+
${i(l.topbar)}
|
|
59
|
+
);
|
|
60
|
+
padding-block: var(--sken-layout-region-topbar-padding-block, 0);
|
|
61
|
+
padding-inline: var(--sken-layout-region-topbar-padding-inline, 0);
|
|
62
|
+
border-bottom: 1px solid var(--sken-border);
|
|
63
|
+
}
|
|
64
|
+
.primary-nav {
|
|
65
|
+
grid-area: primary-nav;
|
|
66
|
+
background: var(
|
|
67
|
+
--sken-layout-region-primary-nav-background,
|
|
68
|
+
${i(l["primary-nav"])}
|
|
69
|
+
);
|
|
70
|
+
padding-block: var(--sken-layout-region-primary-nav-padding-block, 0);
|
|
71
|
+
padding-inline: var(--sken-layout-region-primary-nav-padding-inline, 0);
|
|
72
|
+
border-bottom: 1px solid var(--sken-border);
|
|
73
|
+
}
|
|
34
74
|
.body {
|
|
35
75
|
display: grid;
|
|
36
76
|
grid-template-columns: 1fr;
|
|
37
77
|
grid-template-areas: 'content';
|
|
38
78
|
min-block-size: 0; /* allow children to shrink + scroll */
|
|
39
79
|
}
|
|
40
|
-
|
|
41
80
|
.body.with-sidebar {
|
|
42
81
|
grid-template-columns: var(--sken-layout-sidebar-width, 16rem) 1fr;
|
|
43
82
|
grid-template-areas: 'sidebar content';
|
|
@@ -46,36 +85,98 @@ var s = {
|
|
|
46
85
|
grid-template-columns: 1fr var(--sken-layout-sidebar-width, 16rem);
|
|
47
86
|
grid-template-areas: 'content sidebar';
|
|
48
87
|
}
|
|
49
|
-
|
|
50
|
-
/* ── Per-region grid placement ───────────────────────────────
|
|
51
|
-
The light-DOM <sken-layout-region> children are projected
|
|
52
|
-
here through the unnamed <slot>. The grid-area rule per
|
|
53
|
-
name positions each one in the right cell. We select the
|
|
54
|
-
slotted custom elements by attribute, which works
|
|
55
|
-
transparently across the shadow boundary. */
|
|
56
|
-
::slotted(sken-layout-region[name='topbar']) {
|
|
57
|
-
grid-area: topbar;
|
|
58
|
-
}
|
|
59
|
-
::slotted(sken-layout-region[name='primary-nav']) {
|
|
60
|
-
grid-area: primary-nav;
|
|
61
|
-
}
|
|
62
|
-
::slotted(sken-layout-region[name='sidebar']) {
|
|
88
|
+
.sidebar {
|
|
63
89
|
grid-area: sidebar;
|
|
64
90
|
min-block-size: 0;
|
|
65
|
-
|
|
66
|
-
|
|
91
|
+
background: var(
|
|
92
|
+
--sken-layout-region-sidebar-background,
|
|
93
|
+
${i(l.sidebar)}
|
|
94
|
+
);
|
|
95
|
+
padding-block: var(--sken-layout-region-sidebar-padding-block, 0);
|
|
96
|
+
padding-inline: var(--sken-layout-region-sidebar-padding-inline, 0);
|
|
97
|
+
border-inline-end: 1px solid var(--sken-border);
|
|
67
98
|
}
|
|
68
|
-
|
|
99
|
+
.content {
|
|
69
100
|
grid-area: content;
|
|
70
101
|
min-block-size: 0;
|
|
102
|
+
background: var(
|
|
103
|
+
--sken-layout-region-content-background,
|
|
104
|
+
${i(l.content)}
|
|
105
|
+
);
|
|
106
|
+
padding-block: var(--sken-layout-region-content-padding-block, 0);
|
|
107
|
+
padding-inline: var(--sken-layout-region-content-padding-inline, 0);
|
|
71
108
|
}
|
|
72
|
-
|
|
109
|
+
.footer {
|
|
73
110
|
grid-area: footer;
|
|
74
|
-
|
|
75
|
-
|
|
111
|
+
background: var(
|
|
112
|
+
--sken-layout-region-footer-background,
|
|
113
|
+
${i(l.footer)}
|
|
114
|
+
);
|
|
115
|
+
padding-block: var(--sken-layout-region-footer-padding-block, 0);
|
|
116
|
+
padding-inline: var(--sken-layout-region-footer-padding-inline, 0);
|
|
117
|
+
border-top: 1px solid var(--sken-border);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* ── Density: comfortable ─────────────────────────────────────
|
|
121
|
+
When density=comfortable, the layout applies the Sken
|
|
122
|
+
default rhythm: 8/16px on chrome cells, 16/24px on the
|
|
123
|
+
content area, 12/16px on the footer. The values come
|
|
124
|
+
from the spacing scale (--sken-2, --sken-3, --sken-4,
|
|
125
|
+
--sken-6) so a single token change ripples through
|
|
126
|
+
every cell. A consumer override on any
|
|
127
|
+
--sken-layout-region-{role}-padding-{block|inline}
|
|
128
|
+
always wins over the density preset. */
|
|
129
|
+
:host([density='comfortable']) .topbar,
|
|
130
|
+
:host([density='comfortable']) .primary-nav,
|
|
131
|
+
:host([density='comfortable']) .content,
|
|
132
|
+
:host([density='comfortable']) .sidebar,
|
|
133
|
+
:host([density='comfortable']) .footer {
|
|
134
|
+
--sken-layout-region-topbar-padding-block: var(--sken-2);
|
|
135
|
+
--sken-layout-region-topbar-padding-inline: var(--sken-4);
|
|
136
|
+
--sken-layout-region-primary-nav-padding-block: var(--sken-2);
|
|
137
|
+
--sken-layout-region-primary-nav-padding-inline: var(--sken-4);
|
|
138
|
+
--sken-layout-region-sidebar-padding-block: var(--sken-4);
|
|
139
|
+
--sken-layout-region-sidebar-padding-inline: var(--sken-4);
|
|
140
|
+
--sken-layout-region-content-padding-block: var(--sken-6);
|
|
141
|
+
--sken-layout-region-content-padding-inline: var(--sken-6);
|
|
142
|
+
--sken-layout-region-footer-padding-block: var(--sken-3);
|
|
143
|
+
--sken-layout-region-footer-padding-inline: var(--sken-4);
|
|
76
144
|
}
|
|
77
145
|
|
|
78
|
-
/* ──
|
|
146
|
+
/* ── Density: compact ────────────────────────────────────────
|
|
147
|
+
When density=compact, every per-cell padding is halved
|
|
148
|
+
from the comfortable value. We use calc(var(--sken-N) *
|
|
149
|
+
0.5) instead of hardcoded half-values so a future
|
|
150
|
+
token change automatically cascades. As with
|
|
151
|
+
comfortable, a consumer override on any
|
|
152
|
+
--sken-layout-region-{role}-padding-{block|inline}
|
|
153
|
+
always wins. */
|
|
154
|
+
:host([density='compact']) .topbar,
|
|
155
|
+
:host([density='compact']) .primary-nav,
|
|
156
|
+
:host([density='compact']) .content,
|
|
157
|
+
:host([density='compact']) .sidebar,
|
|
158
|
+
:host([density='compact']) .footer {
|
|
159
|
+
--sken-layout-region-topbar-padding-block: calc(var(--sken-2) * 0.5);
|
|
160
|
+
--sken-layout-region-topbar-padding-inline: calc(var(--sken-4) * 0.5);
|
|
161
|
+
--sken-layout-region-primary-nav-padding-block: calc(var(--sken-2) * 0.5);
|
|
162
|
+
--sken-layout-region-primary-nav-padding-inline: calc(var(--sken-4) * 0.5);
|
|
163
|
+
--sken-layout-region-sidebar-padding-block: calc(var(--sken-4) * 0.5);
|
|
164
|
+
--sken-layout-region-sidebar-padding-inline: calc(var(--sken-4) * 0.5);
|
|
165
|
+
--sken-layout-region-content-padding-block: calc(var(--sken-6) * 0.5);
|
|
166
|
+
--sken-layout-region-content-padding-inline: calc(var(--sken-6) * 0.5);
|
|
167
|
+
--sken-layout-region-footer-padding-block: calc(var(--sken-3) * 0.5);
|
|
168
|
+
--sken-layout-region-footer-padding-inline: calc(var(--sken-4) * 0.5);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* ── Grid templates per variant ───────────────────────────────
|
|
172
|
+
Each variant declares which rows the host grid reserves.
|
|
173
|
+
The default host grid is 2 rows (topbar + body); variants
|
|
174
|
+
that include primary-nav or footer add more rows. Rows
|
|
175
|
+
with no rendered content (e.g. footer on a variant that
|
|
176
|
+
does not include a footer) collapse to 0 because the
|
|
177
|
+
variant does not render the matching wrapper, and an
|
|
178
|
+
empty 'auto' row in a grid takes the height of its
|
|
179
|
+
content (which is 0). */
|
|
79
180
|
:host([variant='full-bleed']) {
|
|
80
181
|
grid-template-areas: 'body';
|
|
81
182
|
grid-template-rows: 1fr;
|
|
@@ -90,10 +191,6 @@ var s = {
|
|
|
90
191
|
grid-template-rows: 1fr;
|
|
91
192
|
grid-template-areas: 'body';
|
|
92
193
|
}
|
|
93
|
-
:host([variant='sidebar-content']) .body {
|
|
94
|
-
grid-template-columns: var(--sken-layout-sidebar-width, 16rem) 1fr;
|
|
95
|
-
grid-template-areas: 'sidebar content';
|
|
96
|
-
}
|
|
97
194
|
:host([variant='header-sidebar']) {
|
|
98
195
|
grid-template-rows: auto auto 1fr;
|
|
99
196
|
grid-template-areas:
|
|
@@ -121,85 +218,65 @@ var s = {
|
|
|
121
218
|
}
|
|
122
219
|
|
|
123
220
|
/* ── Sidebar position ─────────────────────────────────────────
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
:host([sidebar-position='end']) ::slotted(sken-layout-region[name='sidebar']) {
|
|
221
|
+
When the sidebar sits on the inline-end side, the border
|
|
222
|
+
moves to the inline-start side. The default rule above
|
|
223
|
+
already paints the border on the inline-end; here we
|
|
224
|
+
swap it. */
|
|
225
|
+
:host([sidebar-position='end']) .sidebar {
|
|
130
226
|
border-inline-end: none;
|
|
131
|
-
border-inline-start: 1px solid
|
|
132
|
-
var(--sken-border, color-mix(in srgb, currentColor 12%, transparent));
|
|
227
|
+
border-inline-start: 1px solid var(--sken-border);
|
|
133
228
|
}
|
|
134
229
|
|
|
135
230
|
/* ── Sidebar width override ─────────────────────────────────── */
|
|
136
231
|
:host([sidebar-size='sm']) {
|
|
137
|
-
--sken-layout-sidebar-width: ${i(
|
|
232
|
+
--sken-layout-sidebar-width: ${i(c.sm)};
|
|
138
233
|
}
|
|
139
234
|
:host([sidebar-size='md']) {
|
|
140
|
-
--sken-layout-sidebar-width: ${i(
|
|
235
|
+
--sken-layout-sidebar-width: ${i(c.md)};
|
|
141
236
|
}
|
|
142
237
|
:host([sidebar-size='lg']) {
|
|
143
|
-
--sken-layout-sidebar-width: ${i(
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/* ── Variant-aware region hiding ─────────────────────────────
|
|
147
|
-
Roles the active variant does not include are hidden
|
|
148
|
-
outright. This way a consumer that always renders the
|
|
149
|
-
same set of regions (e.g. a shared layout component) does
|
|
150
|
-
not get phantom space when a page uses a different
|
|
151
|
-
variant. */
|
|
152
|
-
:host([variant='full-bleed']) ::slotted(sken-layout-region[name='topbar']),
|
|
153
|
-
:host([variant='full-bleed']) ::slotted(sken-layout-region[name='primary-nav']),
|
|
154
|
-
:host([variant='full-bleed']) ::slotted(sken-layout-region[name='sidebar']),
|
|
155
|
-
:host([variant='full-bleed']) ::slotted(sken-layout-region[name='footer']) {
|
|
156
|
-
display: none;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
:host([variant='header-content']) ::slotted(sken-layout-region[name='primary-nav']),
|
|
160
|
-
:host([variant='header-content']) ::slotted(sken-layout-region[name='sidebar']),
|
|
161
|
-
:host([variant='header-content']) ::slotted(sken-layout-region[name='footer']) {
|
|
162
|
-
display: none;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
:host([variant='sidebar-content']) ::slotted(sken-layout-region[name='topbar']),
|
|
166
|
-
:host([variant='sidebar-content']) ::slotted(sken-layout-region[name='primary-nav']),
|
|
167
|
-
:host([variant='sidebar-content']) ::slotted(sken-layout-region[name='footer']) {
|
|
168
|
-
display: none;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
:host([variant='header-sidebar']) ::slotted(sken-layout-region[name='footer']) {
|
|
172
|
-
display: none;
|
|
238
|
+
--sken-layout-sidebar-width: ${i(c.lg)};
|
|
173
239
|
}
|
|
174
240
|
`;
|
|
175
241
|
}
|
|
176
242
|
render() {
|
|
177
|
-
let e = this.#e
|
|
243
|
+
let e = this.#e, t = this.#t, n = [
|
|
178
244
|
"body",
|
|
179
|
-
|
|
180
|
-
|
|
245
|
+
t ? "with-sidebar" : "",
|
|
246
|
+
t && this.sidebarPosition === "end" ? "sidebar-end" : ""
|
|
181
247
|
].filter(Boolean).join(" ");
|
|
182
248
|
return r`
|
|
183
|
-
|
|
184
|
-
|
|
249
|
+
${e.includes("topbar") ? r`<div class="topbar" part="topbar">
|
|
250
|
+
<slot name="topbar"></slot>
|
|
251
|
+
</div>` : ""}
|
|
252
|
+
${e.includes("primary-nav") ? r`<div class="primary-nav" part="primary-nav">
|
|
253
|
+
<slot name="primary-nav"></slot>
|
|
254
|
+
</div>` : ""}
|
|
255
|
+
<div class=${n} part="body">
|
|
256
|
+
${t ? r`<div class="sidebar" part="sidebar">
|
|
257
|
+
<slot name="sidebar"></slot>
|
|
258
|
+
</div>` : ""}
|
|
259
|
+
<div class="content" part="content">
|
|
260
|
+
<slot name="content"></slot>
|
|
261
|
+
</div>
|
|
185
262
|
</div>
|
|
263
|
+
${e.includes("footer") ? r`<div class="footer" part="footer">
|
|
264
|
+
<slot name="footer"></slot>
|
|
265
|
+
</div>` : ""}
|
|
186
266
|
`;
|
|
187
267
|
}
|
|
188
|
-
#e(e) {
|
|
189
|
-
return e === "sidebar-content" || e === "header-sidebar" || e === "header-sidebar-footer";
|
|
190
|
-
}
|
|
191
268
|
};
|
|
192
|
-
e([o({ reflect: !0 })],
|
|
269
|
+
e([o({ reflect: !0 })], u.prototype, "variant", void 0), e([o({
|
|
193
270
|
attribute: "topbar-mode",
|
|
194
271
|
reflect: !0
|
|
195
|
-
})],
|
|
272
|
+
})], u.prototype, "topbarMode", void 0), e([o({
|
|
196
273
|
attribute: "sidebar-position",
|
|
197
274
|
reflect: !0
|
|
198
|
-
})],
|
|
275
|
+
})], u.prototype, "sidebarPosition", void 0), e([o({
|
|
199
276
|
attribute: "sidebar-size",
|
|
200
277
|
reflect: !0
|
|
201
|
-
})],
|
|
278
|
+
})], u.prototype, "sidebarSize", void 0), e([o({ reflect: !0 })], u.prototype, "density", void 0), u = e([a("sken-layout")], u);
|
|
202
279
|
//#endregion
|
|
203
|
-
export {
|
|
280
|
+
export { u as SkenLayout };
|
|
204
281
|
|
|
205
282
|
//# sourceMappingURL=sken-layout.js.map
|
package/dist/sken-layout.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sken-layout.js","names":["#variantHasSidebar"],"sources":["../src/components/sken-layout.ts"],"sourcesContent":["// ── <sken-layout> — structural layout primitive ────────────────────\n// Defines the page-level structure of a multi-region interface\n// (topbar, primary nav, sidebar, content, footer) without imposing\n// what lives inside each region. Composition by contract:\n//\n// <sken-layout variant=\"header-sidebar\">\n// <sken-layout-region name=\"topbar\">…</sken-layout-region>\n// <sken-layout-region name=\"primary-nav\">…</sken-layout-region>\n// <sken-layout-region name=\"sidebar\">…</sken-layout-region>\n// <sken-layout-region name=\"content\">…</sken-layout-region>\n// </sken-layout>\n//\n// Design notes:\n// - We project the light-DOM regions into a shadow-DOM grid via\n// a single <slot>. Inside the shadow we own the grid template\n// + per-name `grid-area` CSS rules; the consumer's regions\n// sit in the slot. Empty regions (no consumer region for a\n// name) simply do not project; the grid still has the area\n// declared but the slot stays empty, so no space is reserved.\n// - We DO NOT use named <slot name=\"topbar\"> etc. because that\n// would force the consumer to keep the regions in a fixed\n// order. A single unnamed <slot> lets the consumer arrange\n// the regions in any order; the grid-area CSS rule per name\n// is what places them in the layout. (A Vue adapter that\n// renders regions via <template v-for> is therefore free.)\n// - For roles the active variant does not include, we hide\n// the region via `display: none` so a consumer that always\n// renders the same set of regions (e.g. from a layout\n// component shared across pages) does not get phantom space.\n// The CSS rule uses `:host([variant=…])` so it does not\n// depend on JS state.\n//\n// See ADR-0006 for the substrate decision. See the\n// @sken-ds/contracts types `SkenLayoutProps`, `SkenLayoutSlots`,\n// `SkenLayoutVariant` for the contract surface.\n\nimport { LitElement, html, css, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport type {\n SkenLayoutVariant,\n SkenLayoutTopbarMode,\n SkenLayoutSidebarPosition,\n SkenLayoutSidebarSize,\n} from '@sken-ds/contracts'\nimport './sken-layout-region.js'\n\n/**\n * Sidebar width in `rem` per size concept. The product can\n * override with `--sken-layout-sidebar-width` (CSS custom\n * property) if it needs a different value.\n */\nconst SIDEBAR_WIDTH: Record<SkenLayoutSidebarSize, string> = {\n sm: '12rem',\n md: '16rem',\n lg: '20rem',\n}\n\n@customElement('sken-layout')\nexport class SkenLayout extends LitElement {\n @property({ reflect: true }) variant: SkenLayoutVariant = 'header-content'\n @property({ attribute: 'topbar-mode', reflect: true }) topbarMode: SkenLayoutTopbarMode = 'fixed'\n @property({ attribute: 'sidebar-position', reflect: true })\n sidebarPosition: SkenLayoutSidebarPosition = 'start'\n @property({ attribute: 'sidebar-size', reflect: true }) sidebarSize: SkenLayoutSidebarSize = 'md'\n\n static styles = css`\n /* ── The host ────────────────────────────────────────────────\n The host owns the page-level grid. The body row is a\n sub-grid; the topbar / primary-nav / footer sit in their\n own rows. The shadow DOM owns the layout; the slot inside\n projects the consumer's regions into the grid cells. */\n :host {\n display: grid;\n block-size: 100dvh;\n grid-template-columns: 1fr;\n grid-template-rows: auto 1fr;\n grid-template-areas:\n 'topbar'\n 'body';\n background: var(--sken-background, Canvas);\n color: var(--sken-foreground, CanvasText);\n font-family: var(--sken-family-sans, system-ui, sans-serif);\n }\n\n .body {\n display: grid;\n grid-template-columns: 1fr;\n grid-template-areas: 'content';\n min-block-size: 0; /* allow children to shrink + scroll */\n }\n\n .body.with-sidebar {\n grid-template-columns: var(--sken-layout-sidebar-width, 16rem) 1fr;\n grid-template-areas: 'sidebar content';\n }\n .body.with-sidebar.sidebar-end {\n grid-template-columns: 1fr var(--sken-layout-sidebar-width, 16rem);\n grid-template-areas: 'content sidebar';\n }\n\n /* ── Per-region grid placement ───────────────────────────────\n The light-DOM <sken-layout-region> children are projected\n here through the unnamed <slot>. The grid-area rule per\n name positions each one in the right cell. We select the\n slotted custom elements by attribute, which works\n transparently across the shadow boundary. */\n ::slotted(sken-layout-region[name='topbar']) {\n grid-area: topbar;\n }\n ::slotted(sken-layout-region[name='primary-nav']) {\n grid-area: primary-nav;\n }\n ::slotted(sken-layout-region[name='sidebar']) {\n grid-area: sidebar;\n min-block-size: 0;\n border-inline-end: 1px solid\n var(--sken-border, color-mix(in srgb, currentColor 12%, transparent));\n }\n ::slotted(sken-layout-region[name='content']) {\n grid-area: content;\n min-block-size: 0;\n }\n ::slotted(sken-layout-region[name='footer']) {\n grid-area: footer;\n border-top: 1px solid\n var(--sken-border, color-mix(in srgb, currentColor 12%, transparent));\n }\n\n /* ── Grid templates per variant ─────────────────────────────── */\n :host([variant='full-bleed']) {\n grid-template-areas: 'body';\n grid-template-rows: 1fr;\n }\n :host([variant='header-content']) {\n grid-template-areas:\n 'topbar'\n 'body';\n grid-template-rows: auto 1fr;\n }\n :host([variant='sidebar-content']) {\n grid-template-rows: 1fr;\n grid-template-areas: 'body';\n }\n :host([variant='sidebar-content']) .body {\n grid-template-columns: var(--sken-layout-sidebar-width, 16rem) 1fr;\n grid-template-areas: 'sidebar content';\n }\n :host([variant='header-sidebar']) {\n grid-template-rows: auto auto 1fr;\n grid-template-areas:\n 'topbar'\n 'primary-nav'\n 'body';\n }\n :host([variant='header-sidebar-footer']) {\n grid-template-rows: auto auto 1fr auto;\n grid-template-areas:\n 'topbar'\n 'primary-nav'\n 'body'\n 'footer';\n }\n\n /* ── Topbar mode ──────────────────────────────────────────────\n 'fixed': the host is 100dvh and the body scrolls under the\n topbar. This is the default for admin consoles.\n 'auto': the topbar scrolls away with the page (marketing,\n landing). */\n :host([topbar-mode='auto']) {\n block-size: auto;\n min-block-size: 100dvh;\n }\n\n /* ── Sidebar position ─────────────────────────────────────────\n The 'with-sidebar' class is applied via JS in render() so\n we can include the 'sidebar-end' modifier in the same\n selector chain. (You cannot combine the [sidebar-position]\n attribute with the '.with-sidebar' class in a single\n selector, because the class is conditional.) */\n :host([sidebar-position='end']) ::slotted(sken-layout-region[name='sidebar']) {\n border-inline-end: none;\n border-inline-start: 1px solid\n var(--sken-border, color-mix(in srgb, currentColor 12%, transparent));\n }\n\n /* ── Sidebar width override ─────────────────────────────────── */\n :host([sidebar-size='sm']) {\n --sken-layout-sidebar-width: ${unsafeCSS(SIDEBAR_WIDTH.sm)};\n }\n :host([sidebar-size='md']) {\n --sken-layout-sidebar-width: ${unsafeCSS(SIDEBAR_WIDTH.md)};\n }\n :host([sidebar-size='lg']) {\n --sken-layout-sidebar-width: ${unsafeCSS(SIDEBAR_WIDTH.lg)};\n }\n\n /* ── Variant-aware region hiding ─────────────────────────────\n Roles the active variant does not include are hidden\n outright. This way a consumer that always renders the\n same set of regions (e.g. a shared layout component) does\n not get phantom space when a page uses a different\n variant. */\n :host([variant='full-bleed']) ::slotted(sken-layout-region[name='topbar']),\n :host([variant='full-bleed']) ::slotted(sken-layout-region[name='primary-nav']),\n :host([variant='full-bleed']) ::slotted(sken-layout-region[name='sidebar']),\n :host([variant='full-bleed']) ::slotted(sken-layout-region[name='footer']) {\n display: none;\n }\n\n :host([variant='header-content']) ::slotted(sken-layout-region[name='primary-nav']),\n :host([variant='header-content']) ::slotted(sken-layout-region[name='sidebar']),\n :host([variant='header-content']) ::slotted(sken-layout-region[name='footer']) {\n display: none;\n }\n\n :host([variant='sidebar-content']) ::slotted(sken-layout-region[name='topbar']),\n :host([variant='sidebar-content']) ::slotted(sken-layout-region[name='primary-nav']),\n :host([variant='sidebar-content']) ::slotted(sken-layout-region[name='footer']) {\n display: none;\n }\n\n :host([variant='header-sidebar']) ::slotted(sken-layout-region[name='footer']) {\n display: none;\n }\n `\n\n override render() {\n const hasSidebar = this.#variantHasSidebar(this.variant)\n const bodyClasses = [\n 'body',\n hasSidebar ? 'with-sidebar' : '',\n hasSidebar && this.sidebarPosition === 'end' ? 'sidebar-end' : '',\n ]\n .filter(Boolean)\n .join(' ')\n\n return html`\n <div class=${bodyClasses} part=\"body\">\n <slot></slot>\n </div>\n `\n }\n\n /**\n * Single source of truth for which variants include a sidebar.\n * Used to apply the `.with-sidebar` class on the body grid\n * wrapper. Mirrors the per-variant CSS templates above.\n */\n #variantHasSidebar(variant: SkenLayoutVariant): boolean {\n return variant === 'sidebar-content' || variant === 'header-sidebar' || variant === 'header-sidebar-footer'\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sken-layout': SkenLayout\n }\n}\n"],"mappings":";;;;;AAmDA,IAAM,IAAuD;CAC3D,IAAI;CACJ,IAAI;CACJ,IAAI;AACN,GAGa,IAAN,cAAyB,EAAW;;EAKoD,aAJnC,KAAA,UAAA,kBACgC,KAAA,aAAA,SAE7C,KAAA,kBAAA,SACgD,KAAA,cAAA;;;EAE7E,KAAA,SAAA,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCA0HgB,EAAU,EAAc,EAAE,EAAE;;;qCAG5B,EAAU,EAAc,EAAE,EAAE;;;qCAG5B,EAAU,EAAc,EAAE,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiC/D,SAAkB;EAChB,IAAM,IAAa,KAAKA,GAAmB,KAAK,OAAO,GACjD,IAAc;GAClB;GACA,IAAa,iBAAiB;GAC9B,KAAc,KAAK,oBAAoB,QAAQ,gBAAgB;EACjE,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;EAEX,OAAO,CAAI;mBACI,EAAY;;;;CAI7B;CAOA,GAAmB,GAAqC;EACtD,OAAO,MAAY,qBAAqB,MAAY,oBAAoB,MAAY;CACtF;AACF;AAhMG,EAAA,CAAA,EAAS,EAAE,SAAS,GAAK,CAAC,CAAA,GAAA,EAAA,WAAA,WAAA,KAAA,CAAA,GAC1B,EAAA,CAAA,EAAS;CAAE,WAAW;CAAe,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,cAAA,KAAA,CAAA,GACpD,EAAA,CAAA,EAAS;CAAE,WAAW;CAAoB,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,mBAAA,KAAA,CAAA,GAEzD,EAAA,CAAA,EAAS;CAAE,WAAW;CAAgB,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,eAAA,KAAA,CAAA,GANvD,IAAA,EAAA,CAAA,EAAc,aAAa,CAAA,GAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"sken-layout.js","names":["#activeRoles","#hasSidebar"],"sources":["../src/components/sken-layout.ts"],"sourcesContent":["// ── <sken-layout> — structural layout primitive ────────────────────\n// Defines the page-level structure of a multi-region interface\n// (topbar, primary nav, sidebar, content, footer) without imposing\n// what lives inside each region. Composition by contract:\n//\n// <sken-layout variant=\"header-sidebar\">\n// <sken-layout-region name=\"topbar\">…</sken-layout-region>\n// <sken-layout-region name=\"primary-nav\">…</sken-layout-region>\n// <sken-layout-region name=\"sidebar\">…</sken-layout-region>\n// <sken-layout-region name=\"content\">…</sken-layout-region>\n// </sken-layout>\n//\n// Design notes (v0.3.10 — fix for SKEN-LAYOUT-REGIONS-RENDERING.md):\n// - The shadow root projects the consumer's light-DOM regions via\n// NAMED slots, one per role (topbar, primary-nav, sidebar,\n// content, footer). Each named slot sits inside a wrapper\n// element (e.g. <div class=\"topbar\">…</div>) that is the actual\n// grid item of the host's CSS grid. The wrapper is needed\n// because the consumer's <sken-layout-region> is `display:\n// contents` and would otherwise collapse the grid item away.\n// - Only the slots the active variant includes are rendered.\n// The single source of truth is SkenLayoutVariantRoles in\n// @sken-ds/contracts. Roles the variant does not include\n// simply do not appear in the shadow root, so the host's\n// grid template (which is fixed per variant) renders the\n// remaining rows at the height of their content.\n// - This is a behavioural fix over the previous design (single\n// unnamed slot + variant-aware `display: none` rules on\n// `::slotted()`), which placed every region inside the\n// `.body` sub-grid and therefore prevented the host's\n// `grid-template-areas` from placing them in the correct\n// row (the footer ended up next to the topbar in row 0).\n//\n// See ADR-0006 for the substrate decision. See the\n// @sken-ds/contracts types `SkenLayoutProps`, `SkenLayoutSlots`,\n// `SkenLayoutVariant`, `SkenLayoutVariantRoles` for the contract\n// surface.\n\nimport type {\n SkenLayoutDensity,\n SkenLayoutRegionRole,\n SkenLayoutSidebarPosition,\n SkenLayoutSidebarSize,\n SkenLayoutTopbarMode,\n SkenLayoutVariant,\n SkenLayoutVariantRolesMap,\n} from '@sken-ds/contracts'\nimport { SkenLayoutVariantRoles } from '@sken-ds/contracts'\nimport { LitElement, css, html, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport './sken-layout-region.js'\n\n/**\n * Sidebar width in `rem` per size concept. The product can\n * override with `--sken-layout-sidebar-width` (CSS custom\n * property) if it needs a different value.\n */\nconst SIDEBAR_WIDTH: Record<SkenLayoutSidebarSize, string> = {\n sm: '12rem',\n md: '16rem',\n lg: '20rem',\n}\n\n/**\n * Per-cell background tokens. The values reference the\n * Sken color tokens, not raw colors, so a theme switch\n * (`data-theme=\"dark\"`) recolors every cell without the\n * primitive knowing about it.\n *\n * Mapping rationale:\n * - topbar is on `--sken-card` (white) because it is the\n * \"elevated\" chrome; the border-bottom separates it from\n * the page below.\n * - primary-nav is on `--sken-background` (page colour) so\n * it sits flush with the page; the border-bottom separates\n * it from the workspace.\n * - sidebar is on `--sken-muted` (subtle off-white) with a\n * border-inline-end; it is a \"rail\", not a \"page\".\n * - content is on `--sken-background`; no border (the\n * workspace is unbounded).\n * - footer is on `--sken-muted` with a border-top; it is\n * the same role as the sidebar (chrome).\n */\nconst REGION_BACKGROUND: Record<SkenLayoutRegionRole, string> = {\n topbar: 'var(--sken-card)',\n 'primary-nav': 'var(--sken-background)',\n sidebar: 'var(--sken-muted)',\n content: 'var(--sken-background)',\n footer: 'var(--sken-muted)',\n}\n\n@customElement('sken-layout')\nexport class SkenLayout extends LitElement {\n @property({ reflect: true }) variant: SkenLayoutVariant = 'header-content'\n @property({ attribute: 'topbar-mode', reflect: true }) topbarMode: SkenLayoutTopbarMode = 'fixed'\n @property({ attribute: 'sidebar-position', reflect: true })\n sidebarPosition: SkenLayoutSidebarPosition = 'start'\n @property({ attribute: 'sidebar-size', reflect: true }) sidebarSize: SkenLayoutSidebarSize = 'md'\n @property({ reflect: true }) density: SkenLayoutDensity = 'none'\n\n /**\n * Roles the active variant renders in the shadow root. Sourced\n * from {@link SkenLayoutVariantRoles}. Used to drive the\n * template (only the slots the variant includes are projected)\n * and to apply the per-variant `with-sidebar` class on the\n * body sub-grid wrapper.\n */\n get #activeRoles(): readonly SkenLayoutRegionRole[] {\n return (SkenLayoutVariantRoles as SkenLayoutVariantRolesMap)[this.variant]\n }\n\n /** True if the active variant renders a sidebar region. */\n get #hasSidebar(): boolean {\n return this.#activeRoles.includes('sidebar')\n }\n\n static styles = css`\n /* ── The host ────────────────────────────────────────────────\n The host owns the page-level grid. The topbar / primary-nav\n / footer sit in their own rows; the body is a sub-grid that\n holds the sidebar (when present) and the content. */\n :host {\n display: grid;\n block-size: 100dvh;\n grid-template-columns: 1fr;\n grid-template-rows: auto 1fr;\n grid-template-areas:\n 'topbar'\n 'body';\n background: var(--sken-background, Canvas);\n color: var(--sken-foreground, CanvasText);\n font-family: var(--sken-family-sans, system-ui, sans-serif);\n }\n\n /* ── Per-cell grid items ─────────────────────────────────────\n Each named slot sits inside a wrapper element that is the\n actual grid item. The wrapper's class matches the role\n (topbar, primary-nav, body, footer). The variant rules\n below assign the right 'grid-area' to each role. The\n 'display: contents' <sken-layout-region> is projected\n through the named <slot> and inherits the wrapper's\n background, border, and padding. */\n .topbar {\n grid-area: topbar;\n background: var(\n --sken-layout-region-topbar-background,\n ${unsafeCSS(REGION_BACKGROUND.topbar)}\n );\n padding-block: var(--sken-layout-region-topbar-padding-block, 0);\n padding-inline: var(--sken-layout-region-topbar-padding-inline, 0);\n border-bottom: 1px solid var(--sken-border);\n }\n .primary-nav {\n grid-area: primary-nav;\n background: var(\n --sken-layout-region-primary-nav-background,\n ${unsafeCSS(REGION_BACKGROUND['primary-nav'])}\n );\n padding-block: var(--sken-layout-region-primary-nav-padding-block, 0);\n padding-inline: var(--sken-layout-region-primary-nav-padding-inline, 0);\n border-bottom: 1px solid var(--sken-border);\n }\n .body {\n display: grid;\n grid-template-columns: 1fr;\n grid-template-areas: 'content';\n min-block-size: 0; /* allow children to shrink + scroll */\n }\n .body.with-sidebar {\n grid-template-columns: var(--sken-layout-sidebar-width, 16rem) 1fr;\n grid-template-areas: 'sidebar content';\n }\n .body.with-sidebar.sidebar-end {\n grid-template-columns: 1fr var(--sken-layout-sidebar-width, 16rem);\n grid-template-areas: 'content sidebar';\n }\n .sidebar {\n grid-area: sidebar;\n min-block-size: 0;\n background: var(\n --sken-layout-region-sidebar-background,\n ${unsafeCSS(REGION_BACKGROUND.sidebar)}\n );\n padding-block: var(--sken-layout-region-sidebar-padding-block, 0);\n padding-inline: var(--sken-layout-region-sidebar-padding-inline, 0);\n border-inline-end: 1px solid var(--sken-border);\n }\n .content {\n grid-area: content;\n min-block-size: 0;\n background: var(\n --sken-layout-region-content-background,\n ${unsafeCSS(REGION_BACKGROUND.content)}\n );\n padding-block: var(--sken-layout-region-content-padding-block, 0);\n padding-inline: var(--sken-layout-region-content-padding-inline, 0);\n }\n .footer {\n grid-area: footer;\n background: var(\n --sken-layout-region-footer-background,\n ${unsafeCSS(REGION_BACKGROUND.footer)}\n );\n padding-block: var(--sken-layout-region-footer-padding-block, 0);\n padding-inline: var(--sken-layout-region-footer-padding-inline, 0);\n border-top: 1px solid var(--sken-border);\n }\n\n /* ── Density: comfortable ─────────────────────────────────────\n When density=comfortable, the layout applies the Sken\n default rhythm: 8/16px on chrome cells, 16/24px on the\n content area, 12/16px on the footer. The values come\n from the spacing scale (--sken-2, --sken-3, --sken-4,\n --sken-6) so a single token change ripples through\n every cell. A consumer override on any\n --sken-layout-region-{role}-padding-{block|inline}\n always wins over the density preset. */\n :host([density='comfortable']) .topbar,\n :host([density='comfortable']) .primary-nav,\n :host([density='comfortable']) .content,\n :host([density='comfortable']) .sidebar,\n :host([density='comfortable']) .footer {\n --sken-layout-region-topbar-padding-block: var(--sken-2);\n --sken-layout-region-topbar-padding-inline: var(--sken-4);\n --sken-layout-region-primary-nav-padding-block: var(--sken-2);\n --sken-layout-region-primary-nav-padding-inline: var(--sken-4);\n --sken-layout-region-sidebar-padding-block: var(--sken-4);\n --sken-layout-region-sidebar-padding-inline: var(--sken-4);\n --sken-layout-region-content-padding-block: var(--sken-6);\n --sken-layout-region-content-padding-inline: var(--sken-6);\n --sken-layout-region-footer-padding-block: var(--sken-3);\n --sken-layout-region-footer-padding-inline: var(--sken-4);\n }\n\n /* ── Density: compact ────────────────────────────────────────\n When density=compact, every per-cell padding is halved\n from the comfortable value. We use calc(var(--sken-N) *\n 0.5) instead of hardcoded half-values so a future\n token change automatically cascades. As with\n comfortable, a consumer override on any\n --sken-layout-region-{role}-padding-{block|inline}\n always wins. */\n :host([density='compact']) .topbar,\n :host([density='compact']) .primary-nav,\n :host([density='compact']) .content,\n :host([density='compact']) .sidebar,\n :host([density='compact']) .footer {\n --sken-layout-region-topbar-padding-block: calc(var(--sken-2) * 0.5);\n --sken-layout-region-topbar-padding-inline: calc(var(--sken-4) * 0.5);\n --sken-layout-region-primary-nav-padding-block: calc(var(--sken-2) * 0.5);\n --sken-layout-region-primary-nav-padding-inline: calc(var(--sken-4) * 0.5);\n --sken-layout-region-sidebar-padding-block: calc(var(--sken-4) * 0.5);\n --sken-layout-region-sidebar-padding-inline: calc(var(--sken-4) * 0.5);\n --sken-layout-region-content-padding-block: calc(var(--sken-6) * 0.5);\n --sken-layout-region-content-padding-inline: calc(var(--sken-6) * 0.5);\n --sken-layout-region-footer-padding-block: calc(var(--sken-3) * 0.5);\n --sken-layout-region-footer-padding-inline: calc(var(--sken-4) * 0.5);\n }\n\n /* ── Grid templates per variant ───────────────────────────────\n Each variant declares which rows the host grid reserves.\n The default host grid is 2 rows (topbar + body); variants\n that include primary-nav or footer add more rows. Rows\n with no rendered content (e.g. footer on a variant that\n does not include a footer) collapse to 0 because the\n variant does not render the matching wrapper, and an\n empty 'auto' row in a grid takes the height of its\n content (which is 0). */\n :host([variant='full-bleed']) {\n grid-template-areas: 'body';\n grid-template-rows: 1fr;\n }\n :host([variant='header-content']) {\n grid-template-areas:\n 'topbar'\n 'body';\n grid-template-rows: auto 1fr;\n }\n :host([variant='sidebar-content']) {\n grid-template-rows: 1fr;\n grid-template-areas: 'body';\n }\n :host([variant='header-sidebar']) {\n grid-template-rows: auto auto 1fr;\n grid-template-areas:\n 'topbar'\n 'primary-nav'\n 'body';\n }\n :host([variant='header-sidebar-footer']) {\n grid-template-rows: auto auto 1fr auto;\n grid-template-areas:\n 'topbar'\n 'primary-nav'\n 'body'\n 'footer';\n }\n\n /* ── Topbar mode ──────────────────────────────────────────────\n 'fixed': the host is 100dvh and the body scrolls under the\n topbar. This is the default for admin consoles.\n 'auto': the topbar scrolls away with the page (marketing,\n landing). */\n :host([topbar-mode='auto']) {\n block-size: auto;\n min-block-size: 100dvh;\n }\n\n /* ── Sidebar position ─────────────────────────────────────────\n When the sidebar sits on the inline-end side, the border\n moves to the inline-start side. The default rule above\n already paints the border on the inline-end; here we\n swap it. */\n :host([sidebar-position='end']) .sidebar {\n border-inline-end: none;\n border-inline-start: 1px solid var(--sken-border);\n }\n\n /* ── Sidebar width override ─────────────────────────────────── */\n :host([sidebar-size='sm']) {\n --sken-layout-sidebar-width: ${unsafeCSS(SIDEBAR_WIDTH.sm)};\n }\n :host([sidebar-size='md']) {\n --sken-layout-sidebar-width: ${unsafeCSS(SIDEBAR_WIDTH.md)};\n }\n :host([sidebar-size='lg']) {\n --sken-layout-sidebar-width: ${unsafeCSS(SIDEBAR_WIDTH.lg)};\n }\n `\n\n override render() {\n const roles = this.#activeRoles\n const hasSidebar = this.#hasSidebar\n const bodyClasses = [\n 'body',\n hasSidebar ? 'with-sidebar' : '',\n hasSidebar && this.sidebarPosition === 'end' ? 'sidebar-end' : '',\n ]\n .filter(Boolean)\n .join(' ')\n\n return html`\n ${\n roles.includes('topbar')\n ? html`<div class=\"topbar\" part=\"topbar\">\n <slot name=\"topbar\"></slot>\n </div>`\n : ''\n }\n ${\n roles.includes('primary-nav')\n ? html`<div class=\"primary-nav\" part=\"primary-nav\">\n <slot name=\"primary-nav\"></slot>\n </div>`\n : ''\n }\n <div class=${bodyClasses} part=\"body\">\n ${\n hasSidebar\n ? html`<div class=\"sidebar\" part=\"sidebar\">\n <slot name=\"sidebar\"></slot>\n </div>`\n : ''\n }\n <div class=\"content\" part=\"content\">\n <slot name=\"content\"></slot>\n </div>\n </div>\n ${\n roles.includes('footer')\n ? html`<div class=\"footer\" part=\"footer\">\n <slot name=\"footer\"></slot>\n </div>`\n : ''\n }\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sken-layout': SkenLayout\n }\n}\n"],"mappings":";;;;;;AAyDA,IAAM,IAAuD;CAC3D,IAAI;CACJ,IAAI;CACJ,IAAI;AACN,GAsBM,IAA0D;CAC9D,QAAQ;CACR,eAAe;CACf,SAAS;CACT,SAAS;CACT,QAAQ;AACV,GAGa,IAAN,cAAyB,EAAW;;EAMiB,aALA,KAAA,UAAA,kBACgC,KAAA,aAAA,SAE7C,KAAA,kBAAA,SACgD,KAAA,cAAA,MACnC,KAAA,UAAA;;CAS1D,IAAIA,KAAgD;EAClD,OAAQ,EAAqD,KAAK;CACpE;CAGA,IAAIC,KAAuB;EACzB,OAAO,KAAKD,GAAa,SAAS,SAAS;CAC7C;;EAEgB,KAAA,SAAA,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA8BX,EAAU,EAAkB,MAAM,EAAE;;;;;;;;;;UAUpC,EAAU,EAAkB,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;UAyB5C,EAAU,EAAkB,OAAO,EAAE;;;;;;;;;;;UAWrC,EAAU,EAAkB,OAAO,EAAE;;;;;;;;;UASrC,EAAU,EAAkB,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAuHT,EAAU,EAAc,EAAE,EAAE;;;qCAG5B,EAAU,EAAc,EAAE,EAAE;;;qCAG5B,EAAU,EAAc,EAAE,EAAE;;;;CAI/D,SAAkB;EAChB,IAAM,IAAQ,KAAKA,IACb,IAAa,KAAKC,IAClB,IAAc;GAClB;GACA,IAAa,iBAAiB;GAC9B,KAAc,KAAK,oBAAoB,QAAQ,gBAAgB;EACjE,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;EAEX,OAAO,CAAI;QAEP,EAAM,SAAS,QAAQ,IACnB,CAAI;;sBAGJ,GACL;QAEC,EAAM,SAAS,aAAa,IACxB,CAAI;;sBAGJ,GACL;mBACY,EAAY;UAErB,IACI,CAAI;;wBAGJ,GACL;;;;;QAMD,EAAM,SAAS,QAAQ,IACnB,CAAI;;sBAGJ,GACL;;CAEL;AACF;AA5RG,EAAA,CAAA,EAAS,EAAE,SAAS,GAAK,CAAC,CAAA,GAAA,EAAA,WAAA,WAAA,KAAA,CAAA,GAC1B,EAAA,CAAA,EAAS;CAAE,WAAW;CAAe,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,cAAA,KAAA,CAAA,GACpD,EAAA,CAAA,EAAS;CAAE,WAAW;CAAoB,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,mBAAA,KAAA,CAAA,GAEzD,EAAA,CAAA,EAAS;CAAE,WAAW;CAAgB,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,eAAA,KAAA,CAAA,GACrD,EAAA,CAAA,EAAS,EAAE,SAAS,GAAK,CAAC,CAAA,GAAA,EAAA,WAAA,WAAA,KAAA,CAAA,GAP5B,IAAA,EAAA,CAAA,EAAc,aAAa,CAAA,GAAA,CAAA"}
|
|
@@ -208,7 +208,9 @@ var s = 1, c = !0, l = class extends t {
|
|
|
208
208
|
buttons from being squashed when the host's vertical
|
|
209
209
|
rhythm is tight (sm). The explicit block-size wins. */
|
|
210
210
|
flex-shrink: 0;
|
|
211
|
-
transition:
|
|
211
|
+
transition:
|
|
212
|
+
color 120ms ease,
|
|
213
|
+
background-color 120ms ease;
|
|
212
214
|
}
|
|
213
215
|
|
|
214
216
|
.stepper:hover:not(:disabled) {
|
|
@@ -408,10 +410,10 @@ var s = 1, c = !0, l = class extends t {
|
|
|
408
410
|
return r`
|
|
409
411
|
<div class="field" part="field">
|
|
410
412
|
${this.label ? r`
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
413
|
+
<label class="label" part="label" data-required=${this.required}>
|
|
414
|
+
${this.label}
|
|
415
|
+
</label>
|
|
416
|
+
` : i}
|
|
415
417
|
<div class="input-wrapper" part="wrapper">
|
|
416
418
|
<div class="slot slot-start" part="slot-start">
|
|
417
419
|
<slot name="start"></slot>
|
|
@@ -441,49 +443,37 @@ var s = 1, c = !0, l = class extends t {
|
|
|
441
443
|
<slot name="end"></slot>
|
|
442
444
|
</div>
|
|
443
445
|
${this.showStepperButtons ? r`
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
446
|
+
<div class="steppers" part="steppers">
|
|
447
|
+
<button
|
|
448
|
+
class="stepper"
|
|
449
|
+
part="stepper stepper-up"
|
|
450
|
+
type="button"
|
|
451
|
+
aria-label="Increment"
|
|
452
|
+
?disabled=${this.disabled || this.readonly || this.value !== void 0 && this.max !== void 0 && this.value >= this.max}
|
|
453
|
+
@click=${this.#p}
|
|
454
|
+
>
|
|
455
|
+
+
|
|
456
|
+
</button>
|
|
457
|
+
<button
|
|
458
|
+
class="stepper"
|
|
459
|
+
part="stepper stepper-down"
|
|
460
|
+
type="button"
|
|
461
|
+
aria-label="Decrement"
|
|
462
|
+
?disabled=${this.disabled || this.readonly || this.value !== void 0 && this.min !== void 0 && this.value <= this.min}
|
|
463
|
+
@click=${this.#m}
|
|
464
|
+
>
|
|
465
|
+
−
|
|
466
|
+
</button>
|
|
467
|
+
</div>
|
|
468
|
+
` : i}
|
|
467
469
|
</div>
|
|
468
|
-
${e.length > 0 ? r`
|
|
469
|
-
<div class="messages" part="messages">${e}</div>
|
|
470
|
-
` : i}
|
|
470
|
+
${e.length > 0 ? r` <div class="messages" part="messages">${e}</div> ` : i}
|
|
471
471
|
</div>
|
|
472
472
|
`;
|
|
473
473
|
}
|
|
474
474
|
#s() {
|
|
475
475
|
let e = [];
|
|
476
|
-
return this.invalidText && e.push(r`<p class="message" data-tone="invalid" part="message-invalid"
|
|
477
|
-
${this.invalidText}
|
|
478
|
-
</p>`), this.warningText && e.push(r`<p class="message" data-tone="warning" part="message-warning">
|
|
479
|
-
${this.warningText}
|
|
480
|
-
</p>`), this.infoText && e.push(r`<p class="message" data-tone="info" part="message-info">
|
|
481
|
-
${this.infoText}
|
|
482
|
-
</p>`), this.validText && e.push(r`<p class="message" data-tone="valid" part="message-valid">
|
|
483
|
-
${this.validText}
|
|
484
|
-
</p>`), this.helperText && e.length === 0 && e.push(r`<p class="message" data-tone="helper" part="message-helper">
|
|
485
|
-
${this.helperText}
|
|
486
|
-
</p>`), e;
|
|
476
|
+
return this.invalidText && e.push(r`<p class="message" data-tone="invalid" part="message-invalid">${this.invalidText}</p>`), this.warningText && e.push(r`<p class="message" data-tone="warning" part="message-warning">${this.warningText}</p>`), this.infoText && e.push(r`<p class="message" data-tone="info" part="message-info">${this.infoText}</p>`), this.validText && e.push(r`<p class="message" data-tone="valid" part="message-valid">${this.validText}</p>`), this.helperText && e.length === 0 && e.push(r`<p class="message" data-tone="helper" part="message-helper">${this.helperText}</p>`), e;
|
|
487
477
|
}
|
|
488
478
|
#c;
|
|
489
479
|
#l;
|