@fusion.dev/helix 0.145.0 → 0.146.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 (153) hide show
  1. package/custom-elements.json +7841 -3357
  2. package/dist/accordion/item/accordion-item.css.js +12 -8
  3. package/dist/accordion/item/accordion-item.d.ts +8 -0
  4. package/dist/aura/root/aura-root.css.js +3 -0
  5. package/dist/aura/root/aura-root.d.ts +21 -9
  6. package/dist/aura/root/aura-root.js +23 -12
  7. package/dist/badge/root/badge-root.css.js +86 -16
  8. package/dist/badge/root/badge-root.d.ts +18 -0
  9. package/dist/badge/root/badge-root.js +6 -0
  10. package/dist/blockquote/root/blockquote-root.css.js +2 -2
  11. package/dist/blockquote/root/blockquote-root.d.ts +2 -0
  12. package/dist/breadcrumbs/root/breadcrumbs-root.css.js +23 -0
  13. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +1 -0
  14. package/dist/button/root/button-root.css.js +4 -3
  15. package/dist/button/root/button-root.d.ts +2 -0
  16. package/dist/callout/root/callout-root.css.js +4 -3
  17. package/dist/callout/root/callout-root.d.ts +6 -2
  18. package/dist/card/root/card-root.d.ts +6 -0
  19. package/dist/chat/message/chat-message.css.js +0 -62
  20. package/dist/chat/message/chat-message.js +2 -1
  21. package/dist/chat/root/chat-root.css.js +7 -0
  22. package/dist/chat/root/chat-root.d.ts +2 -0
  23. package/dist/chat/root/chat-root.js +2 -1
  24. package/dist/chat/typing.css.d.ts +1 -0
  25. package/dist/chat/typing.css.js +62 -0
  26. package/dist/checkbox/root/checkbox-root.css.js +15 -0
  27. package/dist/checkbox/root/checkbox-root.d.ts +2 -1
  28. package/dist/code/root/code-root.css.js +2 -2
  29. package/dist/code/root/code-root.d.ts +2 -0
  30. package/dist/code-block/root/code-block-root.css.js +24 -0
  31. package/dist/code-block/root/code-block-root.d.ts +2 -1
  32. package/dist/color-input/root/color-input-root.css.js +10 -0
  33. package/dist/color-picker/root/color-picker-root.css.js +8 -0
  34. package/dist/color-picker/root/color-picker-root.d.ts +1 -0
  35. package/dist/copy-button/root/copy-button-root.css.js +15 -6
  36. package/dist/copy-button/root/copy-button-root.d.ts +7 -0
  37. package/dist/data-table/root/data-table-root.css.js +14 -7
  38. package/dist/data-table/root/data-table-root.d.ts +5 -0
  39. package/dist/date-input/root/date-input-root.css.js +10 -0
  40. package/dist/donut-chart/root/donut-chart-root.css.js +19 -0
  41. package/dist/donut-chart/root/donut-chart-root.d.ts +3 -0
  42. package/dist/drawer/root/drawer-root.css.js +47 -0
  43. package/dist/drawer/root/drawer-root.d.ts +5 -0
  44. package/dist/drilldown/item/drilldown-item.css.js +6 -6
  45. package/dist/drilldown/item/drilldown-item.d.ts +6 -0
  46. package/dist/drilldown/root/drilldown-root.css.js +25 -12
  47. package/dist/drilldown/root/drilldown-root.d.ts +10 -0
  48. package/dist/element-events.generated.js +15 -5
  49. package/dist/file-input/root/file-input-root.css.js +12 -11
  50. package/dist/file-input/root/file-input-root.d.ts +11 -0
  51. package/dist/filter-input/root/filter-input-root.css.js +6 -5
  52. package/dist/filter-input/root/filter-input-root.d.ts +5 -0
  53. package/dist/flex/root/flex-root.css.js +9 -0
  54. package/dist/flex/root/flex-root.d.ts +17 -6
  55. package/dist/graph/root/graph-root.css.js +11 -8
  56. package/dist/graph/root/graph-root.d.ts +8 -0
  57. package/dist/grid/root/grid-root.d.ts +4 -1
  58. package/dist/heatmap/root/heatmap-root.css.js +2 -1
  59. package/dist/icon-button/root/icon-button-root.css.js +68 -13
  60. package/dist/icon-button/root/icon-button-root.d.ts +4 -0
  61. package/dist/kbd/root/kbd-root.css.js +27 -0
  62. package/dist/kbd/root/kbd-root.d.ts +2 -0
  63. package/dist/lightbox/item/lightbox-item.css.js +4 -0
  64. package/dist/lightbox/root/lightbox-root.css.js +41 -0
  65. package/dist/line-chart/root/line-chart-root.css.js +16 -0
  66. package/dist/line-chart/root/line-chart-root.d.ts +2 -0
  67. package/dist/listbox/root/listbox-root.css.js +9 -0
  68. package/dist/listbox/root/listbox-root.d.ts +1 -0
  69. package/dist/loader/root/loader-root.css.js +3 -3
  70. package/dist/loader/root/loader-root.d.ts +2 -0
  71. package/dist/megamenu/root/megamenu-root.css.js +16 -13
  72. package/dist/megamenu/root/megamenu-root.d.ts +11 -0
  73. package/dist/menu/item/menu-item.css.js +25 -4
  74. package/dist/menu/item/menu-item.d.ts +1 -0
  75. package/dist/meter/root/meter-root.css.js +6 -3
  76. package/dist/meter/root/meter-root.d.ts +1 -0
  77. package/dist/navigation/root/navigation-root.d.ts +7 -0
  78. package/dist/notifications/root/notifications-root.css.js +6 -0
  79. package/dist/number-input/root/number-input-root.css.js +12 -9
  80. package/dist/number-input/root/number-input-root.d.ts +8 -0
  81. package/dist/object-inspector/root/object-inspector-root.css.js +2 -6
  82. package/dist/option/root/option-root.css.js +1 -1
  83. package/dist/orb/root/orb-root.d.ts +14 -6
  84. package/dist/orb/root/orb-root.js +16 -27
  85. package/dist/pin-input/root/pin-input-root.css.js +4 -4
  86. package/dist/pin-input/root/pin-input-root.d.ts +4 -0
  87. package/dist/progress/root/progress-root.css.js +4 -2
  88. package/dist/progress/root/progress-root.d.ts +1 -0
  89. package/dist/qr-code/root/qr-code-root.css.js +11 -0
  90. package/dist/quote/root/quote-root.css.js +3 -0
  91. package/dist/quote/root/quote-root.d.ts +2 -0
  92. package/dist/radio/root/radio-root.css.js +16 -0
  93. package/dist/radio/root/radio-root.d.ts +2 -1
  94. package/dist/sandbox/frame.d.ts +3 -2
  95. package/dist/sandbox/frame.js +19 -5
  96. package/dist/sandbox/index.d.ts +1 -0
  97. package/dist/sandbox/source/sandbox-source.css.js +70 -0
  98. package/dist/sandbox/source/sandbox-source.d.ts +34 -0
  99. package/dist/sandbox/source/sandbox-source.js +15 -0
  100. package/dist/sandbox/terminal/sandbox-terminal.d.ts +10 -2
  101. package/dist/sandbox/terminal/sandbox-terminal.js +18 -5
  102. package/dist/sandbox/tokens.d.ts +39 -0
  103. package/dist/sandbox/tokens.js +9 -0
  104. package/dist/scatter-chart/root/scatter-chart-root.css.js +9 -0
  105. package/dist/scatter-chart/root/scatter-chart-root.d.ts +2 -0
  106. package/dist/skeleton/root/skeleton-root.css.js +11 -11
  107. package/dist/skeleton/root/skeleton-root.d.ts +1 -0
  108. package/dist/skip-link/root/skip-link-root.css.js +12 -0
  109. package/dist/skip-link/root/skip-link-root.d.ts +3 -3
  110. package/dist/slider/root/slider-root.css.js +26 -0
  111. package/dist/sparkline/root/sparkline-root.css.js +49 -0
  112. package/dist/sparkline/root/sparkline-root.d.ts +6 -0
  113. package/dist/sparkline/root/sparkline-root.js +2 -1
  114. package/dist/speed-dial/item/speed-dial-item.css.js +7 -6
  115. package/dist/speed-dial/item/speed-dial-item.d.ts +3 -0
  116. package/dist/speed-dial/root/speed-dial-root.css.js +10 -5
  117. package/dist/speed-dial/root/speed-dial-root.d.ts +7 -1
  118. package/dist/speed-dial/root/speed-dial-root.js +0 -1
  119. package/dist/stat/root/stat-root.css.js +4 -0
  120. package/dist/steps/root/steps-root.css.js +28 -0
  121. package/dist/steps/root/steps-root.d.ts +5 -0
  122. package/dist/tabs/root/tabs-root.css.js +2 -2
  123. package/dist/tabs/root/tabs-root.d.ts +4 -0
  124. package/dist/tabs/tab/tab.css.js +16 -9
  125. package/dist/tabs/tab/tab.d.ts +7 -0
  126. package/dist/tag/group/tag-group.css.js +6 -0
  127. package/dist/text/clamp.d.ts +5 -2
  128. package/dist/text/clamp.js +3 -1
  129. package/dist/text/root/text-root.css.js +0 -6
  130. package/dist/text/root/text-root.d.ts +2 -1
  131. package/dist/textarea/root/textarea-root.css.js +27 -0
  132. package/dist/time-input/root/time-input-root.css.js +12 -0
  133. package/dist/time-picker/root/time-picker-root.css.js +1 -1
  134. package/dist/toast/item/toast-item.css.js +10 -0
  135. package/dist/toast/root/toast-root.d.ts +1 -0
  136. package/dist/toast/root/toast-root.js +1 -0
  137. package/dist/toggle/group/toggle-group.css.js +10 -7
  138. package/dist/toggle/group/toggle-group.d.ts +6 -1
  139. package/dist/toggle/root/toggle-root.d.ts +6 -0
  140. package/dist/toolbar/root/toolbar-root.css.js +1 -0
  141. package/dist/toolbar/root/toolbar-root.d.ts +2 -0
  142. package/dist/tooltip/root/tooltip-root.css.js +5 -5
  143. package/dist/tooltip/root/tooltip-root.d.ts +4 -0
  144. package/dist/tree/item/tree-item.css.js +19 -9
  145. package/dist/tree/item/tree-item.d.ts +9 -0
  146. package/dist/trend/root/trend-root.css.js +3 -5
  147. package/dist/trend/root/trend-root.d.ts +2 -2
  148. package/dist/virtual-list/root/virtual-list-root.css.js +14 -0
  149. package/dist/virtual-list/root/virtual-list-root.d.ts +7 -1
  150. package/lint.json +1 -1
  151. package/package.json +9 -9
  152. package/types/jsx.d.ts +4289 -631
  153. package/types/vue.d.ts +1296 -127
