@fusion.dev/helix 0.142.1 → 0.144.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 (160) hide show
  1. package/README.md +9 -5
  2. package/custom-elements.json +29287 -1905
  3. package/dist/accordion/item/accordion-item.css.js +6 -1
  4. package/dist/accordion/item/accordion-item.d.ts +1 -0
  5. package/dist/announcement/root/announcement-root.d.ts +3 -3
  6. package/dist/app-header/root/app-header-root.d.ts +1 -3
  7. package/dist/aura/shader.d.ts +5 -1
  8. package/dist/aura/shader.js +88 -613
  9. package/dist/avatar/root/avatar-root.d.ts +3 -3
  10. package/dist/badge/root/badge-root.css.js +38 -2
  11. package/dist/badge/root/badge-root.d.ts +17 -0
  12. package/dist/badge/root/badge-root.js +3 -0
  13. package/dist/bar-chart/root/bar-chart-root.css.js +10 -0
  14. package/dist/blockquote/root/blockquote-root.css.js +9 -5
  15. package/dist/blockquote/root/blockquote-root.d.ts +5 -0
  16. package/dist/button/root/button-root.css.js +38 -1
  17. package/dist/button/root/button-root.d.ts +5 -0
  18. package/dist/button/root/button-root.js +2 -1
  19. package/dist/callout/root/callout-root.css.js +69 -11
  20. package/dist/callout/root/callout-root.d.ts +25 -2
  21. package/dist/callout/root/callout-root.js +4 -0
  22. package/dist/card/root/card-root.css.js +27 -1
  23. package/dist/card/root/card-root.d.ts +11 -0
  24. package/dist/carousel/root/carousel-root.js +2 -1
  25. package/dist/checkbox/root/checkbox-root.css.js +3 -3
  26. package/dist/checkbox-group/root/checkbox-group-root.d.ts +2 -0
  27. package/dist/checkbox-group/root/checkbox-group-root.js +2 -0
  28. package/dist/code-block/root/code-block-root.css.js +23 -0
  29. package/dist/code-block/root/code-block-root.d.ts +15 -0
  30. package/dist/code-block/root/code-block-root.js +8 -0
  31. package/dist/color-picker/root/color-picker-root.css.js +64 -0
  32. package/dist/color-picker/root/color-picker-root.d.ts +2 -1
  33. package/dist/color-picker/root/color-picker-root.js +0 -1
  34. package/dist/combobox/root/combobox-root.css.js +5 -4
  35. package/dist/copy-button/root/copy-button-root.css.js +5 -0
  36. package/dist/data-table/root/data-table-root.css.js +7 -0
  37. package/dist/date-input/root/date-input-root.css.js +19 -0
  38. package/dist/date-input/root/date-input-root.d.ts +8 -0
  39. package/dist/date-input/root/date-input-root.js +2 -0
  40. package/dist/date-picker/root/date-picker-root.css.js +83 -3
  41. package/dist/date-picker/root/date-picker-root.d.ts +1 -0
  42. package/dist/dialog/root/dialog-root.css.js +47 -0
  43. package/dist/divider/root/divider-root.css.js +8 -3
  44. package/dist/divider/root/divider-root.d.ts +17 -1
  45. package/dist/divider/root/divider-root.js +4 -0
  46. package/dist/donut-chart/root/donut-chart-root.css.js +10 -0
  47. package/dist/drawer/root/drawer-root.css.js +53 -5
  48. package/dist/element-events.generated.js +48 -14
  49. package/dist/empty/root/empty-root.css.js +9 -9
  50. package/dist/empty/root/empty-root.d.ts +9 -0
  51. package/dist/file-input/root/file-input-root.d.ts +0 -1
  52. package/dist/file-input/root/file-input-root.js +2 -1
  53. package/dist/filter-input/root/filter-input-root.d.ts +0 -1
  54. package/dist/filter-input/root/filter-input-root.js +2 -1
  55. package/dist/grid/root/grid-root.d.ts +15 -11
  56. package/dist/grid/root/grid-root.js +49 -15
  57. package/dist/heatmap/root/heatmap-root.css.js +33 -5
  58. package/dist/heatmap/root/heatmap-root.d.ts +4 -1
  59. package/dist/icon/index.d.ts +1 -0
  60. package/dist/icon/index.js +1 -0
  61. package/dist/icon/root/icon-root.d.ts +1 -1
  62. package/dist/icon/root/icon-root.js +1 -1
  63. package/dist/icon/root/index.d.ts +2 -0
  64. package/dist/icon/root/index.js +2 -0
  65. package/dist/icon-button/root/icon-button-root.css.js +80 -16
  66. package/dist/icon-button/root/icon-button-root.d.ts +8 -1
  67. package/dist/icon-button/root/icon-button-root.js +2 -1
  68. package/dist/image/root/image-root.css.js +1 -1
  69. package/dist/input/root/input-root.css.js +3 -3
  70. package/dist/input/root/input-root.d.ts +3 -1
  71. package/dist/input/root/input-root.js +0 -1
  72. package/dist/legend/root/legend-root.css.js +40 -13
  73. package/dist/legend/root/legend-root.d.ts +6 -0
  74. package/dist/legend/root/legend-root.js +1 -1
  75. package/dist/lightbox/root/lightbox-root.css.js +84 -0
  76. package/dist/lightbox/root/lightbox-root.d.ts +1 -0
  77. package/dist/line-chart/root/line-chart-root.css.js +10 -0
  78. package/dist/list/item/list-item.css.js +7 -1
  79. package/dist/loader/root/loader-root.css.js +10 -0
  80. package/dist/loader/root/loader-root.d.ts +10 -4
  81. package/dist/menu/item/menu-item.css.js +1 -1
  82. package/dist/menu/root/menu-root.d.ts +0 -3
  83. package/dist/meter/root/meter-root.css.js +27 -5
  84. package/dist/meter/root/meter-root.d.ts +5 -0
  85. package/dist/notifications/notification/notification.css.js +5 -0
  86. package/dist/number-input/root/number-input-root.css.js +3 -3
  87. package/dist/number-input/root/number-input-root.d.ts +6 -0
  88. package/dist/orb/root/orb-root.d.ts +11 -2
  89. package/dist/orb/root/orb-root.js +5 -1
  90. package/dist/pin-input/root/pin-input-root.css.js +12 -5
  91. package/dist/pin-input/root/pin-input-root.d.ts +5 -0
  92. package/dist/popover/root/popover-root.css.js +36 -0
  93. package/dist/popover/root/popover-root.d.ts +1 -0
  94. package/dist/progress/root/progress-root.css.js +22 -1
  95. package/dist/progress/root/progress-root.d.ts +5 -0
  96. package/dist/qr-code/root/qr-code-root.css.js +2 -1
  97. package/dist/qr-code/root/qr-code-root.d.ts +2 -2
  98. package/dist/quote/root/quote-root.css.js +1 -1
  99. package/dist/quote/root/quote-root.d.ts +1 -0
  100. package/dist/rating/root/rating-root.d.ts +3 -0
  101. package/dist/sandbox/index.d.ts +2 -2
  102. package/dist/sandbox/root/sandbox-root.d.ts +20 -1
  103. package/dist/sandbox/root/sandbox-root.js +27 -10
  104. package/dist/sandbox/source/sandbox-source.d.ts +6 -1
  105. package/dist/sandbox/source/sandbox-source.js +13 -3
  106. package/dist/sandbox/terminal/sandbox-terminal.d.ts +3 -1
  107. package/dist/sandbox/terminal/sandbox-terminal.js +3 -1
  108. package/dist/shared/chart/tooltip.css.js +25 -2
  109. package/dist/shared/field/field-segments.css.d.ts +1 -0
  110. package/dist/shared/field/field-segments.css.js +40 -0
  111. package/dist/skeleton/root/skeleton-root.css.js +60 -5
  112. package/dist/skeleton/root/skeleton-root.d.ts +21 -2
  113. package/dist/skeleton/root/skeleton-root.js +3 -0
  114. package/dist/stat/root/stat-root.css.js +7 -7
  115. package/dist/stat/root/stat-root.d.ts +8 -0
  116. package/dist/switch/root/switch-root.css.js +13 -5
  117. package/dist/switch/root/switch-root.d.ts +25 -1
  118. package/dist/switch/root/switch-root.js +7 -0
  119. package/dist/table/column/table-column.css.js +5 -0
  120. package/dist/tabs/panel/tab-panel.css.js +1 -1
  121. package/dist/tabs/panel/tab-panel.d.ts +2 -0
  122. package/dist/tabs/root/tabs-root.css.js +13 -7
  123. package/dist/tabs/root/tabs-root.d.ts +5 -0
  124. package/dist/tabs/tab/tab.css.js +4 -4
  125. package/dist/tabs/tab/tab.d.ts +5 -0
  126. package/dist/tag/group/tag-group.css.d.ts +1 -0
  127. package/dist/tag/group/tag-group.css.js +6 -0
  128. package/dist/tag/group/tag-group.d.ts +25 -0
  129. package/dist/tag/group/tag-group.js +16 -0
  130. package/dist/tag/index.d.ts +1 -0
  131. package/dist/tag/index.js +1 -0
  132. package/dist/tag/root/tag-root.css.js +50 -0
  133. package/dist/tag/root/tag-root.d.ts +6 -3
  134. package/dist/text/root/text-root.css.js +58 -1
  135. package/dist/text/root/text-root.d.ts +11 -2
  136. package/dist/text/root/text-root.js +19 -1
  137. package/dist/textarea/root/textarea-root.css.js +12 -4
  138. package/dist/textarea/root/textarea-root.d.ts +4 -0
  139. package/dist/time-input/root/time-input-root.css.js +19 -0
  140. package/dist/time-input/root/time-input-root.d.ts +8 -1
  141. package/dist/time-input/root/time-input-root.js +2 -1
  142. package/dist/toast/item/toast-item.css.js +16 -0
  143. package/dist/toast/root/toast-root.css.js +31 -7
  144. package/dist/toast/root/toast-root.d.ts +6 -9
  145. package/dist/toggle/group/toggle-group.css.js +16 -0
  146. package/dist/toggle/group/toggle-group.d.ts +3 -0
  147. package/dist/tour/root/tour-root.css.js +8 -0
  148. package/dist/tour/stop/tour-stop.css.js +37 -0
  149. package/dist/trend/root/trend-root.css.js +12 -5
  150. package/dist/trend/root/trend-root.d.ts +6 -2
  151. package/dist/trend/root/trend-root.js +0 -1
  152. package/dist/video/root/video-root.d.ts +0 -1
  153. package/dist/video/root/video-root.js +0 -1
  154. package/dist/video-playlist/menu/video-playlist-menu.d.ts +0 -1
  155. package/dist/video-playlist/menu/video-playlist-menu.js +0 -1
  156. package/lint.json +1 -1
  157. package/package.json +6 -6
  158. package/types/jsx.d.ts +9515 -2061
  159. package/types/svelte.d.ts +1 -0
  160. package/types/vue.d.ts +2302 -233
