@fusion.dev/helix 0.144.0 → 0.145.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/custom-elements.json +9978 -916
  2. package/dist/accordion/item/accordion-item.css.js +14 -3
  3. package/dist/accordion/item/accordion-item.d.ts +2 -0
  4. package/dist/aura/palette.d.ts +38 -0
  5. package/dist/aura/palette.js +22 -0
  6. package/dist/aura/root/aura-root.css.js +24 -3
  7. package/dist/aura/root/aura-root.d.ts +42 -7
  8. package/dist/aura/root/aura-root.js +31 -25
  9. package/dist/breadcrumbs/breadcrumb/breadcrumb.css.js +7 -7
  10. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +5 -0
  11. package/dist/breadcrumbs/root/breadcrumbs-root.css.js +1 -1
  12. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +3 -0
  13. package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -0
  14. package/dist/button-group/root/button-group-root.d.ts +3 -0
  15. package/dist/canvas/root/canvas-root.css.js +1 -0
  16. package/dist/carousel/root/carousel-root.css.js +17 -1
  17. package/dist/data-table/root/data-table-root.css.js +63 -0
  18. package/dist/data-table/root/data-table-root.d.ts +1 -0
  19. package/dist/description-list/item/description-list-item.css.js +11 -0
  20. package/dist/drilldown/item/drilldown-item.css.js +2 -1
  21. package/dist/drilldown/root/drilldown-root.css.js +2 -1
  22. package/dist/element-events.generated.js +58 -9
  23. package/dist/flex/root/flex-root.css.js +134 -9
  24. package/dist/flex/root/flex-root.d.ts +51 -5
  25. package/dist/flex/root/flex-root.js +17 -1
  26. package/dist/grid/root/grid-root.css.js +114 -11
  27. package/dist/grid/root/grid-root.d.ts +37 -0
  28. package/dist/grid/root/grid-root.js +13 -1
  29. package/dist/list/item/list-item.css.js +21 -1
  30. package/dist/list/item/list-item.d.ts +3 -0
  31. package/dist/list/root/list-root.css.js +13 -1
  32. package/dist/menu/index.d.ts +1 -0
  33. package/dist/menu/index.js +1 -0
  34. package/dist/menu/item/menu-item.css.js +15 -1
  35. package/dist/menu/item/menu-item.d.ts +3 -0
  36. package/dist/menu/item/menu-item.js +2 -0
  37. package/dist/menu/section/menu-section.css.d.ts +1 -0
  38. package/dist/menu/section/menu-section.css.js +14 -0
  39. package/dist/menu/section/menu-section.d.ts +24 -0
  40. package/dist/menu/section/menu-section.js +16 -0
  41. package/dist/navigation/root/navigation-root.css.js +3 -2
  42. package/dist/navigation/root/navigation-root.d.ts +6 -0
  43. package/dist/notifications/root/notifications-root.css.js +24 -1
  44. package/dist/notifications/root/notifications-root.d.ts +1 -0
  45. package/dist/object-inspector/root/object-inspector-root.css.js +36 -1
  46. package/dist/object-inspector/root/object-inspector-root.d.ts +4 -1
  47. package/dist/object-inspector/root/object-inspector-root.js +2 -1
  48. package/dist/orb/index.d.ts +1 -1
  49. package/dist/orb/index.js +1 -1
  50. package/dist/orb/root/orb-root.d.ts +31 -5
  51. package/dist/orb/root/orb-root.js +33 -4
  52. package/dist/outline/root/outline-root.css.js +10 -0
  53. package/dist/outline/root/outline-root.d.ts +7 -0
  54. package/dist/sandbox/frame.d.ts +63 -0
  55. package/dist/sandbox/frame.js +132 -0
  56. package/dist/sandbox/index.d.ts +1 -0
  57. package/dist/sandbox/index.js +1 -0
  58. package/dist/sandbox/levels.d.ts +10 -0
  59. package/dist/sandbox/levels.js +5 -0
  60. package/dist/sandbox/root/sandbox-root.d.ts +3 -0
  61. package/dist/sandbox/root/sandbox-root.js +13 -3
  62. package/dist/sandbox/source/sandbox-source.d.ts +1 -0
  63. package/dist/sandbox/source/sandbox-source.js +7 -3
  64. package/dist/sandbox/terminal/sandbox-terminal.css.js +39 -0
  65. package/dist/sandbox/terminal/sandbox-terminal.d.ts +42 -1
  66. package/dist/sandbox/terminal/sandbox-terminal.js +47 -3
  67. package/dist/scroll-area/root/scroll-area-root.css.js +83 -1
  68. package/dist/scroll-area/root/scroll-area-root.d.ts +6 -0
  69. package/dist/skip-link/root/skip-link-root.css.js +8 -8
  70. package/dist/skip-link/root/skip-link-root.d.ts +9 -0
  71. package/dist/speed-dial/item/speed-dial-item.css.js +11 -4
  72. package/dist/speed-dial/item/speed-dial-item.d.ts +4 -0
  73. package/dist/speed-dial/root/speed-dial-root.css.js +7 -3
  74. package/dist/speed-dial/root/speed-dial-root.d.ts +9 -0
  75. package/dist/speed-dial/root/speed-dial-root.js +4 -0
  76. package/dist/steps/step/step.js +2 -1
  77. package/dist/table/root/table-root.css.js +18 -0
  78. package/dist/table/root/table-root.d.ts +6 -0
  79. package/dist/table/root/table-root.js +2 -0
  80. package/dist/table/row/table-row.css.js +18 -0
  81. package/dist/table/row/table-row.d.ts +2 -0
  82. package/dist/table/row/table-row.js +2 -0
  83. package/dist/tabs/panel/tab-panel.css.js +5 -1
  84. package/dist/tabs/root/tabs-root.css.js +56 -1
  85. package/dist/tabs/tab/tab.css.js +5 -1
  86. package/dist/text/clamp.d.ts +8 -0
  87. package/dist/text/clamp.js +1 -0
  88. package/dist/text/root/text-root.css.js +85 -45
  89. package/dist/text/root/text-root.d.ts +48 -7
  90. package/dist/text/root/text-root.js +17 -11
  91. package/dist/timeline/group/timeline-group.css.d.ts +1 -0
  92. package/dist/timeline/group/timeline-group.css.js +32 -0
  93. package/dist/timeline/group/timeline-group.d.ts +25 -0
  94. package/dist/timeline/group/timeline-group.js +16 -0
  95. package/dist/timeline/index.d.ts +1 -0
  96. package/dist/timeline/index.js +1 -0
  97. package/dist/timeline/item/timeline-item.css.js +43 -16
  98. package/dist/timeline/root/timeline-root.css.js +56 -0
  99. package/dist/timeline/root/timeline-root.d.ts +26 -0
  100. package/dist/timeline/root/timeline-root.js +7 -0
  101. package/dist/toolbar/root/toolbar-root.css.js +3 -0
  102. package/dist/toolbar/root/toolbar-root.d.ts +3 -0
  103. package/dist/tree/item/tree-item.css.js +72 -0
  104. package/dist/tree/item/tree-item.d.ts +10 -0
  105. package/dist/video/root/video-root.css.js +6 -0
  106. package/dist/video/root/video-root.d.ts +3 -0
  107. package/dist/virtual-list/root/virtual-list-root.css.js +5 -0
  108. package/dist/virtual-list/root/virtual-list-root.d.ts +4 -3
  109. package/lint.json +1 -1
  110. package/package.json +6 -6
  111. package/types/jsx.d.ts +4033 -671
  112. package/types/svelte.d.ts +2 -0
  113. package/types/vue.d.ts +1078 -202