@@ -8,11 +8,11 @@ all: unset;
8
8
 
9
9
  box-sizing: border-box;
10
10
  align-items: center;
11
- color: var(--helix-color-foreground);
11
+ color: var(--accordion-item-color, var(--helix-color-foreground));
12
12
  cursor: pointer;
13
13
  display: flex;
14
- font-size: var(--helix-text-md);
15
- font-weight: var(--helix-weight-medium);
14
+ font-size: var(--accordion-item-font-size, var(--helix-text-md));
15
+ font-weight: var(--accordion-item-font-weight, var(--helix-weight-medium));
16
16
  inline-size: 100%;
17
17
 
18
18
  gap: var(--helix-space-xs);
@@ -24,7 +24,7 @@ transition: background-color var(--helix-duration-fast) var(--helix-easing-stand
24
24
 
25
25
  [part="chevron"] {
26
26
  block-size: 1em;
27
- color: var(--helix-color-foreground-subtle);
27
+ color: var(--accordion-item-chevron-color, var(--helix-color-foreground-subtle));
28
28
  flex: 0 0 auto;
29
29
  inline-size: 1em;
30
30
  transform: scaleY(1);
@@ -33,7 +33,7 @@ transition: transform var(--helix-duration-fast) var(--helix-easing-standard);
33
33
 
34
34
  ::slotted([slot="chevron"]) {
35
35
  block-size: 1em;
36
- color: var(--helix-color-foreground-subtle);
36
+ color: var(--accordion-item-chevron-color, var(--helix-color-foreground-subtle));
37
37
  flex: 0 0 auto;
38
38
  inline-size: 1em;
39
39
  transition: transform var(--helix-duration-fast) var(--helix-easing-standard);
@@ -49,14 +49,18 @@ margin-inline-start: auto;
49
49
  transform: scaleY(-1);
50
50
  }
51
51
 
52
+ [part="trigger"]:hover:not(:disabled) {
53
+ background-color: var(--accordion-item-hover-background-color, transparent);
54
+ }
55
+
52
56
  [part="trigger"]:hover:not(:disabled) [part="chevron"],
53
57
  [part="trigger"]:hover:not(:disabled) ::slotted([slot="chevron"]) {
54
- color: var(--helix-color-foreground);
58
+ color: var(--accordion-item-chevron-hover-color, var(--helix-color-foreground));
55
59
  }
56
60
 
57
61
  [part="trigger"]:disabled {
58
62
  cursor: not-allowed;
59
- opacity: 0.5;
63
+ opacity: var(--accordion-item-disabled-opacity, 0.5);
60
64
  }
61
65
 
62
66
  [part="trigger"]:focus-visible {
@@ -81,7 +85,7 @@ overflow: hidden;
81
85
  }
82
86
 
83
87
  [part="content-inner"] > slot {
84
- color: var(--helix-color-foreground-muted);
88
+ color: var(--accordion-item-content-color, var(--helix-color-foreground-muted));
85
89
  display: block;
86
90
  line-height: var(--helix-leading-normal);
87
91
  padding: var(--accordion-item-padding, var(--helix-space-sm) var(--helix-space-md));
@@ -27,6 +27,14 @@ import type { CSSResultGroup } from 'lit';
27
27
  * @csspart heading - The heading that holds the trigger.
28
28
  * @csspart trigger - The button that opens and closes the section, holding the summary.
29
29
  *
30
+ * @cssproperty --accordion-item-chevron-color - The color of the open and close indicator.
31
+ * @cssproperty --accordion-item-chevron-hover-color - The indicator's color while the pointer is on the trigger.
32
+ * @cssproperty --accordion-item-color - The color of the trigger's text.
33
+ * @cssproperty --accordion-item-content-color - The color of the content's text.
34
+ * @cssproperty --accordion-item-disabled-opacity - How faint a disabled trigger is drawn.
35
+ * @cssproperty --accordion-item-font-size - The size of the trigger's text.
36
+ * @cssproperty --accordion-item-font-weight - The weight of the trigger's text.
37
+ * @cssproperty --accordion-item-hover-background-color - The trigger's fill while the pointer is on it. Unset, there is none.
30
38
  * @cssproperty --accordion-item-padding - The padding of the trigger and the content.
31
39
  */
32
40
  export declare class HelixAccordionItem extends HelixHeadlessAccordionItem {
@@ -36,6 +36,9 @@ color: var(--_aura-glow);
36
36
  column-rule-color: var(--aura-peak, var(--helix-color-primary-active));
37
37
  outline-color: var(--_aura-ground);
38
38
  text-decoration-color: var(--_aura-haze);
39
+
40
+ transition-duration: var(--helix-duration-fast);
41
+ transition-property: caret-color, color, column-rule-color, outline-color, text-decoration-color;
39
42
  }
40
43
 
41
44
  [part="content"] {
@@ -40,7 +40,9 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
40
40
  *
41
41
  * **The colors are the theme's, and each has a hook**: `--aura-ground`,
42
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.
43
+ * fallback gradient alike, from wherever on the page you set them. A hook
44
+ * changed while the aura draws, by a class, a style or the color mode,
45
+ * reaches the shader on the next frame.
44
46
  *
45
47
  * Where the gradient shows in place of the shader, the aura matches
46
48
  * `:state(fallback)` and sends `helix-aura-fallback` with the reason.
@@ -197,18 +199,25 @@ export declare class HelixAura extends HelixElement {
197
199
  * states.
198
200
  */
199
201
  variant?: 'aurora' | 'braid' | 'caustics' | 'flow' | 'fracture' | 'lattice' | 'particles' | 'rays' | 'streaks' | 'threads' | 'waves';
200
- constructor();
201
202
  /**
202
203
  * The four ramp stops, resolved.
203
204
  *
204
- * **Cached, because reading them is not free and they do not move.** Each
205
- * read sets a style, calls `getComputedStyle`, fills a pixel and reads it
206
- * back: a style recalc and a canvas readback apiece. Doing that inside
207
- * `paint` meant four of each on every frame, forever, to fetch values that
208
- * change only when the color mode does. The controller already says when
209
- * that happens, so this is filled from there and from the first paint.
205
+ * **Read on every frame drawn, and converted only when they moved.** A hook
206
+ * can change anywhere above the aura at any time: a class on a section, a
207
+ * style written by script, a scoped theme, the color mode. Each frame reads
208
+ * the five colors the canvas carries off its live computed style, which is
209
+ * a string compare while nothing changed, and `paletteOf` converts them only
210
+ * when the text differs. Converting on every frame was the cost: a style
211
+ * recalc and a canvas readback per stop, forever, for values that rarely
212
+ * move.
213
+ *
214
+ * A stopped loop draws no frame to read in, so a change of any of the five
215
+ * also runs a short transition on the canvas, and its end paints one frame.
216
+ * That covers a reader who asked for no motion.
210
217
  */
211
218
  private palette;
219
+ /** The canvas's live computed style, and the five colors it last carried. */
220
+ private carried;
212
221
  /** Why the gradient shows, while it does, or `undefined` while the shader draws. */
213
222
  private fallback;
214
223
  /** Why the last `build` drew nothing, for the fallback it leads to. */
@@ -458,7 +467,8 @@ export declare class HelixAura extends HelixElement {
458
467
  */
459
468
  private readonly handleRestored;
460
469
  /**
461
- * Resolves the ramp. Called when the palette moves, not when a frame draws.
470
+ * Resolves the ramp, converting only when the colors the canvas carries
471
+ * moved since the last read.
462
472
  *
463
473
  * From the canvas's own computed style, which carries each stop on a color
464
474
  * property: the `--aura-*` hook where a page set one, and the token
@@ -466,6 +476,8 @@ export declare class HelixAura extends HelixElement {
466
476
  * chosen for a light page or a dark one.
467
477
  */
468
478
  private readPalette;
479
+ /** One frame for a stopped loop, once a color the canvas carries has moved. */
480
+ private readonly handleRestyle;
469
481
  private link;
470
482
  /**
471
483
  * Re-reads the box and resizes the drawing buffer to match.
@@ -5,7 +5,7 @@ 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, HelixAuraFallbackEvent, HelixElement, MAX_FRAME_STEP, PaintGateController, readColor, TokenColorController, } from '@fusion.dev/helix-core';
8
+ import { customElement, HelixAuraFallbackEvent, HelixElement, MAX_FRAME_STEP, PaintGateController, readColor, } 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';
@@ -17,10 +17,8 @@ const MAX_CANVAS_PIXELS = 4_194_304;
17
17
  const OPENING_PATIENCE = 500;
18
18
  const SOFTWARE_RENDERER = /swiftshader|llvmpipe|softpipe|software rasterizer|basic render/i;
19
19
  let HelixAura = class HelixAura extends HelixElement {
20
- static { HelixAura_1 = this; }
21
- static { this.styles = styles; }
22
20
  constructor() {
23
- super();
21
+ super(...arguments);
24
22
  this.bloom = 0.5;
25
23
  this.drift = 0;
26
24
  this.gain = 1;
@@ -31,6 +29,7 @@ let HelixAura = class HelixAura extends HelixElement {
31
29
  this.tilt = 14;
32
30
  this.variance = 1;
33
31
  this.palette = { ...RESTING_PALETTE };
32
+ this.carried = null;
34
33
  this.refused = 'unavailable';
35
34
  this.canvas = null;
36
35
  this.gl = null;
@@ -99,6 +98,9 @@ let HelixAura = class HelixAura extends HelixElement {
99
98
  this.open();
100
99
  }
101
100
  };
101
+ this.handleRestyle = () => {
102
+ this.paintOnce();
103
+ };
102
104
  this.held = 0;
103
105
  this.handlePointer = (event) => {
104
106
  if (this.gate.reduced) {
@@ -117,11 +119,9 @@ let HelixAura = class HelixAura extends HelixElement {
117
119
  const rect = this.getBoundingClientRect();
118
120
  this.box = { ...this.box, left: rect.left, top: rect.top };
119
121
  };
120
- new TokenColorController(this, () => {
121
- this.readPalette();
122
- this.paintOnce();
123
- });
124
122
  }
123
+ static { HelixAura_1 = this; }
124
+ static { this.styles = styles; }
125
125
  static { this.CONTEXT = {
126
126
  alpha: true,
127
127
  antialias: false,
@@ -154,11 +154,11 @@ let HelixAura = class HelixAura extends HelixElement {
154
154
  }
155
155
  this.canvas?.addEventListener('webglcontextlost', this.handleLost);
156
156
  this.canvas?.addEventListener('webglcontextrestored', this.handleRestored);
157
+ this.canvas?.addEventListener('transitionend', this.handleRestyle);
157
158
  this.addEventListener('pointermove', this.handlePointer);
158
159
  this.addEventListener('pointerleave', this.handleLeave);
159
160
  this.gate.watch();
160
161
  window.addEventListener('scroll', this.handleScroll, { capture: true, passive: true });
161
- this.readPalette();
162
162
  if (this.measure() || (this.width && !this.opened)) {
163
163
  this.open();
164
164
  }
@@ -262,6 +262,7 @@ let HelixAura = class HelixAura extends HelixElement {
262
262
  }
263
263
  this.canvas?.removeEventListener('webglcontextlost', this.handleLost);
264
264
  this.canvas?.removeEventListener('webglcontextrestored', this.handleRestored);
265
+ this.canvas?.removeEventListener('transitionend', this.handleRestyle);
265
266
  this.removeEventListener('pointermove', this.handlePointer);
266
267
  this.removeEventListener('pointerleave', this.handleLeave);
267
268
  window.removeEventListener('scroll', this.handleScroll, { capture: true });
@@ -276,9 +277,18 @@ let HelixAura = class HelixAura extends HelixElement {
276
277
  this.dispatchEvent(new HelixAuraFallbackEvent({ reason }));
277
278
  }
278
279
  readPalette() {
279
- const canvas = this.renderRoot.querySelector('canvas');
280
- if (canvas) {
281
- this.palette = paletteOf(getComputedStyle(canvas), readColor);
280
+ const canvas = this.canvas;
281
+ if (!canvas) {
282
+ return;
283
+ }
284
+ if (this.carried?.canvas !== canvas) {
285
+ this.carried = { canvas, style: getComputedStyle(canvas), text: '' };
286
+ }
287
+ const { style } = this.carried;
288
+ const text = `${style.color} ${style.textDecorationColor} ${style.outlineColor} ${style.columnRuleColor} ${style.caretColor}`;
289
+ if (text !== this.carried.text) {
290
+ this.carried.text = text;
291
+ this.palette = paletteOf(style, readColor);
282
292
  }
283
293
  }
284
294
  link(vertex, fragment) {
@@ -356,6 +366,7 @@ let HelixAura = class HelixAura extends HelixElement {
356
366
  if (!gl || !this.program || !this.width) {
357
367
  return;
358
368
  }
369
+ this.readPalette();
359
370
  const { glow, ground, haze, peak } = this.palette;
360
371
  gl.uniform3fv(uniforms.uGround ?? null, ground);
361
372
  gl.uniform3fv(uniforms.uHaze ?? null, haze);
@@ -7,6 +7,8 @@ export const styles = createSheet(`:host {
7
7
  --_badge-dot: var(--helix-space-xs);
8
8
 
9
9
  --_badge-on: var(--helix-color-foreground-on-primary);
10
+
11
+ --_badge-fill: var(--helix-color-primary-surface);
10
12
  display: inline-flex;
11
13
  position: relative;
12
14
  vertical-align: middle;
@@ -15,7 +17,7 @@ vertical-align: middle;
15
17
  [part="indicator"] {
16
18
  align-items: center;
17
19
 
18
- background-color: var(--badge-background-color, var(--helix-color-primary-surface));
20
+ background-color: var(--badge-background-color, var(--_badge-fill));
19
21
  block-size: var(--_badge-size);
20
22
  border-radius: var(--helix-radii-full);
21
23
 
@@ -65,12 +67,12 @@ opacity var(--helix-duration-fast) var(--helix-easing-standard),
65
67
  scale var(--helix-duration-fast) var(--helix-easing-accelerate);
66
68
  }
67
69
 
68
- :host([tone="primary"]) [part="indicator"] {
69
- background-color: var(--badge-background-color, var(--helix-color-primary-surface));
70
+ :host([tone="primary"]) {
71
+ --_badge-fill: var(--helix-color-primary-surface);
70
72
  }
71
73
 
72
- :host([tone="accent"]) [part="indicator"] {
73
- background-color: var(--badge-background-color, var(--helix-color-accent-surface));
74
+ :host([tone="accent"]) {
75
+ --_badge-fill: var(--helix-color-accent-surface);
74
76
  }
75
77
 
76
78
  :host([tone="accent"]) {
@@ -84,25 +86,25 @@ background-color: var(--badge-background-color, var(--helix-color-accent-surface
84
86
  --_badge-on: var(--helix-color-foreground-on-status);
85
87
  }
86
88
 
87
- :host([tone="info"]) [part="indicator"] {
88
- background-color: var(--badge-background-color, var(--helix-color-info-surface));
89
+ :host([tone="info"]) {
90
+ --_badge-fill: var(--helix-color-info-surface);
89
91
  }
90
92
 
91
- :host([tone="success"]) [part="indicator"] {
92
- background-color: var(--badge-background-color, var(--helix-color-success-surface));
93
+ :host([tone="success"]) {
94
+ --_badge-fill: var(--helix-color-success-surface);
93
95
  }
94
96
 
95
- :host([tone="warning"]) [part="indicator"] {
96
- background-color: var(--badge-background-color, var(--helix-color-warning-surface));
97
+ :host([tone="warning"]) {
98
+ --_badge-fill: var(--helix-color-warning-surface);
97
99
  }
98
100
 
99
- :host([tone="danger"]) [part="indicator"] {
100
- background-color: var(--badge-background-color, var(--helix-color-danger-surface));
101
+ :host([tone="danger"]) {
102
+ --_badge-fill: var(--helix-color-danger-surface);
101
103
  }
102
104
 
103
- :host([tone="neutral"]) [part="indicator"] {
104
- background-color: var(--badge-background-color, var(--helix-color-surface-raised));
105
- color: var(--badge-color, var(--helix-color-foreground));
105
+ :host([tone="neutral"]) {
106
+ --_badge-fill: var(--helix-color-surface-raised);
107
+ --_badge-on: var(--helix-color-foreground);
106
108
  }
107
109
 
108
110
  :host([placement="top-start"]) [part="indicator"],
@@ -140,6 +142,74 @@ position: static;
140
142
  translate: none;
141
143
  }
142
144
 
145
+ :host([emphasis="outlined"]) [part="indicator"] {
146
+ background-color: var(--badge-background-color, var(--helix-color-background));
147
+ box-shadow:
148
+ inset 0 0 0 var(--helix-border-thick) var(--_badge-fill),
149
+ 0 0 0 var(--helix-border-thick) var(--badge-ring-color, var(--helix-color-background));
150
+ color: var(--badge-color, var(--helix-color-foreground));
151
+ }
152
+
153
+ :host([emphasis="subtle"]) [part="indicator"] {
154
+ background-color: var(
155
+ --badge-background-color,
156
+ color-mix(in oklab, var(--_badge-fill) 22%, var(--helix-color-background))
157
+ );
158
+ color: var(--badge-color, var(--helix-color-foreground));
159
+ }
160
+
161
+ :host([emphasis="outlined"][placement="inline"]) [part="indicator"] {
162
+ box-shadow: inset 0 0 0 var(--helix-border-thick) var(--_badge-fill);
163
+ }
164
+
165
+ :host([attention="pulse"]) [part="indicator"]:not([data-blank]) {
166
+ animation: badge-pulse var(--badge-attention-duration, 1.5s) var(--helix-easing-standard) infinite;
167
+ }
168
+
169
+ :host([attention="bounce"]) [part="indicator"]:not([data-blank]) {
170
+ animation: badge-bounce var(--badge-attention-duration, 1s) var(--helix-easing-standard) infinite;
171
+ }
172
+
173
+ @keyframes badge-pulse {
174
+ 0%,
175
+ 100% {
176
+ transform: scale(1);
177
+ }
178
+
179
+ 50% {
180
+ transform: scale(1.18);
181
+ }
182
+ }
183
+
184
+ @keyframes badge-bounce {
185
+ 0%,
186
+ 20%,
187
+ 53%,
188
+ 100% {
189
+ transform: translateY(0);
190
+ }
191
+
192
+ 40%,
193
+ 43% {
194
+ transform: translateY(-30%);
195
+ }
196
+
197
+ 70% {
198
+ transform: translateY(-15%);
199
+ }
200
+
201
+ 90% {
202
+ transform: translateY(-4%);
203
+ }
204
+ }
205
+
206
+ @media (prefers-reduced-motion: reduce) {
207
+ :host([attention="pulse"]) [part="indicator"]:not([data-blank]),
208
+ :host([attention="bounce"]) [part="indicator"]:not([data-blank]) {
209
+ animation: none;
210
+ }
211
+ }
212
+
143
213
  @media print {
144
214
  :host {
145
215
  box-shadow: none;
@@ -20,6 +20,7 @@ import type { CSSResultGroup } from 'lit';
20
20
  * @aliases Count, Indicator, Pip
21
21
  * @documentation https://fusion.dev/helix/components/badge
22
22
  *
23
+ * @cssproperty --badge-attention-duration - How long one beat of `attention` takes.
23
24
  * @cssproperty --badge-background-color - The fill of the indicator.
24
25
  * @cssproperty --badge-color - The color of the count, to pair with a fill set through `--badge-background-color`.
25
26
  * @cssproperty --badge-gap - The space between the content and the count under `placement="inline"`.
@@ -27,6 +28,23 @@ import type { CSSResultGroup } from 'lit';
27
28
  * @cssproperty --badge-ring-color - The color of the ring between the indicator and what is behind it.
28
29
  */
29
30
  export declare class HelixBadge extends HelixHeadlessBadge {
31
+ /**
32
+ * An effect that draws the eye to the mark: `pulse` swells it in a loop and
33
+ * `bounce` hops it, as Web Awesome's badge does.
34
+ *
35
+ * Absent is still, which is right for almost every count: a mark that moves
36
+ * is a mark that interrupts. Still for a reader who asked the system for
37
+ * less motion, and while the mark is going away.
38
+ */
39
+ attention?: 'bounce' | 'pulse';
40
+ /**
41
+ * How strongly the mark is drawn: `solid`, `outlined` or `subtle`, `Tag`'s
42
+ * axis.
43
+ *
44
+ * Absent is `solid`, the tone's fill. `outlined` draws the fill as a ring on
45
+ * the page's ground and `subtle` as a tint, both with the page's ink.
46
+ */
47
+ emphasis?: 'outlined' | 'solid' | 'subtle';
30
48
  /**
31
49
  * Where the mark sits: a corner, `top-start`, `bottom-end` or `bottom-start`,
32
50
  * or `inline`, in the line after the content.
@@ -11,6 +11,12 @@ import { styles } from './badge-root.css.js';
11
11
  let HelixBadge = class HelixBadge extends HelixHeadlessBadge {
12
12
  static { this.styles = styles; }
13
13
  };
14
+ __decorate([
15
+ property({ reflect: true })
16
+ ], HelixBadge.prototype, "attention", void 0);
17
+ __decorate([
18
+ property({ reflect: true })
19
+ ], HelixBadge.prototype, "emphasis", void 0);
14
20
  __decorate([
15
21
  property({ reflect: true })
16
22
  ], HelixBadge.prototype, "placement", void 0);
@@ -17,9 +17,9 @@ slot:not([name]) {
17
17
  color: var(--blockquote-color, var(--helix-color-foreground-muted));
18
18
  font-family: var(--blockquote-font-family, var(--helix-font-display));
19
19
  font-size: var(--blockquote-size, var(--helix-text-xl));
20
- font-weight: var(--helix-weight-medium);
20
+ font-weight: var(--blockquote-font-weight, var(--helix-weight-medium));
21
21
  letter-spacing: var(--helix-tracking-tight);
22
- line-height: var(--helix-leading-tight);
22
+ line-height: var(--blockquote-line-height, var(--helix-leading-tight));
23
23
  }
24
24
 
25
25
  slot:not([name])::slotted(*) {
@@ -18,7 +18,9 @@ import type { CSSResultGroup } from 'lit';
18
18
  * @cssproperty --blockquote-attribution-size - The font size of the attribution.
19
19
  * @cssproperty --blockquote-color - The color of the quoted passage.
20
20
  * @cssproperty --blockquote-font-family - The typeface of the quoted passage, the display face by default.
21
+ * @cssproperty --blockquote-font-weight - The weight of the quoted passage, medium by default.
21
22
  * @cssproperty --blockquote-gap - The space between the passage and its attribution.
23
+ * @cssproperty --blockquote-line-height - The line height of the quoted passage, the tight leading by default.
22
24
  * @cssproperty --blockquote-size - The font size of the quoted passage.
23
25
  */
24
26
  export declare class HelixBlockquote extends HelixHeadlessBlockquote {
@@ -15,6 +15,29 @@ margin: var(--helix-space-none);
15
15
  padding: var(--helix-space-none);
16
16
  }
17
17
 
18
+ [part="expand"] {
19
+ all: unset;
20
+ border-radius: var(--breadcrumbs-radius, var(--helix-radii-sm));
21
+ box-sizing: border-box;
22
+ color: var(--breadcrumbs-link-color, var(--helix-color-foreground-muted));
23
+ cursor: pointer;
24
+ line-height: var(--helix-leading-normal);
25
+ padding: var(--helix-space-2xs) var(--helix-space-xs);
26
+ }
27
+
28
+ [part="expand"]:hover {
29
+ background-color: var(
30
+ --breadcrumbs-hover-color,
31
+ color-mix(in oklab, var(--helix-color-foreground) 8%, transparent)
32
+ );
33
+ color: var(--breadcrumbs-current-color, var(--helix-color-foreground));
34
+ }
35
+
36
+ [part="expand"]:focus-visible {
37
+ outline: var(--helix-size-focus-ring) solid var(--helix-color-focus-ring);
38
+ outline-offset: var(--helix-size-focus-offset);
39
+ }
40
+
18
41
  @media print {
19
42
  :host {
20
43
  print-color-adjust: economy;
@@ -16,6 +16,7 @@ import '../breadcrumb/breadcrumb.js';
16
16
  *
17
17
  * @slot - The trail's items, in order from root to current page.
18
18
  *
19
+ * @csspart expand - The button in the folded crumb that shows the whole trail.
19
20
  * @csspart list - The ordered list.
20
21
  *
21
22
  * @cssproperty --breadcrumbs-font-size - Size of the trail's text.
@@ -195,10 +195,11 @@ visibility: hidden;
195
195
  }
196
196
 
197
197
  :host(:state(pending)) [part="button"]::after {
198
- animation: helix-button-turn var(--_button-turn) linear infinite;
198
+ animation: helix-button-turn var(--button-spinner-duration, var(--_button-turn)) linear infinite;
199
199
  block-size: var(--button-spinner-size, 1.15em);
200
- border: var(--helix-border-thick) solid color-mix(in oklab, currentColor 30%, transparent);
201
- border-block-start-color: currentColor;
200
+ border: var(--helix-border-thick) solid
201
+ color-mix(in oklab, var(--button-spinner-color, currentColor) 30%, transparent);
202
+ border-block-start-color: var(--button-spinner-color, currentColor);
202
203
  border-radius: var(--helix-radii-full);
203
204
  box-sizing: border-box;
204
205
  content: "";
@@ -43,6 +43,8 @@ declare const HelixButton_base: (new (...args: any[]) => import("../../shared/mi
43
43
  * @cssproperty --button-radius-start-end - The top trailing corner, for a group stacking down.
44
44
  * @cssproperty --button-radius-start-start - The top leading corner, for a group stacking down.
45
45
  * @cssproperty --button-size - Height of the control, for a row height outside the density steps.
46
+ * @cssproperty --button-spinner-color - Color of the ring a pending button turns. It follows the label's color.
47
+ * @cssproperty --button-spinner-duration - How long the ring takes to turn once.
46
48
  * @cssproperty --button-spinner-size - Size of the ring a pending button turns. Defaults to the size of its icons.
47
49
  *
48
50
  * @cssstate pending - The button is pending: `pending` is set. A ring turns over its hidden words.
@@ -4,9 +4,10 @@ export const styles = createSheet(`:host {
4
4
 
5
5
  --_callout-color: var(--callout-accent-color, var(--_callout-tone));
6
6
  --_callout-bar: var(--callout-bar-thickness, var(--helix-border-thick));
7
- --_callout-inset: var(--callout-padding, var(--helix-space-md));
8
7
 
9
- font-size: var(--callout-font-size, var(--helix-text-sm));
8
+ --_callout-inset: var(--callout-padding, var(--helix-space-control));
9
+
10
+ font-size: var(--callout-font-size, var(--helix-text-control));
10
11
  background-color: var(
11
12
  --callout-background-color,
12
13
  color-mix(in oklab, var(--_callout-color) 10%, transparent)
@@ -129,7 +130,7 @@ slot[name="heading"]::slotted(*) {
129
130
  color: var(--helix-color-foreground);
130
131
 
131
132
  display: block;
132
- font-size: var(--callout-font-size, var(--helix-text-sm));
133
+ font-size: var(--callout-font-size, var(--helix-text-control));
133
134
  font-weight: var(--helix-weight-semibold);
134
135
  margin: var(--helix-space-none);
135
136
  }
@@ -14,6 +14,10 @@ import type { CSSResultGroup } from 'lit';
14
14
  * draws it. `separation` is where the box ends: absent is the tint with the
15
15
  * bar, `outlined` an edge with no fill, and `plain` the bar and the mark alone.
16
16
  *
17
+ * The inset and the type follow `data-density`, as the controls around a
18
+ * callout do: set it on a region for tighter or looser callouts, or set
19
+ * `--callout-padding` and `--callout-font-size` on one.
20
+ *
17
21
  * @since 0.1.0
18
22
  * @status stable
19
23
  * @category markers
@@ -33,9 +37,9 @@ import type { CSSResultGroup } from 'lit';
33
37
  * @cssproperty --callout-accent-color - The color of the bar, the mark and the tint, in place of the tone's.
34
38
  * @cssproperty --callout-background-color - The fill behind the callout.
35
39
  * @cssproperty --callout-bar-thickness - The thickness of the bar on the inline start edge.
36
- * @cssproperty --callout-font-size - The size of the callout's text.
40
+ * @cssproperty --callout-font-size - The size of the callout's text. Defaults to the control text step, which follows `data-density`.
37
41
  * @cssproperty --callout-gap - The space between the mark and the content.
38
- * @cssproperty --callout-padding - The inset around the content, to which the bar's width is added at the start.
42
+ * @cssproperty --callout-padding - The inset around the content, to which the bar's width is added at the start. Defaults to the control space step, which follows `data-density`.
39
43
  * @cssproperty --callout-radius - The corner radius of the callout.
40
44
  */
41
45
  export declare class HelixCallout extends HelixHeadlessCallout {
@@ -33,8 +33,14 @@ import type { CSSResultGroup } from 'lit';
33
33
  * @slot header-actions - Controls for the whole card at the end of the header's line, such as a menu.
34
34
  * @slot media - Image, video, or chart that runs edge to edge, outside the inset.
35
35
  *
36
+ * @csspart body - The slot the main content arrives through. A slot draws no box, so it passes inherited properties, such as color and font, to the content; `display: block` gives it one.
37
+ * @csspart footer - The slot the footer arrives through, drawing no box, as `body` does.
38
+ * @csspart footer-actions - The slot the footer's controls arrive through, drawing no box, as `body` does.
36
39
  * @csspart footer-row - The line holding `footer` and `footer-actions`, drawn only while `footer-actions` holds something.
40
+ * @csspart header - The slot the header arrives through, drawing no box, as `body` does.
41
+ * @csspart header-actions - The slot the header's controls arrive through, drawing no box, as `body` does.
37
42
  * @csspart header-row - The line holding `header` and `header-actions`, drawn only while `header-actions` holds something.
43
+ * @csspart media - The slot the media arrives through, drawing no box, as `body` does.
38
44
  *
39
45
  * @cssproperty --card-align - How the regions pack when the card is stretched
40
46
  * taller than its content. `start` by default, so the slack is at the bottom;
@@ -181,68 +181,6 @@ background-color: transparent;
181
181
  padding: var(--helix-space-none);
182
182
  }
183
183
 
184
- [part="indicator"] {
185
-
186
- --_chat-typing-cycle: 1.2s;
187
-
188
- animation: helix-chat-typing var(--_chat-typing-cycle) infinite ease-in-out;
189
- background-image:
190
- radial-gradient(circle closest-side, currentColor 90%, transparent),
191
- radial-gradient(circle closest-side, currentColor 90%, transparent),
192
- radial-gradient(circle closest-side, currentColor 90%, transparent);
193
- background-position:
194
- 0% 50%,
195
- 50% 50%,
196
- 100% 50%;
197
- background-repeat: no-repeat;
198
- background-size:
199
- 20% 30%,
200
- 20% 30%,
201
- 20% 30%;
202
- block-size: 1lh;
203
- display: block;
204
- inline-size: 1.75em;
205
- opacity: 0.7;
206
- }
207
-
208
- @keyframes helix-chat-typing {
209
- 0%,
210
- 60%,
211
- 100% {
212
- background-position:
213
- 0% 50%,
214
- 50% 50%,
215
- 100% 50%;
216
- }
217
-
218
- 20% {
219
- background-position:
220
- 0% 10%,
221
- 50% 50%,
222
- 100% 50%;
223
- }
224
-
225
- 33% {
226
- background-position:
227
- 0% 50%,
228
- 50% 10%,
229
- 100% 50%;
230
- }
231
-
232
- 46% {
233
- background-position:
234
- 0% 50%,
235
- 50% 50%,
236
- 100% 10%;
237
- }
238
- }
239
-
240
- @media (prefers-reduced-motion: reduce) {
241
- [part="indicator"] {
242
- animation: none;
243
- }
244
- }
245
-
246
184
  :host([state="failed"]) [part="meta"] {
247
185
  color: var(--helix-color-danger);
248
186
  }