@@ -29,6 +29,8 @@ import type { CSSResultGroup } from 'lit';
29
29
  * @aliases Gauge, Level, Capacity
30
30
  * @documentation https://fusion.dev/helix/components/meter
31
31
  *
32
+ * @slot label - A visible label, above a bar and under a ring or an arc. Its words name it in place of `label`.
33
+ *
32
34
  * @csspart indicator - The part of the track the value fills.
33
35
  * @csspart indicator-fair - The fill while the reading is in a band next to the good band. Set alongside `indicator`.
34
36
  * @csspart indicator-good - The fill while the reading is in the good band. Set alongside `indicator`.
@@ -40,6 +42,9 @@ import type { CSSResultGroup } from 'lit';
40
42
  * @csspart value - The reading as text, shown when `show-value` is set.
41
43
  *
42
44
  * @cssproperty --meter-color - The fill color. Overrides the band's tone.
45
+ * @cssproperty --meter-label-color - The color of a slotted label.
46
+ * @cssproperty --meter-label-gap - The space between a slotted label and the meter.
47
+ * @cssproperty --meter-label-size - The type size of a slotted label.
43
48
  * @cssproperty --meter-ring-size - The width and height of the drawing in `ring` and `arc`.
44
49
  * @cssproperty --meter-ring-width - The thickness of the stroke in `ring` and `arc`.
