@fusion.dev/helix-headless 0.53.0 → 0.53.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +141 -141
- package/dist/accordion/item/accordion-item.d.ts +13 -13
- package/dist/accordion/root/accordion-root.d.ts +1 -1
- package/dist/area-chart/root/area-chart-root.js +1 -1
- package/dist/avatar/group/avatar-group.d.ts +11 -11
- package/dist/bar-chart/root/bar-chart-root.d.ts +1 -1
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +6 -6
- package/dist/button/root/button-root.d.ts +1 -1
- package/dist/card/root/card-root.d.ts +1 -1
- package/dist/carousel/root/carousel-root.d.ts +14 -14
- package/dist/chat/composer/chat-composer.d.ts +6 -6
- package/dist/chat/root/chat-root.d.ts +9 -9
- package/dist/checkbox/root/checkbox-root.d.ts +2 -2
- package/dist/checkbox/root/checkbox-root.js +1 -1
- package/dist/code-block/root/code-block-root.d.ts +5 -5
- package/dist/color-input/root/color-input-root.d.ts +3 -3
- package/dist/color-picker/root/color-picker-root.d.ts +14 -14
- package/dist/combobox/root/combobox-root.d.ts +25 -5
- package/dist/combobox/root/combobox-root.js +6 -4
- package/dist/command/root/command-root.d.ts +6 -7
- package/dist/data-table/root/data-table-root.d.ts +61 -38
- package/dist/data-table/root/data-table-root.js +8 -3
- package/dist/data-table/root/order.d.ts +3 -3
- package/dist/date-input/root/date-input-root.d.ts +12 -11
- package/dist/dialog/root/dialog-root.d.ts +4 -4
- package/dist/drawer/root/drawer-root.d.ts +5 -5
- package/dist/filter-input/menu/filter-menu.d.ts +7 -1
- package/dist/filter-input/menu/filter-menu.js +2 -1
- package/dist/filter-input/root/filter-input-root.d.ts +6 -6
- package/dist/format-date/root/format-date-root.d.ts +6 -5
- package/dist/heatmap/root/heatmap-root.d.ts +11 -16
- package/dist/image/root/image-root.d.ts +4 -4
- package/dist/input/root/input-root.d.ts +7 -7
- package/dist/line-chart/root/line-chart-root.d.ts +1 -2
- package/dist/list/item/list-item.d.ts +6 -7
- package/dist/list/root/list-root.d.ts +4 -4
- package/dist/megamenu/root/megamenu-root.d.ts +4 -4
- package/dist/notifications/notification/notification.d.ts +10 -10
- package/dist/notifications/root/notifications-root.d.ts +1 -1
- package/dist/option/root/option-root.d.ts +3 -3
- package/dist/pagination/root/pagination-root.d.ts +2 -2
- package/dist/pin-input/root/pin-input-root.d.ts +4 -4
- package/dist/popover/root/popover-root.d.ts +7 -6
- package/dist/radio/root/radio-root.d.ts +12 -2
- package/dist/radio/root/radio-root.js +5 -1
- package/dist/select/root/select-root.d.ts +24 -0
- package/dist/select/root/select-root.js +4 -1
- package/dist/speed-dial/root/speed-dial-root.d.ts +8 -9
- package/dist/stat/root/stat-root.d.ts +3 -3
- package/dist/steps/root/steps-root.d.ts +1 -1
- package/dist/steps/step/step.d.ts +5 -5
- package/dist/switch/root/switch-root.js +1 -1
- package/dist/table/column/table-column.d.ts +28 -28
- package/dist/table/root/table-root.d.ts +14 -17
- package/dist/table/row/table-row.d.ts +4 -4
- package/dist/tabs/panel/tab-panel.d.ts +2 -2
- package/dist/tabs/root/tabs-root.js +11 -4
- package/dist/tabs/tab/tab.d.ts +11 -1
- package/dist/tabs/tab/tab.js +5 -1
- package/dist/time-input/root/time-input-root.d.ts +13 -13
- package/dist/time-picker/root/time-picker-root.d.ts +8 -8
- package/dist/toast/root/toast-root.d.ts +2 -2
- package/dist/toggle/root/toggle-root.d.ts +16 -6
- package/dist/toggle/root/toggle-root.js +5 -1
- package/dist/tooltip/root/tooltip-root.d.ts +2 -2
- package/dist/tour/stop/tour-stop.d.ts +3 -3
- package/dist/tree/item/tree-item.d.ts +2 -2
- package/dist/tree/item/tree-item.js +4 -3
- package/dist/tree/root/tree-root.d.ts +8 -7
- package/dist/tree/root/tree-root.js +9 -5
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +7 -1
- package/dist/video-playlist/menu/video-playlist-menu.js +4 -2
- package/dist/video-playlist/root/video-playlist-root.d.ts +5 -5
- package/dist/video-playlist/root/video-playlist-root.js +2 -3
- package/package.json +5 -5
- package/types/jsx.d.ts +754 -780
- package/types/vue.d.ts +172 -185
|
@@ -6,8 +6,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
6
6
|
* @description
|
|
7
7
|
* **The component is the truncation.** Given a page and a total it works out
|
|
8
8
|
* which numbers to show and where the runs break, so this is data-driven rather
|
|
9
|
-
* than composed: `<helix-pagination page="4" pages="12">` rather than
|
|
10
|
-
* slotted children a consumer keeps in step with their own query.
|
|
9
|
+
* than composed: `<helix-headless-pagination page="4" pages="12">` rather than
|
|
10
|
+
* twelve slotted children a consumer keeps in step with their own query.
|
|
11
11
|
*
|
|
12
12
|
* **The width does not change as you page.** The run around the current page is
|
|
13
13
|
* `siblings` either side, and grows to absorb a gap slot at a boundary, so the
|
|
@@ -110,10 +110,10 @@ export declare class HelixHeadlessPinInput extends HelixHeadlessPinInput_base {
|
|
|
110
110
|
* marked letters wants `text`, which judges nothing.
|
|
111
111
|
*
|
|
112
112
|
* **Not reflected**: nothing selects on it, so reflecting only writes
|
|
113
|
-
* `type="numeric"` onto every `<helix-pin-input>` ever rendered, an
|
|
114
|
-
* no consumer's markup had. The area rules carry the sentence
|
|
115
|
-
* what CSS selects on". The real inputs take it as a binding,
|
|
116
|
-
* makes the keyboard follow.
|
|
113
|
+
* `type="numeric"` onto every `<helix-headless-pin-input>` ever rendered, an
|
|
114
|
+
* attribute no consumer's markup had. The area rules carry the sentence
|
|
115
|
+
* "reflect only what CSS selects on". The real inputs take it as a binding,
|
|
116
|
+
* which is what makes the keyboard follow.
|
|
117
117
|
*/
|
|
118
118
|
type: PinType;
|
|
119
119
|
/** Focus is delegated, so the host is never the focus target. */
|
|
@@ -64,12 +64,13 @@ export declare class HelixHeadlessPopover extends HelixHeadlessPopover_base {
|
|
|
64
64
|
* The invoker that last opened the panel, when a command did.
|
|
65
65
|
*
|
|
66
66
|
* Kept because the `source` a command hands the handlers is needed twice
|
|
67
|
-
* over. It is the anchor: the
|
|
68
|
-
*
|
|
69
|
-
* against the window origin. And the outside-press
|
|
70
|
-
* invoker is part of the control, the press firing
|
|
71
|
-
* command arriving on the `click` after it, or a
|
|
72
|
-
* the host closes the panel and immediately reopens
|
|
67
|
+
* over. It is the anchor: the host is not a box to position against, a sheet
|
|
68
|
+
* being free to give it none, so a popover opened by a command outside it
|
|
69
|
+
* would otherwise open against the window origin. And the outside-press
|
|
70
|
+
* dismissal has to know the invoker is part of the control, the press firing
|
|
71
|
+
* on `pointerdown` and the command arriving on the `click` after it, or a
|
|
72
|
+
* `--toggle` button outside the host closes the panel and immediately reopens
|
|
73
|
+
* it, for ever.
|
|
73
74
|
*/
|
|
74
75
|
private invoker;
|
|
75
76
|
protected readonly commands: CommandController;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessRadio_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinSelectableItemInterface) & typeof HelixElement;
|
|
4
4
|
/**
|
|
5
5
|
* @summary One choice in a radio group.
|
|
@@ -54,7 +54,7 @@ export declare class HelixHeadlessRadio extends HelixHeadlessRadio_base {
|
|
|
54
54
|
* **The attribute, read when it is asked for, and never a snapshot taken in
|
|
55
55
|
* the constructor.** A field initializer runs there, and an element the HTML
|
|
56
56
|
* parser created has none of its attributes yet at that moment: measured on
|
|
57
|
-
* this element, on `Option` and on `Toggle`, `<helix-radio value="a"
|
|
57
|
+
* this element, on `Option` and on `Toggle`, `<helix-headless-radio value="a"
|
|
58
58
|
* selected>` reported `defaultSelected` as `false` both from parsed markup
|
|
59
59
|
* and from `createElement` followed by `setAttribute`, which is every way a
|
|
60
60
|
* consumer writes one. The snapshot could only ever be true for an element
|
|
@@ -89,6 +89,16 @@ export declare class HelixHeadlessRadio extends HelixHeadlessRadio_base {
|
|
|
89
89
|
* same reason.
|
|
90
90
|
*/
|
|
91
91
|
focusable: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Asks for the render that follows a hydration, so the stop stops being every
|
|
94
|
+
* choice's.
|
|
95
|
+
*
|
|
96
|
+
* `tabindex` reads `childrenKnown` and a hydrating render is one where that is
|
|
97
|
+
* false, which is what keeps the hydrating render the server's. Nothing else
|
|
98
|
+
* would ask: the group writes an already-false `focusable` onto every choice
|
|
99
|
+
* but one, which changes nothing and so re-renders nothing.
|
|
100
|
+
*/
|
|
101
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
92
102
|
protected render(): TemplateResult;
|
|
93
103
|
}
|
|
94
104
|
declare global {
|
|
@@ -18,6 +18,10 @@ let HelixHeadlessRadio = class HelixHeadlessRadio extends MixinSelectableItem(He
|
|
|
18
18
|
set defaultSelected(next) {
|
|
19
19
|
this.toggleAttribute('selected', next);
|
|
20
20
|
}
|
|
21
|
+
firstUpdated(changed) {
|
|
22
|
+
super.firstUpdated(changed);
|
|
23
|
+
this.finishHydration();
|
|
24
|
+
}
|
|
21
25
|
render() {
|
|
22
26
|
return html `<button
|
|
23
27
|
part="item"
|
|
@@ -25,7 +29,7 @@ let HelixHeadlessRadio = class HelixHeadlessRadio extends MixinSelectableItem(He
|
|
|
25
29
|
role="radio"
|
|
26
30
|
aria-checked=${this.selected ? 'true' : 'false'}
|
|
27
31
|
?disabled=${this.disabled}
|
|
28
|
-
tabindex=${this.selected || this.focusable ? '0' : '-1'}
|
|
32
|
+
tabindex=${this.selected || this.focusable || !this.childrenKnown ? '0' : '-1'}
|
|
29
33
|
@click=${() => this.select()}
|
|
30
34
|
>
|
|
31
35
|
<span part="box"><span part="mark" aria-hidden="true"></span></span>
|
|
@@ -134,6 +134,30 @@ export declare class HelixHeadlessSelect extends HelixHeadlessSelect_base {
|
|
|
134
134
|
* `slotchange`, which a declarative shadow root fires before anything listens,
|
|
135
135
|
* so a hydrated select kept "Choose" for good. Nothing on a server or while
|
|
136
136
|
* hydrating what one sent, which drew the placeholder too.
|
|
137
|
+
*
|
|
138
|
+
* **And the placeholder is a statement, so a render that cannot read the
|
|
139
|
+
* words does not make it.** "Choose" means nothing is chosen. `value` is an
|
|
140
|
+
* attribute and a server has it, the words are the children's and a server
|
|
141
|
+
* has none, so a `<helix-select default-value="two">` served "Choose" over an
|
|
142
|
+
* answer the consumer had already given: false to a reader, and false to a
|
|
143
|
+
* crawler, on every select in the library's own examples. Where a value is
|
|
144
|
+
* declared and the word for it cannot be read, the trigger says nothing and
|
|
145
|
+
* keeps its box, which is the answer this library reaches for everywhere it
|
|
146
|
+
* cannot tell empty from unknown. `firstUpdated` asks for the render that
|
|
147
|
+
* fills it in.
|
|
148
|
+
*
|
|
149
|
+
* The placeholder still stands where there is genuinely no value, which is
|
|
150
|
+
* what it is for and the one case a server can be sure of.
|
|
151
|
+
*
|
|
152
|
+
* **`nothing` and never `''`, which is the difference between a word that
|
|
153
|
+
* arrives and one that never does.** Lit's hydration primes a child part with
|
|
154
|
+
* whatever the render computed, and `''` is a primitive, so `_commitText`
|
|
155
|
+
* takes the branch that assumes the server left a text node to overwrite.
|
|
156
|
+
* There is none, the write lands on the closing part marker's comment data,
|
|
157
|
+
* and the trigger stays empty for the life of the page: measured by
|
|
158
|
+
* `check:spec:dsd`, which caught all nine of these and showed a blank select
|
|
159
|
+
* beside a client's "Option Two". `nothing` primes the sentinel instead, so
|
|
160
|
+
* the commit creates the text node it needs.
|
|
137
161
|
*/
|
|
138
162
|
private get display();
|
|
139
163
|
/** Closes the list and puts focus back where it came from. */
|
|
@@ -74,7 +74,10 @@ let HelixHeadlessSelect = class HelixHeadlessSelect extends MixinControllerOpen(
|
|
|
74
74
|
const words = optionsAmong(this.knownChildren)
|
|
75
75
|
.filter((option) => chosen.has(option.value))
|
|
76
76
|
.map((option) => option.text);
|
|
77
|
-
|
|
77
|
+
if (words.length > 0) {
|
|
78
|
+
return words.join(', ');
|
|
79
|
+
}
|
|
80
|
+
return chosen.size > 0 && !this.childrenKnown ? nothing : this.placeholder;
|
|
78
81
|
}
|
|
79
82
|
close() {
|
|
80
83
|
if (!this.open) {
|
|
@@ -15,11 +15,10 @@ declare const HelixHeadlessSpeedDial_base: (new (...args: any[]) => import("@fus
|
|
|
15
15
|
* mean defining what a dial with a submenu in it does.
|
|
16
16
|
*
|
|
17
17
|
* **The trigger is a control the consumer slots**, and the floating action
|
|
18
|
-
* button is the usual one: `
|
|
19
|
-
*
|
|
20
|
-
* `
|
|
21
|
-
*
|
|
22
|
-
* layer.
|
|
18
|
+
* button is the usual one: `IconButton` with `shape="circle"` and `raised`.
|
|
19
|
+
* There is no `helix-fab`, because it would re-declare `emphasis`, `tone`,
|
|
20
|
+
* `label` and a size around a control that already has all four. A round raised
|
|
21
|
+
* button is a shape, and where it sits is `data-dock` in the base layer.
|
|
23
22
|
*
|
|
24
23
|
* **Nothing is reserved from the keyboard.** A menu that drills has to keep the
|
|
25
24
|
* horizontal pair for going in and coming back; a dial goes nowhere, so all four
|
|
@@ -105,10 +104,10 @@ export declare class HelixHeadlessSpeedDial extends HelixHeadlessSpeedDial_base
|
|
|
105
104
|
*
|
|
106
105
|
* **This is the case the tier rule blocks and a render method unblocks.** A
|
|
107
106
|
* bare `<button>` is what the headless tier can write: it must not reach for
|
|
108
|
-
* `
|
|
109
|
-
*
|
|
110
|
-
* of its own overrides this to use one. Written inline, the only way
|
|
111
|
-
*
|
|
107
|
+
* `Button`, which lives a tier above and would make `headless` depend on
|
|
108
|
+
* `styled`. So the base draws the plain control and a tier that has buttons
|
|
109
|
+
* of its own overrides this to use one. Written inline, the only way to
|
|
110
|
+
* change it would be to reimplement the template, panel and all.
|
|
112
111
|
*/
|
|
113
112
|
protected renderTrigger(): TemplateResult;
|
|
114
113
|
protected render(): TemplateResult;
|
|
@@ -35,9 +35,9 @@ export declare class HelixHeadlessStat extends HelixElement {
|
|
|
35
35
|
* The row directions set them side by side, for a figure in a line of text or
|
|
36
36
|
* a narrow strip where a stacked pair would be two lines of almost nothing.
|
|
37
37
|
*
|
|
38
|
-
* A property rather than a `
|
|
39
|
-
*
|
|
40
|
-
*
|
|
38
|
+
* A property rather than a `Flex` around it, because the unit has to stay on
|
|
39
|
+
* the value's baseline whichever way the pair goes, and only this element
|
|
40
|
+
* knows which of its children the unit belongs to.
|
|
41
41
|
*
|
|
42
42
|
* **Optional rather than defaulted to `column`, which is not a style
|
|
43
43
|
* preference.** A reflecting property with a default writes its attribute onto
|
|
@@ -22,7 +22,7 @@ declare const HelixHeadlessSteps_base: (new (...args: any[]) => import("@fusion.
|
|
|
22
22
|
* @aliases Stepper, Wizard, Progress steps
|
|
23
23
|
* @documentation https://fusion.dev/helix/components/steps
|
|
24
24
|
*
|
|
25
|
-
* @slot - The steps
|
|
25
|
+
* @slot - The steps.
|
|
26
26
|
*
|
|
27
27
|
* @event {HelixActivateEvent} helix-activate - Fired once the current one has moved, so the element already holds it.
|
|
28
28
|
* @event {HelixBeforeActivateEvent} helix-before-activate - Fired before the active step changes. Cancelable: refusing it takes the decision and nothing moves.
|
|
@@ -6,9 +6,9 @@ import '../../button/index.js';
|
|
|
6
6
|
*
|
|
7
7
|
* @description
|
|
8
8
|
* **The name is a button, and only the name.** The marker is `aria-hidden`
|
|
9
|
-
* decoration, so wrapping it would add hit area and no meaning. It is
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* decoration, so wrapping it would add hit area and no meaning. It is `Button`
|
|
10
|
+
* rather than a `<button>` this element resets: the hover wash, the focus ring
|
|
11
|
+
* and the disabled treatment are decisions the button carries.
|
|
12
12
|
*
|
|
13
13
|
* **It says nothing about where a reader may go.** Every step is pressable and
|
|
14
14
|
* announces itself with `helix-select`; refusing the ones ahead is `disabled`,
|
|
@@ -27,7 +27,7 @@ import '../../button/index.js';
|
|
|
27
27
|
* @documentation https://fusion.dev/helix/components/steps
|
|
28
28
|
*
|
|
29
29
|
* @slot - The step's name.
|
|
30
|
-
* @slot content - What the stage holds. Always rendered here, a tier with no stylesheet having nothing to fold it with
|
|
30
|
+
* @slot content - What the stage holds. Always rendered here, a tier with no stylesheet having nothing to fold it with, so whether it is folded away is the sheet's answer and not this tier's.
|
|
31
31
|
* @slot description - A line under the name, for what the stage is for.
|
|
32
32
|
* @slot marker - Replaces the number, or the check a complete step shows.
|
|
33
33
|
*
|
|
@@ -36,7 +36,7 @@ import '../../button/index.js';
|
|
|
36
36
|
* @csspart body - The name and its description.
|
|
37
37
|
* @csspart content - What the stage holds, while it is open.
|
|
38
38
|
* @csspart description - The line under it.
|
|
39
|
-
* @csspart label - The step's name, which is a
|
|
39
|
+
* @csspart label - The step's name, which is a control.
|
|
40
40
|
* @csspart label-button - The inner control.
|
|
41
41
|
* @csspart lead - The half line arriving from the step before.
|
|
42
42
|
* @csspart mark - The glyph inside the marker: a tick, a dot, or an empty ring.
|
|
@@ -47,7 +47,7 @@ let HelixHeadlessSwitch = class HelixHeadlessSwitch extends MixinControllerCheck
|
|
|
47
47
|
part="control"
|
|
48
48
|
type="checkbox"
|
|
49
49
|
role="switch"
|
|
50
|
-
.checked=${this.checked}
|
|
50
|
+
.checked=${this.checked || nothing}
|
|
51
51
|
?disabled=${this.isDisabled}
|
|
52
52
|
?required=${this.required}
|
|
53
53
|
aria-describedby=${this.describedBy ?? nothing}
|
|
@@ -25,9 +25,9 @@ export declare const at: (row: Readonly<Record<string, unknown>>, path: string)
|
|
|
25
25
|
*
|
|
26
26
|
* **`align` is a string anybody can write**, the union on the property being a
|
|
27
27
|
* compile-time claim and nothing else, and both tables put the value straight
|
|
28
|
-
* into CSS: `
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
* into CSS: `Table` into a rule in each row's shadow root, `DataTable` into the
|
|
29
|
+
* cell it draws. One guard, here with the property, rather than one in each
|
|
30
|
+
* table and only one of them written.
|
|
31
31
|
*/
|
|
32
32
|
export declare const edgeOf: (align: string | undefined) => string | undefined;
|
|
33
33
|
/**
|
|
@@ -38,23 +38,23 @@ export declare const edgeOf: (align: string | undefined) => string | undefined;
|
|
|
38
38
|
* the table has another track; remove one and it does not. That is what ties
|
|
39
39
|
* the two together, and a table-level track list on its own does not: a list
|
|
40
40
|
* that is accidentally the headings is invalid CSS a grid ignores in silence,
|
|
41
|
-
* drawing the whole table as one column. `
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
41
|
+
* drawing the whole table as one column. `Table`'s `columns` is dealt out a
|
|
42
|
+
* track at a time against the columns declared under it, so a heading among the
|
|
43
|
+
* widths costs its own column a width and no more, and a list longer or shorter
|
|
44
|
+
* than the columns is trimmed or shared rather than being a second count of
|
|
45
|
+
* them. A column's own `width` wins over the track in its place.
|
|
46
46
|
*
|
|
47
47
|
* **It is also where every per-column fact goes**, which is the reason
|
|
48
|
-
* `
|
|
49
|
-
*
|
|
50
|
-
*
|
|
48
|
+
* `DataTable` needs no column config object. `field` names the key the cell
|
|
49
|
+
* reads, `sortable` says a reader may reorder by it, `align` says which edge
|
|
50
|
+
* the values line up against, and `cell` takes a function for anything the
|
|
51
51
|
* field alone cannot express. The schema is markup and the data is a property:
|
|
52
52
|
* a schema is small, declarative, and something a reader should be able to see
|
|
53
53
|
* in the HTML, and data is large and windowed.
|
|
54
54
|
*
|
|
55
55
|
* **The same element serves both tables**, the markup one and the data one. It
|
|
56
|
-
* is identified by a flag rather than by `instanceof`, so a `
|
|
57
|
-
*
|
|
56
|
+
* is identified by a flag rather than by `instanceof`, so a `TableColumn` works
|
|
57
|
+
* inside either without the two roots sharing anything else.
|
|
58
58
|
*
|
|
59
59
|
* **It generates no box of its own**, the same as a row: the heading is a grid
|
|
60
60
|
* item of the table, so it lines up with the cells under it rather than sitting
|
|
@@ -64,10 +64,10 @@ export declare const edgeOf: (align: string | undefined) => string | undefined;
|
|
|
64
64
|
* both, so the columns after it keep their own widths and every row keeps its
|
|
65
65
|
* cells under their headings. `hidden="until-found"` keeps its track, the
|
|
66
66
|
* heading being left drawn, as every Helix element leaves one with that value.
|
|
67
|
-
* `
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
67
|
+
* `DataTable` draws the cells, so it leaves out the ones under a hidden column.
|
|
68
|
+
* A `Table`'s cells are markup the consumer wrote, so hide them with the
|
|
69
|
+
* column, as removing a column means removing its cells: a row with a cell more
|
|
70
|
+
* than the table has tracks wraps into the next.
|
|
71
71
|
*
|
|
72
72
|
* **A heading that does something holds a control that does it.** The host is
|
|
73
73
|
* the column header, and a header is not focusable, so a sortable heading is a
|
|
@@ -99,15 +99,15 @@ export declare class HelixHeadlessTableColumn extends HelixElement {
|
|
|
99
99
|
/**
|
|
100
100
|
* Which edge the values line up against.
|
|
101
101
|
*
|
|
102
|
-
* `end` is what a column of numbers wants, so digits of the same magnitude
|
|
103
|
-
* above each other. Left unset the cell inherits the table's own
|
|
104
|
-
* which is `start` for text in either writing direction.
|
|
105
|
-
* aligns the cells it draws. A `
|
|
106
|
-
* wrote, so the table writes nothing onto them: it publishes the
|
|
107
|
-
* cell under this column as `--table-cell-align`, which
|
|
108
|
-
* reads. The heading is this element's own, and
|
|
109
|
-
* the same edge in either table. `end` is the
|
|
110
|
-
* right-to-left table it is the left.
|
|
102
|
+
* `end` is what a column of numbers wants, so digits of the same magnitude
|
|
103
|
+
* sit above each other. Left unset the cell inherits the table's own
|
|
104
|
+
* alignment, which is `start` for text in either writing direction.
|
|
105
|
+
* `DataTable` aligns the cells it draws. A `Table`'s cells are markup the
|
|
106
|
+
* consumer wrote, so the table writes nothing onto them: it publishes the
|
|
107
|
+
* edge to each cell under this column as `--table-cell-align`, which
|
|
108
|
+
* `@fusion.dev/helix` reads. The heading is this element's own, and
|
|
109
|
+
* `@fusion.dev/helix` sets it to the same edge in either table. `end` is the
|
|
110
|
+
* inline end, so in a right-to-left table it is the left.
|
|
111
111
|
*
|
|
112
112
|
* **Reflected, because the heading is drawn by a stylesheet and has no other
|
|
113
113
|
* way to learn it.** Set as a property, which is how React sets it, an
|
|
@@ -181,8 +181,8 @@ export declare class HelixHeadlessTableColumn extends HelixElement {
|
|
|
181
181
|
* The track this column takes, as CSS.
|
|
182
182
|
*
|
|
183
183
|
* A single track value, so anything valid in `grid-template-columns` works:
|
|
184
|
-
* `16rem`, `auto`, `minmax(0, 2fr)`. Left unset the column takes the track
|
|
185
|
-
*
|
|
184
|
+
* `16rem`, `auto`, `minmax(0, 2fr)`. Left unset the column takes the track in
|
|
185
|
+
* its place in a `Table`'s `columns`, where that table sets one, and
|
|
186
186
|
* otherwise shares what is left over equally, as `minmax(max-content, 1fr)`.
|
|
187
187
|
* Set here, it wins over that list, which is what lets a reader resize a
|
|
188
188
|
* column in a table that set one.
|
|
@@ -34,21 +34,20 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
|
|
|
34
34
|
* @csspart loading - Shown while the rows are still on their way.
|
|
35
35
|
* @csspart table - The grid.
|
|
36
36
|
*
|
|
37
|
-
* @cssproperty --table-template - The column track list this element worked out from the columns declared in it. Written by the component, read by the sheet that paints: a stylesheet takes it to lay the grid out, and setting it does nothing, because the component writes it inline on the very element that reads it and an inline declaration beats any sheet.
|
|
37
|
+
* @cssproperty --table-template - The column track list this element worked out from the columns declared in it. Written by the component, read by the sheet that paints: a stylesheet takes it to lay the grid out, and setting it does nothing, because the component writes it inline on the very element that reads it and an inline declaration beats any sheet. `columns` is the one to set.
|
|
38
38
|
*/
|
|
39
39
|
export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
|
|
40
40
|
/**
|
|
41
41
|
* The column widths as one track list, written once on the table.
|
|
42
42
|
*
|
|
43
|
-
* With `
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* down to one column.
|
|
43
|
+
* With `TableColumn` children, each track sizes the column in its place, a
|
|
44
|
+
* hidden column counted, so hiding one takes its track with it and the rest
|
|
45
|
+
* keep theirs. The columns decide how many tracks there are and this list
|
|
46
|
+
* only how wide: a track past the last column is dropped, and a column past
|
|
47
|
+
* the last track shares what is left. With no columns declared it is the
|
|
48
|
+
* whole track list. Tracks count as the grid counts them, so `minmax(0, 1fr)`
|
|
49
|
+
* is one and `repeat(2, 8rem)` is two, and one the grid would refuse leaves
|
|
50
|
+
* its column at the default rather than taking the table down to one column.
|
|
52
51
|
*
|
|
53
52
|
* **A column's own `width` wins over its track here.** The width is written
|
|
54
53
|
* on the column it sizes, which is the more particular statement, and it is
|
|
@@ -62,13 +61,11 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
|
|
|
62
61
|
* whole answer: a table given one lays its grid out in the first paint, and a
|
|
63
62
|
* table sized only by its columns is one track wide until it upgrades.
|
|
64
63
|
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* take the same CSS hook, `--table-columns` and `--data-table-columns`, which
|
|
71
|
-
* wins over whichever list the element worked out.
|
|
64
|
+
* **Data Table has none of this, and should not.** Its columns are its schema
|
|
65
|
+
* rather than an option, so there is always a column to write a `width` on
|
|
66
|
+
* and a list here would be a second way to say what that says. This table's
|
|
67
|
+
* cells are markup, and a table written as rows of cells with no column
|
|
68
|
+
* declared in it has nowhere else to be sized from.
|
|
72
69
|
*/
|
|
73
70
|
columns: string;
|
|
74
71
|
/**
|
|
@@ -4,10 +4,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
4
4
|
* @summary One row of a table.
|
|
5
5
|
*
|
|
6
6
|
* @description
|
|
7
|
-
*
|
|
8
|
-
* the table's own grid and every column lines up
|
|
9
|
-
* still exists as an element, which is what a
|
|
10
|
-
* cells are laid out by the table algorithm.
|
|
7
|
+
* The row renders its cells straight through and lays out none of them, so a
|
|
8
|
+
* sheet can take them into the table's own grid and every column lines up
|
|
9
|
+
* across every row. The row still exists as an element, which is what a
|
|
10
|
+
* `<table>` gives away when its cells are laid out by the table algorithm.
|
|
11
11
|
*
|
|
12
12
|
* @since 0.1.0
|
|
13
13
|
* @status stable
|
|
@@ -52,8 +52,8 @@ export declare class HelixHeadlessTabPanel extends HelixElement {
|
|
|
52
52
|
* a choice nobody made. `ElementInternals` holds it instead.
|
|
53
53
|
*
|
|
54
54
|
* The attribute still seeds the property, which is what
|
|
55
|
-
* `<helix-tab-panel selected>` in a consumer's markup means. Only
|
|
56
|
-
* back is gone.
|
|
55
|
+
* `<helix-headless-tab-panel selected>` in a consumer's markup means. Only
|
|
56
|
+
* the write back is gone.
|
|
57
57
|
*/
|
|
58
58
|
protected willUpdate(changed: PropertyValues): void;
|
|
59
59
|
protected render(): TemplateResult;
|
|
@@ -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, HelixElement, IndicatorController, KeyboardNavigationController, MixinControllerActive, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, HelixElement, IndicatorController, KeyboardNavigationController, MixinControllerActive, whenHydrated, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { HelixHeadlessTabPanel } from '../panel/tab-panel.js';
|
|
@@ -47,12 +47,19 @@ let HelixHeadlessTabs = class HelixHeadlessTabs extends MixinControllerActive(He
|
|
|
47
47
|
const declared = this.active === '' ? tabs.find((tab) => tab.selected) : undefined;
|
|
48
48
|
const value = (declared ?? this.resolveActive(tabs))?.value ?? '';
|
|
49
49
|
for (const tab of tabs) {
|
|
50
|
-
|
|
50
|
+
const selected = tab.value === value;
|
|
51
|
+
whenHydrated(tab, () => {
|
|
52
|
+
tab.selected = selected;
|
|
53
|
+
});
|
|
51
54
|
}
|
|
52
55
|
const names = new Map(tabs.map((tab) => [tab.value, (tab.textContent ?? '').trim()]));
|
|
53
56
|
for (const panel of this.panels) {
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
const selected = panel.value === value;
|
|
58
|
+
const label = names.get(panel.value) ?? '';
|
|
59
|
+
whenHydrated(panel, () => {
|
|
60
|
+
panel.selected = selected;
|
|
61
|
+
panel.label = label;
|
|
62
|
+
});
|
|
56
63
|
}
|
|
57
64
|
}
|
|
58
65
|
connectedCallback() {
|
package/dist/tabs/tab/tab.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessTab_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinSelectableItemInterface) & typeof HelixElement;
|
|
4
4
|
/**
|
|
5
5
|
* @summary One tab in a tab list.
|
|
@@ -27,6 +27,16 @@ declare const HelixHeadlessTab_base: (new (...args: any[]) => import("@fusion.de
|
|
|
27
27
|
*/
|
|
28
28
|
export declare class HelixHeadlessTab extends HelixHeadlessTab_base {
|
|
29
29
|
protected itemPart: string;
|
|
30
|
+
/**
|
|
31
|
+
* Asks for the render that follows a hydration, so the stop stops being every
|
|
32
|
+
* tab's.
|
|
33
|
+
*
|
|
34
|
+
* `tabindex` reads `childrenKnown` and a hydrating render is one where that is
|
|
35
|
+
* false, which is what keeps the hydrating render the server's. Nothing else
|
|
36
|
+
* would ask: the root writes an already-false `selected` onto an unchosen tab,
|
|
37
|
+
* which changes nothing and so re-renders nothing.
|
|
38
|
+
*/
|
|
39
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
30
40
|
protected render(): TemplateResult;
|
|
31
41
|
}
|
|
32
42
|
declare global {
|
package/dist/tabs/tab/tab.js
CHANGED
|
@@ -11,6 +11,10 @@ let HelixHeadlessTab = class HelixHeadlessTab extends MixinSelectableItem(HelixE
|
|
|
11
11
|
super(...arguments);
|
|
12
12
|
this.itemPart = 'tab';
|
|
13
13
|
}
|
|
14
|
+
firstUpdated(changed) {
|
|
15
|
+
super.firstUpdated(changed);
|
|
16
|
+
this.finishHydration();
|
|
17
|
+
}
|
|
14
18
|
render() {
|
|
15
19
|
return html `<button
|
|
16
20
|
part="tab"
|
|
@@ -18,7 +22,7 @@ let HelixHeadlessTab = class HelixHeadlessTab extends MixinSelectableItem(HelixE
|
|
|
18
22
|
type="button"
|
|
19
23
|
aria-selected=${this.selected ? 'true' : 'false'}
|
|
20
24
|
?disabled=${this.disabled}
|
|
21
|
-
tabindex=${this.selected ? '0' : '-1'}
|
|
25
|
+
tabindex=${this.selected || !this.childrenKnown ? '0' : '-1'}
|
|
22
26
|
@click=${() => this.select()}
|
|
23
27
|
>
|
|
24
28
|
<slot></slot>
|
|
@@ -8,10 +8,10 @@ declare const HelixHeadlessTimeInput_base: (new (...args: any[]) => import("@fus
|
|
|
8
8
|
* @summary A time, typed or picked from a list.
|
|
9
9
|
*
|
|
10
10
|
* @description
|
|
11
|
-
* **The list is `
|
|
11
|
+
* **The list is `TimePicker`, not a second one written here.** It is worth
|
|
12
12
|
* having on its own, flat in a settings pane with nothing to open, and this
|
|
13
13
|
* element is the field, the overlay and the form. Exactly the arrangement Input
|
|
14
|
-
* Date has with `
|
|
14
|
+
* Date has with `DatePicker` and Color Input with `ColorPicker`.
|
|
15
15
|
*
|
|
16
16
|
* **Typed as well as picked, and that is the division the list depends on.** A
|
|
17
17
|
* list at a step offers the times a product actually has, and the field is how a
|
|
@@ -120,8 +120,8 @@ export declare class HelixHeadlessTimeInput extends HelixHeadlessTimeInput_base
|
|
|
120
120
|
*
|
|
121
121
|
* Absent is one. `range` holds a start and an end, `multiple` holds any
|
|
122
122
|
* number, and both are carried as one comma-separated value, which is what a
|
|
123
|
-
* form submits. `
|
|
124
|
-
* why a wheel cannot do either.
|
|
123
|
+
* form submits. `TimePicker` carries the longer note on the interaction and
|
|
124
|
+
* on why a wheel cannot do either.
|
|
125
125
|
*/
|
|
126
126
|
mode?: 'multiple' | 'range';
|
|
127
127
|
/**
|
|
@@ -185,7 +185,7 @@ export declare class HelixHeadlessTimeInput extends HelixHeadlessTimeInput_base
|
|
|
185
185
|
* `list` offers whole times, which is what a product with slots or opening
|
|
186
186
|
* hours has. `wheels` splits them into an hour, a minute and a meridiem where
|
|
187
187
|
* the locale uses one, which is the only way to reach `23:45` without
|
|
188
|
-
* scrolling most of a day. `
|
|
188
|
+
* scrolling most of a day. `TimePicker` carries the longer note on the trade.
|
|
189
189
|
*
|
|
190
190
|
* **Optional rather than defaulted, which is not a style preference.** A
|
|
191
191
|
* reflecting property with a default writes its attribute onto every host the
|
|
@@ -218,14 +218,14 @@ export declare class HelixHeadlessTimeInput extends HelixHeadlessTimeInput_base
|
|
|
218
218
|
* Slot fallback, so a consumer replaces it by slotting; and a method, so the
|
|
219
219
|
* tier above replaces it by overriding.
|
|
220
220
|
*
|
|
221
|
-
* **A named import rather than `<helix-icon>`**, on three counts.
|
|
222
|
-
* `
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
221
|
+
* **A named import rather than `<helix-headless-icon>`**, on three counts.
|
|
222
|
+
* `Icon` indexes the whole icon map at runtime, `icons[this.name]`, and no
|
|
223
|
+
* bundler can shake a runtime lookup, so every consumer of any component that
|
|
224
|
+
* renders one ships all 50kB of path data; a named import ships one path. The
|
|
225
|
+
* import is checked when the package compiles, where a `name` string is
|
|
226
|
+
* checked only by a later name lookup. And `Icon` is not registered on the
|
|
227
|
+
* headless tier at all, which registers `helix-headless-icon`, so a headless
|
|
228
|
+
* consumer gets an inert unknown element and no mark whatsoever.
|
|
229
229
|
*/
|
|
230
230
|
protected renderTrigger(): TemplateResult;
|
|
231
231
|
protected render(): TemplateResult;
|
|
@@ -25,8 +25,8 @@ declare const HelixHeadlessTimePicker_base: (new (...args: any[]) => import("@fu
|
|
|
25
25
|
*
|
|
26
26
|
* @description
|
|
27
27
|
* **A list rather than three wheels**, and the reason is what a list already
|
|
28
|
-
* is. `
|
|
29
|
-
*
|
|
28
|
+
* is. `Listbox` brings the keyboard, the typeahead, the scroll into view and
|
|
29
|
+
* the announcement of a set of options, and a time at a step is a set of
|
|
30
30
|
* options. Three little wheels for hours, minutes and a meridiem are three
|
|
31
31
|
* controls to build, three to test, and a tab stop each for something a reader
|
|
32
32
|
* answers once.
|
|
@@ -145,7 +145,7 @@ export declare class HelixHeadlessTimePicker extends HelixHeadlessTimePicker_bas
|
|
|
145
145
|
*
|
|
146
146
|
* Absent is one. `range` holds a start and an end with everything between
|
|
147
147
|
* them shown as part of the answer, `multiple` holds any number, and both are
|
|
148
|
-
* carried as one comma-separated value: the same shape `
|
|
148
|
+
* carried as one comma-separated value: the same shape `DatePicker` uses,
|
|
149
149
|
* because it is the same question asked of a different unit.
|
|
150
150
|
*
|
|
151
151
|
* **A range is two picks, and a third starts over.** That is the calendar's
|
|
@@ -335,11 +335,11 @@ export declare class HelixHeadlessTimePicker extends HelixHeadlessTimePicker_bas
|
|
|
335
335
|
/**
|
|
336
336
|
* Reveals once the wheels, or the list and its rows, have rendered themselves.
|
|
337
337
|
*
|
|
338
|
-
* `updated` is this element's own moment, and each wheel is a `
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
338
|
+
* `updated` is this element's own moment, and each wheel is a `Listbox` that
|
|
339
|
+
* was created during this very render: its first update has been scheduled
|
|
340
|
+
* and has not run, so it has no rows and no height and `reveal` measures zero
|
|
341
|
+
* and gives up. Measured on a standalone picker, every column sat at
|
|
342
|
+
* `scrollTop: 0` with the answer nine rows down, which reads as a wheel
|
|
343
343
|
* showing the wrong time rather than as one that failed to scroll.
|
|
344
344
|
*
|
|
345
345
|
* Whatever opens a panel calls `reveal` again afterwards, for the separate
|
|
@@ -34,7 +34,7 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
34
34
|
* @aliases Toaster, Snackbar
|
|
35
35
|
* @documentation https://fusion.dev/helix/components/toast
|
|
36
36
|
*
|
|
37
|
-
* @slot - The messages
|
|
37
|
+
* @slot - The messages.
|
|
38
38
|
*
|
|
39
39
|
* @event {HelixDismissEvent} helix-dismiss - A message asking to go, by its control or by its timer, dispatched by the message and heard here because the stack is what a consumer holds. Cancelable: refusing it takes the decision and the message stays.
|
|
40
40
|
*
|
|
@@ -55,7 +55,7 @@ export declare class HelixHeadlessToast extends HelixElement {
|
|
|
55
55
|
* **Optional, and bottom-end is the absence of it.** Reflecting *and*
|
|
56
56
|
* defaulting is the pair that writes onto a host: every toast region anybody
|
|
57
57
|
* rendered would gain a `placement="bottom-end"` nobody typed, which a React
|
|
58
|
-
* consumer's server markup does not have.
|
|
58
|
+
* consumer's server markup does not have. A sheet carries the resting
|
|
59
59
|
* arrangement in its own `:host` rule and the selectors describe only the
|
|
60
60
|
* departures, which is what `orientation` does.
|
|
61
61
|
*/
|