@@ -31,15 +31,26 @@ transform: scaleY(1);
31
31
  transition: transform var(--helix-duration-fast) var(--helix-easing-standard);
32
32
  }
33
33
 
34
- :host(:not([chevron-placement="start"])) [part="chevron"] {
34
+ ::slotted([slot="chevron"]) {
35
+ block-size: 1em;
36
+ color: var(--helix-color-foreground-subtle);
37
+ flex: 0 0 auto;
38
+ inline-size: 1em;
39
+ transition: transform var(--helix-duration-fast) var(--helix-easing-standard);
40
+ }
41
+
42
+ :host(:not([chevron-placement="start"])) [part="chevron"],
43
+ :host(:not([chevron-placement="start"])) ::slotted([slot="chevron"]) {
35
44
  margin-inline-start: auto;
36
45
  }
37
46
 
38
- :host(:state(open)) [part="chevron"] {
47
+ :host(:state(open)) [part="chevron"],
48
+ :host(:state(open)) ::slotted([slot="chevron"]) {
39
49
  transform: scaleY(-1);
40
50
  }
41
51
 
42
- [part="trigger"]:hover:not(:disabled) [part="chevron"] {
52
+ [part="trigger"]:hover:not(:disabled) [part="chevron"],
53
+ [part="trigger"]:hover:not(:disabled) ::slotted([slot="chevron"]) {
43
54
  color: var(--helix-color-foreground);
44
55
  }
45
56
 
@@ -16,6 +16,8 @@ import type { CSSResultGroup } from 'lit';
16
16
  * @documentation https://fusion.dev/helix/components/accordion
17
17
  *
18
18
  * @slot - The content shown when the section is open.
19
+ * @slot chevron - Replaces the open and close indicator. A slotted icon is sized, colored and
20
+ * turned like the drawn one.
19
21
  * @slot summary - The text of the button that opens and closes the section. Always shown.
20
22
  *
21
23
  * @csspart chevron - The open and close indicator.
@@ -0,0 +1,38 @@
1
+ import type { ColorBytes, TokenColor } from '@fusion.dev/helix-core';
2
+ /** The four ramp stops a shape is drawn through, as channels in `0..1`. */
3
+ export interface AuraPalette {
4
+ glow: TokenColor;
5
+ ground: TokenColor;
6
+ haze: TokenColor;
7
+ peak: TokenColor;
8
+ }
9
+ /** The computed colors the canvas carries, one per stop and two for the peak. */
10
+ export type PaletteStyle = Pick<CSSStyleDeclaration, 'caretColor' | 'color' | 'columnRuleColor' | 'outlineColor' | 'textDecorationColor'>;
11
+ /** The default theme's dark page, ink on black, which is drawn until a read. */
12
+ export declare const RESTING_PALETTE: AuraPalette;
13
+ /**
14
+ * The ramp, from the colors the canvas's stylesheet resolved for it.
15
+ *
16
+ * **Carried on color properties of the canvas, which a canvas never paints**,
17
+ * because a custom property is handed back as the text that was written and a
18
+ * color property is resolved by the engine first. Read there, each stop takes
19
+ * the `--aura-*` hook a page wrote anywhere above the aura, and the token
20
+ * otherwise, the same way the fallback gradient on the host does:
21
+ *
22
+ * - `color`: `--aura-glow`, or `primary`.
23
+ * - `text-decoration-color`: `--aura-haze`, or `primary-subtle`.
24
+ * - `outline-color`: `--aura-ground`, or the background.
25
+ * - `column-rule-color` and `caret-color`: `--aura-peak`, or the light and the
26
+ * dark page's own peak.
27
+ *
28
+ * **Light pages peak on the pressed `primary-active` and dark ones on the
29
+ * foreground**, and the ground is what says which: mixing a saturated hue
30
+ * toward near-black takes the chroma out of exactly the pixels carrying the
31
+ * most of it. Read from the ground's own luminance rather than asked of the
32
+ * color mode, which is a private token this tier may not reach for. A page
33
+ * that sets `--aura-peak` sets both, so its peak is used either way.
34
+ *
35
+ * @param style The canvas's computed style.
36
+ * @param read Turns a resolved color into bytes, `undefined` where it cannot.
37
+ */
38
+ export declare const paletteOf: (style: PaletteStyle, read: (value: string) => ColorBytes | undefined) => AuraPalette;
@@ -0,0 +1,22 @@
1
+ export const RESTING_PALETTE = {
2
+ glow: [0.88, 0.88, 0.88],
3
+ ground: [0, 0, 0],
4
+ haze: [0.16, 0.16, 0.16],
5
+ peak: [1, 1, 1],
6
+ };
7
+ export const paletteOf = (style, read) => {
8
+ const channels = (value, fallback) => {
9
+ const bytes = read(value);
10
+ return bytes ? [bytes[0] / 255, bytes[1] / 255, bytes[2] / 255] : [...fallback];
11
+ };
12
+ const ground = channels(style.outlineColor, RESTING_PALETTE.ground);
13
+ const light = ground[0] * 0.2126 + ground[1] * 0.7152 + ground[2] * 0.0722 > 0.5;
14
+ return {
15
+ glow: channels(style.color, RESTING_PALETTE.glow),
16
+ ground,
17
+ haze: channels(style.textDecorationColor, RESTING_PALETTE.haze),
18
+ peak: light
19
+ ? channels(style.columnRuleColor, [0.02, 0.02, 0.02])
20
+ : channels(style.caretColor, RESTING_PALETTE.peak),
21
+ };
22
+ };
@@ -1,5 +1,10 @@
1
1
  import { createSheet } from '@fusion.dev/helix-core';
2
2
  export const styles = createSheet(`:host {
3
+
4
+ --_aura-glow: var(--aura-glow, var(--helix-color-primary));
5
+ --_aura-ground: var(--aura-ground, var(--helix-color-background));
6
+ --_aura-haze: var(--aura-haze, var(--helix-color-primary-subtle));
7
+
3
8
  position: relative;
4
9
  display: block;
5
10
  inline-size: 100%;
@@ -7,9 +12,9 @@ block-size: 100%;
7
12
 
8
13
  background-image: radial-gradient(
9
14
  120% 90% at 62% 12%,
10
- color-mix(in oklab, var(--helix-color-primary) 38%, var(--helix-color-background)) 0%,
11
- var(--helix-color-primary-subtle) 38%,
12
- var(--helix-color-background) 78%
15
+ color-mix(in oklab, var(--_aura-glow) 38%, var(--_aura-ground)) 0%,
16
+ var(--_aura-haze) 38%,
17
+ var(--_aura-ground) 78%
13
18
  );
14
19
  }
15
20
 
@@ -25,6 +30,22 @@ pointer-events: auto;
25
30
  display: block;
26
31
  inline-size: 100%;
27
32
  block-size: 100%;
33
+
34
+ caret-color: var(--aura-peak, var(--helix-color-foreground));
35
+ color: var(--_aura-glow);
36
+ column-rule-color: var(--aura-peak, var(--helix-color-primary-active));
37
+ outline-color: var(--_aura-ground);
38
+ text-decoration-color: var(--_aura-haze);
39
+ }
40
+
41
+ [part="content"] {
42
+ inset: 0;
43
+ pointer-events: none;
44
+ position: absolute;
45
+ }
46
+
47
+ ::slotted(*) {
48
+ pointer-events: auto;
28
49
  }
29
50
 
30
51
  [part="canvas"][hidden] {
@@ -33,13 +33,37 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
33
33
  * allow. Its behavior is drawing to a canvas, so there is no structure for you
34
34
  * to restyle and nothing for a headless version to hold.
35
35
  *
36
+ * **Content placed inside sits over the field**, in a `content` part that
37
+ * covers the aura, so an interactive aura answers the pointer over the
38
+ * content too. Clicks still reach the content. Style `::part(content)` to
39
+ * place it, such as centering a hero's heading.
40
+ *
41
+ * **The colors are the theme's, and each has a hook**: `--aura-ground`,
42
+ * `--aura-haze`, `--aura-glow` and `--aura-peak`, read by the shader and by the
43
+ * fallback gradient alike, from wherever on the page you set them.
44
+ *
45
+ * Where the gradient shows in place of the shader, the aura matches
46
+ * `:state(fallback)` and sends `helix-aura-fallback` with the reason.
47
+ *
36
48
  * @since 0.1.0
37
49
  * @status stable
38
50
  * @category media
39
51
  * @aliases Backdrop, Background, Atmosphere, Gradient
40
52
  * @documentation https://fusion.dev/helix/components/aura
41
53
  *
54
+ * @slot - Content drawn over the field, such as a heading.
55
+ *
56
+ * @event {HelixAuraFallbackEvent} helix-aura-fallback - Fired each time the aura stops drawing its shader and shows its gradient, with the reason.
57
+ *
42
58
  * @csspart canvas - The surface the shader draws into.
59
+ * @csspart content - The box over the field that holds the content. It covers the aura.
60
+ *
61
+ * @cssproperty --aura-glow - The bright stop of the ramp. Defaults to `--helix-color-primary`.
62
+ * @cssproperty --aura-ground - The page the field fades into. Defaults to `--helix-color-background`.
63
+ * @cssproperty --aura-haze - The faint stop between the ground and the glow. Defaults to `--helix-color-primary-subtle`.
64
+ * @cssproperty --aura-peak - The hottest stop, at the center of a shape. Defaults to `--helix-color-primary-active` on a light page and `--helix-color-foreground` on a dark one.
65
+ *
66
+ * @cssstate fallback - The aura shows its gradient: the renderer draws on the CPU, there is no WebGL, or the browser took the context back. Cleared once the shader draws again.
43
67
  */
44
68
  export declare class HelixAura extends HelixElement {
45
69
  static styles: CSSResultGroup;
@@ -173,8 +197,7 @@ export declare class HelixAura extends HelixElement {
173
197
  * states.
174
198
  */
175
199
  variant?: 'aurora' | 'braid' | 'caustics' | 'flow' | 'fracture' | 'lattice' | 'particles' | 'rays' | 'streaks' | 'threads' | 'waves';
176
- /** Repaints when the palette moves, which no re-render would do on its own. */
177
- private readonly tokens;
200
+ constructor();
178
201
  /**
179
202
  * The four ramp stops, resolved.
180
203
  *
@@ -186,6 +209,10 @@ export declare class HelixAura extends HelixElement {
186
209
  * that happens, so this is filled from there and from the first paint.
187
210
  */
188
211
  private palette;
212
+ /** Why the gradient shows, while it does, or `undefined` while the shader draws. */
213
+ private fallback;
214
+ /** Why the last `build` drew nothing, for the fallback it leads to. */
215
+ private refused;
189
216
  private canvas;
190
217
  private gl;
191
218
  private program;
@@ -413,6 +440,15 @@ export declare class HelixAura extends HelixElement {
413
440
  * loss was canceled.
414
441
  */
415
442
  private readonly handleLost;
443
+ /**
444
+ * Shows the gradient, and says so once for each time it starts to.
445
+ *
446
+ * The state is what a stylesheet reads, and the event is what a script
447
+ * logs, such as to count how many readers see the gradient. Sent again only
448
+ * after the shader has drawn in between, so a context that is lost while
449
+ * the gradient already shows is not said twice.
450
+ */
451
+ private fallBack;
416
452
  /**
417
453
  * Draws again on the context the browser gave back.
418
454
  *
@@ -424,11 +460,10 @@ export declare class HelixAura extends HelixElement {
424
460
  /**
425
461
  * Resolves the ramp. Called when the palette moves, not when a frame draws.
426
462
  *
427
- * Light pages peak on the pressed `primary-active` and dark ones on the
428
- * foreground, and the ground is what says which: mixing a saturated hue
429
- * toward near-black takes the chroma out of exactly the pixels carrying the
430
- * most of it. Read from the ground's own luminance rather than asked of the
431
- * color mode, which is a private token this tier may not reach for.
463
+ * From the canvas's own computed style, which carries each stop on a color
464
+ * property: the `--aura-*` hook where a page set one, and the token
465
+ * otherwise. `paletteOf` says which property is which, and how the peak is
466
+ * chosen for a light page or a dark one.
432
467
  */
433
468
  private readPalette;
434
469
  private link;
@@ -5,10 +5,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  var HelixAura_1;
8
- import { customElement, HelixElement, MAX_FRAME_STEP, PaintGateController, TokenColorController, } from '@fusion.dev/helix-core';
8
+ import { customElement, HelixAuraFallbackEvent, HelixElement, MAX_FRAME_STEP, PaintGateController, readColor, TokenColorController, } from '@fusion.dev/helix-core';
9
9
  import { html } from 'lit';
10
10
  import { property } from 'lit/decorators.js';
11
11
  import { tiltFor } from '../axis.js';
12
+ import { paletteOf, RESTING_PALETTE } from '../palette.js';
12
13
  import { FRAGMENT, INTERACTIONS, SHAPES, VERTEX } from '../shader.js';
13
14
  import { styles } from './aura-root.css.js';
14
15
  const MAX_CANVAS_EDGE = 4096;
@@ -16,8 +17,10 @@ const MAX_CANVAS_PIXELS = 4_194_304;
16
17
  const OPENING_PATIENCE = 500;
17
18
  const SOFTWARE_RENDERER = /swiftshader|llvmpipe|softpipe|software rasterizer|basic render/i;
18
19
  let HelixAura = class HelixAura extends HelixElement {
20
+ static { HelixAura_1 = this; }
21
+ static { this.styles = styles; }
19
22
  constructor() {
20
- super(...arguments);
23
+ super();
21
24
  this.bloom = 0.5;
22
25
  this.drift = 0;
23
26
  this.gain = 1;
@@ -27,16 +30,8 @@ let HelixAura = class HelixAura extends HelixElement {
27
30
  this.speed = 1;
28
31
  this.tilt = 14;
29
32
  this.variance = 1;
30
- this.tokens = new TokenColorController(this, () => {
31
- this.readPalette();
32
- this.paintOnce();
33
- });
34
- this.palette = {
35
- glow: [0.88, 0.88, 0.88],
36
- ground: [0, 0, 0],
37
- haze: [0.16, 0.16, 0.16],
38
- peak: [1, 1, 1],
39
- };
33
+ this.palette = { ...RESTING_PALETTE };
34
+ this.refused = 'unavailable';
40
35
  this.canvas = null;
41
36
  this.gl = null;
42
37
  this.program = null;
@@ -87,6 +82,7 @@ let HelixAura = class HelixAura extends HelixElement {
87
82
  }
88
83
  this.program = null;
89
84
  this.canvas?.toggleAttribute('hidden', true);
85
+ this.fallBack('lost');
90
86
  };
91
87
  this.handleRestored = () => {
92
88
  if (!this.prepare()) {
@@ -121,9 +117,11 @@ let HelixAura = class HelixAura extends HelixElement {
121
117
  const rect = this.getBoundingClientRect();
122
118
  this.box = { ...this.box, left: rect.left, top: rect.top };
123
119
  };
120
+ new TokenColorController(this, () => {
121
+ this.readPalette();
122
+ this.paintOnce();
123
+ });
124
124
  }
125
- static { HelixAura_1 = this; }
126
- static { this.styles = styles; }
127
125
  static { this.CONTEXT = {
128
126
  alpha: true,
129
127
  antialias: false,
@@ -132,7 +130,8 @@ let HelixAura = class HelixAura extends HelixElement {
132
130
  stencil: false,
133
131
  }; }
134
132
  render() {
135
- return html `<canvas part="canvas" aria-hidden="true"></canvas>`;
133
+ return html `<canvas part="canvas" aria-hidden="true"></canvas>
134
+ <div part="content"><slot></slot></div>`;
136
135
  }
137
136
  firstUpdated(changed) {
138
137
  super.firstUpdated(changed);
@@ -150,6 +149,7 @@ let HelixAura = class HelixAura extends HelixElement {
150
149
  this.gl = null;
151
150
  }
152
151
  if (!this.program && !this.gl?.isContextLost() && !this.build()) {
152
+ this.fallBack(this.refused);
153
153
  return;
154
154
  }
155
155
  this.canvas?.addEventListener('webglcontextlost', this.handleLost);
@@ -182,8 +182,10 @@ let HelixAura = class HelixAura extends HelixElement {
182
182
  return false;
183
183
  }
184
184
  if (HelixAura_1.drawsInSoftware()) {
185
+ this.refused = 'software';
185
186
  return false;
186
187
  }
188
+ this.refused = 'unavailable';
187
189
  let gl = canvas.getContext('webgl2', HelixAura_1.CONTEXT);
188
190
  if (gl?.isContextLost()) {
189
191
  const fresh = document.createElement('canvas');
@@ -212,6 +214,8 @@ let HelixAura = class HelixAura extends HelixElement {
212
214
  return false;
213
215
  }
214
216
  this.canvas?.toggleAttribute('hidden', false);
217
+ this.fallback = undefined;
218
+ this.toggleState('fallback', false);
215
219
  gl.useProgram(this.program);
216
220
  for (const name of [
217
221
  'uBloom',
@@ -263,17 +267,19 @@ let HelixAura = class HelixAura extends HelixElement {
263
267
  window.removeEventListener('scroll', this.handleScroll, { capture: true });
264
268
  this.release = window.setTimeout(this.drop, 0);
265
269
  }
270
+ fallBack(reason) {
271
+ if (this.fallback !== undefined) {
272
+ return;
273
+ }
274
+ this.fallback = reason;
275
+ this.toggleState('fallback', true);
276
+ this.dispatchEvent(new HelixAuraFallbackEvent({ reason }));
277
+ }
266
278
  readPalette() {
267
- const ground = this.tokens.read('--helix-color-background', [0, 0, 0]);
268
- const light = ground[0] * 0.2126 + ground[1] * 0.7152 + ground[2] * 0.0722 > 0.5;
269
- this.palette = {
270
- glow: this.tokens.read('--helix-color-primary', [0.88, 0.88, 0.88]),
271
- ground,
272
- haze: this.tokens.read('--helix-color-primary-subtle', [0.16, 0.16, 0.16]),
273
- peak: light
274
- ? this.tokens.read('--helix-color-primary-active', [0.02, 0.02, 0.02])
275
- : this.tokens.read('--helix-color-foreground', [1, 1, 1]),
276
- };
279
+ const canvas = this.renderRoot.querySelector('canvas');
280
+ if (canvas) {
281
+ this.palette = paletteOf(getComputedStyle(canvas), readColor);
282
+ }
277
283
  }
278
284
  link(vertex, fragment) {
279
285
  const gl = this.gl;
@@ -38,7 +38,7 @@ display: none;
38
38
 
39
39
  ::slotted(a) {
40
40
  background-color: transparent;
41
- border-radius: var(--helix-radii-sm);
41
+ border-radius: var(--breadcrumbs-radius, var(--helix-radii-sm));
42
42
  padding: var(--helix-space-2xs) var(--helix-space-xs);
43
43
  transition: background-color var(--helix-duration-fast) var(--helix-easing-standard);
44
44
  }
@@ -61,17 +61,17 @@ outline-offset: var(--helix-size-focus-offset);
61
61
  }
62
62
 
63
63
  :host {
64
- font-weight: var(--helix-weight-medium);
64
+ font-weight: var(--breadcrumbs-font-weight, var(--helix-weight-medium));
65
65
  }
66
66
 
67
67
  :host([current]) {
68
- color: var(--helix-color-foreground);
68
+ color: var(--breadcrumbs-current-color, var(--helix-color-foreground));
69
69
  }
70
70
 
71
71
  [part="link"] {
72
72
  align-items: center;
73
- border-radius: var(--helix-radii-sm);
74
- color: var(--helix-color-foreground-muted);
73
+ border-radius: var(--breadcrumbs-radius, var(--helix-radii-sm));
74
+ color: var(--breadcrumbs-link-color, var(--helix-color-foreground-muted));
75
75
  display: inline-flex;
76
76
  gap: var(--helix-space-xs);
77
77
  padding: var(--helix-space-2xs) var(--helix-space-xs);
@@ -95,11 +95,11 @@ background-color: var(
95
95
  --breadcrumbs-hover-color,
96
96
  color-mix(in oklab, var(--helix-color-foreground) 8%, transparent)
97
97
  );
98
- color: var(--helix-color-foreground);
98
+ color: var(--breadcrumbs-current-color, var(--helix-color-foreground));
99
99
  }
100
100
 
101
101
  :host([current]) [part="link"] {
102
- color: var(--helix-color-foreground);
102
+ color: var(--breadcrumbs-current-color, var(--helix-color-foreground));
103
103
  }
104
104
 
105
105
  :host([hidden]) {
@@ -25,7 +25,12 @@ import type { CSSResultGroup } from 'lit';
25
25
  *
26
26
  * @cssproperty --breadcrumbs-control-padding-inline - Inline padding of a control slotted into a crumb, matching the steps either side of it.
27
27
  * @cssproperty --breadcrumbs-control-size - How tall a control slotted into a crumb is.
28
+ * @cssproperty --breadcrumbs-current-color - Text color of the current page's crumb.
29
+ * @cssproperty --breadcrumbs-font-weight - Weight of every crumb's text.
28
30
  * @cssproperty --breadcrumbs-hover-color - Fill behind a step under the pointer.
31
+ * @cssproperty --breadcrumbs-link-color - Text color of a crumb that is not the current page. A link
32
+ * you slot inherits it unless your own styles set a color.
33
+ * @cssproperty --breadcrumbs-radius - Corner radius of the fill behind a step under the pointer.
29
34
  * @cssproperty --breadcrumbs-separator-color - Color of the chevron.
30
35
  */
31
36
  export declare class HelixBreadcrumb extends HelixHeadlessBreadcrumb {
@@ -7,7 +7,7 @@ display: block;
7
7
  align-items: center;
8
8
  display: flex;
9
9
  flex-wrap: wrap;
10
- font-size: var(--helix-text-sm);
10
+ font-size: var(--breadcrumbs-font-size, var(--helix-text-sm));
11
11
  gap: var(--breadcrumbs-gap, var(--helix-space-xs));
12
12
 
13
13
  list-style: none;
@@ -1,5 +1,6 @@
1
1
  import { HelixHeadlessBreadcrumbs } from '@fusion.dev/helix-headless/breadcrumbs';
2
2
  import type { CSSResultGroup } from 'lit';
3
+ import '../breadcrumb/breadcrumb.js';
3
4
  /**
4
5
  * @summary Shows the path to the current page.
5
6
  *
@@ -17,9 +18,11 @@ import type { CSSResultGroup } from 'lit';
17
18
  *
18
19
  * @csspart list - The ordered list.
19
20
  *
21
+ * @cssproperty --breadcrumbs-font-size - Size of the trail's text.
20
22
  * @cssproperty --breadcrumbs-gap - Space between items and separators.
21
23
  */
22
24
  export declare class HelixBreadcrumbs extends HelixHeadlessBreadcrumbs {
25
+ static tier: string;
23
26
  static styles: CSSResultGroup;
24
27
  }
25
28
  declare global {
@@ -7,7 +7,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { customElement } from '@fusion.dev/helix-core';
8
8
  import { HelixHeadlessBreadcrumbs } from '@fusion.dev/helix-headless/breadcrumbs';
9
9
  import { styles } from './breadcrumbs-root.css.js';
10
+ import '../breadcrumb/breadcrumb.js';
10
11
  let HelixBreadcrumbs = class HelixBreadcrumbs extends HelixHeadlessBreadcrumbs {
12
+ static { this.tier = 'helix-'; }
11
13
  static { this.styles = styles; }
12
14
  };
13
15
  HelixBreadcrumbs = __decorate([
@@ -12,6 +12,9 @@ import type { CSSResultGroup } from 'lit';
12
12
  * shadow root, where this component's styles cannot reach. The same rule works
13
13
  * for your own anchor styled as a button.
14
14
  *
15
+ * The buttons take their height from the region, so set `data-density` on the
16
+ * group to make every button in it smaller or larger together.
17
+ *
15
18
  * @since 0.1.0
16
19
  * @status stable
17
20
  * @category actions
@@ -84,6 +84,7 @@ transition: none;
84
84
  inset: 0;
85
85
  overflow: visible;
86
86
  position: absolute;
87
+ z-index: var(--helix-layer-beneath);
87
88
  }
88
89
 
89
90
  [part="edge"] {
@@ -170,11 +170,27 @@ outline-offset: var(--helix-size-focus-offset);
170
170
 
171
171
  [part="rotation"] svg,
172
172
  [part="previous"] svg,
173
- [part="next"] svg {
173
+ [part="next"] svg,
174
+ ::slotted([slot="previous-icon"]),
175
+ ::slotted([slot="next-icon"]) {
174
176
  block-size: 1em;
175
177
  inline-size: 1em;
176
178
  }
177
179
 
180
+ :host(:dir(rtl)) ::slotted([slot="previous-icon"]),
181
+ :host(:dir(rtl)) ::slotted([slot="next-icon"]) {
182
+ scale: -1 1;
183
+ }
184
+
185
+ :host([mouse-drag]) [part="track"] {
186
+ cursor: grab;
187
+ }
188
+
189
+ :host(:state(dragging)) [part="track"] {
190
+ cursor: grabbing;
191
+ user-select: none;
192
+ }
193
+
178
194
  [part="track"] {
179
195
 
180
196
  --_carousel-share: calc(
@@ -87,6 +87,7 @@ cursor: pointer;
87
87
  }
88
88
 
89
89
  [part~="cell"]:focus-visible,
90
+ [part="more-cell"]:focus-visible,
90
91
  [part~="select"]:focus-visible,
91
92
  [part="select-all"]:focus-visible {
92
93
  outline: var(--helix-size-focus-ring) solid var(--helix-color-focus-ring);
@@ -142,6 +143,68 @@ margin-inline-start: auto;
142
143
  grid-column: 1 / -1;
143
144
  }
144
145
 
146
+ :host([child-field]) [part~="cell-header"] {
147
+ --_data-table-gutter: calc(var(--helix-size-icon-tight) + var(--helix-space-2xs));
148
+ padding-inline-start: calc(
149
+ (var(--data-table-level, 1) - 1) *
150
+ var(--data-table-indent, var(--_data-table-gutter))
151
+ );
152
+ }
153
+
154
+ :host([child-field]) [part~="cell-header"]:not(:has([part~="toggle"])) {
155
+ padding-inline-start: calc(
156
+ (var(--data-table-level, 1) - 1) *
157
+ var(--data-table-indent, var(--_data-table-gutter)) +
158
+ var(--_data-table-gutter)
159
+ );
160
+ }
161
+
162
+ [part~="toggle"] {
163
+ align-items: center;
164
+ background: none;
165
+ block-size: var(--helix-size-icon-tight);
166
+ border: none;
167
+ color: var(--helix-color-foreground-muted);
168
+ cursor: pointer;
169
+ display: inline-flex;
170
+ inline-size: var(--helix-size-icon-tight);
171
+ justify-content: center;
172
+ margin-inline-end: var(--helix-space-2xs);
173
+ padding: 0;
174
+ vertical-align: middle;
175
+ }
176
+
177
+ [part="toggle-mark"] {
178
+ block-size: 100%;
179
+ inline-size: 100%;
180
+ }
181
+
182
+ [part="more"] {
183
+ display: contents;
184
+ }
185
+
186
+ [part="more-cell"] {
187
+ display: flex;
188
+ grid-column: 1 / -1;
189
+ padding-block: var(--data-table-padding-block, var(--helix-space-sm));
190
+ }
191
+
192
+ [part="more-button"] {
193
+ background: none;
194
+ border: var(--helix-border-thin) solid var(--helix-color-border);
195
+ border-radius: var(--helix-radii-sm);
196
+ color: var(--data-table-color, var(--helix-color-foreground));
197
+ cursor: pointer;
198
+ font-family: var(--helix-font-sans);
199
+ font-size: var(--data-table-text, var(--helix-text-sm));
200
+ padding-block: var(--helix-space-2xs);
201
+ padding-inline: var(--helix-space-sm);
202
+ }
203
+
204
+ [part="more-button"]:hover {
205
+ background-color: var(--helix-color-surface-raised);
206
+ }
207
+
145
208
  :host([windowed]) [part="table"] {
146
209
  block-size: var(--data-table-block-size, 24em);
147
210
  overflow-y: auto;
@@ -44,6 +44,7 @@ import '../../table/index.js';
44
44
  * @cssproperty --data-table-heading-background-color - The fill behind a heading while `windowed`.
45
45
  * It is opaque, because rows scroll under the sticky heading. Unset otherwise.
46
46
  * @cssproperty --data-table-heading-color - The text color of a heading.
47
+ * @cssproperty --data-table-indent - How far a tree grid's row header steps in for each level. It defaults to the width of the mark that opens a row.
47
48
  * @cssproperty --data-table-padding-block - The space above and below a cell's content.
48
49
  * @cssproperty --data-table-padding-inline - The space on either side of a cell's content.
49
50
  * @cssproperty --data-table-rule-color - The color of the line between rows. It takes a
@@ -24,6 +24,17 @@ overflow-wrap: anywhere;
24
24
  text-align: var(--_description-list-value-align, start);
25
25
  }
26
26
 
27
+ ::slotted(dd) {
28
+ color: var(--helix-color-foreground);
29
+ font-variant-numeric: var(--_description-list-value-figures, normal);
30
+ grid-column: -2 / -1;
31
+ justify-self: var(--_description-list-value-align, stretch);
32
+ margin: 0;
33
+ min-inline-size: 0;
34
+ overflow-wrap: anywhere;
35
+ text-align: var(--_description-list-value-align, start);
36
+ }
37
+
27
38
  @media print {
28
39
  :host {
29
40
  break-inside: avoid;
@@ -27,7 +27,8 @@ text-overflow: ellipsis;
27
27
  white-space: nowrap;
28
28
  }
29
29
 
30
- [part="mark"] {
30
+ [part="mark"],
31
+ slot[name="chevron"]::slotted(*) {
31
32
  block-size: var(--helix-size-icon-tight);
32
33
  color: var(--helix-color-foreground-subtle);
33
34
  flex: none;
@@ -31,7 +31,8 @@ inline-size: var(--helix-size-control-tight);
31
31
  justify-content: center;
32
32
  }
33
33
 
34
- [part="back"] svg {
34
+ [part="back"] svg,
35
+ slot[name="back-icon"]::slotted(*) {
35
36
  block-size: var(--helix-size-icon-tight);
36
37
  inline-size: var(--helix-size-icon-tight);
37
38
  }