45
50
  * @cssproperty --meter-size - The thickness of the bar.
@@ -241,6 +241,11 @@ outline: var(--helix-size-focus-ring) solid var(--helix-color-focus-ring);
241
241
  outline-offset: var(--helix-size-focus-offset);
242
242
  }
243
243
 
244
+ [part="item"]:focus-visible {
245
+ outline: var(--helix-size-focus-ring) solid var(--helix-color-focus-ring);
246
+ outline-offset: calc(var(--helix-size-focus-offset) * -1);
247
+ }
248
+
244
249
  @media print {
245
250
  [part="dismiss"] {
246
251
  display: none;
@@ -2,9 +2,9 @@ import { createSheet } from '@fusion.dev/helix-core';
2
2
  export const styles = createSheet(`[part="field"] {
3
3
  align-items: center;
4
4
  background-color: var(--number-input-background-color, var(--helix-color-well));
5
- block-size: var(--helix-size-control);
6
- border: var(--helix-border-thin) solid var(--helix-color-border);
7
- border-radius: var(--helix-radii-sm);
5
+ block-size: var(--number-input-size, var(--helix-size-control));
6
+ border: var(--helix-border-thin) solid var(--number-input-border-color, var(--helix-color-border));
7
+ border-radius: var(--number-input-radius, var(--helix-radii-sm));
8
8
  box-sizing: border-box;
9
9
  display: flex;
10
10
 
@@ -22,6 +22,9 @@ import type { CSSResultGroup } from 'lit';
22
22
  * @documentation https://fusion.dev/helix/components/number-input
23
23
  *
24
24
  * @slot end - Content after the number, such as a unit.
25
+ * @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
26
+ * @slot hint - Help under the control, for content richer than the `hint` text.
27
+ * @slot label - The label, for content richer than the `label` text.
25
28
  * @slot start - Content before the number, such as a unit or an icon.
26
29
  *
27
30
  * @csspart control - The input that holds the number.
@@ -30,6 +33,9 @@ import type { CSSResultGroup } from 'lit';
30
33
  * @csspart increment - The button that steps the value up.
31
34
  *
32
35
  * @cssproperty --number-input-background-color - The fill behind the number.
36
+ * @cssproperty --number-input-border-color - Edge of the field at rest. Hover, focus and an error still draw their own.
37
+ * @cssproperty --number-input-radius - Corner radius of the field.
38
+ * @cssproperty --number-input-size - Height of the field.
33
39
  */
34
40
  export declare class HelixNumberInput extends HelixHeadlessNumberInput {
35
41
  static styles: CSSResultGroup;
@@ -31,8 +31,10 @@ import { type OrbState } from '../shapes.js';
31
31
  * `prefers-reduced-motion`, it draws one still frame.
32
32
  *
33
33
  * The orb is styled only and has behavior, which the tier split does not
34
- * otherwise allow. The behavior is drawing dots to a canvas, so there is no
35
- * structure to restyle and nothing for a headless element to hold.
34
+ * otherwise allow. Its role, name and busy state follow `state`, and the rest
35
+ * is drawing dots to a canvas, so there is no structure to restyle. For a
36
+ * drawing of your own, the headless `Loader` holds the same busy progress bar
37
+ * and its name.
36
38
  *
37
39
  * @since 0.8.0
38
40
  * @status stable
@@ -85,6 +87,13 @@ export declare class HelixOrb extends HelixElement {
85
87
  * markup.
86
88
  */
87
89
  state: OrbState;
90
+ /**
91
+ * The word for each state, for a page in another language.
92
+ *
93
+ * A state left out keeps its English word, and `label` wins over both. It is
94
+ * a property with no attribute, keyed by state, such as `{ thinking: '…' }`.
95
+ */
96
+ stateLabels: Partial<Record<OrbState, string>>;
88
97
  private canvas;
89
98
  private context;
90
99
  /**
@@ -28,6 +28,7 @@ let HelixOrb = class HelixOrb extends HelixElement {
28
28
  super(...arguments);
29
29
  this.label = '';
30
30
  this.state = 'thinking';
31
+ this.stateLabels = {};
31
32
  this.context = null;
32
33
  this.gate = new PaintGateController(this, {
33
34
  canRun: () => !!this.context && !this.lost,
@@ -73,7 +74,7 @@ let HelixOrb = class HelixOrb extends HelixElement {
73
74
  ? this.state
74
75
  : 'thinking';
75
76
  hostAria(this.internals, {
76
- label: this.label || LABELS[state],
77
+ label: this.label || this.stateLabels[state] || LABELS[state],
77
78
  role: state === 'done' ? 'img' : 'progressbar',
78
79
  });
79
80
  this.internals.ariaBusy = state === 'done' ? 'false' : 'true';
@@ -244,6 +245,9 @@ __decorate([
244
245
  __decorate([
245
246
  property()
246
247
  ], HelixOrb.prototype, "state", void 0);
248
+ __decorate([
249
+ property({ attribute: false })
250
+ ], HelixOrb.prototype, "stateLabels", void 0);
247
251
  HelixOrb = __decorate([
248
252
  customElement('helix-orb')
249
253
  ], HelixOrb);
@@ -13,10 +13,11 @@ gap: var(--pin-input-gap, var(--helix-space-xs));
13
13
 
14
14
  [part="cell"] {
15
15
  all: unset;
16
- background-color: var(--helix-color-well);
17
- block-size: var(--helix-size-control);
18
- border: var(--helix-border-thin) solid var(--helix-color-border);
19
- border-radius: var(--helix-radii-sm);
16
+ background-color: var(--pin-input-cell-background-color, var(--helix-color-well));
17
+ block-size: var(--pin-input-cell-size, var(--helix-size-control));
18
+ border: var(--helix-border-thin) solid
19
+ var(--pin-input-cell-border-color, var(--helix-color-border));
20
+ border-radius: var(--pin-input-cell-radius, var(--helix-radii-sm));
20
21
  box-sizing: border-box;
21
22
  color: var(--helix-color-foreground);
22
23
  font-family: var(--helix-font-sans);
@@ -24,7 +25,7 @@ font-size: var(--helix-text-lg);
24
25
 
25
26
  font-variant-numeric: tabular-nums;
26
27
  font-weight: var(--helix-weight-medium);
27
- inline-size: var(--helix-size-control);
28
+ inline-size: var(--pin-input-cell-size, var(--helix-size-control));
28
29
  text-align: center;
29
30
  transition: border-color var(--helix-duration-fast) var(--helix-easing-standard);
30
31
  }
@@ -56,6 +57,12 @@ background-color: transparent;
56
57
  font-size: var(--helix-text-xl);
57
58
  }
58
59
 
60
+ [part="separator"] {
61
+ align-self: center;
62
+ color: var(--helix-color-foreground-muted);
63
+ font-size: var(--helix-text-lg);
64
+ }
65
+
59
66
  [part="cell"]::placeholder {
60
67
  color: var(--helix-color-foreground-subtle);
61
68
  }
@@ -21,7 +21,12 @@ import type { CSSResultGroup } from 'lit';
21
21
  *
22
22
  * @csspart cell - One box.
23
23
  * @csspart field - The row of boxes.
24
+ * @csspart separator - The text `format` draws between two boxes.
24
25
  *
26
+ * @cssproperty --pin-input-cell-background-color - Fill behind each box.
27
+ * @cssproperty --pin-input-cell-border-color - Edge of each box at rest. Hover, focus and an error still draw their own.
28
+ * @cssproperty --pin-input-cell-radius - Corner radius of each box.
29
+ * @cssproperty --pin-input-cell-size - Width and height of each box.
25
30
  * @cssproperty --pin-input-gap - The space between one box and the next.
26
31
  */
27
32
  export declare class HelixPinInput extends HelixHeadlessPinInput {
@@ -11,6 +11,9 @@ background-color: var(--helix-color-surface-overlay);
11
11
  border: var(--popover-border-width, var(--helix-border-floating)) solid
12
12
  var(--popover-border-color, var(--helix-color-border));
13
13
 
14
+ --_popover-edge: var(--popover-border-width, var(--helix-border-floating)) solid
15
+ var(--popover-border-color, var(--helix-color-border));
16
+
14
17
  border-radius: var(--helix-radii-sm);
15
18
  box-shadow: var(--popover-shadow, var(--helix-shadow-floating));
16
19
  box-sizing: border-box;
@@ -89,6 +92,39 @@ padding: var(--popover-padding, var(--helix-space-md));
89
92
  padding: var(--popover-padding, var(--helix-space-none));
90
93
  }
91
94
 
95
+ [part="popover"]:focus,
96
+ [part="popover"]:focus-visible {
97
+ outline: none;
98
+ }
99
+
100
+ [part~="arrow"] {
101
+ background-color: var(--helix-color-surface-overlay);
102
+ block-size: var(--popover-arrow-size, 0.5rem);
103
+ inline-size: var(--popover-arrow-size, 0.5rem);
104
+ position: absolute;
105
+ rotate: 45deg;
106
+ }
107
+
108
+ [part="popover"][data-placement^="bottom"] [part~="arrow"] {
109
+ border-left: var(--_popover-edge);
110
+ border-top: var(--_popover-edge);
111
+ }
112
+
113
+ [part="popover"][data-placement^="top"] [part~="arrow"] {
114
+ border-bottom: var(--_popover-edge);
115
+ border-right: var(--_popover-edge);
116
+ }
117
+
118
+ [part="popover"][data-placement^="right"] [part~="arrow"] {
119
+ border-bottom: var(--_popover-edge);
120
+ border-left: var(--_popover-edge);
121
+ }
122
+
123
+ [part="popover"][data-placement^="left"] [part~="arrow"] {
124
+ border-right: var(--_popover-edge);
125
+ border-top: var(--_popover-edge);
126
+ }
127
+
92
128
  @media print {
93
129
  :host {
94
130
  display: none;
@@ -18,6 +18,7 @@ import type { CSSResultGroup } from 'lit';
18
18
  * @aliases Popper, Flyout, Overlay
19
19
  * @documentation https://fusion.dev/helix/components/popover
20
20
  *
21
+ * @cssproperty --popover-arrow-size - Size of the point drawn with `arrow`. Tooltip's point is the same size.
21
22
  * @cssproperty --popover-border-color - Color of the panel's edge.
22
23
  * @cssproperty --popover-border-width - Width of the panel's edge. Defaults to
23
24
  * `--helix-border-floating`, which is `0`, so the panel stands out by its shadow unless
@@ -5,9 +5,29 @@ display: block;
5
5
 
6
6
  :host([show-value]) {
7
7
  align-items: center;
8
+ column-gap: var(--helix-space-sm);
8
9
  display: grid;
9
- gap: var(--helix-space-sm);
10
10
  grid-template-columns: 1fr auto;
11
+
12
+ row-gap: var(--progress-label-gap, var(--helix-space-2xs));
13
+ }
14
+
15
+ slot[name="label"]::slotted(*) {
16
+ color: var(--progress-label-color, var(--helix-color-foreground));
17
+ display: block;
18
+ font-size: var(--progress-label-size, var(--helix-text-sm));
19
+ grid-column: 1 / -1;
20
+ margin-block-end: var(--progress-label-gap, var(--helix-space-2xs));
21
+ }
22
+
23
+ :host([show-value]) slot[name="label"]::slotted(*) {
24
+ margin-block-end: 0;
25
+ }
26
+
27
+ :host([shape="ring"]) slot[name="label"]::slotted(*) {
28
+
29
+ grid-column: 1;
30
+ margin-block: 0;
11
31
  }
12
32
 
13
33
  [part="value"] {
@@ -98,6 +118,7 @@ translate: 0;
98
118
  :host([shape="ring"]) {
99
119
  display: inline-grid;
100
120
  place-items: center;
121
+ row-gap: var(--progress-label-gap, var(--helix-space-2xs));
101
122
  }
102
123
 
103
124
  :host([shape="ring"]) [part="track"] {
@@ -18,7 +18,12 @@ import type { CSSResultGroup } from 'lit';
18
18
  * @aliases Progress bar, Loading bar
19
19
  * @documentation https://fusion.dev/helix/components/progress
20
20
  *
21
+ * @slot label - A visible label, above a bar and under a ring. Its words name it in place of `label`.
22
+ *
21
23
  * @cssproperty --progress-color - Fill of the part that is done.
24
+ * @cssproperty --progress-label-color - Color of a slotted label.
25
+ * @cssproperty --progress-label-gap - Space between a slotted label and the bar.
26
+ * @cssproperty --progress-label-size - Type size of a slotted label.
22
27
  * @cssproperty --progress-ring-size - Diameter of the ring.
23
28
  * @cssproperty --progress-ring-width - Thickness of the ring's stroke.
24
29
  * @cssproperty --progress-size - Thickness of the bar.
@@ -23,7 +23,8 @@ fill: var(--qr-code-finder-color, currentColor);
23
23
 
24
24
  [part="logo"] {
25
25
  align-items: center;
26
- background-color: var(--qr-code-background-color, var(--helix-color-surface-raised));
26
+
27
+ background-color: var(--qr-code-background-color, var(--helix-color-foreground-media));
27
28
  border-radius: var(--helix-radii-sm);
28
29
 
29
30
  box-sizing: border-box;
@@ -17,8 +17,8 @@ import type { CSSResultGroup } from 'lit';
17
17
  * @category media
18
18
  * @documentation https://fusion.dev/helix/components/qr-code
19
19
  *
20
- * @cssproperty --qr-code-background-color - The fill behind the modules, including the quiet zone.
21
- * @cssproperty --qr-code-color - Color of the dark modules. Defaults to the page's text color.
20
+ * @cssproperty --qr-code-background-color - The fill behind the modules, including the quiet zone and the logo's box.
21
+ * @cssproperty --qr-code-color - Color of the dark modules. Defaults to the dark media ink, which is the same in both color schemes so the code scans.
22
22
  * @cssproperty --qr-code-finder-color - Color of the three corner squares. Defaults
23
23
  * to the color of the modules.
24
24
  * @cssproperty --qr-code-logo-padding - The clear space around the center logo.
@@ -8,7 +8,7 @@ font: inherit;
8
8
 
9
9
  color: var(--quote-color, var(--helix-color-foreground-muted));
10
10
  font: inherit;
11
- font-style: italic;
11
+ font-style: var(--quote-font-style, italic);
12
12
  }
13
13
 
14
14
  @media print {
@@ -14,6 +14,7 @@ import type { CSSResultGroup } from 'lit';
14
14
  * @documentation https://fusion.dev/helix/components/quote
15
15
  *
16
16
  * @cssproperty --quote-color - Color of the quoted text.
17
+ * @cssproperty --quote-font-style - The slant of the quoted text, `italic` by default. Set `normal` for a face whose italic is too loud, or `oblique` for one with no italic of its own.
17
18
  */
18
19
  export declare class HelixQuote extends HelixHeadlessQuote {
19
20
  static styles: CSSResultGroup;
@@ -13,6 +13,9 @@ import type { CSSResultGroup } from 'lit';
13
13
  * @aliases Stars, Score, Review score
14
14
  * @documentation https://fusion.dev/helix/components/rating
15
15
  *
16
+ * @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
17
+ * @slot hint - Help under the control, for content richer than the `hint` text.
18
+ * @slot label - The label, for content richer than the `label` text.
16
19
  * @slot mark - The shape of a mark, copied into every position. When the slot is
17
20
  * empty, the stylesheet draws a mark, and `--rating-mark` changes its shape.
18
21
  *
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * The sandbox: a preview that runs what it is given, and the panes around it.
3
3
  *
4
- * The editor is deliberately absent and lives on in `@fusion.dev/helix-editor`, because
5
- * it carries CodeMirror. That is roughly 4 MB installed against a design system
4
+ * The editor is deliberately absent and lives in `@fusion.dev/helix-sandbox`, which
5
+ * is private, because it carries CodeMirror. That is roughly 4 MB installed against a design system
6
6
  * of about the same size, and a `dependencies` entry is paid at install time by
7
7
  * every consumer whether or not they import it, which is the one cost a subpath
8
8
  * export cannot avoid. Its pane takes an editor by slot, so bringing one is a
@@ -127,10 +127,14 @@ export declare class HelixSandbox extends HelixElement {
127
127
  panelSize: number;
128
128
  /**
129
129
  * The name of the divider between the panes, read by screen readers.
130
+ *
131
+ * Empty names the lead pane, "Resize source pane" or "Resize preview pane",
132
+ * since the divider's value is that pane's share.
130
133
  */
131
134
  separatorLabel: string;
132
135
  /**
133
- * Percentage of the sandbox given to the source pane.
136
+ * Percentage of the sandbox given to the lead pane: the source, unless `lead`
137
+ * is `preview`.
134
138
  */
135
139
  split: number;
136
140
  /**
@@ -212,6 +216,21 @@ export declare class HelixSandbox extends HelixElement {
212
216
  * sandbox hears a great deal that is not its source.
213
217
  */
214
218
  private readonly handleSourceChange;
219
+ /**
220
+ * Writes a pane's text into every preview here.
221
+ *
222
+ * `seeding` writes only into a preview that has nothing yet, so a preview
223
+ * given its own `source` keeps it until the first edit.
224
+ */
225
+ private write;
226
+ /**
227
+ * Hands what the source panes already hold to the previews.
228
+ *
229
+ * Only edits were forwarded, so a pane written with a `value` showed its
230
+ * text beside an empty preview until the first keystroke, and the text had
231
+ * to be written twice. Client only, like the other reads of the light DOM.
232
+ */
233
+ private readonly seed;
215
234
  /**
216
235
  * Writes the cursor position onto any status bar slotted here.
217
236
  *
@@ -22,7 +22,7 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
22
22
  this.panelCollapsedSize = 0;
23
23
  this.panelLabel = 'Resize panel';
24
24
  this.panelSize = DEFAULT_PANEL;
25
- this.separatorLabel = 'Resize source pane';
25
+ this.separatorLabel = '';
26
26
  this.split = DEFAULT_SPLIT;
27
27
  this.hasPanel = false;
28
28
  this.bodyHeight = 0;
@@ -37,15 +37,23 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
37
37
  }
38
38
  const { value } = event.detail;
39
39
  const pane = event.composedPath()[0];
40
- if (pane?.name !== 'css' && pane?.name !== 'html') {
40
+ const name = pane?.name;
41
+ if (name !== 'css' && name !== 'html') {
41
42
  return;
42
43
  }
43
- for (const preview of this.previews) {
44
- if (pane.name === 'css') {
45
- preview.styles = value;
44
+ queueMicrotask(() => {
45
+ if (!event.defaultPrevented) {
46
+ this.write(name, value, false);
46
47
  }
47
- else {
48
- preview.source = value;
48
+ });
49
+ };
50
+ this.seed = () => {
51
+ const slot = this.renderRoot.querySelector('slot[name="source"]');
52
+ for (const pane of slot?.assignedElements({ flatten: true }) ?? []) {
53
+ const { name, value } = pane;
54
+ const text = typeof value === 'string' ? value : pane.getAttribute('value');
55
+ if ((name === 'css' || name === 'html') && text) {
56
+ this.write(name, text, true);
49
57
  }
50
58
  }
51
59
  };
@@ -132,6 +140,14 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
132
140
  const slot = this.renderRoot.querySelector('slot[name="source"]');
133
141
  return (slot?.assignedElements({ flatten: true }) ?? []).some((pane) => pane === target || pane.contains(target));
134
142
  }
143
+ write(name, value, seeding) {
144
+ for (const preview of this.previews) {
145
+ const key = name === 'css' ? 'styles' : 'source';
146
+ if (!seeding || !preview[key]) {
147
+ preview[key] = value;
148
+ }
149
+ }
150
+ }
135
151
  parts(selector) {
136
152
  return [...this.querySelectorAll(selector)];
137
153
  }
@@ -213,6 +229,7 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
213
229
  this.finishHydration();
214
230
  }
215
231
  this.watchBody(this.watch === undefined);
232
+ this.seed();
216
233
  }
217
234
  disconnectedCallback() {
218
235
  super.disconnectedCallback();
@@ -246,15 +263,15 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
246
263
  part="panes"
247
264
  exportparts="separator"
248
265
  default-position=${Number.isFinite(this.defaultSplit) ? this.defaultSplit : DEFAULT_SPLIT}
249
- label=${this.separatorLabel}
266
+ label=${this.separatorLabel || (first === 'preview' ? 'Resize preview pane' : 'Resize source pane')}
250
267
  orientation=${vertical ? 'vertical' : 'horizontal'}
251
268
  .position=${split}
252
269
  @helix-before-collapse=${this.handleCollapse}
253
270
  @helix-before-resize=${this.handlePanesChange}
254
271
  >
255
272
  ${''}
256
- <div part="pane" data-pane=${first} slot="start"><slot name=${first}></slot></div>
257
- <div part="pane" data-pane=${second} slot="end"><slot name=${second}></slot></div>
273
+ <div part="pane" data-pane=${first} slot="start"><slot name=${first} @slotchange=${this.seed}></slot></div>
274
+ <div part="pane" data-pane=${second} slot="end"><slot name=${second} @slotchange=${this.seed}></slot></div>
258
275
  </helix-splitter>
259
276
  <div part="panel" slot="end"><slot name="panel" @slotchange=${this.readPanel}></slot></div>
260
277
  </helix-splitter>
@@ -8,7 +8,8 @@ import type { CSSResultGroup, TemplateResult } from 'lit';
8
8
  * keyboards, and screen reader support come from the platform.
9
9
  *
10
10
  * Tab inserts two spaces, so you can indent code. To move focus out of the
11
- * field, press Escape and then Tab.
11
+ * field, press Escape and then Tab. Shift+Tab moves focus back as it does
12
+ * anywhere else. The field's description says so to a screen reader.
12
13
  *
13
14
  * @since 0.1.0
14
15
  * @status stable
@@ -28,6 +29,10 @@ export declare class HelixSandboxSource extends HelixElement {
28
29
  * The editable region's name, read by screen readers.
29
30
  */
30
31
  fieldLabel: string;
32
+ /**
33
+ * The field's description, read by screen readers while Tab indents.
34
+ */
35
+ keysDescription: string;
31
36
  /**
32
37
  * Which source this pane holds. Every `helix-before-edit` event includes it.
33
38
  *
@@ -5,13 +5,15 @@ 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
  import { customElement, HelixBeforeEditEvent, HelixCaretEvent, HelixElement, onUnlessFalse, restoreValue, } from '@fusion.dev/helix-core';
8
- import { html } from 'lit';
8
+ import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { styles } from './sandbox-source.css.js';
11
+ const MODIFIERS = new Set(['Alt', 'AltGraph', 'Control', 'Meta', 'Shift']);
11
12
  let HelixSandboxSource = class HelixSandboxSource extends HelixElement {
12
13
  constructor() {
13
14
  super(...arguments);
14
15
  this.fieldLabel = 'Example source';
16
+ this.keysDescription = 'Tab inserts two spaces. To leave, press Escape and then Tab.';
15
17
  this.name = 'html';
16
18
  this.tabIndents = true;
17
19
  this.value = '';
@@ -35,7 +37,10 @@ let HelixSandboxSource = class HelixSandboxSource extends HelixElement {
35
37
  this.escaped = true;
36
38
  return;
37
39
  }
38
- if (event.key !== 'Tab' || !this.tabIndents || this.escaped) {
40
+ if (MODIFIERS.has(event.key)) {
41
+ return;
42
+ }
43
+ if (event.key !== 'Tab' || event.shiftKey || !this.tabIndents || this.escaped) {
39
44
  this.escaped = false;
40
45
  return;
41
46
  }
@@ -59,6 +64,7 @@ let HelixSandboxSource = class HelixSandboxSource extends HelixElement {
59
64
  return html `<textarea
60
65
  part="source"
61
66
  aria-label=${this.fieldLabel}
67
+ aria-describedby=${this.tabIndents ? 'keys' : nothing}
62
68
  spellcheck="false"
63
69
  .value=${this.value}
64
70
  @focus=${this.reportCaret}
@@ -66,13 +72,17 @@ let HelixSandboxSource = class HelixSandboxSource extends HelixElement {
66
72
  @keydown=${this.handleKeydown}
67
73
  @keyup=${this.reportCaret}
68
74
  @pointerup=${this.reportCaret}
69
- ></textarea>`;
75
+ ></textarea>
76
+ <span id="keys" hidden>${this.keysDescription}</span>`;
70
77
  }
71
78
  static { this.styles = styles; }
72
79
  };
73
80
  __decorate([
74
81
  property({ attribute: 'field-label' })
75
82
  ], HelixSandboxSource.prototype, "fieldLabel", void 0);
83
+ __decorate([
84
+ property({ attribute: 'keys-description' })
85
+ ], HelixSandboxSource.prototype, "keysDescription", void 0);
76
86
  __decorate([
77
87
  property()
78
88
  ], HelixSandboxSource.prototype, "name", void 0);
@@ -13,7 +13,9 @@ import type { CSSResultGroup, TemplateResult } from 'lit';
13
13
  * warning. Only consecutive repeats collapse, so the order of messages is kept.
14
14
  *
15
15
  * The panel has `role="log"`, the role for an append-only stream. Screen
16
- * readers announce new output without reading the whole panel again.
16
+ * readers announce new output without reading the whole panel again. A line's
17
+ * level is read before it, except a plain `log`, so an error does not sound
18
+ * like any other line.
17
19
  *
18
20
  * @since 0.1.0
19
21
  * @status stable
@@ -49,7 +49,9 @@ let HelixSandboxTerminal = class HelixSandboxTerminal extends HelixElement {
49
49
  ${this.entries.length === 0
50
50
  ? html `<p part="empty">${this.emptyLabel}</p>`
51
51
  : this.entries.map((entry) => html `<div part="entry" data-level=${entry.level}>
52
- <span part="level" aria-hidden="true">${entry.level}</span>
52
+ <span part="level" aria-hidden=${entry.level === 'log' ? 'true' : nothing}
53
+ >${entry.level}</span
54
+ >
53
55
  <span part="message">${entry.text}</span>
54
56
  ${entry.count > 1
55
57
  ? html `<span part="count" aria-label="${entry.count} times"
@@ -18,7 +18,7 @@ font-weight: var(--helix-weight-medium);
18
18
  margin-block-end: var(--helix-space-2xs);
19
19
  }
20
20
 
21
- [part="tooltip-cell"] {
21
+ [part~="tooltip-cell"] {
22
22
  align-items: baseline;
23
23
  column-gap: var(--helix-space-sm);
24
24
  display: grid;
@@ -36,11 +36,34 @@ font-variant-numeric: tabular-nums;
36
36
  grid-column: 3;
37
37
  }
38
38
 
39
- [part="tooltip-cell"][data-series]::before {
39
+ [part~="tooltip-cell"][data-series]::before {
40
40
  background-color: var(--chart-series);
41
41
  block-size: 0.5em;
42
42
  border-radius: var(--helix-radii-full);
43
43
  content: "";
44
44
  grid-column: 1;
45
45
  inline-size: 0.5em;
46
+ }
47
+
48
+ [part~="tooltip-cell-current"] {
49
+ font-weight: var(--helix-weight-medium);
50
+ }
51
+
52
+ [part~="tooltip-cell-current"] [part="tooltip-name"] {
53
+ opacity: 1;
54
+ }
55
+
56
+ [part="plot"]:focus-visible {
57
+ outline: var(--helix-size-focus-ring) solid var(--helix-color-focus-ring);
58
+ outline-offset: var(--helix-size-focus-offset);
59
+ }
60
+
61
+ [part="live"] {
62
+ block-size: 1px;
63
+ clip-path: inset(50%);
64
+ inline-size: 1px;
65
+ margin: var(--helix-space-none);
66
+ overflow: hidden;
67
+ position: absolute;
68
+ white-space: nowrap;
46
69
  }`);
@@ -0,0 +1 @@
1
+ export declare const styles: import("lit").CSSResult;