@fusion.dev/helix 0.44.0 → 0.45.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.
@@ -47423,7 +47423,7 @@
47423
47423
  "helix": {
47424
47424
  "category": "forms",
47425
47425
  "since": "0.23.0",
47426
- "status": "experimental",
47426
+ "status": "stable",
47427
47427
  "documentation": "https://fusion.dev/helix/components/filter-input",
47428
47428
  "aliases": [
47429
47429
  "FilterToken",
@@ -48070,7 +48070,7 @@
48070
48070
  "helix": {
48071
48071
  "category": "forms",
48072
48072
  "since": "0.23.0",
48073
- "status": "experimental",
48073
+ "status": "stable",
48074
48074
  "documentation": "https://fusion.dev/helix/components/filter-input",
48075
48075
  "aliases": [
48076
48076
  "Facet",
@@ -48748,7 +48748,7 @@
48748
48748
  "helix": {
48749
48749
  "category": "forms",
48750
48750
  "since": "0.25.0",
48751
- "status": "experimental",
48751
+ "status": "stable",
48752
48752
  "documentation": "https://fusion.dev/helix/components/filter-input",
48753
48753
  "aliases": [
48754
48754
  "FacetPicker",
@@ -49367,7 +49367,7 @@
49367
49367
  "helix": {
49368
49368
  "category": "forms",
49369
49369
  "since": "0.23.0",
49370
- "status": "experimental",
49370
+ "status": "stable",
49371
49371
  "documentation": "https://fusion.dev/helix/components/filter-input",
49372
49372
  "aliases": [
49373
49373
  "Comparator",
@@ -51285,7 +51285,7 @@
51285
51285
  "helix": {
51286
51286
  "category": "forms",
51287
51287
  "since": "0.1.0",
51288
- "status": "experimental",
51288
+ "status": "stable",
51289
51289
  "documentation": "https://fusion.dev/helix/components/filter-input",
51290
51290
  "aliases": [
51291
51291
  "SearchField",
@@ -77987,6 +77987,21 @@
77987
77987
  "module": "src/option/group/option-group.ts"
77988
77988
  }
77989
77989
  },
77990
+ {
77991
+ "kind": "method",
77992
+ "name": "nameFromHeading",
77993
+ "privacy": "private",
77994
+ "return": {
77995
+ "type": {
77996
+ "text": "void"
77997
+ }
77998
+ },
77999
+ "description": "Names the run after the heading it drew, whatever the heading is made of.\n\n**The string alone was not the name of the heading, it was the name of one\nway of writing it.** `label` reached `ariaLabel` and the slot reached the\nscreen, so a consumer who took the documented `label` slot for a heading\nricher than a string got a `role=\"group\"` with no accessible name at all,\nand the words they wrote were the one thing a reader could not hear: the\nheading carries `aria-hidden`, because the name was supposed to be on the\nhost already. Set both and they disagreed, the host saying the string and\nthe panel showing the slot.\n\nSo the host points at the heading, which is the one thing that is always\nwhat a reader sees. `ElementInternals` and not an IDREF, because the host\nis in the light DOM and the heading is in this shadow root, which is the\nboundary `aria-labelledby` cannot cross. `MixinField.linkHost` does the\nsame for a field's label and records the measurement.\n\nClient only. Element references need the nodes to exist, and the server has\nthe string.",
78000
+ "inheritedFrom": {
78001
+ "name": "HelixHeadlessOptionGroup",
78002
+ "module": "src/option/group/option-group.ts"
78003
+ }
78004
+ },
77990
78005
  {
77991
78006
  "kind": "field",
77992
78007
  "name": "tier",
@@ -78319,7 +78334,7 @@
78319
78334
  "summary": "A named run of options inside a listbox.",
78320
78335
  "helix": {
78321
78336
  "since": "0.1.0",
78322
- "status": "experimental",
78337
+ "status": "stable",
78323
78338
  "documentation": "https://fusion.dev/helix/components/option",
78324
78339
  "aliases": [
78325
78340
  "OptGroup",
@@ -78973,7 +78988,7 @@
78973
78988
  "helix": {
78974
78989
  "category": "forms",
78975
78990
  "since": "0.1.0",
78976
- "status": "experimental",
78991
+ "status": "stable",
78977
78992
  "documentation": "https://fusion.dev/helix/components/option",
78978
78993
  "aliases": [
78979
78994
  "Item",
@@ -89607,7 +89622,7 @@
89607
89622
  "summary": "A set of choices where exactly one is the answer.",
89608
89623
  "helix": {
89609
89624
  "since": "0.1.0",
89610
- "status": "experimental",
89625
+ "status": "stable",
89611
89626
  "documentation": "https://fusion.dev/helix/components/radio",
89612
89627
  "aliases": [
89613
89628
  "RadioButtons",
@@ -90021,6 +90036,19 @@
90021
90036
  "module": "src/radio/root/radio-root.ts"
90022
90037
  }
90023
90038
  },
90039
+ {
90040
+ "kind": "field",
90041
+ "name": "focusable",
90042
+ "type": {
90043
+ "text": "boolean"
90044
+ },
90045
+ "default": "false",
90046
+ "description": "Whether this choice holds the group's tab stop while nothing is chosen.\n\nThe stop rides on the selection, and an unanswered group has no selection,\nso without this every choice is `tabindex=\"-1\"` and the keyboard cannot\nenter the set at all.\n\n**Written by the group, with no attribute, and it reaches the control\nrather than the host.** A `tabindex` on the host is two faults at once: it\nis markup a consumer rendered and their server never sent, which React\nreports as a mismatch and does not patch up, and it puts the tab stop on\nthe element rather than on the `<button role=\"radio\">` inside it, so a\nscreen reader meets an unnamed box where a native group would have given\nthem an unchecked radio. `Toggle.Root` carries the same property for the\nsame reason.",
90047
+ "inheritedFrom": {
90048
+ "name": "HelixHeadlessRadio",
90049
+ "module": "src/radio/root/radio-root.ts"
90050
+ }
90051
+ },
90024
90052
  {
90025
90053
  "kind": "field",
90026
90054
  "name": "selected",
@@ -90474,7 +90502,7 @@
90474
90502
  "helix": {
90475
90503
  "category": "forms",
90476
90504
  "since": "0.1.0",
90477
- "status": "experimental",
90505
+ "status": "stable",
90478
90506
  "documentation": "https://fusion.dev/helix/components/radio",
90479
90507
  "aliases": [
90480
90508
  "Option",
@@ -92466,9 +92494,8 @@
92466
92494
  "type": {
92467
92495
  "text": "'rtl' | undefined"
92468
92496
  },
92469
- "description": "Writing direction inside the frame.",
92470
- "attribute": "direction",
92471
- "reflects": true
92497
+ "description": "Writing direction inside the frame.\n\nNot reflected. It is payload for the render message and nothing selects on\nit, here or anywhere: a frame is a document of its own and what is written\non this host reaches nothing inside it, which is the same reason\n`colorMode` has to be sent rather than set.",
92498
+ "attribute": "direction"
92472
92499
  },
92473
92500
  {
92474
92501
  "kind": "field",
@@ -92486,9 +92513,8 @@
92486
92513
  "type": {
92487
92514
  "text": "'padded' | 'centered' | 'fullscreen' | 'hug' | undefined"
92488
92515
  },
92489
- "description": "How the example is placed in the frame.",
92490
- "attribute": "layout",
92491
- "reflects": true
92516
+ "description": "How the example is placed in the frame.\n\n`padded` insets it and leaves it at the top, which is the resting case and\nwhat an absent value sends. `centered` gives it a measure and centers that\nbox in the frame. `hug` shrinks the example to its own content and centers\nwhat is left, which is the difference that matters for a component whose\nroot is a full-width block. `fullscreen` is the whole frame with no inset.\n\nNot reflected, for `direction`'s reason: the placement is applied by the\ndocument inside the frame, against its own root, so no rule on this side\ncould read it.",
92517
+ "attribute": "layout"
92492
92518
  },
92493
92519
  {
92494
92520
  "kind": "field",
@@ -92956,7 +92982,7 @@
92956
92982
  "type": {
92957
92983
  "text": "'rtl' | undefined"
92958
92984
  },
92959
- "description": "Writing direction inside the frame.",
92985
+ "description": "Writing direction inside the frame.\n\nNot reflected. It is payload for the render message and nothing selects on\nit, here or anywhere: a frame is a document of its own and what is written\non this host reaches nothing inside it, which is the same reason\n`colorMode` has to be sent rather than set.",
92960
92986
  "fieldName": "direction"
92961
92987
  },
92962
92988
  {
@@ -92973,7 +92999,7 @@
92973
92999
  "type": {
92974
93000
  "text": "'padded' | 'centered' | 'fullscreen' | 'hug' | undefined"
92975
93001
  },
92976
- "description": "How the example is placed in the frame.",
93002
+ "description": "How the example is placed in the frame.\n\n`padded` insets it and leaves it at the top, which is the resting case and\nwhat an absent value sends. `centered` gives it a measure and centers that\nbox in the frame. `hug` shrinks the example to its own content and centers\nwhat is left, which is the difference that matters for a component whose\nroot is a full-width block. `fullscreen` is the whole frame with no inset.\n\nNot reflected, for `direction`'s reason: the placement is applied by the\ndocument inside the frame, against its own root, so no rule on this side\ncould read it.",
92977
93003
  "fieldName": "layout"
92978
93004
  },
92979
93005
  {
@@ -93193,9 +93219,8 @@
93193
93219
  "type": {
93194
93220
  "text": "'horizontal' | 'vertical' | undefined"
93195
93221
  },
93196
- "description": "Whether the panes sit side by side or stacked.",
93197
- "attribute": "orientation",
93198
- "reflects": true
93222
+ "description": "Whether the panes sit side by side or stacked.\n\nNot reflected, for `lead`'s reason above: no rule selects on it. The axis\nreaches the stylesheet as the inner splitter's own `orientation`, which is\nwhere the panes are laid out, and this element's sheet names no host\nattribute at all.",
93223
+ "attribute": "orientation"
93199
93224
  },
93200
93225
  {
93201
93226
  "kind": "field",
@@ -93412,32 +93437,48 @@
93412
93437
  },
93413
93438
  {
93414
93439
  "kind": "method",
93415
- "name": "splitSettled",
93440
+ "name": "requestSplit",
93416
93441
  "privacy": "private",
93417
93442
  "return": {
93418
93443
  "type": {
93419
- "text": "void"
93444
+ "text": "boolean"
93420
93445
  }
93421
93446
  },
93422
- "description": "Says the panes' divider has settled, so a consumer can keep it.\n\nWhen it settles, not while it moves. A drag is a stream of positions and\nonly the one it ends at is a preference; announcing each would ask whoever\nis listening to write to storage a hundred times to record one decision.\n\nThe sandbox does not keep it. Where a preference lives, and whether it\nshould be kept at all, is the consumer's to decide, and a component that\nwrote to storage on its own would be deciding for all of them under a key\nit chose.\n\n**A verb each, rather than one `helix-before-resize` naming which of the two\nmoved.** Both dividers are this element's, so `composedPath()[0]` is the same\nhost for either and the event name is the only thing that can separate them."
93447
+ "parameters": [
93448
+ {
93449
+ "name": "next",
93450
+ "type": {
93451
+ "text": "number"
93452
+ }
93453
+ }
93454
+ ],
93455
+ "description": "Asks for the panes' divider to settle here, and moves it unless refused.\n\nWhen it settles, not while it moves. A drag is a stream of positions and\nonly the one it ends at is a preference; announcing each would ask whoever\nis listening to write to storage a hundred times to record one decision.\n\nThe sandbox does not keep it. Where a preference lives, and whether it\nshould be kept at all, is the consumer's to decide, and a component that\nwrote to storage on its own would be deciding for all of them under a key\nit chose.\n\n**Through `requestChange`, and never the other way round.** Both of these\nfired after `split` and `panelSize` had already been written, with the\nanswer dropped, so a consumer calling `preventDefault()` on an event whose\nown line says refusing it takes the decision changed nothing whatever: the\ndivider stayed where the drag left it and their handler read a value they\nhad just declined. `SandboxSource.edit` two files away already carries the\nargument, that assigning first turns a `before` event into one that has\nalready happened, and `Splitter`, whose `helix-before-resize` these two were\nsplit out of, has always announced through the audited path. Refusing one\nnow leaves `.position` bound to the value this element still holds, so the\ndivider goes back where it was.\n\n**A verb each, rather than one `helix-before-resize` naming which of the two\nmoved.** Both dividers are this element's, so `composedPath()[0]` is the same\nhost for either and the event name is the only thing that can separate them."
93423
93456
  },
93424
93457
  {
93425
93458
  "kind": "method",
93426
- "name": "panelSettled",
93459
+ "name": "requestPanelSize",
93427
93460
  "privacy": "private",
93428
93461
  "return": {
93429
93462
  "type": {
93430
- "text": "void"
93463
+ "text": "boolean"
93431
93464
  }
93432
93465
  },
93433
- "description": "As `splitSettled`, for the panel, whose value is pixels rather than a share."
93466
+ "parameters": [
93467
+ {
93468
+ "name": "next",
93469
+ "type": {
93470
+ "text": "number"
93471
+ }
93472
+ }
93473
+ ],
93474
+ "description": "As `requestSplit`, for the panel, whose value is pixels rather than a share."
93434
93475
  },
93435
93476
  {
93436
93477
  "kind": "field",
93437
93478
  "name": "handlePanesChange",
93438
93479
  "privacy": "private",
93439
93480
  "readonly": true,
93440
- "description": "Answers a divider that has asked to move.\n\nBoth splitters are controlled from here, so neither applies anything on its\nown: each announces where it wants to go and this decides. That is what\nkeeps `split` and `panelSize` the truth about the arrangement rather than a\nstale copy of it.\n\n`target` against `currentTarget`, because a source pane's own change bubbles\nup through these same elements on its way to the host. Only a splitter\nspeaking for itself is one of ours, and only those are stopped: the sandbox\nannounces `helix-before-split` and `helix-before-panel-resize` in their\nplace, and a consumer never sees the two splitters inside it."
93481
+ "description": "Answers a divider that has asked to move.\n\nBoth splitters are controlled from here, so neither applies anything on its\nown: each announces where it wants to go and this decides. That is what\nkeeps `split` and `panelSize` the truth about the arrangement rather than a\nstale copy of it.\n\n`target` against `currentTarget`, because a source pane's own change bubbles\nup through these same elements on its way to the host. Only a splitter\nspeaking for itself is one of ours, and only those are stopped: the sandbox\nannounces `helix-before-split` and `helix-before-panel-resize` in their\nplace, and a consumer never sees the two splitters inside it.\n\n**Refused as well as stopped, which is what \"controlled from here\" costs.**\nA splitter nobody refuses applies the move itself and says so in its own\ndocblock, so the sentence above was true only while nothing downstream ever\ndeclined: refusing `helix-before-split` left `split` at fifty and the\ndivider drawn at fifty-two, one element holding the arrangement and the\nother showing it. Refusing the inner request first makes this element the\nsingle answer.\n\n**And the divider is written back, because a refusal writes nothing.** A\nsplitter draws itself from where the gesture reached until its `position` is\nassigned, which is the setter's stated job, and a bound property Lit did not\nchange is a property Lit does not write. So the answer is assigned either\nway, which for an accepted move is the number the binding is about to carry\nanyway."
93441
93482
  },
93442
93483
  {
93443
93484
  "kind": "field",
@@ -93445,6 +93486,31 @@
93445
93486
  "privacy": "private",
93446
93487
  "readonly": true
93447
93488
  },
93489
+ {
93490
+ "kind": "method",
93491
+ "name": "answer",
93492
+ "privacy": "private",
93493
+ "return": {
93494
+ "type": {
93495
+ "text": "void"
93496
+ }
93497
+ },
93498
+ "parameters": [
93499
+ {
93500
+ "name": "divider",
93501
+ "type": {
93502
+ "text": "EventTarget | null"
93503
+ }
93504
+ },
93505
+ {
93506
+ "name": "position",
93507
+ "type": {
93508
+ "text": "number"
93509
+ }
93510
+ }
93511
+ ],
93512
+ "description": "Puts a divider where this element says it is.\n\nTyped by what is used rather than by the class, which is the whole of the\ncoupling: a splitter this does not import is one that can be replaced."
93513
+ },
93448
93514
  {
93449
93515
  "kind": "method",
93450
93516
  "name": "watchBody",
@@ -93874,7 +93940,7 @@
93874
93940
  "type": {
93875
93941
  "text": "'horizontal' | 'vertical' | undefined"
93876
93942
  },
93877
- "description": "Whether the panes sit side by side or stacked.",
93943
+ "description": "Whether the panes sit side by side or stacked.\n\nNot reflected, for `lead`'s reason above: no rule selects on it. The axis\nreaches the stylesheet as the inner splitter's own `orientation`, which is\nwhere the panes are laid out, and this element's sheet names no host\nattribute at all.",
93878
93944
  "fieldName": "orientation"
93879
93945
  },
93880
93946
  {
@@ -100958,8 +101024,12 @@
100958
101024
  "helix": {
100959
101025
  "category": "navigation",
100960
101026
  "since": "0.1.0",
100961
- "status": "experimental",
101027
+ "status": "stable",
100962
101028
  "documentation": "https://fusion.dev/helix/components/skip-link",
101029
+ "aliases": [
101030
+ "Skip navigation",
101031
+ "Skip to content"
101032
+ ],
100963
101033
  "tier": "styled",
100964
101034
  "group": "SkipLink",
100965
101035
  "part": "Root",
@@ -116054,7 +116124,7 @@
116054
116124
  "helix": {
116055
116125
  "category": "typography",
116056
116126
  "since": "0.1.0",
116057
- "status": "experimental",
116127
+ "status": "stable",
116058
116128
  "documentation": "https://fusion.dev/helix/components/text",
116059
116129
  "aliases": [
116060
116130
  "Paragraph",
@@ -13,7 +13,7 @@ import type { CSSResultGroup } from 'lit';
13
13
  * common chip free of jargon. See the headless note, which records the rule.
14
14
  *
15
15
  * @since 0.23.0
16
- * @status experimental
16
+ * @status stable
17
17
  * @category forms
18
18
  * @aliases FilterToken, FacetChip
19
19
  * @documentation https://fusion.dev/helix/components/filter-input
@@ -14,7 +14,7 @@ import type { CSSResultGroup } from 'lit';
14
14
  * away from its neighbors.
15
15
  *
16
16
  * @since 0.23.0
17
- * @status experimental
17
+ * @status stable
18
18
  * @category forms
19
19
  * @aliases Facet, Dimension
20
20
  * @documentation https://fusion.dev/helix/components/filter-input
@@ -15,7 +15,7 @@ import '../../menu/index.js';
15
15
  * immediately and why the operator is decided here rather than on the chip.
16
16
  *
17
17
  * @since 0.25.0
18
- * @status experimental
18
+ * @status stable
19
19
  * @category forms
20
20
  * @aliases FacetPicker, FilterBuilder
21
21
  * @documentation https://fusion.dev/helix/components/filter-input
@@ -12,7 +12,7 @@ import type { CSSResultGroup } from 'lit';
12
12
  * reason `FilterField`'s note gives.
13
13
  *
14
14
  * @since 0.23.0
15
- * @status experimental
15
+ * @status stable
16
16
  * @category forms
17
17
  * @aliases Comparator, Predicate
18
18
  * @documentation https://fusion.dev/helix/components/filter-input
@@ -26,7 +26,7 @@ import '../../option/index.js';
26
26
  * whatever holds it, not a `size` here.
27
27
  *
28
28
  * @since 0.1.0
29
- * @status experimental
29
+ * @status stable
30
30
  * @category forms
31
31
  * @aliases SearchField, FacetInput, TokenInput
32
32
  * @documentation https://fusion.dev/helix/components/filter-input
@@ -9,7 +9,7 @@ import type { CSSResultGroup } from 'lit';
9
9
  * tells you which list, not something to read on its own.
10
10
  *
11
11
  * @since 0.1.0
12
- * @status experimental
12
+ * @status stable
13
13
  * @aliases OptGroup, Section
14
14
  * @documentation https://fusion.dev/helix/components/option
15
15
  */
@@ -10,7 +10,7 @@ import type { CSSResultGroup } from 'lit';
10
10
  * picked from what they are looking at.
11
11
  *
12
12
  * @since 0.1.0
13
- * @status experimental
13
+ * @status stable
14
14
  * @category forms
15
15
  * @aliases Item, Choice
16
16
  * @documentation https://fusion.dev/helix/components/option
@@ -10,7 +10,7 @@ import type { CSSResultGroup } from 'lit';
10
10
  * group keeps its question above the row rather than beside the first choice.
11
11
  *
12
12
  * @since 0.1.0
13
- * @status experimental
13
+ * @status stable
14
14
  * @aliases RadioButtons, Choice group
15
15
  * @documentation https://fusion.dev/helix/components/radio
16
16
  *
@@ -14,7 +14,7 @@ import type { CSSResultGroup } from 'lit';
14
14
  * and being chosen is an answer rather than a state.
15
15
  *
16
16
  * @since 0.1.0
17
- * @status experimental
17
+ * @status stable
18
18
  * @category forms
19
19
  * @aliases Option, Choice
20
20
  * @documentation https://fusion.dev/helix/components/radio
@@ -87,6 +87,11 @@ export declare class HelixSandboxPreview extends HelixElement {
87
87
  colorMode?: 'dark' | 'light';
88
88
  /**
89
89
  * Writing direction inside the frame.
90
+ *
91
+ * Not reflected. It is payload for the render message and nothing selects on
92
+ * it, here or anywhere: a frame is a document of its own and what is written
93
+ * on this host reaches nothing inside it, which is the same reason
94
+ * `colorMode` has to be sent rather than set.
90
95
  */
91
96
  direction?: 'rtl';
92
97
  /**
@@ -95,6 +100,16 @@ export declare class HelixSandboxPreview extends HelixElement {
95
100
  label: string;
96
101
  /**
97
102
  * How the example is placed in the frame.
103
+ *
104
+ * `padded` insets it and leaves it at the top, which is the resting case and
105
+ * what an absent value sends. `centered` gives it a measure and centers that
106
+ * box in the frame. `hug` shrinks the example to its own content and centers
107
+ * what is left, which is the difference that matters for a component whose
108
+ * root is a full-width block. `fullscreen` is the whole frame with no inset.
109
+ *
110
+ * Not reflected, for `direction`'s reason: the placement is applied by the
111
+ * document inside the frame, against its own root, so no rule on this side
112
+ * could read it.
98
113
  */
99
114
  layout?: 'padded' | 'centered' | 'fullscreen' | 'hug';
100
115
  /**
@@ -114,13 +114,13 @@ __decorate([
114
114
  property({ attribute: 'color-mode' })
115
115
  ], HelixSandboxPreview.prototype, "colorMode", void 0);
116
116
  __decorate([
117
- property({ reflect: true })
117
+ property()
118
118
  ], HelixSandboxPreview.prototype, "direction", void 0);
119
119
  __decorate([
120
120
  property()
121
121
  ], HelixSandboxPreview.prototype, "label", void 0);
122
122
  __decorate([
123
- property({ reflect: true })
123
+ property()
124
124
  ], HelixSandboxPreview.prototype, "layout", void 0);
125
125
  __decorate([
126
126
  property()
@@ -95,6 +95,11 @@ export declare class HelixSandbox extends HelixElement {
95
95
  lead: 'source' | 'preview';
96
96
  /**
97
97
  * Whether the panes sit side by side or stacked.
98
+ *
99
+ * Not reflected, for `lead`'s reason above: no rule selects on it. The axis
100
+ * reaches the stylesheet as the inner splitter's own `orientation`, which is
101
+ * where the panes are laid out, and this element's sheet names no host
102
+ * attribute at all.
98
103
  */
99
104
  orientation?: 'horizontal' | 'vertical';
100
105
  /**
@@ -230,7 +235,7 @@ export declare class HelixSandbox extends HelixElement {
230
235
  */
231
236
  private get axis();
232
237
  /**
233
- * Says the panes' divider has settled, so a consumer can keep it.
238
+ * Asks for the panes' divider to settle here, and moves it unless refused.
234
239
  *
235
240
  * When it settles, not while it moves. A drag is a stream of positions and
236
241
  * only the one it ends at is a preference; announcing each would ask whoever
@@ -241,13 +246,25 @@ export declare class HelixSandbox extends HelixElement {
241
246
  * wrote to storage on its own would be deciding for all of them under a key
242
247
  * it chose.
243
248
  *
249
+ * **Through `requestChange`, and never the other way round.** Both of these
250
+ * fired after `split` and `panelSize` had already been written, with the
251
+ * answer dropped, so a consumer calling `preventDefault()` on an event whose
252
+ * own line says refusing it takes the decision changed nothing whatever: the
253
+ * divider stayed where the drag left it and their handler read a value they
254
+ * had just declined. `SandboxSource.edit` two files away already carries the
255
+ * argument, that assigning first turns a `before` event into one that has
256
+ * already happened, and `Splitter`, whose `helix-before-resize` these two were
257
+ * split out of, has always announced through the audited path. Refusing one
258
+ * now leaves `.position` bound to the value this element still holds, so the
259
+ * divider goes back where it was.
260
+ *
244
261
  * **A verb each, rather than one `helix-before-resize` naming which of the two
245
262
  * moved.** Both dividers are this element's, so `composedPath()[0]` is the same
246
263
  * host for either and the event name is the only thing that can separate them.
247
264
  */
248
- private splitSettled;
249
- /** As `splitSettled`, for the panel, whose value is pixels rather than a share. */
250
- private panelSettled;
265
+ private requestSplit;
266
+ /** As `requestSplit`, for the panel, whose value is pixels rather than a share. */
267
+ private requestPanelSize;
251
268
  /**
252
269
  * Answers a divider that has asked to move.
253
270
  *
@@ -261,9 +278,31 @@ export declare class HelixSandbox extends HelixElement {
261
278
  * speaking for itself is one of ours, and only those are stopped: the sandbox
262
279
  * announces `helix-before-split` and `helix-before-panel-resize` in their
263
280
  * place, and a consumer never sees the two splitters inside it.
281
+ *
282
+ * **Refused as well as stopped, which is what "controlled from here" costs.**
283
+ * A splitter nobody refuses applies the move itself and says so in its own
284
+ * docblock, so the sentence above was true only while nothing downstream ever
285
+ * declined: refusing `helix-before-split` left `split` at fifty and the
286
+ * divider drawn at fifty-two, one element holding the arrangement and the
287
+ * other showing it. Refusing the inner request first makes this element the
288
+ * single answer.
289
+ *
290
+ * **And the divider is written back, because a refusal writes nothing.** A
291
+ * splitter draws itself from where the gesture reached until its `position` is
292
+ * assigned, which is the setter's stated job, and a bound property Lit did not
293
+ * change is a property Lit does not write. So the answer is assigned either
294
+ * way, which for an accepted move is the number the binding is about to carry
295
+ * anyway.
264
296
  */
265
297
  private readonly handlePanesChange;
266
298
  private readonly handlePanelChange;
299
+ /**
300
+ * Puts a divider where this element says it is.
301
+ *
302
+ * Typed by what is used rather than by the class, which is the whole of the
303
+ * coupling: a splitter this does not import is one that can be replaced.
304
+ */
305
+ private answer;
267
306
  connectedCallback(): void;
268
307
  /** Watches the body, whose height is what the pane sizes are computed from. */
269
308
  private watchBody;
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { customElement, HelixBeforePanelResizeEvent, HelixBeforeSplitEvent, HelixElement, } from '@fusion.dev/helix-core';
7
+ import { customElement, HelixBeforePanelResizeEvent, HelixBeforeSplitEvent, HelixElement, requestChange, } from '@fusion.dev/helix-core';
8
8
  import '../../splitter/index.js';
9
9
  import { html } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
@@ -71,8 +71,9 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
71
71
  }
72
72
  const { value } = event.detail;
73
73
  event.stopPropagation();
74
- this.split = Number(value);
75
- this.splitSettled();
74
+ event.preventDefault();
75
+ this.requestSplit(Number(value));
76
+ this.answer(event.currentTarget, this.split);
76
77
  };
77
78
  this.handlePanelChange = (event) => {
78
79
  if (event.target !== event.currentTarget) {
@@ -80,11 +81,11 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
80
81
  }
81
82
  const { value } = event.detail;
82
83
  event.stopPropagation();
83
- if (this.bodyHeight <= 0) {
84
- return;
84
+ event.preventDefault();
85
+ if (this.bodyHeight > 0) {
86
+ this.requestPanelSize(Math.max(0, ((100 - Number(value)) / 100) * this.bodyHeight));
85
87
  }
86
- this.panelSize = Math.max(0, ((100 - Number(value)) / 100) * this.bodyHeight);
87
- this.panelSettled();
88
+ this.answer(event.currentTarget, this.panelPosition);
88
89
  };
89
90
  this.readPanel = () => {
90
91
  this.hasPanel = this.querySelector(':scope > [slot="panel"]') !== null;
@@ -135,11 +136,31 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
135
136
  get axis() {
136
137
  return this.orientation ?? 'horizontal';
137
138
  }
138
- splitSettled() {
139
- this.dispatchEvent(new HelixBeforeSplitEvent({ value: String(this.split) }));
139
+ requestSplit(next) {
140
+ return requestChange({
141
+ apply: (value) => {
142
+ this.split = value;
143
+ },
144
+ event: (value) => new HelixBeforeSplitEvent({ value: String(value) }),
145
+ host: this,
146
+ next,
147
+ });
148
+ }
149
+ requestPanelSize(next) {
150
+ return requestChange({
151
+ apply: (value) => {
152
+ this.panelSize = value;
153
+ },
154
+ event: (value) => new HelixBeforePanelResizeEvent({ value: String(value) }),
155
+ host: this,
156
+ next,
157
+ });
140
158
  }
141
- panelSettled() {
142
- this.dispatchEvent(new HelixBeforePanelResizeEvent({ value: String(this.panelSize) }));
159
+ answer(divider, position) {
160
+ const target = divider;
161
+ if (target && Number.isFinite(position)) {
162
+ target.position = position;
163
+ }
143
164
  }
144
165
  connectedCallback() {
145
166
  super.connectedCallback();
@@ -233,7 +254,7 @@ __decorate([
233
254
  property()
234
255
  ], HelixSandbox.prototype, "lead", void 0);
235
256
  __decorate([
236
- property({ reflect: true })
257
+ property()
237
258
  ], HelixSandbox.prototype, "orientation", void 0);
238
259
  __decorate([
239
260
  property({ attribute: 'panel-collapsed-size', type: Number })
@@ -28,7 +28,7 @@ let HelixSandboxStatusBar = class HelixSandboxStatusBar extends HelixElement {
28
28
  ${position === undefined ? nothing : html `<span part="caret">${position}</span>`}
29
29
  ${language === undefined
30
30
  ? nothing
31
- : html `<span part="language">${LABELS[language] ?? language}</span>`}
31
+ : html `<span part="language">${Object.hasOwn(LABELS, language) ? LABELS[language] : language}</span>`}
32
32
  <slot name="end"></slot>`;
33
33
  }
34
34
  static { this.styles = styles; }
@@ -20,8 +20,9 @@ import type { CSSResultGroup } from 'lit';
20
20
  * region the id its `href` names.
21
21
  *
22
22
  * @since 0.1.0
23
- * @status experimental
23
+ * @status stable
24
24
  * @category navigation
25
+ * @aliases Skip navigation, Skip to content
25
26
  * @documentation https://fusion.dev/helix/components/skip-link
26
27
  *
27
28
  * @cssproperty --skip-link-border-color - Color of the revealed link's edge.
@@ -33,7 +33,7 @@ import type { CSSResultGroup } from 'lit';
33
33
  * cross product, which is the explosion a named ramp exists to prevent.
34
34
  *
35
35
  * @since 0.1.0
36
- * @status experimental
36
+ * @status stable
37
37
  * @category typography
38
38
  * @aliases Paragraph, Copy, Label, Caption, Heading, Title
39
39
  * @documentation https://fusion.dev/helix/components/text
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fusion.dev/helix",
3
3
  "description": "Styled component tier. Extends the headless tier with token-driven presentation.",
4
- "version": "0.44.0",
4
+ "version": "0.45.0",
5
5
  "license": "MIT",
6
6
  "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
7
7
  "repository": {
@@ -47,14 +47,14 @@
47
47
  },
48
48
  "bugs": "https://github.com/project-fusion/fusion/issues",
49
49
  "dependencies": {
50
- "@fusion.dev/helix-core": "0.44.0",
51
- "@fusion.dev/helix-headless": "0.44.0",
52
- "@fusion.dev/helix-styles": "0.44.0"
50
+ "@fusion.dev/helix-core": "0.45.0",
51
+ "@fusion.dev/helix-headless": "0.45.0",
52
+ "@fusion.dev/helix-styles": "0.45.0"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@custom-elements-manifest/analyzer": "^0.11.0",
56
- "@fusion.dev/helix-cem": "0.44.0",
57
- "@fusion.dev/helix-testing": "0.44.0",
56
+ "@fusion.dev/helix-cem": "0.45.0",
57
+ "@fusion.dev/helix-testing": "0.45.0",
58
58
  "@fusion.dev/scripts": "0.0.0-dev",
59
59
  "@happy-dom/global-registrator": "^20.0.0",
60
60
  "@lit-labs/ssr": "^4.1.0",
package/types/jsx.d.ts CHANGED
@@ -13636,6 +13636,21 @@ name is the fault `TreeItem` avoids by mirroring to `data-selected`.
13636
13636
  Splitting them means moving what every stylesheet selects on, which is a
13637
13637
  change of its own rather than a property being added. */
13638
13638
  defaultSelected?: (HelixRadio["defaultSelected"]) | undefined;
13639
+ /** Whether this choice holds the group's tab stop while nothing is chosen.
13640
+
13641
+ The stop rides on the selection, and an unanswered group has no selection,
13642
+ so without this every choice is `tabindex="-1"` and the keyboard cannot
13643
+ enter the set at all.
13644
+
13645
+ **Written by the group, with no attribute, and it reaches the control
13646
+ rather than the host.** A `tabindex` on the host is two faults at once: it
13647
+ is markup a consumer rendered and their server never sent, which React
13648
+ reports as a mismatch and does not patch up, and it puts the tab stop on
13649
+ the element rather than on the `<button role="radio">` inside it, so a
13650
+ screen reader meets an unnamed box where a native group would have given
13651
+ them an unchecked radio. `Toggle.Root` carries the same property for the
13652
+ same reason. */
13653
+ focusable?: (HelixRadio["focusable"]) | undefined;
13639
13654
 
13640
13655
  /** Fired when this choice is made. Cancelable: refusing it takes the decision and nothing moves. */
13641
13656
  "onhelix-select"?: ((e: HelixRadioHelixSelectElementEvent) => void) | undefined;
@@ -13726,6 +13741,21 @@ name is the fault `TreeItem` avoids by mirroring to `data-selected`.
13726
13741
  Splitting them means moving what every stylesheet selects on, which is a
13727
13742
  change of its own rather than a property being added. */
13728
13743
  "prop:defaultSelected"?: (HelixRadio["defaultSelected"]) | undefined;
13744
+ /** Whether this choice holds the group's tab stop while nothing is chosen.
13745
+
13746
+ The stop rides on the selection, and an unanswered group has no selection,
13747
+ so without this every choice is `tabindex="-1"` and the keyboard cannot
13748
+ enter the set at all.
13749
+
13750
+ **Written by the group, with no attribute, and it reaches the control
13751
+ rather than the host.** A `tabindex` on the host is two faults at once: it
13752
+ is markup a consumer rendered and their server never sent, which React
13753
+ reports as a mismatch and does not patch up, and it puts the tab stop on
13754
+ the element rather than on the `<button role="radio">` inside it, so a
13755
+ screen reader meets an unnamed box where a native group would have given
13756
+ them an unchecked radio. `Toggle.Root` carries the same property for the
13757
+ same reason. */
13758
+ "prop:focusable"?: (HelixRadio["focusable"]) | undefined;
13729
13759
  /** Fired when this choice is made. Cancelable: refusing it takes the decision and nothing moves. */
13730
13760
  "on:helix-select"?: ((e: HelixRadioHelixSelectElementEvent) => void) | undefined;
13731
13761
 
@@ -14066,11 +14096,26 @@ keyed on this attribute, and of the 56 tokens that differ by scheme the
14066
14096
  theme engine emits 19. The other 37 would stay light in a dark preview,
14067
14097
  including every one of the 24 series colors a chart reads. */
14068
14098
  colorMode?: (HelixSandboxPreview["colorMode"]) | undefined;
14069
- /** Writing direction inside the frame. */
14099
+ /** Writing direction inside the frame.
14100
+
14101
+ Not reflected. It is payload for the render message and nothing selects on
14102
+ it, here or anywhere: a frame is a document of its own and what is written
14103
+ on this host reaches nothing inside it, which is the same reason
14104
+ `colorMode` has to be sent rather than set. */
14070
14105
  direction?: (HelixSandboxPreview["direction"]) | undefined;
14071
14106
  /** Accessible name for the frame. */
14072
14107
  label?: (HelixSandboxPreview["label"]) | undefined;
14073
- /** How the example is placed in the frame. */
14108
+ /** How the example is placed in the frame.
14109
+
14110
+ `padded` insets it and leaves it at the top, which is the resting case and
14111
+ what an absent value sends. `centered` gives it a measure and centers that
14112
+ box in the frame. `hug` shrinks the example to its own content and centers
14113
+ what is left, which is the difference that matters for a component whose
14114
+ root is a full-width block. `fullscreen` is the whole frame with no inset.
14115
+
14116
+ Not reflected, for `direction`'s reason: the placement is applied by the
14117
+ document inside the frame, against its own root, so no rule on this side
14118
+ could read it. */
14074
14119
  layout?: (HelixSandboxPreview["layout"]) | undefined;
14075
14120
  /** Markup to render. */
14076
14121
  source?: (HelixSandboxPreview["source"]) | undefined;
@@ -14114,11 +14159,26 @@ keyed on this attribute, and of the 56 tokens that differ by scheme the
14114
14159
  theme engine emits 19. The other 37 would stay light in a dark preview,
14115
14160
  including every one of the 24 series colors a chart reads. */
14116
14161
  "prop:colorMode"?: (HelixSandboxPreview["colorMode"]) | undefined;
14117
- /** Writing direction inside the frame. */
14162
+ /** Writing direction inside the frame.
14163
+
14164
+ Not reflected. It is payload for the render message and nothing selects on
14165
+ it, here or anywhere: a frame is a document of its own and what is written
14166
+ on this host reaches nothing inside it, which is the same reason
14167
+ `colorMode` has to be sent rather than set. */
14118
14168
  "prop:direction"?: (HelixSandboxPreview["direction"]) | undefined;
14119
14169
  /** Accessible name for the frame. */
14120
14170
  "prop:label"?: (HelixSandboxPreview["label"]) | undefined;
14121
- /** How the example is placed in the frame. */
14171
+ /** How the example is placed in the frame.
14172
+
14173
+ `padded` insets it and leaves it at the top, which is the resting case and
14174
+ what an absent value sends. `centered` gives it a measure and centers that
14175
+ box in the frame. `hug` shrinks the example to its own content and centers
14176
+ what is left, which is the difference that matters for a component whose
14177
+ root is a full-width block. `fullscreen` is the whole frame with no inset.
14178
+
14179
+ Not reflected, for `direction`'s reason: the placement is applied by the
14180
+ document inside the frame, against its own root, so no rule on this side
14181
+ could read it. */
14122
14182
  "prop:layout"?: (HelixSandboxPreview["layout"]) | undefined;
14123
14183
  /** Markup to render. */
14124
14184
  "prop:source"?: (HelixSandboxPreview["source"]) | undefined;
@@ -14211,7 +14271,12 @@ names below keeps that true whichever way round they sit.
14211
14271
  `split` follows the lead pane rather than the source, so `split="30"` means
14212
14272
  the same thing in both directions: thirty percent to whatever comes first. */
14213
14273
  lead?: (HelixSandbox["lead"]) | undefined;
14214
- /** Whether the panes sit side by side or stacked. */
14274
+ /** Whether the panes sit side by side or stacked.
14275
+
14276
+ Not reflected, for `lead`'s reason above: no rule selects on it. The axis
14277
+ reaches the stylesheet as the inner splitter's own `orientation`, which is
14278
+ where the panes are laid out, and this element's sheet names no host
14279
+ attribute at all. */
14215
14280
  orientation?: (HelixSandbox["orientation"]) | undefined;
14216
14281
  /** What the panel's height becomes when it is closed.
14217
14282
 
@@ -14311,7 +14376,12 @@ names below keeps that true whichever way round they sit.
14311
14376
  `split` follows the lead pane rather than the source, so `split="30"` means
14312
14377
  the same thing in both directions: thirty percent to whatever comes first. */
14313
14378
  "prop:lead"?: (HelixSandbox["lead"]) | undefined;
14314
- /** Whether the panes sit side by side or stacked. */
14379
+ /** Whether the panes sit side by side or stacked.
14380
+
14381
+ Not reflected, for `lead`'s reason above: no rule selects on it. The axis
14382
+ reaches the stylesheet as the inner splitter's own `orientation`, which is
14383
+ where the panes are laid out, and this element's sheet names no host
14384
+ attribute at all. */
14315
14385
  "prop:orientation"?: (HelixSandbox["orientation"]) | undefined;
14316
14386
  /** What the panel's height becomes when it is closed.
14317
14387
 
@@ -32824,6 +32894,20 @@ export type CustomElements = {
32824
32894
  * name is the fault `TreeItem` avoids by mirroring to `data-selected`.
32825
32895
  * Splitting them means moving what every stylesheet selects on, which is a
32826
32896
  * change of its own rather than a property being added. (property only)
32897
+ * - `focusable`: Whether this choice holds the group's tab stop while nothing is chosen.
32898
+ *
32899
+ * The stop rides on the selection, and an unanswered group has no selection,
32900
+ * so without this every choice is `tabindex="-1"` and the keyboard cannot
32901
+ * enter the set at all.
32902
+ *
32903
+ * **Written by the group, with no attribute, and it reaches the control
32904
+ * rather than the host.** A `tabindex` on the host is two faults at once: it
32905
+ * is markup a consumer rendered and their server never sent, which React
32906
+ * reports as a mismatch and does not patch up, and it puts the tab stop on
32907
+ * the element rather than on the `<button role="radio">` inside it, so a
32908
+ * screen reader meets an unnamed box where a native group would have given
32909
+ * them an unchecked radio. `Toggle.Root` carries the same property for the
32910
+ * same reason. (property only)
32827
32911
  * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
32828
32912
  *
32829
32913
  * **Named `whenSettled` because `settled` is taken four times over**, by
@@ -33158,8 +33242,23 @@ export type CustomElements = {
33158
33242
  * theme engine emits 19. The other 37 would stay light in a dark preview,
33159
33243
  * including every one of the 24 series colors a chart reads.
33160
33244
  * - `direction`: Writing direction inside the frame.
33245
+ *
33246
+ * Not reflected. It is payload for the render message and nothing selects on
33247
+ * it, here or anywhere: a frame is a document of its own and what is written
33248
+ * on this host reaches nothing inside it, which is the same reason
33249
+ * `colorMode` has to be sent rather than set.
33161
33250
  * - `label`: Accessible name for the frame.
33162
33251
  * - `layout`: How the example is placed in the frame.
33252
+ *
33253
+ * `padded` insets it and leaves it at the top, which is the resting case and
33254
+ * what an absent value sends. `centered` gives it a measure and centers that
33255
+ * box in the frame. `hug` shrinks the example to its own content and centers
33256
+ * what is left, which is the difference that matters for a component whose
33257
+ * root is a full-width block. `fullscreen` is the whole frame with no inset.
33258
+ *
33259
+ * Not reflected, for `direction`'s reason: the placement is applied by the
33260
+ * document inside the frame, against its own root, so no rule on this side
33261
+ * could read it.
33163
33262
  * - `source`: Markup to render.
33164
33263
  * - `src`: Document the frame loads, which brings the styles and the elements.
33165
33264
  * - `styles`: Stylesheet applied inside the frame, alongside the markup.
@@ -33275,6 +33374,11 @@ export type CustomElements = {
33275
33374
  * `split` follows the lead pane rather than the source, so `split="30"` means
33276
33375
  * the same thing in both directions: thirty percent to whatever comes first.
33277
33376
  * - `orientation`: Whether the panes sit side by side or stacked.
33377
+ *
33378
+ * Not reflected, for `lead`'s reason above: no rule selects on it. The axis
33379
+ * reaches the stylesheet as the inner splitter's own `orientation`, which is
33380
+ * where the panes are laid out, and this element's sheet names no host
33381
+ * attribute at all.
33278
33382
  * - `panel-collapsed-size`/`panelCollapsedSize`: What the panel's height becomes when it is closed.
33279
33383
  *
33280
33384
  * Zero closes it outright. A panel whose contents include the control that
@@ -52296,6 +52400,20 @@ export type CustomElementsSolidJs = {
52296
52400
  * name is the fault `TreeItem` avoids by mirroring to `data-selected`.
52297
52401
  * Splitting them means moving what every stylesheet selects on, which is a
52298
52402
  * change of its own rather than a property being added. (property only)
52403
+ * - `focusable`: Whether this choice holds the group's tab stop while nothing is chosen.
52404
+ *
52405
+ * The stop rides on the selection, and an unanswered group has no selection,
52406
+ * so without this every choice is `tabindex="-1"` and the keyboard cannot
52407
+ * enter the set at all.
52408
+ *
52409
+ * **Written by the group, with no attribute, and it reaches the control
52410
+ * rather than the host.** A `tabindex` on the host is two faults at once: it
52411
+ * is markup a consumer rendered and their server never sent, which React
52412
+ * reports as a mismatch and does not patch up, and it puts the tab stop on
52413
+ * the element rather than on the `<button role="radio">` inside it, so a
52414
+ * screen reader meets an unnamed box where a native group would have given
52415
+ * them an unchecked radio. `Toggle.Root` carries the same property for the
52416
+ * same reason. (property only)
52299
52417
  * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
52300
52418
  *
52301
52419
  * **Named `whenSettled` because `settled` is taken four times over**, by
@@ -52638,8 +52756,23 @@ export type CustomElementsSolidJs = {
52638
52756
  * theme engine emits 19. The other 37 would stay light in a dark preview,
52639
52757
  * including every one of the 24 series colors a chart reads.
52640
52758
  * - `direction`: Writing direction inside the frame.
52759
+ *
52760
+ * Not reflected. It is payload for the render message and nothing selects on
52761
+ * it, here or anywhere: a frame is a document of its own and what is written
52762
+ * on this host reaches nothing inside it, which is the same reason
52763
+ * `colorMode` has to be sent rather than set.
52641
52764
  * - `label`: Accessible name for the frame.
52642
52765
  * - `layout`: How the example is placed in the frame.
52766
+ *
52767
+ * `padded` insets it and leaves it at the top, which is the resting case and
52768
+ * what an absent value sends. `centered` gives it a measure and centers that
52769
+ * box in the frame. `hug` shrinks the example to its own content and centers
52770
+ * what is left, which is the difference that matters for a component whose
52771
+ * root is a full-width block. `fullscreen` is the whole frame with no inset.
52772
+ *
52773
+ * Not reflected, for `direction`'s reason: the placement is applied by the
52774
+ * document inside the frame, against its own root, so no rule on this side
52775
+ * could read it.
52643
52776
  * - `source`: Markup to render.
52644
52777
  * - `src`: Document the frame loads, which brings the styles and the elements.
52645
52778
  * - `styles`: Stylesheet applied inside the frame, alongside the markup.
@@ -52758,6 +52891,11 @@ export type CustomElementsSolidJs = {
52758
52891
  * `split` follows the lead pane rather than the source, so `split="30"` means
52759
52892
  * the same thing in both directions: thirty percent to whatever comes first.
52760
52893
  * - `orientation`: Whether the panes sit side by side or stacked.
52894
+ *
52895
+ * Not reflected, for `lead`'s reason above: no rule selects on it. The axis
52896
+ * reaches the stylesheet as the inner splitter's own `orientation`, which is
52897
+ * where the panes are laid out, and this element's sheet names no host
52898
+ * attribute at all.
52761
52899
  * - `panel-collapsed-size`/`panelCollapsedSize`: What the panel's height becomes when it is closed.
52762
52900
  *
52763
52901
  * Zero closes it outright. A panel whose contents include the control that
package/types/vue.d.ts CHANGED
@@ -7029,6 +7029,21 @@ name is the fault `TreeItem` avoids by mirroring to `data-selected`.
7029
7029
  Splitting them means moving what every stylesheet selects on, which is a
7030
7030
  change of its own rather than a property being added. */
7031
7031
  defaultSelected?: (HelixRadio["defaultSelected"]) | undefined;
7032
+ /** Whether this choice holds the group's tab stop while nothing is chosen.
7033
+
7034
+ The stop rides on the selection, and an unanswered group has no selection,
7035
+ so without this every choice is `tabindex="-1"` and the keyboard cannot
7036
+ enter the set at all.
7037
+
7038
+ **Written by the group, with no attribute, and it reaches the control
7039
+ rather than the host.** A `tabindex` on the host is two faults at once: it
7040
+ is markup a consumer rendered and their server never sent, which React
7041
+ reports as a mismatch and does not patch up, and it puts the tab stop on
7042
+ the element rather than on the `<button role="radio">` inside it, so a
7043
+ screen reader meets an unnamed box where a native group would have given
7044
+ them an unchecked radio. `Toggle.Root` carries the same property for the
7045
+ same reason. */
7046
+ focusable?: (HelixRadio["focusable"]) | undefined;
7032
7047
  };
7033
7048
 
7034
7049
  export type HelixRadioVueEvents = {
@@ -7223,11 +7238,26 @@ keyed on this attribute, and of the 56 tokens that differ by scheme the
7223
7238
  theme engine emits 19. The other 37 would stay light in a dark preview,
7224
7239
  including every one of the 24 series colors a chart reads. */
7225
7240
  colorMode?: (HelixSandboxPreview["colorMode"]) | undefined;
7226
- /** Writing direction inside the frame. */
7241
+ /** Writing direction inside the frame.
7242
+
7243
+ Not reflected. It is payload for the render message and nothing selects on
7244
+ it, here or anywhere: a frame is a document of its own and what is written
7245
+ on this host reaches nothing inside it, which is the same reason
7246
+ `colorMode` has to be sent rather than set. */
7227
7247
  direction?: (HelixSandboxPreview["direction"]) | undefined;
7228
7248
  /** Accessible name for the frame. */
7229
7249
  label?: (HelixSandboxPreview["label"]) | undefined;
7230
- /** How the example is placed in the frame. */
7250
+ /** How the example is placed in the frame.
7251
+
7252
+ `padded` insets it and leaves it at the top, which is the resting case and
7253
+ what an absent value sends. `centered` gives it a measure and centers that
7254
+ box in the frame. `hug` shrinks the example to its own content and centers
7255
+ what is left, which is the difference that matters for a component whose
7256
+ root is a full-width block. `fullscreen` is the whole frame with no inset.
7257
+
7258
+ Not reflected, for `direction`'s reason: the placement is applied by the
7259
+ document inside the frame, against its own root, so no rule on this side
7260
+ could read it. */
7231
7261
  layout?: (HelixSandboxPreview["layout"]) | undefined;
7232
7262
  /** Markup to render. */
7233
7263
  source?: (HelixSandboxPreview["source"]) | undefined;
@@ -7318,7 +7348,12 @@ names below keeps that true whichever way round they sit.
7318
7348
  `split` follows the lead pane rather than the source, so `split="30"` means
7319
7349
  the same thing in both directions: thirty percent to whatever comes first. */
7320
7350
  lead?: (HelixSandbox["lead"]) | undefined;
7321
- /** Whether the panes sit side by side or stacked. */
7351
+ /** Whether the panes sit side by side or stacked.
7352
+
7353
+ Not reflected, for `lead`'s reason above: no rule selects on it. The axis
7354
+ reaches the stylesheet as the inner splitter's own `orientation`, which is
7355
+ where the panes are laid out, and this element's sheet names no host
7356
+ attribute at all. */
7322
7357
  orientation?: (HelixSandbox["orientation"]) | undefined;
7323
7358
  /** What the panel's height becomes when it is closed.
7324
7359