@fusion.dev/helix-headless 0.1.0 → 0.3.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.
- package/custom-elements.json +234 -234
- package/dist/accordion/item/accordion-item.js +0 -108
- package/dist/accordion/root/accordion-root.js +0 -33
- package/dist/announcement/root/announcement-root.js +1 -76
- package/dist/app-header/root/app-header-root.js +0 -84
- package/dist/avatar/group/avatar-group.js +0 -77
- package/dist/avatar/root/avatar-root.js +0 -72
- package/dist/badge/root/badge-root.js +0 -67
- package/dist/bar-chart/root/bar-chart-root.js +3 -263
- package/dist/blockquote/root/blockquote-root.js +0 -46
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +0 -72
- package/dist/breadcrumbs/root/breadcrumbs-root.js +0 -52
- package/dist/button/root/button-root.js +0 -215
- package/dist/button-group/root/button-group-root.js +0 -30
- package/dist/callout/root/callout-root.js +0 -52
- package/dist/card/root/card-root.js +0 -41
- package/dist/carousel/root/carousel-root.d.ts +2 -2
- package/dist/carousel/root/carousel-root.js +2 -362
- package/dist/chat/composer/chat-composer.js +0 -131
- package/dist/chat/message/chat-message.js +0 -137
- package/dist/chat/root/chat-root.js +0 -193
- package/dist/checkbox/root/checkbox-root.js +0 -113
- package/dist/checkbox-group/root/checkbox-group-root.js +1 -157
- package/dist/code/root/code-root.js +0 -26
- package/dist/code-block/root/code-block-root.js +0 -100
- package/dist/color-input/root/color-input-root.js +0 -217
- package/dist/color-picker/color.js +0 -69
- package/dist/color-picker/root/color-picker-root.js +0 -272
- package/dist/combobox/root/combobox-root.js +0 -428
- package/dist/command/root/command-root.js +0 -177
- package/dist/copy-button/root/copy-button-root.js +0 -134
- package/dist/data-table/root/data-table-root.js +0 -336
- package/dist/data-table/root/order.js +0 -100
- package/dist/date-input/root/date-input-root.js +1 -398
- package/dist/date-picker/root/date-picker-root.js +0 -358
- package/dist/dialog/root/dialog-root.js +0 -189
- package/dist/divider/root/divider-root.js +0 -71
- package/dist/donut-chart/root/donut-chart-root.js +0 -214
- package/dist/drawer/root/drawer-root.js +0 -116
- package/dist/drilldown/item/drilldown-item.js +0 -82
- package/dist/drilldown/root/drilldown-root.js +0 -91
- package/dist/element-events.generated.js +0 -5
- package/dist/empty/root/empty-root.js +0 -35
- package/dist/file-input/root/file-input-root.js +0 -232
- package/dist/format-date/root/format-date-root.js +0 -95
- package/dist/heatmap/root/buckets.js +0 -57
- package/dist/heatmap/root/heatmap-root.js +0 -313
- package/dist/icon/root/icon-root.js +0 -48
- package/dist/icon-button/root/icon-button-root.js +0 -30
- package/dist/image/root/image-root.js +0 -174
- package/dist/index.js +0 -9
- package/dist/input/root/input-root.js +0 -228
- package/dist/kbd/root/kbd-root.js +0 -117
- package/dist/legend/root/legend-root.js +0 -73
- package/dist/line-chart/root/line-chart-root.js +0 -172
- package/dist/list/item/list-item.js +0 -92
- package/dist/list/root/list-root.js +0 -26
- package/dist/listbox/root/listbox-root.js +2 -429
- package/dist/loader/root/loader-root.js +0 -40
- package/dist/megamenu/root/megamenu-root.js +0 -284
- package/dist/menu/item/menu-item.js +1 -221
- package/dist/menu/root/menu-root.js +1 -171
- package/dist/meter/root/meter-root.js +1 -152
- package/dist/navigation/root/navigation-root.js +0 -56
- package/dist/notifications/notification/notification.js +0 -159
- package/dist/notifications/root/notifications-root.js +0 -148
- package/dist/number-input/root/number-input-root.js +1 -263
- package/dist/option/group/option-group.js +0 -26
- package/dist/option/root/option-root.js +0 -157
- package/dist/outline/root/outline-root.js +0 -292
- package/dist/pagination/root/pagination-root.js +0 -361
- package/dist/pagination/size/pagination-size.js +0 -104
- package/dist/pagination/summary/pagination-summary.js +0 -90
- package/dist/pin-input/root/pin-input-root.js +0 -276
- package/dist/popover/root/popover-root.js +0 -103
- package/dist/progress/root/progress-root.js +1 -133
- package/dist/qr-code/root/qr-code-root.js +0 -96
- package/dist/quote/root/quote-root.js +0 -25
- package/dist/radio/group/radio-group.js +0 -81
- package/dist/radio/root/radio-root.js +0 -85
- package/dist/rating/root/rating-root.js +0 -220
- package/dist/scroll-area/root/scroll-area-root.js +0 -100
- package/dist/select/root/select-root.js +2 -218
- package/dist/skeleton/root/skeleton-root.js +0 -20
- package/dist/slider/root/slider-root.js +1 -267
- package/dist/sparkline/root/sparkline-root.js +3 -164
- package/dist/speed-dial/item/speed-dial-item.js +0 -52
- package/dist/speed-dial/root/speed-dial-root.js +1 -116
- package/dist/splitter/root/splitter-root.js +0 -489
- package/dist/stat/group/stat-group.js +0 -18
- package/dist/stat/root/stat-root.js +0 -23
- package/dist/steps/root/steps-root.js +0 -62
- package/dist/steps/step/step.js +0 -131
- package/dist/switch/root/switch-root.js +0 -80
- package/dist/table/cell/table-cell.js +0 -23
- package/dist/table/column/table-column.js +0 -158
- package/dist/table/root/table-root.js +0 -82
- package/dist/table/row/table-row.js +0 -21
- package/dist/tabs/panel/tab-panel.js +0 -49
- package/dist/tabs/root/tabs-root.js +0 -98
- package/dist/tabs/tab/tab.js +0 -59
- package/dist/tag/root/tag-root.js +0 -31
- package/dist/textarea/root/textarea-root.js +0 -162
- package/dist/time-input/root/time-input-root.js +0 -283
- package/dist/time-picker/root/time-picker-root.js +0 -326
- package/dist/timeline/item/timeline-item.js +0 -66
- package/dist/timeline/root/timeline-root.js +0 -41
- package/dist/toast/item/toast-item.js +0 -165
- package/dist/toast/root/toast-root.js +0 -51
- package/dist/toggle/group/toggle-group.js +0 -150
- package/dist/toggle/root/toggle-root.js +0 -78
- package/dist/toolbar/root/toolbar-root.js +0 -116
- package/dist/tooltip/root/tooltip-root.js +0 -427
- package/dist/tour/root/tour-root.js +0 -130
- package/dist/tour/stop/tour-stop.js +1 -127
- package/dist/tree/item/tree-item.js +0 -198
- package/dist/tree/root/tree-root.js +0 -97
- package/dist/trend/root/trend-root.js +0 -53
- package/dist/video/root/video-root.d.ts +8 -12
- package/dist/video/root/video-root.js +5 -756
- package/dist/video-playlist/item/video-playlist-item.js +1 -90
- package/dist/video-playlist/menu/video-playlist-menu.js +1 -132
- package/dist/video-playlist/root/video-playlist-root.js +0 -113
- package/dist/virtual-list/root/virtual-list-root.js +0 -105
- package/jsx.d.ts +1408 -2576
- package/package.json +6 -6
- package/vue.d.ts +1 -1
|
@@ -7,77 +7,25 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { customElement, HelixElement, HelixSelectEvent } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
-
/**
|
|
11
|
-
* @summary One action in a speed dial: a mark, and a name beside it.
|
|
12
|
-
*
|
|
13
|
-
* @description
|
|
14
|
-
* **A command, which is why this is a `menuitem` and a megamenu's rows are not.**
|
|
15
|
-
* The distinction is what the thing does, not what it looks like: a megamenu
|
|
16
|
-
* holds destinations, so it is a disclosure of links, and this holds actions a
|
|
17
|
-
* screen can take, which is exactly what `role="menu"` was written for. The
|
|
18
|
-
* roles follow the contents.
|
|
19
|
-
*
|
|
20
|
-
* **The name is text, not a title.** A dial's actions are icons, and an icon
|
|
21
|
-
* with a `title` is an action whose name only exists for whoever hovers it long
|
|
22
|
-
* enough. The label is rendered beside the mark and is the accessible name by
|
|
23
|
-
* being there, so it is read, searched and translated like anything else.
|
|
24
|
-
*
|
|
25
|
-
* @since 0.1.0
|
|
26
|
-
* @status experimental
|
|
27
|
-
* @category actions
|
|
28
|
-
* @aliases Speed dial action, FAB action, Quick action
|
|
29
|
-
* @documentation https://helix.fusion.dev/components/speed-dial
|
|
30
|
-
*
|
|
31
|
-
* @slot - The action's name.
|
|
32
|
-
* @slot icon - The mark, which is what a dial is read by.
|
|
33
|
-
*
|
|
34
|
-
* @event {HelixSelectEvent} helix-select - Fired when the action is chosen. Cancelable: refusing it takes the decision and nothing moves.
|
|
35
|
-
*
|
|
36
|
-
* @csspart icon - The mark's box.
|
|
37
|
-
* @csspart item - The control.
|
|
38
|
-
* @csspart label - The name beside it.
|
|
39
|
-
*/
|
|
40
10
|
let HelixHeadlessSpeedDialItem = class HelixHeadlessSpeedDialItem extends HelixElement {
|
|
41
11
|
constructor() {
|
|
42
12
|
super(...arguments);
|
|
43
|
-
/**
|
|
44
|
-
* Whether the action can be chosen.
|
|
45
|
-
*/
|
|
46
13
|
this.disabled = false;
|
|
47
|
-
/**
|
|
48
|
-
* What this action stands for, carried in the event when it is chosen.
|
|
49
|
-
*/
|
|
50
14
|
this.value = '';
|
|
51
|
-
/**
|
|
52
|
-
* @internal Read by a parent to identify its children across the light DOM,
|
|
53
|
-
* which is cheaper than `instanceof` and is why this is public rather than
|
|
54
|
-
* protected. Not a consumer's to read or set.
|
|
55
|
-
*/
|
|
56
15
|
this.isSpeedDialItem = true;
|
|
57
16
|
this.handleClick = () => {
|
|
58
17
|
this.choose();
|
|
59
18
|
};
|
|
60
19
|
}
|
|
61
|
-
/** Puts focus on the control inside, which is what a reader can reach. */
|
|
62
20
|
focus() {
|
|
63
21
|
this.renderRoot?.querySelector('[part="item"]')?.focus();
|
|
64
22
|
}
|
|
65
|
-
/** `NavigableItem`, so the arrow keys are the shared controller's business. */
|
|
66
23
|
focusItem() {
|
|
67
24
|
this.focus();
|
|
68
25
|
}
|
|
69
|
-
/** Chooses the action, which is the same act as pressing it. */
|
|
70
26
|
select() {
|
|
71
27
|
this.choose();
|
|
72
28
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Whether this is the row the set is on, which here is where focus is.
|
|
75
|
-
*
|
|
76
|
-
* Asked of the document rather than of the shadow root: focus lands on the
|
|
77
|
-
* control inside this element and the platform retargets it, so from outside
|
|
78
|
-
* `activeElement` already is this element. `Menu.Item` records the same;
|
|
79
|
-
* reading it off the shadow root does not survive happy-dom.
|
|
80
|
-
*/
|
|
81
29
|
get selected() {
|
|
82
30
|
return this.ownerDocument.activeElement === this;
|
|
83
31
|
}
|
|
@@ -8,77 +8,18 @@ import { anchorElement, customElement, drawIcon, HelixElement, KeyboardNavigatio
|
|
|
8
8
|
import { plus } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
11
|
-
/**
|
|
12
|
-
* @summary A button that fans out the few actions a screen is for.
|
|
13
|
-
*
|
|
14
|
-
* @description
|
|
15
|
-
* **A menu, and deliberately not a new one.** Its rows are commands, which is
|
|
16
|
-
* what `role="menu"` and `menuitem` exist for, so this takes them and takes the
|
|
17
|
-
* behavior with them: the arrow keys are `KeyboardNavigationController`, the
|
|
18
|
-
* panel is `PopoverController`, and open and closed is `MixinControllerOpen`.
|
|
19
|
-
* `Menu` is built from the same pieces. What is not shared is what actually
|
|
20
|
-
* differs: a dial has no submenus, no headers, no checkable rows and no long
|
|
21
|
-
* list to type ahead through, and shipping it as an appearance of `Menu` would
|
|
22
|
-
* mean defining what a dial with a submenu in it does.
|
|
23
|
-
*
|
|
24
|
-
* **The trigger is a control the consumer slots**, and the floating action
|
|
25
|
-
* button is the usual one: `helix-icon-button` with `shape="circle"` and
|
|
26
|
-
* `raised`. There is no `helix-fab`, because it would re-declare `emphasis`,
|
|
27
|
-
* `tone`, `label` and a size around a control that already has all four. A
|
|
28
|
-
* round raised button is a shape, and where it sits is `data-dock` in the base
|
|
29
|
-
* layer.
|
|
30
|
-
*
|
|
31
|
-
* **Nothing is reserved from the keyboard.** A menu that drills has to keep the
|
|
32
|
-
* horizontal pair for going in and coming back; a dial goes nowhere, so all four
|
|
33
|
-
* arrows move through the actions and a reader who guesses either axis is
|
|
34
|
-
* answered. That is the controller's own house position, and this is a component
|
|
35
|
-
* with no reason to argue with it.
|
|
36
|
-
*
|
|
37
|
-
* @since 0.1.0
|
|
38
|
-
* @status experimental
|
|
39
|
-
* @category actions
|
|
40
|
-
* @aliases FAB, Floating action button, Action button, Quick actions
|
|
41
|
-
* @documentation https://helix.fusion.dev/components/speed-dial
|
|
42
|
-
*
|
|
43
|
-
* @slot - The actions.
|
|
44
|
-
* @slot trigger - The control that opens it. Falls back to a button named by `label`.
|
|
45
|
-
*
|
|
46
|
-
* @event {HelixBeforeCloseEvent} helix-before-close - Fired before it closes, and cancelable.
|
|
47
|
-
* @event {HelixBeforeOpenEvent} helix-before-open - Fired before it opens, and cancelable.
|
|
48
|
-
* @event {Event} toggle - Says the state moved, carrying `newState` and `oldState`.
|
|
49
|
-
*
|
|
50
|
-
* @csspart actions - The region the actions are drawn in.
|
|
51
|
-
* @csspart trigger - The default trigger, where none was slotted.
|
|
52
|
-
*/
|
|
53
11
|
let HelixHeadlessSpeedDial = class HelixHeadlessSpeedDial extends MixinControllerOpen(HelixElement) {
|
|
54
12
|
constructor() {
|
|
55
13
|
super(...arguments);
|
|
56
|
-
/**
|
|
57
|
-
* Names the trigger and the set of actions it opens.
|
|
58
|
-
*/
|
|
59
14
|
this.label = 'Actions';
|
|
60
|
-
/**
|
|
61
|
-
* Space between the trigger and the actions, in pixels.
|
|
62
|
-
*/
|
|
63
15
|
this.offset = 12;
|
|
64
|
-
/**
|
|
65
|
-
* Which way the actions fan out. They move if that side does not fit.
|
|
66
|
-
*
|
|
67
|
-
* Up by default, because the control this hangs off is usually docked to the
|
|
68
|
-
* bottom of the window and there is nothing below it to fan into.
|
|
69
|
-
*/
|
|
70
16
|
this.placement = 'top-end';
|
|
71
|
-
/* Nothing reserved: see the note above. `selects` is false because arriving at
|
|
72
|
-
Delete must not delete, which is the difference between a set of commands
|
|
73
|
-
and a set of choices. */
|
|
74
17
|
this.keys = new KeyboardNavigationController(this, {
|
|
75
18
|
items: () => this.items,
|
|
76
19
|
selects: () => false,
|
|
77
20
|
});
|
|
78
21
|
this.panel = new PopoverController(this, {
|
|
79
22
|
anchor: () => this.trigger,
|
|
80
|
-
/* The host, so a press on the trigger is not counted as a press outside.
|
|
81
|
-
`Menu` and `Megamenu` both say the same about their own. */
|
|
82
23
|
boundary: () => this,
|
|
83
24
|
offset: () => this.offset,
|
|
84
25
|
onDismiss: () => this.close(),
|
|
@@ -88,8 +29,6 @@ let HelixHeadlessSpeedDial = class HelixHeadlessSpeedDial extends MixinControlle
|
|
|
88
29
|
this.handleTriggerClick = () => {
|
|
89
30
|
this.requestOpen(!this.open);
|
|
90
31
|
};
|
|
91
|
-
/* Chosen, so the dial shuts behind it. An action that leaves the fan standing
|
|
92
|
-
open is one a reader has to dismiss after asking for it. */
|
|
93
32
|
this.handleSelect = () => {
|
|
94
33
|
this.close();
|
|
95
34
|
};
|
|
@@ -102,16 +41,13 @@ let HelixHeadlessSpeedDial = class HelixHeadlessSpeedDial extends MixinControlle
|
|
|
102
41
|
event.preventDefault();
|
|
103
42
|
};
|
|
104
43
|
}
|
|
105
|
-
/** Whatever the consumer slotted, or the button rendered in its place. */
|
|
106
44
|
get trigger() {
|
|
107
45
|
return anchorElement(this.renderRoot?.querySelector('slot[name="trigger"]'), this.renderRoot?.querySelector('[part="trigger"]') ?? this);
|
|
108
46
|
}
|
|
109
|
-
/** The actions, which are this element's own rows and nothing else slotted. */
|
|
110
47
|
get items() {
|
|
111
48
|
const slot = this.renderRoot?.querySelector('slot:not([name])');
|
|
112
49
|
return (slot?.assignedElements?.() ?? []).filter((one) => one.isSpeedDialItem === true);
|
|
113
50
|
}
|
|
114
|
-
/** Shuts it and puts the reader back on the trigger. */
|
|
115
51
|
close() {
|
|
116
52
|
if (!this.requestOpen(false)) {
|
|
117
53
|
return;
|
|
@@ -128,29 +64,6 @@ let HelixHeadlessSpeedDial = class HelixHeadlessSpeedDial extends MixinControlle
|
|
|
128
64
|
this.removeEventListener('helix-select', this.handleSelect);
|
|
129
65
|
this.removeEventListener('keydown', this.handleKeydown);
|
|
130
66
|
}
|
|
131
|
-
/**
|
|
132
|
-
* Tells a slotted trigger what it is doing, since it cannot know.
|
|
133
|
-
*
|
|
134
|
-
* The fallback button is rendered by this element and says so in its own
|
|
135
|
-
* template. A trigger the consumer slotted is their markup, and the state it
|
|
136
|
-
* needs to announce is state only this element holds: without this, the
|
|
137
|
-
* arrangement this component recommends, an icon button slotted as the
|
|
138
|
-
* trigger, is a control that opens a menu and never says it has one. A
|
|
139
|
-
* consumer who has to mirror `open` back onto their own trigger is a consumer
|
|
140
|
-
* who will forget, and the failure is silent to everyone who can see the
|
|
141
|
-
* screen.
|
|
142
|
-
*
|
|
143
|
-
* **Never `setAttribute`.** Writing `aria-expanded` onto the consumer's
|
|
144
|
-
* element is a hydration mismatch React reports and does not patch up,
|
|
145
|
-
* measured against React 19.2.8. `tellDisclosure` carries the argument and the
|
|
146
|
-
* measurement: the state travels as a property, into the trigger's own shadow
|
|
147
|
-
* root, where React neither looks nor compares.
|
|
148
|
-
*
|
|
149
|
-
* `aria-haspopup` goes with it rather than being written separately. An
|
|
150
|
-
* attribute the consumer's server never sent is a mismatch whether or not it
|
|
151
|
-
* moves afterwards, measured in both load orders, and a trigger that says it
|
|
152
|
-
* is expanded is already saying it has something to expand.
|
|
153
|
-
*/
|
|
154
67
|
announce() {
|
|
155
68
|
const trigger = this.trigger;
|
|
156
69
|
if (trigger === this.renderRoot?.querySelector('[part="trigger"]')) {
|
|
@@ -163,22 +76,8 @@ let HelixHeadlessSpeedDial = class HelixHeadlessSpeedDial extends MixinControlle
|
|
|
163
76
|
this.announce();
|
|
164
77
|
if (this.open) {
|
|
165
78
|
this.panel.show();
|
|
166
|
-
/* On the first action, which is where a reader who opened this with the
|
|
167
|
-
keyboard expects to be. The pointer does not mind either way.
|
|
168
|
-
|
|
169
|
-
Checked again on the way in, because this is a frame late and the dial
|
|
170
|
-
may have shut in the meantime. Opening and pressing Escape straight
|
|
171
|
-
away left focus on an action of a closed dial: the close put it back on
|
|
172
|
-
the trigger, and then this, still queued from the open, took it away
|
|
173
|
-
again. */
|
|
174
79
|
this.updateComplete.then(() => {
|
|
175
80
|
if (this.open) {
|
|
176
|
-
/* The first action that can *take* focus, not the first action. A
|
|
177
|
-
dial whose first item is disabled otherwise opens onto a row that
|
|
178
|
-
refuses focus, so the reader lands nowhere and their first arrow
|
|
179
|
-
key starts from nothing. `KeyboardNavigationController` filters
|
|
180
|
-
disabled items itself; this is the one place that reaches past it
|
|
181
|
-
and indexes the list. */
|
|
182
81
|
this.items.find((one) => !one.disabled)?.focusItem();
|
|
183
82
|
}
|
|
184
83
|
});
|
|
@@ -187,16 +86,6 @@ let HelixHeadlessSpeedDial = class HelixHeadlessSpeedDial extends MixinControlle
|
|
|
187
86
|
this.panel.hide();
|
|
188
87
|
}
|
|
189
88
|
}
|
|
190
|
-
/**
|
|
191
|
-
* The control that opens it, behind a seam the styled tier can move.
|
|
192
|
-
*
|
|
193
|
-
* **This is the case the tier rule blocks and a render method unblocks.** A
|
|
194
|
-
* bare `<button>` is what the headless tier can write: it must not reach for
|
|
195
|
-
* `helix-button`, which lives a tier above and would make `headless` depend
|
|
196
|
-
* on `styled`. So the base draws the plain control and a tier that has buttons
|
|
197
|
-
* of its own overrides this to use one. Written inline, the only way
|
|
198
|
-
* to change it would be to reimplement the template, panel and all.
|
|
199
|
-
*/
|
|
200
89
|
renderTrigger() {
|
|
201
90
|
return html `<slot name="trigger" @click=${this.handleTriggerClick}>
|
|
202
91
|
<button
|
|
@@ -206,11 +95,7 @@ let HelixHeadlessSpeedDial = class HelixHeadlessSpeedDial extends MixinControlle
|
|
|
206
95
|
aria-haspopup="menu"
|
|
207
96
|
aria-label=${this.label}
|
|
208
97
|
>
|
|
209
|
-
${
|
|
210
|
-
/* A glyph, so a consumer who slots no trigger does not get an empty
|
|
211
|
-
control for a button whose whole job is to be found. `plus` is what
|
|
212
|
-
a speed dial opens with everywhere it exists. */
|
|
213
|
-
''}
|
|
98
|
+
${''}
|
|
214
99
|
${drawIcon(plus)}
|
|
215
100
|
</button>
|
|
216
101
|
</slot>`;
|