@0001-labs/design-system-1 0.3.0 → 0.3.1
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/DS1/0-face/constraint-panel.ts +27 -6
- package/DS1/0-face/constraint-site.ts +3 -2
- package/DS1/0-face/constraints.ts +27 -0
- package/DS1/0-face/define.ts +1 -1
- package/DS1/0-face/fault-lines.ts +159 -0
- package/DS1/1-root/cjk.css +1 -1
- package/DS1/1-root/fonts.css +1 -1
- package/DS1/1-root/one.css +3 -2
- package/DS1/2-core/ds-avatar.ts +47 -8
- package/DS1/2-core/styles/ds-button-host.css +2 -1
- package/DS1/2-core/styles/ds-button.css +2 -1
- package/DS1/2-core/styles/ds-tag.css +2 -1
- package/DS1/3-unit/context-trigger.ts +29 -2
- package/DS1/3-unit/ds-form.ts +2 -1
- package/DS1/3-unit/ds-table.ts +2 -1
- package/DS1/4-page/ds-container.ts +2 -1
- package/dist/0-face/constraint-panel.d.ts.map +1 -1
- package/dist/0-face/constraint-panel.js +28 -6
- package/dist/0-face/constraint-site.d.ts +1 -0
- package/dist/0-face/constraint-site.d.ts.map +1 -1
- package/dist/0-face/constraint-site.js +3 -2
- package/dist/0-face/constraints.d.ts.map +1 -1
- package/dist/0-face/constraints.js +27 -0
- package/dist/0-face/define.js +1 -1
- package/dist/0-face/fault-lines.d.ts +20 -0
- package/dist/0-face/fault-lines.d.ts.map +1 -0
- package/dist/0-face/fault-lines.js +172 -0
- package/dist/2-core/ds-avatar.d.ts +5 -0
- package/dist/2-core/ds-avatar.d.ts.map +1 -1
- package/dist/2-core/ds-avatar.js +53 -9
- package/dist/3-unit/context-trigger.d.ts.map +1 -1
- package/dist/3-unit/context-trigger.js +32 -2
- package/dist/3-unit/ds-form.d.ts.map +1 -1
- package/dist/3-unit/ds-form.js +2 -1
- package/dist/3-unit/ds-table.d.ts.map +1 -1
- package/dist/3-unit/ds-table.js +2 -1
- package/dist/4-page/ds-container.d.ts.map +1 -1
- package/dist/4-page/ds-container.js +2 -1
- package/dist/design-system-1.bundle.js +372 -32
- package/dist/design-system-1.bundle.js.map +1 -1
- package/dist/design-system-1.bundle.min.js +3380 -3128
- package/dist/design-system-1.bundle.min.js.map +1 -1
- package/package.json +6 -4
|
@@ -2260,6 +2260,198 @@ function initGridFit() {
|
|
|
2260
2260
|
fit();
|
|
2261
2261
|
}
|
|
2262
2262
|
//#endregion
|
|
2263
|
+
//#region DS1/0-face/fault-lines.ts
|
|
2264
|
+
var tolerance = 1;
|
|
2265
|
+
var near$1 = (a, b) => Math.abs(a - b) <= tolerance;
|
|
2266
|
+
var style = (el) => el.ownerDocument.defaultView.getComputedStyle(el);
|
|
2267
|
+
var visible$1 = (el) => {
|
|
2268
|
+
const box = el.getBoundingClientRect();
|
|
2269
|
+
return box.width > 0 && box.height > 0 && style(el).visibility !== "hidden" && style(el).display !== "none";
|
|
2270
|
+
};
|
|
2271
|
+
/** Walk each open shadow tree once; slotted children already occur in the light tree. */
|
|
2272
|
+
function elements(root) {
|
|
2273
|
+
return Array.from(root.querySelectorAll("*")).flatMap((el) => [el, ...el.shadowRoot ? elements(el.shadowRoot) : []]);
|
|
2274
|
+
}
|
|
2275
|
+
/** Related grids opt in by name; unlabelled card grids are candidates for human review. */
|
|
2276
|
+
function faultLineGrids(root) {
|
|
2277
|
+
return elements(root).flatMap((element) => {
|
|
2278
|
+
const family = element.getAttribute("data-ds-fault-lines");
|
|
2279
|
+
if (family === "off" || !visible$1(element)) return [];
|
|
2280
|
+
const children = Array.from(element.children).filter(visible$1);
|
|
2281
|
+
if (!children.length) return [];
|
|
2282
|
+
if (family === null && (!/grid/.test(style(element).display) || children.length < 2 || !children.every((child) => child.matches("ds-card, .ds-card, ds-button, button")))) return [];
|
|
2283
|
+
const axis = element.getAttribute("data-ds-fault-axis") === "y" ? "y" : "x";
|
|
2284
|
+
const boxes = children.map((child) => child.getBoundingClientRect());
|
|
2285
|
+
const crossStart = (box) => axis === "x" ? box.top : box.left;
|
|
2286
|
+
const crossEnd = (box) => axis === "x" ? box.bottom : box.right;
|
|
2287
|
+
const start = (box) => axis === "x" ? box.left : box.top;
|
|
2288
|
+
const end = (box) => axis === "x" ? box.right : box.bottom;
|
|
2289
|
+
const bands = [];
|
|
2290
|
+
for (const box of boxes.sort((a, b) => crossStart(a) - crossStart(b))) {
|
|
2291
|
+
const band = bands.find((row) => near$1(crossStart(row[0]), crossStart(box)));
|
|
2292
|
+
if (band) band.push(box);
|
|
2293
|
+
else bands.push([box]);
|
|
2294
|
+
}
|
|
2295
|
+
const band = [...bands].sort((a, b) => b.length - a.length)[0].sort((a, b) => start(a) - start(b));
|
|
2296
|
+
const lines = band.flatMap((box) => [start(box), end(box)]);
|
|
2297
|
+
const gaps = band.slice(1).map((box, index) => start(box) - end(band[index]));
|
|
2298
|
+
const crossGaps = bands.slice(1).map((row, index) => Math.min(...row.map(crossStart)) - Math.max(...bands[index].map(crossEnd)));
|
|
2299
|
+
const internalDrift = bands.some((row) => row.length === band.length && row.slice().sort((a, b) => start(a) - start(b)).some((box, index) => !near$1(start(box), lines[index * 2]) || !near$1(end(box), lines[index * 2 + 1]))) || crossGaps.some((gap) => !near$1(gap, crossGaps[0]));
|
|
2300
|
+
return [{
|
|
2301
|
+
element,
|
|
2302
|
+
family,
|
|
2303
|
+
axis,
|
|
2304
|
+
lines,
|
|
2305
|
+
gaps,
|
|
2306
|
+
crossGap: crossGaps[0],
|
|
2307
|
+
internalDrift,
|
|
2308
|
+
start: lines[0],
|
|
2309
|
+
end: lines[lines.length - 1]
|
|
2310
|
+
}];
|
|
2311
|
+
});
|
|
2312
|
+
}
|
|
2313
|
+
function referenceFor(grids, i) {
|
|
2314
|
+
const current = grids[i];
|
|
2315
|
+
return grids.slice(0, i).find((other) => {
|
|
2316
|
+
if (other.axis !== current.axis || other.lines.length !== current.lines.length) return false;
|
|
2317
|
+
if (current.family !== null || other.family !== null) return current.family !== null && current.family === other.family;
|
|
2318
|
+
return near$1(current.start, other.start) && near$1(current.end, other.end);
|
|
2319
|
+
});
|
|
2320
|
+
}
|
|
2321
|
+
/** Fault lines compare rendered tracks across separate sections, in the current viewport. */
|
|
2322
|
+
function inspectFaultLines(root) {
|
|
2323
|
+
const grids = faultLineGrids(root);
|
|
2324
|
+
const findings = [];
|
|
2325
|
+
for (let i = 0; i < grids.length; i++) {
|
|
2326
|
+
const current = grids[i];
|
|
2327
|
+
if (current.internalDrift) findings.push({
|
|
2328
|
+
element: current.element,
|
|
2329
|
+
...current.family === null ? { review: true } : {},
|
|
2330
|
+
message: `Fault lines at ${current.element.ownerDocument.documentElement.clientWidth}px: tracks or repeated gaps drift inside ${current.family || "this card grid"}. Align its complete rows and repeated spacing.`
|
|
2331
|
+
});
|
|
2332
|
+
const reference = referenceFor(grids, i);
|
|
2333
|
+
if (!reference) continue;
|
|
2334
|
+
const drift = current.lines.map((line, index) => Math.abs(line - reference.lines[index]));
|
|
2335
|
+
const gapDrift = current.gaps.some((gap, index) => !near$1(gap, reference.gaps[index]));
|
|
2336
|
+
const rowDrift = current.crossGap !== void 0 && reference.crossGap !== void 0 && !near$1(current.crossGap, reference.crossGap);
|
|
2337
|
+
if (!drift.some((value) => value > tolerance) && !gapDrift && !rowDrift) continue;
|
|
2338
|
+
const width = current.element.ownerDocument.documentElement.clientWidth;
|
|
2339
|
+
const review = current.family === null;
|
|
2340
|
+
findings.push({
|
|
2341
|
+
element: current.element,
|
|
2342
|
+
...review ? { review: true } : {},
|
|
2343
|
+
message: `Fault lines at ${width}px: ${current.family || "these card grids"} ${review ? "may be related but have" : "have"} misaligned ${current.axis === "x" ? "column" : "row"} edges or unequal gaps (edge drift ${Math.round(Math.max(...drift))}px; gaps ${current.gaps.map(Math.round).join("/")}px versus ${reference.gaps.map(Math.round).join("/")}px${rowDrift ? `; cross-axis gap ${Math.round(current.crossGap)}px versus ${Math.round(reference.crossGap)}px` : ""}). ${review ? "Name the related groups with data-ds-fault-lines to enforce alignment, or mark an intentional exception off." : "Use the same tracks and gap for this family at this viewport."}`
|
|
2344
|
+
});
|
|
2345
|
+
}
|
|
2346
|
+
return findings;
|
|
2347
|
+
}
|
|
2348
|
+
/** The same rendered geometry as the checker, painted without affecting layout or hit testing. */
|
|
2349
|
+
function paintFaultLines(root, layer) {
|
|
2350
|
+
const doc = layer.ownerDocument;
|
|
2351
|
+
const width = doc.documentElement.clientWidth;
|
|
2352
|
+
const height = doc.defaultView.innerHeight;
|
|
2353
|
+
layer.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
2354
|
+
layer.setAttribute("width", String(width));
|
|
2355
|
+
layer.setAttribute("height", String(height));
|
|
2356
|
+
layer.setAttribute("aria-hidden", "true");
|
|
2357
|
+
layer.style.cssText = "position:fixed;inset:0;pointer-events:none;overflow:hidden;z-index:2147483644";
|
|
2358
|
+
layer.replaceChildren();
|
|
2359
|
+
const grids = faultLineGrids(root);
|
|
2360
|
+
const failed = new Set(inspectFaultLines(root).map((finding) => finding.element));
|
|
2361
|
+
const drawn = /* @__PURE__ */ new Set();
|
|
2362
|
+
const referenceInk = "#087ba8";
|
|
2363
|
+
const faultInk = "#de0331";
|
|
2364
|
+
function mark(tag, attributes, title) {
|
|
2365
|
+
const node = doc.createElementNS("http://www.w3.org/2000/svg", tag);
|
|
2366
|
+
for (const [key, value] of Object.entries(attributes)) node.setAttribute(key, String(value));
|
|
2367
|
+
if (title) {
|
|
2368
|
+
const tip = doc.createElementNS(node.namespaceURI, "title");
|
|
2369
|
+
tip.textContent = title;
|
|
2370
|
+
node.appendChild(tip);
|
|
2371
|
+
}
|
|
2372
|
+
layer.appendChild(node);
|
|
2373
|
+
return node;
|
|
2374
|
+
}
|
|
2375
|
+
for (let index = 0; index < grids.length; index++) {
|
|
2376
|
+
const grid = grids[index];
|
|
2377
|
+
const reference = referenceFor(grids, index) ?? grid;
|
|
2378
|
+
for (const edge of reference.lines) {
|
|
2379
|
+
const key = `${grid.axis}:${edge}`;
|
|
2380
|
+
if (drawn.has(key)) continue;
|
|
2381
|
+
drawn.add(key);
|
|
2382
|
+
mark("line", {
|
|
2383
|
+
"data-fault-reference": "",
|
|
2384
|
+
x1: grid.axis === "x" ? edge : 0,
|
|
2385
|
+
y1: grid.axis === "y" ? edge : 0,
|
|
2386
|
+
x2: grid.axis === "x" ? edge : width,
|
|
2387
|
+
y2: grid.axis === "y" ? edge : height,
|
|
2388
|
+
stroke: referenceInk,
|
|
2389
|
+
"stroke-width": 1,
|
|
2390
|
+
"stroke-dasharray": "4 4"
|
|
2391
|
+
}, "Reference edge");
|
|
2392
|
+
}
|
|
2393
|
+
if (!failed.has(grid.element)) continue;
|
|
2394
|
+
for (const child of Array.from(grid.element.children).filter(visible$1)) {
|
|
2395
|
+
const box = child.getBoundingClientRect();
|
|
2396
|
+
const edges = grid.axis === "x" ? [box.left, box.right] : [box.top, box.bottom];
|
|
2397
|
+
for (const edge of edges) {
|
|
2398
|
+
if (reference.lines.some((expected) => near$1(edge, expected))) continue;
|
|
2399
|
+
mark("line", {
|
|
2400
|
+
"data-fault-actual": "",
|
|
2401
|
+
x1: grid.axis === "x" ? edge : box.left,
|
|
2402
|
+
y1: grid.axis === "y" ? edge : box.top,
|
|
2403
|
+
x2: grid.axis === "x" ? edge : box.right,
|
|
2404
|
+
y2: grid.axis === "y" ? edge : box.bottom,
|
|
2405
|
+
stroke: faultInk,
|
|
2406
|
+
"stroke-width": 2
|
|
2407
|
+
}, "Actual edge differs from the dashed reference");
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
const rows = [];
|
|
2411
|
+
for (const child of Array.from(grid.element.children).filter(visible$1)) {
|
|
2412
|
+
const box = child.getBoundingClientRect();
|
|
2413
|
+
const start = grid.axis === "x" ? box.top : box.left;
|
|
2414
|
+
const row = rows.find((row) => near$1(grid.axis === "x" ? row[0].top : row[0].left, start));
|
|
2415
|
+
if (row) row.push(box);
|
|
2416
|
+
else rows.push([box]);
|
|
2417
|
+
}
|
|
2418
|
+
rows.sort((a, b) => grid.axis === "x" ? a[0].top - b[0].top : a[0].left - b[0].left);
|
|
2419
|
+
const bounds = grid.element.getBoundingClientRect();
|
|
2420
|
+
const crossGap = reference.crossGap ?? grid.crossGap;
|
|
2421
|
+
if (crossGap !== void 0) for (let row = 1; row < rows.length; row++) {
|
|
2422
|
+
const previousEnd = Math.max(...rows[row - 1].map((box) => grid.axis === "x" ? box.bottom : box.right));
|
|
2423
|
+
const actual = Math.min(...rows[row].map((box) => grid.axis === "x" ? box.top : box.left));
|
|
2424
|
+
const expected = previousEnd + crossGap;
|
|
2425
|
+
if (near$1(actual, expected)) continue;
|
|
2426
|
+
for (const [edge, kind] of [[expected, "reference"], [actual, "actual"]]) mark("line", {
|
|
2427
|
+
[`data-fault-${kind}`]: "",
|
|
2428
|
+
x1: grid.axis === "x" ? bounds.left : edge,
|
|
2429
|
+
y1: grid.axis === "x" ? edge : bounds.top,
|
|
2430
|
+
x2: grid.axis === "x" ? bounds.right : edge,
|
|
2431
|
+
y2: grid.axis === "x" ? edge : bounds.bottom,
|
|
2432
|
+
stroke: kind === "reference" ? referenceInk : faultInk,
|
|
2433
|
+
"stroke-width": kind === "reference" ? 1 : 2,
|
|
2434
|
+
"stroke-dasharray": kind === "reference" ? "4 4" : ""
|
|
2435
|
+
}, `Row gap ${Math.round(actual - previousEnd)}px; reference ${Math.round(crossGap)}px`);
|
|
2436
|
+
}
|
|
2437
|
+
const box = grid.element.getBoundingClientRect();
|
|
2438
|
+
const label = mark("text", {
|
|
2439
|
+
"data-fault-gap": "",
|
|
2440
|
+
x: Math.max(4, box.left),
|
|
2441
|
+
y: Math.max(16, Math.min(height - 4, box.top + 16)),
|
|
2442
|
+
fill: faultInk,
|
|
2443
|
+
stroke: "var(--ds-background-color, white)",
|
|
2444
|
+
"stroke-width": 3,
|
|
2445
|
+
"paint-order": "stroke",
|
|
2446
|
+
"font-family": "var(--ds-typeface-regular, sans-serif)",
|
|
2447
|
+
"font-size": 12
|
|
2448
|
+
});
|
|
2449
|
+
const gaps = grid.gaps.map((gap) => Math.round(gap)).join("/");
|
|
2450
|
+
const expected = reference.gaps.map((gap) => Math.round(gap)).join("/");
|
|
2451
|
+
label.textContent = `Gap ${gaps || "—"}px · reference ${expected || "—"}px` + (grid.crossGap !== void 0 && reference.crossGap !== void 0 && !near$1(grid.crossGap, reference.crossGap) ? ` · row gap ${Math.round(grid.crossGap)}px / ${Math.round(reference.crossGap)}px` : "");
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
//#endregion
|
|
2263
2455
|
//#region DS1/0-face/button-label.ts
|
|
2264
2456
|
function labelledButtons(root) {
|
|
2265
2457
|
return [...root.querySelectorAll("ds-button:not([icon]):not([split]),button:not(ds-button button),a[role=\"button\"]")].filter((button) => button.getBoundingClientRect().width && (button.textContent?.trim() || button.getAttribute("text")));
|
|
@@ -2635,6 +2827,11 @@ function inspectWordWrap(root) {
|
|
|
2635
2827
|
}
|
|
2636
2828
|
//#endregion
|
|
2637
2829
|
//#region DS1/0-face/constraints.ts
|
|
2830
|
+
/** The actual initial, including a component nested in another open shadow root. */
|
|
2831
|
+
function isAvatarInitial(element) {
|
|
2832
|
+
for (let parent = element; parent; parent = parent.assignedSlot ?? parent.parentElement ?? parent.getRootNode().host ?? null) if (parent.matches("ds-avatar, .ds-avatar")) return true;
|
|
2833
|
+
return false;
|
|
2834
|
+
}
|
|
2638
2835
|
/** A pixel either way is the same place. */
|
|
2639
2836
|
var near = (a, b) => Math.abs(a - b) <= 1;
|
|
2640
2837
|
var px = (n) => `${Math.round(n)}px`;
|
|
@@ -2697,6 +2894,19 @@ function rows(found) {
|
|
|
2697
2894
|
return groups.filter((row) => row.length > 1);
|
|
2698
2895
|
}
|
|
2699
2896
|
var constraints = [
|
|
2897
|
+
{
|
|
2898
|
+
code: "page.fault-lines",
|
|
2899
|
+
rule: "Fault lines keep related card and control grids aligned across the whole page, with matching track edges and gaps at every checked viewport width.",
|
|
2900
|
+
why: "Compare separate sections in the same alignment family; responsive layouts may change together, while unrelated groups and intentional exceptions remain independent.",
|
|
2901
|
+
components: ["ds-page"],
|
|
2902
|
+
check: {
|
|
2903
|
+
file: "tests/fault-lines.test.ts",
|
|
2904
|
+
test: "fault lines catch shifted tracks and unequal gaps across sections at each viewport"
|
|
2905
|
+
},
|
|
2906
|
+
measures: ["alignment group", "alignment groups"],
|
|
2907
|
+
count: (root) => faultLineGrids(root).length,
|
|
2908
|
+
inspect: inspectFaultLines
|
|
2909
|
+
},
|
|
2700
2910
|
{
|
|
2701
2911
|
code: "select.hug",
|
|
2702
2912
|
rule: "Select and date-picker triggers use hug sizing, never fill sizing or growing to occupy the available row.",
|
|
@@ -2759,6 +2969,19 @@ var constraints = [
|
|
|
2759
2969
|
count: (root) => measureTextContrast(root).length,
|
|
2760
2970
|
inspect: inspectTextContrast
|
|
2761
2971
|
},
|
|
2972
|
+
{
|
|
2973
|
+
code: "avatar.initial-contrast",
|
|
2974
|
+
rule: "Avatar initials have at least 4.5:1 contrast against their rendered fill, including after a theme or identity colour changes.",
|
|
2975
|
+
why: "Check each initial inside the avatar’s shadow root and in overlapping groups; decorative initials still need to be readable. Explicit ink overrides must pass too.",
|
|
2976
|
+
components: ["ds-avatar"],
|
|
2977
|
+
check: {
|
|
2978
|
+
file: "tests/avatar-contrast.test.ts",
|
|
2979
|
+
test: "avatar initials stay readable after theme and CSS-variable changes, and the avatar constraint catches overrides"
|
|
2980
|
+
},
|
|
2981
|
+
measures: ["avatar initial", "avatar initials"],
|
|
2982
|
+
count: (root) => measureTextContrast(root).filter((result) => isAvatarInitial(result.element)).length,
|
|
2983
|
+
inspect: (root) => inspectTextContrast(root).filter((finding) => isAvatarInitial(finding.element))
|
|
2984
|
+
},
|
|
2762
2985
|
{
|
|
2763
2986
|
code: "card.media-level",
|
|
2764
2987
|
rule: "A card's picture stands on the card's foot, a square below the words at least, so the pictures of cards side by side stand on one level whatever the words above them.",
|
|
@@ -2925,14 +3148,16 @@ function skillBlock(list = constraints) {
|
|
|
2925
3148
|
lines.push("", skillEnd);
|
|
2926
3149
|
return lines.join("\n");
|
|
2927
3150
|
}
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
3151
|
+
var VIEWPORT_WIDTHS = [
|
|
3152
|
+
...[
|
|
3153
|
+
320,
|
|
3154
|
+
375,
|
|
3155
|
+
393,
|
|
3156
|
+
430
|
|
3157
|
+
],
|
|
3158
|
+
768,
|
|
3159
|
+
1024,
|
|
3160
|
+
1440
|
|
2936
3161
|
];
|
|
2937
3162
|
/** An element as a person finds it: its tag, id and classes, and the start of its words. */
|
|
2938
3163
|
function describeElement(element) {
|
|
@@ -2972,7 +3197,7 @@ var wait = (ms) => new Promise((done) => setTimeout(done, ms));
|
|
|
2972
3197
|
* order of `widths`. The page reflows at each width without loading again. The address carries `ph=out`,
|
|
2973
3198
|
* the analytics opt-out most trackers honour, so the check counts no visits.
|
|
2974
3199
|
*/
|
|
2975
|
-
async function inspectInFrame(host, url, widths =
|
|
3200
|
+
async function inspectInFrame(host, url, widths = VIEWPORT_WIDTHS, height = 844) {
|
|
2976
3201
|
const frame = document.createElement("iframe");
|
|
2977
3202
|
frame.setAttribute("aria-hidden", "true");
|
|
2978
3203
|
frame.tabIndex = -1;
|
|
@@ -3032,7 +3257,7 @@ function checkPage(page) {
|
|
|
3032
3257
|
* each width as it comes. Stops starting pages when `signal` aborts. Whatever the pages store in this
|
|
3033
3258
|
* browser while they are checked is put back afterwards.
|
|
3034
3259
|
*/
|
|
3035
|
-
async function checkSite({ pages, widths =
|
|
3260
|
+
async function checkSite({ pages, widths = VIEWPORT_WIDTHS, inspect, onResult, signal, atOnce = 3 }) {
|
|
3036
3261
|
const kept = storedNow();
|
|
3037
3262
|
const results = [];
|
|
3038
3263
|
const total = pages.length * widths.length;
|
|
@@ -3149,7 +3374,8 @@ function createConstraintPanel() {
|
|
|
3149
3374
|
--danger: var(--ds-danger-color, light-dark(#de0331, #ff5f5f));
|
|
3150
3375
|
}
|
|
3151
3376
|
:host([hidden]) { display: none !important; }
|
|
3152
|
-
.
|
|
3377
|
+
.fault-lines { z-index: 0 !important; }
|
|
3378
|
+
.rings { z-index: 1; position: absolute; inset: 0; overflow: hidden; }
|
|
3153
3379
|
.frames { position: absolute; width: 0; height: 0; overflow: hidden; }
|
|
3154
3380
|
.ring {
|
|
3155
3381
|
position: absolute;
|
|
@@ -3171,6 +3397,7 @@ function createConstraintPanel() {
|
|
|
3171
3397
|
text-align: center;
|
|
3172
3398
|
}
|
|
3173
3399
|
aside {
|
|
3400
|
+
z-index: 2;
|
|
3174
3401
|
position: absolute;
|
|
3175
3402
|
inset-block: 0;
|
|
3176
3403
|
inset-inline-end: 0;
|
|
@@ -3217,14 +3444,18 @@ function createConstraintPanel() {
|
|
|
3217
3444
|
.code b { color: var(--danger); font-weight: 400; }
|
|
3218
3445
|
.rule { color: var(--muted); }
|
|
3219
3446
|
p { margin: 0; }
|
|
3447
|
+
:host([data-lines-only]) aside { inset-block: 0 auto; width: auto; padding: calc(var(--u) / 2); }
|
|
3448
|
+
:host([data-lines-only]) aside > :not(header), :host([data-lines-only]) header > :not([data-lines], [data-close]) { display: none; }
|
|
3449
|
+
:host([data-lines-only]) header { margin: 0; }
|
|
3220
3450
|
@media print { :host { display: none !important; } }
|
|
3221
|
-
</style><div class="rings"></div><div class="frames"></div><aside aria-label="Constraints">
|
|
3222
|
-
<header><strong>Constraints</strong><button type="button" data-run>Page</button><button type="button" data-site>Site</button><button type="button" data-close aria-label="Close">Close</button></header>
|
|
3223
|
-
<p data-status aria-live="polite"></p>
|
|
3451
|
+
</style><svg class="fault-lines" aria-hidden="true"></svg><div class="rings"></div><div class="frames"></div><aside aria-label="Constraints">
|
|
3452
|
+
<header><strong>Constraints</strong><button type="button" data-run>Page</button><button type="button" data-site>Site</button><button type="button" data-lines>Lines</button><button type="button" data-close aria-label="Close">Close</button></header>
|
|
3453
|
+
<p data-status aria-live="polite"></p><p class="rule">Fault lines: dashed reference · red drift</p>
|
|
3224
3454
|
<ol data-findings></ol>
|
|
3225
3455
|
<section data-rules hidden><h3>Rules</h3><ol></ol></section>
|
|
3226
3456
|
<section data-pages hidden><h3>Pages</h3><ol></ol></section>
|
|
3227
3457
|
</aside>`;
|
|
3458
|
+
const faultLines = shadow.querySelector(".fault-lines");
|
|
3228
3459
|
const rings = shadow.querySelector(".rings");
|
|
3229
3460
|
const list = shadow.querySelector("[data-findings]");
|
|
3230
3461
|
const rulesSection = shadow.querySelector("[data-rules]");
|
|
@@ -3234,6 +3465,12 @@ function createConstraintPanel() {
|
|
|
3234
3465
|
const status = shadow.querySelector("[data-status]");
|
|
3235
3466
|
const title = shadow.querySelector("strong");
|
|
3236
3467
|
const frames = shadow.querySelector(".frames");
|
|
3468
|
+
const linesButton = shadow.querySelector("[data-lines]");
|
|
3469
|
+
const setLinesOnly = (enabled) => {
|
|
3470
|
+
panel.toggleAttribute("data-lines-only", enabled);
|
|
3471
|
+
linesButton.textContent = enabled ? "Results" : "Lines";
|
|
3472
|
+
};
|
|
3473
|
+
linesButton.addEventListener("click", () => setLinesOnly(!panel.hasAttribute("data-lines-only")));
|
|
3237
3474
|
const siteButton = shadow.querySelector("[data-site]");
|
|
3238
3475
|
let site = null;
|
|
3239
3476
|
let findings = [];
|
|
@@ -3241,6 +3478,7 @@ function createConstraintPanel() {
|
|
|
3241
3478
|
let frame = 0;
|
|
3242
3479
|
const place = () => {
|
|
3243
3480
|
frame = 0;
|
|
3481
|
+
paintFaultLines(document, faultLines);
|
|
3244
3482
|
rings.replaceChildren(...findings.map(({ element }, index) => {
|
|
3245
3483
|
const rect = element.getBoundingClientRect();
|
|
3246
3484
|
const ring = document.createElement("div");
|
|
@@ -3256,6 +3494,8 @@ function createConstraintPanel() {
|
|
|
3256
3494
|
const schedule = () => {
|
|
3257
3495
|
if (!frame) frame = requestAnimationFrame(place);
|
|
3258
3496
|
};
|
|
3497
|
+
const layoutChanges = new MutationObserver(schedule);
|
|
3498
|
+
const sizeChanges = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(schedule);
|
|
3259
3499
|
const stopSite = () => {
|
|
3260
3500
|
site?.abort();
|
|
3261
3501
|
site = null;
|
|
@@ -3408,7 +3648,7 @@ function createConstraintPanel() {
|
|
|
3408
3648
|
title.textContent = "Constraints";
|
|
3409
3649
|
status.textContent = "Finding the pages…";
|
|
3410
3650
|
const pages = await findSitePages();
|
|
3411
|
-
const widths = `${
|
|
3651
|
+
const widths = `${VIEWPORT_WIDTHS.slice(0, -1).join(", ")} and ${VIEWPORT_WIDTHS[VIEWPORT_WIDTHS.length - 1]}px`;
|
|
3412
3652
|
let broken = 0;
|
|
3413
3653
|
const results = await checkSite({
|
|
3414
3654
|
pages,
|
|
@@ -3435,8 +3675,22 @@ function createConstraintPanel() {
|
|
|
3435
3675
|
const show = (mode = "page") => {
|
|
3436
3676
|
if (!panel.isConnected) document.body.appendChild(panel);
|
|
3437
3677
|
panel.hidden = false;
|
|
3678
|
+
setLinesOnly(window.innerWidth < 640);
|
|
3438
3679
|
if (mode === "site") runSite();
|
|
3439
3680
|
else run();
|
|
3681
|
+
layoutChanges.observe(document.body, {
|
|
3682
|
+
subtree: true,
|
|
3683
|
+
childList: true,
|
|
3684
|
+
attributes: true,
|
|
3685
|
+
attributeFilter: [
|
|
3686
|
+
"style",
|
|
3687
|
+
"class",
|
|
3688
|
+
"hidden",
|
|
3689
|
+
"data-ds-fault-lines",
|
|
3690
|
+
"data-ds-fault-axis"
|
|
3691
|
+
]
|
|
3692
|
+
});
|
|
3693
|
+
sizeChanges?.observe(document.body);
|
|
3440
3694
|
window.addEventListener("scroll", schedule, {
|
|
3441
3695
|
passive: true,
|
|
3442
3696
|
capture: true
|
|
@@ -3446,6 +3700,11 @@ function createConstraintPanel() {
|
|
|
3446
3700
|
const hide = () => {
|
|
3447
3701
|
stopSite();
|
|
3448
3702
|
panel.hidden = true;
|
|
3703
|
+
if (frame) cancelAnimationFrame(frame);
|
|
3704
|
+
frame = 0;
|
|
3705
|
+
faultLines.replaceChildren();
|
|
3706
|
+
layoutChanges.disconnect();
|
|
3707
|
+
sizeChanges?.disconnect();
|
|
3449
3708
|
window.removeEventListener("scroll", schedule, { capture: true });
|
|
3450
3709
|
window.removeEventListener("resize", schedule);
|
|
3451
3710
|
};
|
|
@@ -5030,7 +5289,7 @@ function define(name, element) {
|
|
|
5030
5289
|
const type = element;
|
|
5031
5290
|
const prototype = element.prototype;
|
|
5032
5291
|
const original = prototype.createRenderRoot;
|
|
5033
|
-
if (original) {
|
|
5292
|
+
if (original && typeof document !== "undefined") {
|
|
5034
5293
|
const definingDocument = document;
|
|
5035
5294
|
prototype.createRenderRoot = function() {
|
|
5036
5295
|
var _this$renderOptions;
|
|
@@ -5884,7 +6143,7 @@ _Badge.styles = r$4(ds_badge_default);
|
|
|
5884
6143
|
define("ds-badge", Badge);
|
|
5885
6144
|
//#endregion
|
|
5886
6145
|
//#region DS1/2-core/styles/ds-tag.css?inline
|
|
5887
|
-
var ds_tag_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n:host {\n display: inline-flex;\n flex: 0 0 auto;\n width: max-content;\n max-width: 100%;\n min-width: 0;\n vertical-align: bottom;\n /* The tag's own tokens, unset by default and in unscaled px: its height, side padding,\n corners and text size; --ds-tag-accent colours it. */\n --_tag-size: var(--ds-tag-size);\n --_tag-height: calc(var(--_tag-size) * var(--ds-sf, 1));\n --_tag-padding-size: var(--ds-tag-padding-size);\n --_tag-padding: calc(var(--_tag-padding-size) * var(--ds-sf, 1));\n --_tag-corner-size: var(--ds-tag-corner-size);\n --_tag-radius: calc(var(--_tag-corner-size) * var(--ds-sf, 1));\n --_tag-text-size: var(--ds-tag-text-size);\n --_tag-font-size: calc(var(--_tag-text-size) * var(--ds-sf, 1));\n}\n:host([hidden]) { display: none !important; }\n/* The face stays one control high at the foot of its box, on the lower sixteen,\n even when a row stretches the tag to a square. */\n.frame {\n display: block;\n align-self: flex-end;\n box-sizing: border-box;\n max-width: 100%;\n padding-inline: var(--_tag-padding, calc(4px * var(--ds-sf, 1)));\n border-radius: var(--_tag-radius, var(--ds-radius));\n background: var(--ds-tag-background, light-dark(color-mix(in srgb, var(--ds-tag-accent, var(--ds-grey, #7a7a7a)) 28%, white), color-mix(in srgb, var(--ds-tag-accent, var(--ds-grey, #7a7a7a)) 20%, var(--ds-black, #2a2a2a))));\n color: var(--ds-tag-color, light-dark(color-mix(in srgb, var(--ds-tag-accent, var(--ds-grey, #7a7a7a)) 45%, black), var(--ds-tag-accent, var(--ds-grey, #7a7a7a))));\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--_tag-font-size, var(--ds-type-size-default));\n line-height: var(--_tag-height, var(--ds-control-height));\n letter-spacing: var(--ds-type-letterspacing-default);\n overflow: hidden;\n text-overflow: clip;\n white-space: nowrap;\n}\n/* The words in a box of their own, so cut words fade over their last square\n while the fill stays whole; never an ellipsis (0-face/cut-fade.ts marks them). */\n.words {\n display: block;\n overflow: hidden;\n text-overflow: clip;\n white-space: nowrap;\n}\n.words[data-cut=\"end\"] {\n mask-image: linear-gradient(to right, #000 calc(100% - var(--ds-unit)), transparent);\n}\n:host(:dir(rtl)) .words[data-cut=\"end\"] {\n mask-image: linear-gradient(to left, #000 calc(100% - var(--ds-unit)), transparent);\n}\n";
|
|
6146
|
+
var ds_tag_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n:host {\n display: inline-flex;\n flex: 0 0 auto;\n width: max-content;\n max-width: 100%;\n min-width: 0;\n vertical-align: bottom;\n /* The tag's own tokens, unset by default and in unscaled px: its height, side padding,\n corners and text size; --ds-tag-accent colours it. */\n --_tag-size: var(--ds-tag-size);\n --_tag-height: calc(var(--_tag-size) * var(--ds-sf, 1));\n --_tag-padding-size: var(--ds-tag-padding-size);\n --_tag-padding: calc(var(--_tag-padding-size) * var(--ds-sf, 1));\n --_tag-corner-size: var(--ds-tag-corner-size);\n --_tag-radius: calc(var(--_tag-corner-size) * var(--ds-sf, 1));\n --_tag-text-size: var(--ds-tag-text-size);\n --_tag-font-size: calc(var(--_tag-text-size) * var(--ds-sf, 1));\n}\n:host([hidden]) { display: none !important; }\n/* The face stays one control high at the foot of its box, on the lower sixteen,\n even when a row stretches the tag to a square. */\n.frame {\n display: block;\n align-self: flex-end;\n box-sizing: border-box;\n max-width: 100%;\n padding-inline: var(--_tag-padding, calc(4px * var(--ds-sf, 1)));\n border-radius: var(--_tag-radius, var(--ds-radius));\n background: var(--ds-tag-background, light-dark(color-mix(in srgb, var(--ds-tag-accent, var(--ds-grey, #7a7a7a)) 28%, white), color-mix(in srgb, var(--ds-tag-accent, var(--ds-grey, #7a7a7a)) 20%, var(--ds-black, #2a2a2a))));\n /* Tint the dark-mode ink: raw grey/accent colours cannot meet 4.5:1 on this fill. */\n color: var(--ds-tag-color, light-dark(color-mix(in srgb, var(--ds-tag-accent, var(--ds-grey, #7a7a7a)) 45%, black), color-mix(in srgb, var(--ds-tag-accent, var(--ds-grey, #7a7a7a)) 30%, white)));\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--_tag-font-size, var(--ds-type-size-default));\n line-height: var(--_tag-height, var(--ds-control-height));\n letter-spacing: var(--ds-type-letterspacing-default);\n overflow: hidden;\n text-overflow: clip;\n white-space: nowrap;\n}\n/* The words in a box of their own, so cut words fade over their last square\n while the fill stays whole; never an ellipsis (0-face/cut-fade.ts marks them). */\n.words {\n display: block;\n overflow: hidden;\n text-overflow: clip;\n white-space: nowrap;\n}\n.words[data-cut=\"end\"] {\n mask-image: linear-gradient(to right, #000 calc(100% - var(--ds-unit)), transparent);\n}\n:host(:dir(rtl)) .words[data-cut=\"end\"] {\n mask-image: linear-gradient(to left, #000 calc(100% - var(--ds-unit)), transparent);\n}\n";
|
|
5888
6147
|
//#endregion
|
|
5889
6148
|
//#region DS1/2-core/ds-tag.ts
|
|
5890
6149
|
var _Tag;
|
|
@@ -6206,10 +6465,10 @@ _Control.properties = { disabled: {
|
|
|
6206
6465
|
} };
|
|
6207
6466
|
//#endregion
|
|
6208
6467
|
//#region DS1/2-core/styles/ds-button-host.css?inline
|
|
6209
|
-
var ds_button_host_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n/* ds-button.css */\n\n:host([control=\"host\"]),\n:host([control=\"slotted\"]) ::slotted(:is(button, a)) {\n box-sizing: border-box !important;\n display: inline-flex !important;\n align-items: center !important;\n justify-content: var(--ds-button-align, flex-start) !important;\n gap: var(--ds-button-gap, calc(4px * var(--ds-sf))) !important;\n min-width: 0 !important;\n max-width: 100% !important;\n height: var(--ds-button-height, var(--_button-height, var(--ds-control-height))) !important;\n /* Important, so a page's `* { padding: 0 }` reset cannot reach it: the\n padding is set through --ds-button-padding. */\n padding: var(--ds-button-padding, 0) !important;\n border-radius: var(--_button-radius, var(--ds-radius)) !important;\n corner-shape: var(--ds-corner-shape, round) !important;\n background: var(--ds-button-background, transparent) !important;\n color: var(--ds-button-color, var(--ds-button-text-color)) !important;\n font-family: var(--ds-typeface-regular) !important;\n font-feature-settings: var(--ds-font-features) !important;\n font-size: var(--_button-font-size, var(--ds-type-size-default)) !important;\n font-weight: var(--ds-type-weight-default) !important;\n line-height: var(--ds-type-lineheight-default) !important;\n letter-spacing: var(--ds-type-letterspacing-default) !important;\n white-space: nowrap !important;\n cursor: pointer !important;\n user-select: none !important;\n -webkit-user-select: none !important;\n -webkit-tap-highlight-color: transparent !important;\n outline: none !important;\n transition: opacity 120ms ease !important;\n}\n\n:host([control=\"host\"]) ::slotted(*) {\n flex: 0 0 auto !important;\n}\n\n:host([fit][control=\"slotted\"]) ::slotted(:is(button, a)) {\n width: max-content !important;\n min-width: var(--ds-button-min-width, 0px) !important;\n justify-content: var(--ds-button-align, flex-start) !important;\n}\n\n:host([control=\"host\"][primary]),\n:host([control=\"slotted\"][primary]) {\n --ds-button-padding: 0 var(--_button-padding, calc(var(--ds-button-inset, 4px) * var(--ds-sf)));\n --ds-button-background: var(--ds-button-primary-fill, var(--ds-button-background-color-primary));\n --ds-button-color: var(--ds-button-primary-text, var(--ds-button-text-color-on-accent));\n}\n\n:host([control=\"host\"][secondary]),\n:host([control=\"slotted\"][secondary]) {\n --ds-button-padding: 0 var(--_button-padding, calc(var(--ds-button-inset, 4px) * var(--ds-sf)));\n --ds-button-background: var(--ds-button-secondary-fill, var(--ds-button-background-color-secondary));\n}\n\n:host([control=\"host\"][secondary]:hover:not([disabled])),\n:host([control=\"slotted\"][secondary]:hover:not([disabled])) {\n --ds-button-background: var(--ds-fill-hover);\n}\n\n:host([control=\"host\"][active]),\n:host([control=\"slotted\"][active]) {\n --ds-button-background: var(--ds-fill);\n}\n\n/* A tab: muted until it is hovered or current. */\n:host([control=\"host\"][role=\"tab\"]),\n:host([control=\"host\"][choice]),\n:host([control=\"slotted\"][choice]) {\n --ds-button-padding: 0 calc(4px * var(--ds-sf));\n --ds-button-color: var(--ds-text-color-muted);\n}\n\n:host([control=\"host\"][role=\"tab\"]:hover:not([disabled])),\n:host([control=\"host\"][choice]:hover:not([disabled])),\n:host([control=\"slotted\"][choice]:hover:not([disabled])) {\n --ds-button-background: color-mix(in srgb, var(--ds-fill) 72%, transparent);\n --ds-button-color: var(--ds-text-color);\n}\n\n:host([control=\"host\"][role=\"tab\"][active]),\n:host([control=\"host\"][role=\"tab\"][active]:hover:not([disabled])),\n:host([control=\"host\"][choice][active]),\n:host([control=\"host\"][choice][active]:hover:not([disabled])),\n:host([control=\"slotted\"][choice][active]),\n:host([control=\"slotted\"][choice][active]:hover:not([disabled])) {\n --ds-button-background: var(--ds-fill);\n --ds-button-color: var(--ds-text-color);\n}\n\n:host([control=\"host\"]) ::slotted([slot=\"icon\"]) {\n display: inline-flex !important;\n align-items: center !important;\n justify-content: center !important;\n width: var(--ds-control-height) !important;\n height: var(--ds-control-height) !important;\n}\n\n:host([control=\"host\"]) ::slotted([slot=\"trailing\"]) {\n color: var(--ds-text-color-muted) !important;\n font-variant-numeric: tabular-nums !important;\n}\n\n:host([control=\"host\"][icon]),\n:host([control=\"slotted\"][icon]) {\n justify-content: center !important;\n width: var(--ds-button-height, var(--ds-control-height)) !important;\n height: var(--ds-button-height, var(--ds-control-height)) !important;\n padding: 0 !important;\n color: var(--ds-button-color, var(--ds-text-color-muted)) !important;\n}\n\n:host([control=\"host\"][icon]:hover:not([disabled])) {\n --ds-button-color: var(--ds-text-color);\n}\n\n/* A choice in a ds-menu: a full-width row, filled under the pointer or focus. */\n:host([control=\"host\"][role=\"option\"]),\n:host([control=\"host\"][role=\"menuitem\"]),\n:host([control=\"host\"][role=\"menuitemradio\"]),\n:host([control=\"host\"][role=\"menuitemcheckbox\"]) {\n --ds-button-height: auto;\n --ds-button-padding: calc(4px * var(--ds-sf)) calc(6px * var(--ds-sf));\n width: var(--ds-button-width, 100%) !important;\n min-height: var(--ds-row-height) !important;\n border-radius: var(--ds-radius) !important;\n}\n\n:host([control=\"host\"][role=\"option\"]:hover),\n:host([control=\"host\"][role=\"menuitem\"]:hover),\n:host([control=\"host\"][role=\"menuitemradio\"]:hover),\n:host([control=\"host\"][role=\"menuitemcheckbox\"]:hover),\n:host([control=\"host\"][role=\"option\"]:focus-visible),\n:host([control=\"host\"][role=\"menuitem\"]:focus-visible) {\n --ds-button-background: var(--ds-fill);\n outline: none !important;\n}\n\n:host([control=\"host\"][role=\"option\"][active]) {\n --ds-button-background: var(--ds-fill);\n}\n\n:host([control=\"host\"]:focus-visible),\n:host([control=\"slotted\"]) ::slotted(:is(button, a):focus-visible) {\n outline: 2px solid var(--ds-focus-ring) !important;\n outline-offset: 1px !important;\n}\n\n:host([control=\"host\"][disabled]),\n:host([control=\"slotted\"]) ::slotted(:is(button:disabled, a[aria-disabled=\"true\"])) {\n cursor: default !important;\n opacity: 0.5 !important;\n pointer-events: none !important;\n}\n\n/* The light-DOM button keeps native forms, submitters and fieldset semantics.\n DS1 owns its face; product layout belongs on the host. */\n:host([control=\"slotted\"]) ::slotted(:is(button, a)) {\n appearance: none !important;\n box-sizing: border-box !important;\n border: 0 !important;\n margin: 0 !important;\n width: 100% !important;\n min-height: var(--ds-button-height, var(--_button-height, var(--ds-control-height))) !important;\n max-height: var(--ds-button-height, var(--_button-height, var(--ds-control-height))) !important;\n box-shadow: none !important;\n text-align: start !important;\n text-transform: none !important;\n text-decoration: none !important;\n overflow: hidden !important;\n text-overflow: clip !important;\n}\n:host([control=\"slotted\"][icon]) ::slotted(:is(button, a)) {\n justify-content: center !important;\n}\n\n:host([control=\"slotted\"]) {\n /* The native focus ring extends beyond the face; only its text is clipped. */\n overflow: visible;\n /* The face is one control high, as the host and native faces are. Its box\n stays one square, as before, with the face at its foot, so the words take\n the lower sixteen of the square in a row or at the foot of a line and no\n row around it changes height. */\n align-items: flex-end;\n min-height: var(--ds-row-height);\n vertical-align: bottom;\n width: var(--ds-button-width, var(--_button-inline-size, max-content));\n}\n/* An icon's square: the face takes its first sixteen, the spare four above. */\n:host([control=\"slotted\"][icon]) {\n justify-content: flex-start !important;\n width: max(var(--ds-row-height), var(--ds-button-height, var(--ds-control-height))) !important;\n height: max(var(--ds-row-height), var(--ds-button-height, var(--ds-control-height))) !important;\n}\n:host([control=\"slotted\"][icon]) ::slotted(:is(button, a)) {\n width: var(--ds-button-height, var(--ds-control-height)) !important;\n}\n:host([control=\"slotted\"][fixed]) {\n width: var(--ds-button-width, calc(4 * var(--ds-unit)));\n}\n:host([control=\"slotted\"][wide]) {\n width: var(--ds-button-width, calc(8 * var(--ds-unit)));\n}\n:host([control=\"slotted\"][fit]) {\n width: max-content;\n}\n\n:host([control=\"host\"][danger]),\n:host([control=\"slotted\"][danger]) {\n --ds-button-color: var(--ds-danger-color, var(--ds-tuned-red));\n}\n\n:host([hidden]) { display: none !important; }\n\n/* Native actions in menus, including grouped and nested choices. */\n:host([menu-item]) {\n flex: 0 0 auto;\n width: 100%;\n --ds-button-height: var(--ds-row-height);\n --ds-button-align: flex-start;\n --ds-button-padding: 0 calc(4px * var(--ds-sf));\n}\n/* A row-high entry's words and icon stand on the lower sixteen, the spare four above. */\n:host([menu-item][control=\"host\"]),\n:host([menu-item][control=\"slotted\"]) ::slotted(:is(button, a)) {\n align-items: flex-end !important;\n}\n:host([menu-item]:is(:hover, :focus-within):not([disabled])) {\n --ds-button-background: var(--ds-fill);\n}\n:host([menu-item][control=\"slotted\"]) ::slotted([aria-checked=\"true\"]) {\n box-shadow: inset 0 0 0 1px var(--ds-focus-ring) !important;\n}\n\n/* A paper tab (`ds-tabs paper`): a row high with its words on the sixteen,\n rounded at the top only and square at the foot, where it joins the page. */\n:host([control=\"host\"][paper]),\n:host([control=\"slotted\"][paper]) ::slotted(:is(button, a)) {\n align-items: flex-end !important;\n border-start-start-radius: var(--ds-radius) !important;\n border-start-end-radius: var(--ds-radius) !important;\n border-end-start-radius: 0 !important;\n border-end-end-radius: 0 !important;\n}\n\n/* A tab in a joined run (`ds-tabs split`): square inside, rounded at the run's ends. */\n:host([control=\"host\"][segment]) {\n border-radius: 0 !important;\n}\n:host([control=\"host\"]:is([segment=\"first\"], [segment=\"only\"])) {\n border-start-start-radius: var(--ds-radius) !important;\n border-end-start-radius: var(--ds-radius) !important;\n}\n:host([control=\"host\"]:is([segment=\"last\"], [segment=\"only\"])) {\n border-start-end-radius: var(--ds-radius) !important;\n border-end-end-radius: var(--ds-radius) !important;\n}\n\n:host([control=\"host\"]:not([icon]):not([split]):not([menu-item])) {\n min-width: max-content !important;\n min-width: calc-size(max-content, round(up, size, var(--ds-unit))) !important;\n}\n:host([control=\"slotted\"]) ::slotted(:is(button, a)) {\n min-width: max-content !important;\n overflow: visible !important;\n}\n";
|
|
6468
|
+
var ds_button_host_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n/* ds-button.css */\n\n:host([control=\"host\"]),\n:host([control=\"slotted\"]) ::slotted(:is(button, a)) {\n box-sizing: border-box !important;\n display: inline-flex !important;\n align-items: center !important;\n justify-content: var(--ds-button-align, flex-start) !important;\n gap: var(--ds-button-gap, calc(4px * var(--ds-sf))) !important;\n min-width: 0 !important;\n max-width: 100% !important;\n height: var(--ds-button-height, var(--_button-height, var(--ds-control-height))) !important;\n /* Important, so a page's `* { padding: 0 }` reset cannot reach it: the\n padding is set through --ds-button-padding. */\n padding: var(--ds-button-padding, 0) !important;\n border-radius: var(--_button-radius, var(--ds-radius)) !important;\n corner-shape: var(--ds-corner-shape, round) !important;\n background: var(--ds-button-background, transparent) !important;\n color: var(--ds-button-color, var(--ds-button-text-color)) !important;\n font-family: var(--ds-typeface-regular) !important;\n font-feature-settings: var(--ds-font-features) !important;\n font-size: var(--_button-font-size, var(--ds-type-size-default)) !important;\n font-weight: var(--ds-type-weight-default) !important;\n line-height: var(--ds-type-lineheight-default) !important;\n letter-spacing: var(--ds-type-letterspacing-default) !important;\n white-space: nowrap !important;\n cursor: pointer !important;\n user-select: none !important;\n -webkit-user-select: none !important;\n -webkit-tap-highlight-color: transparent !important;\n outline: none !important;\n transition: opacity 120ms ease !important;\n}\n\n:host([control=\"host\"]) ::slotted(*) {\n flex: 0 0 auto !important;\n}\n\n:host([fit][control=\"slotted\"]) ::slotted(:is(button, a)) {\n /* The host hugs on the grid; its visible face must occupy that same box. */\n width: 100% !important;\n min-width: var(--ds-button-min-width, 0px) !important;\n justify-content: var(--ds-button-align, flex-start) !important;\n}\n\n:host([control=\"host\"][primary]),\n:host([control=\"slotted\"][primary]) {\n --ds-button-padding: 0 var(--_button-padding, calc(var(--ds-button-inset, 4px) * var(--ds-sf)));\n --ds-button-background: var(--ds-button-primary-fill, var(--ds-button-background-color-primary));\n --ds-button-color: var(--ds-button-primary-text, var(--ds-button-text-color-on-accent));\n}\n\n:host([control=\"host\"][secondary]),\n:host([control=\"slotted\"][secondary]) {\n --ds-button-padding: 0 var(--_button-padding, calc(var(--ds-button-inset, 4px) * var(--ds-sf)));\n --ds-button-background: var(--ds-button-secondary-fill, var(--ds-button-background-color-secondary));\n}\n\n:host([control=\"host\"][secondary]:hover:not([disabled])),\n:host([control=\"slotted\"][secondary]:hover:not([disabled])) {\n --ds-button-background: var(--ds-fill-hover);\n}\n\n:host([control=\"host\"][active]),\n:host([control=\"slotted\"][active]) {\n --ds-button-background: var(--ds-fill);\n}\n\n/* A tab: muted until it is hovered or current. */\n:host([control=\"host\"][role=\"tab\"]),\n:host([control=\"host\"][choice]),\n:host([control=\"slotted\"][choice]) {\n --ds-button-padding: 0 calc(4px * var(--ds-sf));\n --ds-button-color: var(--ds-text-color-muted);\n}\n\n:host([control=\"host\"][role=\"tab\"]:hover:not([disabled])),\n:host([control=\"host\"][choice]:hover:not([disabled])),\n:host([control=\"slotted\"][choice]:hover:not([disabled])) {\n --ds-button-background: color-mix(in srgb, var(--ds-fill) 72%, transparent);\n --ds-button-color: var(--ds-text-color);\n}\n\n:host([control=\"host\"][role=\"tab\"][active]),\n:host([control=\"host\"][role=\"tab\"][active]:hover:not([disabled])),\n:host([control=\"host\"][choice][active]),\n:host([control=\"host\"][choice][active]:hover:not([disabled])),\n:host([control=\"slotted\"][choice][active]),\n:host([control=\"slotted\"][choice][active]:hover:not([disabled])) {\n --ds-button-background: var(--ds-fill);\n --ds-button-color: var(--ds-text-color);\n}\n\n:host([control=\"host\"]) ::slotted([slot=\"icon\"]) {\n display: inline-flex !important;\n align-items: center !important;\n justify-content: center !important;\n width: var(--ds-control-height) !important;\n height: var(--ds-control-height) !important;\n}\n\n:host([control=\"host\"]) ::slotted([slot=\"trailing\"]) {\n color: var(--ds-text-color-muted) !important;\n font-variant-numeric: tabular-nums !important;\n}\n\n:host([control=\"host\"][icon]),\n:host([control=\"slotted\"][icon]) {\n justify-content: center !important;\n width: var(--ds-button-height, var(--ds-control-height)) !important;\n height: var(--ds-button-height, var(--ds-control-height)) !important;\n padding: 0 !important;\n color: var(--ds-button-color, var(--ds-text-color-muted)) !important;\n}\n\n:host([control=\"host\"][icon]:hover:not([disabled])) {\n --ds-button-color: var(--ds-text-color);\n}\n\n/* A choice in a ds-menu: a full-width row, filled under the pointer or focus. */\n:host([control=\"host\"][role=\"option\"]),\n:host([control=\"host\"][role=\"menuitem\"]),\n:host([control=\"host\"][role=\"menuitemradio\"]),\n:host([control=\"host\"][role=\"menuitemcheckbox\"]) {\n --ds-button-height: auto;\n --ds-button-padding: calc(4px * var(--ds-sf)) calc(6px * var(--ds-sf));\n width: var(--ds-button-width, 100%) !important;\n min-height: var(--ds-row-height) !important;\n border-radius: var(--ds-radius) !important;\n}\n\n:host([control=\"host\"][role=\"option\"]:hover),\n:host([control=\"host\"][role=\"menuitem\"]:hover),\n:host([control=\"host\"][role=\"menuitemradio\"]:hover),\n:host([control=\"host\"][role=\"menuitemcheckbox\"]:hover),\n:host([control=\"host\"][role=\"option\"]:focus-visible),\n:host([control=\"host\"][role=\"menuitem\"]:focus-visible) {\n --ds-button-background: var(--ds-fill);\n outline: none !important;\n}\n\n:host([control=\"host\"][role=\"option\"][active]) {\n --ds-button-background: var(--ds-fill);\n}\n\n:host([control=\"host\"]:focus-visible),\n:host([control=\"slotted\"]) ::slotted(:is(button, a):focus-visible) {\n outline: 2px solid var(--ds-focus-ring) !important;\n outline-offset: 1px !important;\n}\n\n:host([control=\"host\"][disabled]),\n:host([control=\"slotted\"]) ::slotted(:is(button:disabled, a[aria-disabled=\"true\"])) {\n cursor: default !important;\n opacity: 0.5 !important;\n pointer-events: none !important;\n}\n\n/* The light-DOM button keeps native forms, submitters and fieldset semantics.\n DS1 owns its face; product layout belongs on the host. */\n:host([control=\"slotted\"]) ::slotted(:is(button, a)) {\n appearance: none !important;\n box-sizing: border-box !important;\n border: 0 !important;\n margin: 0 !important;\n width: 100% !important;\n min-height: var(--ds-button-height, var(--_button-height, var(--ds-control-height))) !important;\n max-height: var(--ds-button-height, var(--_button-height, var(--ds-control-height))) !important;\n box-shadow: none !important;\n text-align: start !important;\n text-transform: none !important;\n text-decoration: none !important;\n overflow: hidden !important;\n text-overflow: clip !important;\n}\n:host([control=\"slotted\"][icon]) ::slotted(:is(button, a)) {\n justify-content: center !important;\n}\n\n:host([control=\"slotted\"]) {\n /* The native focus ring extends beyond the face; only its text is clipped. */\n overflow: visible;\n /* The face is one control high, as the host and native faces are. Its box\n stays one square, as before, with the face at its foot, so the words take\n the lower sixteen of the square in a row or at the foot of a line and no\n row around it changes height. */\n align-items: flex-end;\n min-height: var(--ds-row-height);\n vertical-align: bottom;\n width: var(--ds-button-width, var(--_button-inline-size, max-content));\n}\n/* An icon's square: the face takes its first sixteen, the spare four above. */\n:host([control=\"slotted\"][icon]) {\n justify-content: flex-start !important;\n width: max(var(--ds-row-height), var(--ds-button-height, var(--ds-control-height))) !important;\n height: max(var(--ds-row-height), var(--ds-button-height, var(--ds-control-height))) !important;\n}\n:host([control=\"slotted\"][icon]) ::slotted(:is(button, a)) {\n width: var(--ds-button-height, var(--ds-control-height)) !important;\n}\n:host([control=\"slotted\"][fixed]) {\n width: var(--ds-button-width, calc(4 * var(--ds-unit)));\n}\n:host([control=\"slotted\"][wide]) {\n width: var(--ds-button-width, calc(8 * var(--ds-unit)));\n}\n:host([control=\"slotted\"][fit]) {\n width: max-content;\n}\n\n:host([control=\"host\"][danger]),\n:host([control=\"slotted\"][danger]) {\n --ds-button-color: var(--ds-danger-color, var(--ds-tuned-red));\n}\n\n:host([hidden]) { display: none !important; }\n\n/* Native actions in menus, including grouped and nested choices. */\n:host([menu-item]) {\n flex: 0 0 auto;\n width: 100%;\n --ds-button-height: var(--ds-row-height);\n --ds-button-align: flex-start;\n --ds-button-padding: 0 calc(4px * var(--ds-sf));\n}\n/* A row-high entry's words and icon stand on the lower sixteen, the spare four above. */\n:host([menu-item][control=\"host\"]),\n:host([menu-item][control=\"slotted\"]) ::slotted(:is(button, a)) {\n align-items: flex-end !important;\n}\n:host([menu-item]:is(:hover, :focus-within):not([disabled])) {\n --ds-button-background: var(--ds-fill);\n}\n:host([menu-item][control=\"slotted\"]) ::slotted([aria-checked=\"true\"]) {\n box-shadow: inset 0 0 0 1px var(--ds-focus-ring) !important;\n}\n\n/* A paper tab (`ds-tabs paper`): a row high with its words on the sixteen,\n rounded at the top only and square at the foot, where it joins the page. */\n:host([control=\"host\"][paper]),\n:host([control=\"slotted\"][paper]) ::slotted(:is(button, a)) {\n align-items: flex-end !important;\n border-start-start-radius: var(--ds-radius) !important;\n border-start-end-radius: var(--ds-radius) !important;\n border-end-start-radius: 0 !important;\n border-end-end-radius: 0 !important;\n}\n\n/* A tab in a joined run (`ds-tabs split`): square inside, rounded at the run's ends. */\n:host([control=\"host\"][segment]) {\n border-radius: 0 !important;\n}\n:host([control=\"host\"]:is([segment=\"first\"], [segment=\"only\"])) {\n border-start-start-radius: var(--ds-radius) !important;\n border-end-start-radius: var(--ds-radius) !important;\n}\n:host([control=\"host\"]:is([segment=\"last\"], [segment=\"only\"])) {\n border-start-end-radius: var(--ds-radius) !important;\n border-end-end-radius: var(--ds-radius) !important;\n}\n\n:host([control=\"host\"]:not([icon]):not([split]):not([menu-item])) {\n min-width: max-content !important;\n min-width: calc-size(max-content, round(up, size, var(--ds-unit))) !important;\n}\n:host([control=\"slotted\"]) ::slotted(:is(button, a)) {\n min-width: max-content !important;\n overflow: visible !important;\n}\n";
|
|
6210
6469
|
//#endregion
|
|
6211
6470
|
//#region DS1/2-core/styles/ds-button.css?inline
|
|
6212
|
-
var ds_button_default = "/* ds-button.css */\n/* Core button component styles. The face is a <button>, or an <a> when the\n element has an href: both draw alike in every variant and state. */\n\n:host {\n display: inline-flex;\n /* At the foot of a line, so a 16px face takes the lower sixteen of the square. */\n vertical-align: bottom;\n min-width: 0;\n flex: 0 0 auto;\n width: var(--ds-button-width, var(--_button-inline-size, max-content));\n max-width: 100%;\n overflow: visible;\n /* The button's own tokens, unset by default and in unscaled px as --ds-control-size is,\n resolved here at this button's scale. Each face reads them first and falls back to its\n own measure, so a page that sets none draws exactly as before. --ds-button-inline-size is\n the width: unset hugs, 100% fills, a length is fixed. */\n --_button-size: var(--ds-button-size);\n --_button-height: calc(var(--_button-size) * var(--ds-sf));\n --_button-corner-size: var(--ds-button-corner-size);\n --_button-radius: calc(var(--_button-corner-size) * var(--ds-sf));\n --_button-text-size: var(--ds-button-text-size);\n --_button-font-size: calc(var(--_button-text-size) * var(--ds-sf));\n --_button-padding-size: var(--ds-button-padding-size);\n --_button-padding: calc(var(--_button-padding-size) * var(--ds-sf));\n --_button-inline-size: var(--ds-button-inline-size);\n}\n\n/* Other controls drawn on this face keep their own measures: an icon or a count's square, a\n tab, a menu entry, a split run and a paper tab. Their colours still follow the faces. */\n:host(:is([icon], [square], [split], [menu-item], [role=\"option\"], [role^=\"menuitem\"], [role=\"tab\"], [choice], [segment], [paper])) {\n --_button-height: initial;\n --_button-radius: initial;\n --_button-font-size: initial;\n --_button-padding: initial;\n --_button-inline-size: initial;\n}\n\n/* Label width is standard. Fixed grid widths are explicit layout choices. */\n:host([fixed]) { width: var(--ds-button-width, calc(4 * var(--ds-unit))); }\n:host([wide]) { width: var(--ds-button-width, calc(8 * var(--ds-unit))); }\n/* Keep fit as an explicit intrinsic-width alias for existing consumers. */\n:host([fit]) {\n flex: 0 0 auto;\n width: max-content;\n}\n:host([fit]) :is(button, a) {\n flex: 0 0 auto;\n width:
|
|
6471
|
+
var ds_button_default = "/* ds-button.css */\n/* Core button component styles. The face is a <button>, or an <a> when the\n element has an href: both draw alike in every variant and state. */\n\n:host {\n display: inline-flex;\n /* At the foot of a line, so a 16px face takes the lower sixteen of the square. */\n vertical-align: bottom;\n min-width: 0;\n flex: 0 0 auto;\n width: var(--ds-button-width, var(--_button-inline-size, max-content));\n max-width: 100%;\n overflow: visible;\n /* The button's own tokens, unset by default and in unscaled px as --ds-control-size is,\n resolved here at this button's scale. Each face reads them first and falls back to its\n own measure, so a page that sets none draws exactly as before. --ds-button-inline-size is\n the width: unset hugs, 100% fills, a length is fixed. */\n --_button-size: var(--ds-button-size);\n --_button-height: calc(var(--_button-size) * var(--ds-sf));\n --_button-corner-size: var(--ds-button-corner-size);\n --_button-radius: calc(var(--_button-corner-size) * var(--ds-sf));\n --_button-text-size: var(--ds-button-text-size);\n --_button-font-size: calc(var(--_button-text-size) * var(--ds-sf));\n --_button-padding-size: var(--ds-button-padding-size);\n --_button-padding: calc(var(--_button-padding-size) * var(--ds-sf));\n --_button-inline-size: var(--ds-button-inline-size);\n}\n\n/* Other controls drawn on this face keep their own measures: an icon or a count's square, a\n tab, a menu entry, a split run and a paper tab. Their colours still follow the faces. */\n:host(:is([icon], [square], [split], [menu-item], [role=\"option\"], [role^=\"menuitem\"], [role=\"tab\"], [choice], [segment], [paper])) {\n --_button-height: initial;\n --_button-radius: initial;\n --_button-font-size: initial;\n --_button-padding: initial;\n --_button-inline-size: initial;\n}\n\n/* Label width is standard. Fixed grid widths are explicit layout choices. */\n:host([fixed]) { width: var(--ds-button-width, calc(4 * var(--ds-unit))); }\n:host([wide]) { width: var(--ds-button-width, calc(8 * var(--ds-unit))); }\n/* Keep fit as an explicit intrinsic-width alias for existing consumers. */\n:host([fit]) {\n flex: 0 0 auto;\n width: max-content;\n}\n:host([fit]) :is(button, a) {\n flex: 0 0 auto;\n /* Hug sizing belongs to the host, including its grid rounding. */\n width: 100%;\n min-width: var(--ds-button-min-width, 0px);\n justify-content: var(--ds-button-align, flex-start);\n}\n:host([fit]) :is(button, a) ds-text,\n:host([fit]) :is(button, a) ::slotted(*) {\n flex: 0 0 auto;\n width: max-content;\n}\n\n:is(button, a) {\n box-sizing: border-box;\n max-height: var(--_button-height, var(--ds-control-height));\n height: var(--_button-height, var(--ds-control-height));\n min-height: var(--_button-height, var(--ds-control-height));\n width: 100%;\n max-width: 100%;\n min-width: 0;\n display: inline-flex;\n align-items: center;\n justify-content: flex-start;\n border: none;\n border-radius: var(--_button-radius, var(--ds-radius));\n corner-shape: var(--ds-corner-shape, round);\n cursor: pointer;\n padding: 0;\n color: var(--button-color, var(--button-text-color));\n font-family: var(--ds-typeface-regular);\n font-size: var(--_button-font-size, var(--ds-type-size-default));\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n -webkit-tap-highlight-color: transparent;\n white-space: nowrap;\n overflow-x: clip;\n overflow-y: visible;\n text-overflow: clip;\n /* Default to no-background when no variant is specified */\n background-color: transparent;\n text-decoration: none;\n}\n\n:is(button, a) ds-text,\n:is(button, a) ::slotted(*) {\n overflow-x: clip;\n overflow-y: visible;\n text-overflow: clip;\n white-space: nowrap;\n max-width: 100%;\n text-align: left;\n justify-content: flex-start;\n color: inherit;\n}\n\n/* Words drawn by a translation key take the button's text size too: unset, the expression\n ds-text resolves for itself (component-metrics.css). */\n:is(button, a) ds-text {\n --ds-type-size-default: var(--_button-font-size, calc(var(--ds-text-size, 14px) * var(--ds-sf, 1)));\n}\n\n:is(button, a)[primary] {\n background-color: var(--ds-button-primary-fill, var(--accent-color));\n color: var(--ds-button-primary-text, var(--button-text-color-on-light, var(--black)));\n text-decoration-line: none;\n font-family: var(--ds-typeface-regular);\n padding: 0 var(--_button-padding, calc(var(--ds-button-inset, 4px) * var(--ds-sf)));\n}\n\n/* The secondary face's words are the text's ink, as on `.ds-button--secondary`\n and the host and slotted faces; the grey is the face, not the words. */\n:is(button, a)[secondary] {\n background-color: var(--ds-button-secondary-fill, var(--button-background-color-secondary));\n color: var(--ds-button-color, var(--ds-button-text-color));\n font-family: var(--ds-typeface-regular);\n padding: 0 var(--_button-padding, calc(var(--ds-button-inset, 4px) * var(--ds-sf)));\n}\n\n/* An entry in a menu or a list of options is one row high on this face too,\n as on the host and slotted faces: the menu's --ds-button-height (one\n square, or a compact row), its words at the start, padded 4px. */\n:host(:is([menu-item], [role=\"option\"], [role^=\"menuitem\"])) :is(button, a) {\n /* Its words and icon on the lower sixteen of the row, the spare four above. */\n align-items: flex-end;\n height: var(--ds-button-height, var(--ds-row-height));\n min-height: var(--ds-button-height, var(--ds-row-height));\n max-height: var(--ds-button-height, var(--ds-row-height));\n justify-content: var(--ds-button-align, flex-start);\n padding: 0 calc(var(--ds-button-inset, 4px) * var(--ds-sf));\n}\n\n/* `danger`: a destructive action's words in the danger colour, on this face\n as on the host and slotted faces and `.ds-button--danger`. */\n:host([danger]) :is(button, a) {\n color: var(--ds-danger-color, var(--ds-tuned-red));\n}\n\n/* Disabled, as in the slotted and host modes. A disabled link has no href. */\n:is(button:disabled, a[aria-disabled=\"true\"]) {\n cursor: default;\n opacity: 0.5;\n}\n\n.loading {\n opacity: 0.7;\n}\n\n/* A button that holds only an icon — every close button — is a 16-unit\n square, scaled with the page, in the shape's corners: the icon fills it,\n no word-padding around it, so the glyph's lines are the same size wherever\n a page or a panel closes, on the web and in the app alike. The element\n marks itself `icon` when its only child is an ds-icon. */\n:host([icon]) {\n flex: 0 0 auto;\n width: var(--ds-control-height);\n height: var(--ds-control-height);\n}\n:host([icon]) :is(button, a) {\n width: var(--ds-control-height);\n padding: 0 !important;\n justify-content: center;\n}\n:host([icon]) ::slotted(ds-icon) {\n flex: 0 0 auto;\n width: var(--ds-control-height);\n height: var(--ds-control-height);\n}\n\n/* A button marked `square` is a 16-unit square whatever it holds, a count\n or an initial, its words in its middle with no word-padding around them. */\n:host([square]) {\n flex: 0 0 auto;\n width: var(--ds-control-height);\n}\n:host([square]) :is(button, a) {\n width: var(--ds-control-height);\n padding: 0 !important;\n justify-content: center;\n}\n\n/* Words and an icon hug them, as on every face (controls.css): this face has\n no gap, and on a filled face the icon takes the padding on its side, its\n own room around the glyph standing in for it. */\n:host(:is([primary], [secondary]):not([icon])) ::slotted(ds-icon:last-child:not(:first-child)) {\n margin-inline-end: calc(-4px * var(--ds-sf));\n}\n:host(:is([primary], [secondary]):not([icon])) ::slotted(ds-icon:first-child:not(:last-child)) {\n margin-inline-start: calc(-4px * var(--ds-sf));\n}\n\n/* A paper tab (`ds-tabs paper`) on this face: a row high with its words on\n the sixteen, half a square of room at its sides, in the run's colours,\n rounded at the top only and square at the foot, where it joins the page. */\n:host([paper]) :is(button, a) {\n height: var(--ds-row-height);\n min-height: var(--ds-row-height);\n max-height: var(--ds-row-height);\n align-items: flex-end;\n padding: 0 calc(10px * var(--ds-sf));\n border-radius: var(--ds-radius) var(--ds-radius) 0 0;\n background-color: var(--ds-button-background, transparent);\n color: var(--ds-button-color, var(--button-text-color));\n}\n\n/* A segment gets its outside corners from the enclosing split control, or\n from its place in a joined run of tabs (`ds-tabs split`). */\n:host([segment]) :is(button, a) {\n border-radius: 0 !important;\n}\n:host(:is([segment=\"first\"], [segment=\"only\"])) :is(button, a) {\n border-start-start-radius: var(--ds-radius) !important;\n border-end-start-radius: var(--ds-radius) !important;\n}\n:host(:is([segment=\"last\"], [segment=\"only\"])) :is(button, a) {\n border-start-end-radius: var(--ds-radius) !important;\n border-end-end-radius: var(--ds-radius) !important;\n}\n\n/* A label is never truncated to meet a chosen width. Round its minimum up,\n so explicit widths and flex layouts retain enough space for all the words. */\n:host(:not([icon]):not([split]):not([menu-item])) {\n min-width: max-content;\n min-width: calc-size(max-content, round(up, size, var(--ds-unit)));\n}\n/* A menu entry keeps a fixed width, so its words may still be cut and fade. */\n:host(:not([menu-item])) :is(button, a),\n:host(:not([menu-item])) :is(button, a) ds-text,\n:host(:not([menu-item])) :is(button, a) ::slotted(*) {\n overflow: visible;\n mask-image: none;\n text-overflow: clip;\n}\n";
|
|
6213
6472
|
//#endregion
|
|
6214
6473
|
//#region DS1/2-core/button-split.ts
|
|
6215
6474
|
function choices(host) {
|
|
@@ -6903,6 +7162,7 @@ function bindContextMenuTrigger(trigger, open, { resolve = () => trigger, touch
|
|
|
6903
7162
|
let suppressed = null;
|
|
6904
7163
|
let release;
|
|
6905
7164
|
let disposed = false;
|
|
7165
|
+
let mousePress;
|
|
6906
7166
|
if (aria) trigger.setAttribute("aria-haspopup", "menu");
|
|
6907
7167
|
if (selection) trigger.classList.add("ds-context-trigger");
|
|
6908
7168
|
const enabled = (control) => control.isConnected && !control.matches(":disabled, [disabled], [aria-disabled=\"true\"], [data-disabled]") && !control.closest("[hidden], [inert]");
|
|
@@ -6926,6 +7186,7 @@ function bindContextMenuTrigger(trigger, open, { resolve = () => trigger, touch
|
|
|
6926
7186
|
release = setTimeout(clearSuppression, 1e3);
|
|
6927
7187
|
};
|
|
6928
7188
|
const cancel = () => {
|
|
7189
|
+
mousePress = void 0;
|
|
6929
7190
|
clearTimeout(timer);
|
|
6930
7191
|
timer = void 0;
|
|
6931
7192
|
point = void 0;
|
|
@@ -6939,7 +7200,16 @@ function bindContextMenuTrigger(trigger, open, { resolve = () => trigger, touch
|
|
|
6939
7200
|
};
|
|
6940
7201
|
const context = (event) => {
|
|
6941
7202
|
if (event.defaultPrevented) return;
|
|
6942
|
-
const
|
|
7203
|
+
const pressed = mousePress;
|
|
7204
|
+
mousePress = void 0;
|
|
7205
|
+
const gesture = pressed && event.button === 2 && Math.hypot(event.clientX - pressed.event.clientX, event.clientY - pressed.event.clientY) <= 10 ? new Proxy(pressed.event, { get(target, key) {
|
|
7206
|
+
if (key === "composedPath") return () => pressed.path;
|
|
7207
|
+
if (key === "target") return pressed.target;
|
|
7208
|
+
const value = Reflect.get(target, key, target);
|
|
7209
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
7210
|
+
} }) : event;
|
|
7211
|
+
if (gesture !== event && (typeof gesture.target?.nodeType !== "number" || !trigger.contains(gesture.target))) return;
|
|
7212
|
+
const control = resolve(gesture);
|
|
6943
7213
|
if (!control || !enabled(control)) return;
|
|
6944
7214
|
cancel();
|
|
6945
7215
|
if (suppressed === control) {
|
|
@@ -6949,7 +7219,7 @@ function bindContextMenuTrigger(trigger, open, { resolve = () => trigger, touch
|
|
|
6949
7219
|
if (open({
|
|
6950
7220
|
x: event.clientX,
|
|
6951
7221
|
y: event.clientY
|
|
6952
|
-
}, control,
|
|
7222
|
+
}, control, gesture) === false) return;
|
|
6953
7223
|
event.preventDefault();
|
|
6954
7224
|
if (selection && event.button === 0) arm(control);
|
|
6955
7225
|
};
|
|
@@ -6992,6 +7262,15 @@ function bindContextMenuTrigger(trigger, open, { resolve = () => trigger, touch
|
|
|
6992
7262
|
if (open(at, control, event) !== false) arm(control);
|
|
6993
7263
|
}, 500);
|
|
6994
7264
|
};
|
|
7265
|
+
const rememberMouse = (event) => {
|
|
7266
|
+
mousePress = !event.defaultPrevented && event.pointerType === "mouse" && event.button === 2 ? {
|
|
7267
|
+
event,
|
|
7268
|
+
path: event.composedPath(),
|
|
7269
|
+
target: event.target
|
|
7270
|
+
} : void 0;
|
|
7271
|
+
};
|
|
7272
|
+
trigger.addEventListener("pointerdown", rememberMouse, true);
|
|
7273
|
+
trigger.addEventListener("pointercancel", cancel, true);
|
|
6995
7274
|
trigger.addEventListener("contextmenu", context);
|
|
6996
7275
|
trigger.addEventListener("keydown", key);
|
|
6997
7276
|
trigger.addEventListener("pointerdown", press);
|
|
@@ -7004,6 +7283,8 @@ function bindContextMenuTrigger(trigger, open, { resolve = () => trigger, touch
|
|
|
7004
7283
|
trigger.removeEventListener("contextmenu", context);
|
|
7005
7284
|
trigger.removeEventListener("keydown", key);
|
|
7006
7285
|
trigger.removeEventListener("pointerdown", press);
|
|
7286
|
+
trigger.removeEventListener("pointerdown", rememberMouse, true);
|
|
7287
|
+
trigger.removeEventListener("pointercancel", cancel, true);
|
|
7007
7288
|
if (aria) {
|
|
7008
7289
|
if (previousAria === null) trigger.removeAttribute("aria-haspopup");
|
|
7009
7290
|
else trigger.setAttribute("aria-haspopup", previousAria);
|
|
@@ -11987,8 +12268,21 @@ var _Avatar;
|
|
|
11987
12268
|
provideIcons({ avatar: avatarIcon });
|
|
11988
12269
|
/** The ink that reads on a fill: black on a light one, white on a dark one. */
|
|
11989
12270
|
var inkOn = (rgb) => {
|
|
11990
|
-
const
|
|
11991
|
-
|
|
12271
|
+
const fill = [...rgb, 1];
|
|
12272
|
+
const white = [
|
|
12273
|
+
1,
|
|
12274
|
+
1,
|
|
12275
|
+
1,
|
|
12276
|
+
1
|
|
12277
|
+
];
|
|
12278
|
+
if (contrastRatio([
|
|
12279
|
+
42 / 255,
|
|
12280
|
+
42 / 255,
|
|
12281
|
+
42 / 255,
|
|
12282
|
+
1
|
|
12283
|
+
], fill) >= 4.5) return "var(--ds-black)";
|
|
12284
|
+
if (contrastRatio(white, fill) >= 4.5) return "var(--ds-white)";
|
|
12285
|
+
return "black";
|
|
11992
12286
|
};
|
|
11993
12287
|
/** Saved identity colours are hex; their ink must stay legible in either theme. */
|
|
11994
12288
|
function avatarInk(color) {
|
|
@@ -12023,6 +12317,14 @@ function inkOnResolved(fill) {
|
|
|
12023
12317
|
var Avatar = class extends i$4 {
|
|
12024
12318
|
constructor() {
|
|
12025
12319
|
super();
|
|
12320
|
+
this.inkFrame = 0;
|
|
12321
|
+
this.queueInk = () => {
|
|
12322
|
+
const view = this.ownerDocument.defaultView;
|
|
12323
|
+
if (!this.inkFrame) this.inkFrame = view.requestAnimationFrame(() => {
|
|
12324
|
+
this.inkFrame = 0;
|
|
12325
|
+
this.resolveInk();
|
|
12326
|
+
});
|
|
12327
|
+
};
|
|
12026
12328
|
this.label = "";
|
|
12027
12329
|
this.initial = "?";
|
|
12028
12330
|
this.src = "";
|
|
@@ -12034,6 +12336,28 @@ var Avatar = class extends i$4 {
|
|
|
12034
12336
|
this.fit = "cover";
|
|
12035
12337
|
this.logo = this.mask = this.outlined = this.pending = this.plain = this.loaded = this.failed = false;
|
|
12036
12338
|
}
|
|
12339
|
+
connectedCallback() {
|
|
12340
|
+
super.connectedCallback();
|
|
12341
|
+
const view = this.ownerDocument.defaultView;
|
|
12342
|
+
this.inkObserver = new view.MutationObserver(this.queueInk);
|
|
12343
|
+
for (let parent = this; parent; parent = parent.parentElement ?? parent.getRootNode().host ?? null) this.inkObserver.observe(parent, {
|
|
12344
|
+
attributes: true,
|
|
12345
|
+
attributeFilter: [
|
|
12346
|
+
"class",
|
|
12347
|
+
"style",
|
|
12348
|
+
"data-theme"
|
|
12349
|
+
]
|
|
12350
|
+
});
|
|
12351
|
+
view.addEventListener("load", this.queueInk, true);
|
|
12352
|
+
}
|
|
12353
|
+
disconnectedCallback() {
|
|
12354
|
+
super.disconnectedCallback();
|
|
12355
|
+
this.inkObserver?.disconnect();
|
|
12356
|
+
const view = this.ownerDocument.defaultView;
|
|
12357
|
+
view.cancelAnimationFrame(this.inkFrame);
|
|
12358
|
+
this.inkFrame = 0;
|
|
12359
|
+
view.removeEventListener("load", this.queueInk, true);
|
|
12360
|
+
}
|
|
12037
12361
|
willUpdate(changed) {
|
|
12038
12362
|
if (changed.has("src")) {
|
|
12039
12363
|
this.loaded = false;
|
|
@@ -12043,7 +12367,7 @@ var Avatar = class extends i$4 {
|
|
|
12043
12367
|
}
|
|
12044
12368
|
/** A fill named by a variable (`var(--brand-highlight)`) gets its ink once the browser has resolved it. */
|
|
12045
12369
|
updated() {
|
|
12046
|
-
if (this.ink || this.pending || this.plain
|
|
12370
|
+
if (this.ink || this.pending || this.plain) return;
|
|
12047
12371
|
this.resolveInk();
|
|
12048
12372
|
}
|
|
12049
12373
|
/** Reads the fill as drawn; while the variable is still undefined (its stylesheet on its way), looks again next
|
|
@@ -12051,12 +12375,28 @@ var Avatar = class extends i$4 {
|
|
|
12051
12375
|
resolveInk(tries = 0) {
|
|
12052
12376
|
const frame = this.renderRoot.querySelector(".frame");
|
|
12053
12377
|
if (!frame || !this.isConnected) return;
|
|
12054
|
-
|
|
12055
|
-
|
|
12056
|
-
|
|
12378
|
+
if (this.ink || this.pending || this.plain) return;
|
|
12379
|
+
const view = this.ownerDocument.defaultView;
|
|
12380
|
+
const read = colorReader(this.ownerDocument);
|
|
12381
|
+
let fill = read(view.getComputedStyle(frame).backgroundColor);
|
|
12382
|
+
if (fill && fill[3] > 0) {
|
|
12383
|
+
for (let parent = this; parent && fill[3] < 1; parent = parent.parentElement ?? parent.getRootNode().host ?? null) {
|
|
12384
|
+
const background = read(view.getComputedStyle(parent).backgroundColor);
|
|
12385
|
+
if (background) fill = composite(fill, background);
|
|
12386
|
+
}
|
|
12387
|
+
if (fill[3] < 1) return;
|
|
12388
|
+
const tokens = view.getComputedStyle(this);
|
|
12389
|
+
const black = read(tokens.getPropertyValue("--ds-black").trim()), white = read(tokens.getPropertyValue("--ds-white").trim());
|
|
12390
|
+
const ink = black && contrastRatio(black, fill) >= 4.5 ? "var(--ds-black)" : white && contrastRatio(white, fill) >= 4.5 ? "var(--ds-white)" : contrastRatio([
|
|
12391
|
+
0,
|
|
12392
|
+
0,
|
|
12393
|
+
0,
|
|
12394
|
+
1
|
|
12395
|
+
], fill) >= 4.5 ? "black" : "white";
|
|
12396
|
+
if (frame.style.color !== ink) frame.style.color = ink;
|
|
12057
12397
|
return;
|
|
12058
12398
|
}
|
|
12059
|
-
if (tries < 60) requestAnimationFrame(() => this.resolveInk(tries + 1));
|
|
12399
|
+
if (tries < 60) this.ownerDocument.defaultView.requestAnimationFrame(() => this.resolveInk(tries + 1));
|
|
12060
12400
|
if (tries === 0 && this.ownerDocument.readyState !== "complete") this.ownerDocument.defaultView?.addEventListener("load", () => this.resolveInk(60), { once: true });
|
|
12061
12401
|
}
|
|
12062
12402
|
render() {
|
|
@@ -12071,7 +12411,7 @@ var Avatar = class extends i$4 {
|
|
|
12071
12411
|
class="frame"
|
|
12072
12412
|
style=${o({
|
|
12073
12413
|
backgroundColor: !this.pending && !this.plain ? this.color || void 0 : void 0,
|
|
12074
|
-
color: !this.pending ? this.ink || avatarInk(this.color) : void 0
|
|
12414
|
+
color: !this.pending ? this.ink || (!this.plain ? avatarInk(this.color) : void 0) : void 0
|
|
12075
12415
|
})}
|
|
12076
12416
|
role=${this.label ? "img" : A}
|
|
12077
12417
|
aria-label=${this.label || A}
|
|
@@ -14928,7 +15268,7 @@ _Form.styles = i$5`
|
|
|
14928
15268
|
pointer-events: none;
|
|
14929
15269
|
}
|
|
14930
15270
|
`;
|
|
14931
|
-
|
|
15271
|
+
define("ds-form", Form);
|
|
14932
15272
|
//#endregion
|
|
14933
15273
|
//#region DS1/3-unit/styles/ds-list.css?inline
|
|
14934
15274
|
var ds_list_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n/* ds-list.css */\n\n:host {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: var(--ds-list-gap, 0);\n width: 100%;\n min-width: 0;\n}\n:host([hidden]) { display: none !important; }\n\n:host([columns]) {\n display: grid;\n grid-template-columns: repeat(var(--ds-list-columns, 2), minmax(0, 1fr));\n column-gap: var(--ds-list-column-gap, calc(var(--ds-unit) / 2));\n}\n\n:host([columns=\"2\"]) {\n --ds-list-columns: 2;\n}\n\n:host([columns=\"3\"]) {\n --ds-list-columns: 3;\n}\n\n/* The group's name on the square above its rows: words on the lower sixteen of the square with\n the spare four above, in the muted ink, as a day's heading stands over Money's payments. It\n names the list (aria-label), so the drawn words are hidden from assistive technology. */\n.heading {\n box-sizing: border-box;\n flex: none;\n grid-column: 1 / -1;\n width: 100%;\n height: var(--ds-unit);\n padding-top: calc(4px * var(--ds-sf));\n overflow: hidden;\n color: var(--ds-list-heading-color, var(--ds-text-color-muted));\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n white-space: nowrap;\n text-overflow: clip;\n}\n/* A cut heading fades over its last square, never an ellipsis (0-face/cut-fade.ts marks it). */\n.heading[data-cut=\"end\"] { mask-image: linear-gradient(to right, #000 calc(100% - var(--ds-unit)), transparent); }\n:host(:dir(rtl)) .heading[data-cut=\"end\"] { mask-image: linear-gradient(to left, #000 calc(100% - var(--ds-unit)), transparent); }\n";
|
|
@@ -15966,7 +16306,7 @@ function text(value) {
|
|
|
15966
16306
|
if (blank(value)) return "";
|
|
15967
16307
|
return typeof value === "number" ? value.toLocaleString() : String(value);
|
|
15968
16308
|
}
|
|
15969
|
-
|
|
16309
|
+
define("ds-table", DsTable);
|
|
15970
16310
|
//#endregion
|
|
15971
16311
|
//#region DS1/3-unit/styles/ds-table-of-contents.css?inline
|
|
15972
16312
|
var ds_table_of_contents_default = "/* Shape is a surface preference. Keep these base lengths unscaled: each\n * component resolves them with its own --ds-sf in component-metrics.css. */\n[data-ds-shape=\"square\"],\n:host([data-ds-shape=\"square\"]) {\n --ds-corner-size: 0px;\n --ds-corner-shape: round;\n --ds-button-inset: 0.5px;\n}\n\n[data-ds-shape=\"rounded\"],\n:host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 4px;\n --ds-corner-shape: round;\n --ds-button-inset: 2.5px;\n}\n\n[data-ds-shape=\"circular\"],\n:host([data-ds-shape=\"circular\"]) {\n --ds-corner-size: 999px;\n --ds-corner-shape: round;\n --ds-button-inset: 5px;\n}\n\n/* A squircle needs twice an arc's radius for the same apparent corner.\n * Circular controls keep true semicircles even in a squircle browser. */\n@supports (corner-shape: squircle) {\n [data-ds-shape=\"rounded\"],\n :host([data-ds-shape=\"rounded\"]) {\n --ds-corner-size: 8px;\n --ds-corner-shape: squircle;\n }\n}\n/* Resolve dimensions where a component is drawn. Inherited calc() values have\n * already used their ancestor's scale. Base tokens stay unscaled and inherit;\n * resolved tokens can still be overridden directly on a component.\n * data-ds-surface gives ordinary layout elements the same scaled measures.\n */\n:root,\n:host,\n:where([data-ds-surface]) {\n --ds-unit: calc(var(--ds-1, 20px) * var(--ds-sf, 1));\n --ds-control-height: calc(var(--ds-control-size, var(--ds-08, 16px)) * var(--ds-sf, 1));\n --ds-row-height: calc(var(--ds-row-size, var(--ds-1, 20px)) * var(--ds-sf, 1));\n --ds-type-size-default: calc(var(--ds-text-size, 14px) * var(--ds-sf, 1));\n --ds-type-size-small: calc(var(--ds-small-text-size, 10px) * var(--ds-sf, 1));\n --ds-type-size-heading: calc(var(--ds-heading-text-size, 13px) * var(--ds-sf, 1));\n --ds-type-size-display: calc(var(--ds-display-text-size, 20px) * var(--ds-sf, 1));\n --ds-type-lineheight-default: calc(var(--ds-text-leading, 16px) * var(--ds-sf, 1));\n --ds-type-letterspacing-default: calc(var(--ds-text-tracking, -0.3px) * var(--ds-sf, 1));\n --ds-radius: calc(var(--ds-corner-size, 4px) * var(--ds-sf, 1));\n --ds-radius-card: calc(var(--ds-card-corner-size, 4px) * var(--ds-sf, 1));\n}\n:host {\n display: block;\n width: var(--ds-toc-width, calc(12 * var(--ds-unit)));\n max-width: 100%;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n:host([hidden]) { display: none !important; }\n.title { display: flex; align-items: flex-end; min-height: var(--ds-unit); }\n.links { margin-top: var(--ds-unit); }\na, ::slotted(a) {\n box-sizing: border-box;\n display: block;\n min-height: var(--ds-unit);\n padding-top: calc(4px * var(--ds-sf));\n padding-inline-start: calc(var(--toc-depth, 0) * var(--ds-unit));\n color: var(--ds-toc-color, var(--ds-text-color-muted));\n font: inherit;\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: inherit;\n text-decoration: none;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: clip;\n}\n/* A cut label fades over its last square, never an ellipsis (0-face/cut-fade.ts marks it). */\na[data-cut=\"end\"], ::slotted(a[data-cut=\"end\"]) {\n mask-image: linear-gradient(to right, #000 calc(100% - var(--ds-unit)), transparent);\n}\n:host(:dir(rtl)) a[data-cut=\"end\"], :host(:dir(rtl)) ::slotted(a[data-cut=\"end\"]) {\n mask-image: linear-gradient(to left, #000 calc(100% - var(--ds-unit)), transparent);\n}\na:hover, ::slotted(a:hover) { color: var(--ds-text-color); text-decoration: underline; }\na[aria-current], ::slotted(a[aria-current]) { color: var(--ds-toc-current-color, var(--ds-sharp-blue)); }\na:focus-visible, ::slotted(a:focus-visible) { outline: 1px solid var(--ds-focus-ring); outline-offset: 1px; }\n";
|
|
@@ -16161,7 +16501,7 @@ var Container = class extends i$4 {
|
|
|
16161
16501
|
};
|
|
16162
16502
|
_Container = Container;
|
|
16163
16503
|
_Container.styles = r$4(ds_container_default);
|
|
16164
|
-
|
|
16504
|
+
define("ds-container", Container);
|
|
16165
16505
|
//#endregion
|
|
16166
16506
|
//#region DS1/4-page/styles/ds-grid.css?inline
|
|
16167
16507
|
var ds_grid_default = "/* A one-square pitch by default. Rules stay hairlines at every surface scale. */\n:host {\n --grid-scale: var(--ds-sf, var(--sf, 1));\n display: block;\n position: fixed;\n top: 0;\n left: 50%;\n transform: translateX(-50%);\n width: var(--ds-grid-width, calc(1440px * var(--grid-scale)));\n height: var(--ds-grid-height, max(100vh, calc(1280px * var(--grid-scale))));\n pointer-events: none;\n z-index: var(--ds-grid-z-index, 300);\n}\n:host([hidden]) { display: none !important; }\n:host([align=\"left\"]) { left: 0; transform: none; }\n:host([align=\"right\"]) { left: auto; right: 0; transform: none; }\n@media (max-width: 768px) {\n :host { width: calc(100% - 1px); max-width: 100vw; }\n}\n/* The containing element establishes positioning; its content stays above the paper. */\n:host([contained]) { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; transform: none; z-index: 0; }\n.paper {\n position: absolute;\n inset: 0;\n --cell: var(--ds-grid-unit, calc(var(--pitch-x) * var(--grid-scale)));\n --row: var(--ds-grid-row, calc(var(--pitch-y) * var(--grid-scale)));\n --stroke: var(--ds-grid-stroke, 1px);\n background-color: var(--paper);\n background-size: var(--cell) var(--row);\n background-position: calc(var(--ds-grid-origin-x, 0px) - var(--stroke) / 2) calc(var(--ds-grid-origin-y, 0px) - var(--stroke) / 2);\n background-repeat: repeat;\n}\n[data-pattern=\"grid\"] { background-image: linear-gradient(to right, var(--ink) var(--stroke), transparent var(--stroke)), linear-gradient(to bottom, var(--ink) var(--stroke), transparent var(--stroke)); }\n[data-pattern=\"lines\"] { background-image: linear-gradient(to bottom, var(--ink) var(--stroke), transparent var(--stroke)); }\n[data-pattern=\"columns\"] { background-image: linear-gradient(to right, var(--ink) var(--stroke), transparent var(--stroke)); }\n[data-pattern=\"dots\"] {\n background-image: radial-gradient(circle, var(--ink) var(--stroke), transparent var(--stroke));\n background-position: var(--ds-grid-origin-x, 0px) calc(var(--ds-grid-origin-y, 0px) - var(--row) / 2);\n}\n[data-pattern=\"none\"] { background-image: none; }\n@media print { :host(:not([contained])) { display: none; } }\n";
|