@fusion.dev/helix-core 0.145.0 → 0.147.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 +6585 -1920
- package/dist/controllers/aria-forward-controller/aria-forward-controller.d.ts +3 -2
- package/dist/controllers/aria-forward-controller/aria-forward-controller.js +8 -17
- package/dist/controllers/chart-pointer-controller/chart-pointer-controller.d.ts +71 -3
- package/dist/controllers/chart-pointer-controller/chart-pointer-controller.js +50 -9
- package/dist/controllers/chart-pointer-controller/reading-step.d.ts +7 -1
- package/dist/controllers/chart-pointer-controller/reading-step.js +5 -0
- package/dist/controllers/copy-controller/copy-controller.d.ts +4 -1
- package/dist/controllers/copy-controller/copy-controller.js +2 -1
- package/dist/controllers/countdown-controller/countdown-controller.d.ts +4 -1
- package/dist/controllers/countdown-controller/countdown-controller.js +3 -1
- package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.d.ts +14 -55
- package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.js +7 -39
- package/dist/controllers/relative-clock-controller/relative-clock-controller.d.ts +44 -0
- package/dist/controllers/relative-clock-controller/relative-clock-controller.js +31 -0
- package/dist/controllers/source-controller/source-controller.d.ts +10 -3
- package/dist/controllers/source-controller/source-controller.js +9 -4
- package/dist/controllers/swipe-controller/swipe-controller.d.ts +10 -1
- package/dist/controllers/swipe-controller/swipe-controller.js +1 -1
- package/dist/controllers/virtualize-controller/virtualize-controller.d.ts +48 -1
- package/dist/controllers/virtualize-controller/virtualize-controller.js +52 -7
- package/dist/events/action.d.ts +12 -0
- package/dist/events/action.js +6 -0
- package/dist/events/activate.d.ts +22 -0
- package/dist/events/activate.js +11 -0
- package/dist/events/aura-fallback.d.ts +12 -0
- package/dist/events/aura-fallback.js +11 -0
- package/dist/events/band.d.ts +13 -0
- package/dist/events/band.js +11 -0
- package/dist/events/before-activate.d.ts +24 -0
- package/dist/events/before-activate.js +11 -0
- package/dist/events/before-change.d.ts +26 -0
- package/dist/events/before-change.js +11 -0
- package/dist/events/before-close.d.ts +6 -0
- package/dist/events/before-close.js +11 -0
- package/dist/events/before-collapse.d.ts +6 -0
- package/dist/events/before-collapse.js +11 -0
- package/dist/events/before-edit.d.ts +6 -0
- package/dist/events/before-edit.js +11 -0
- package/dist/events/before-move.d.ts +17 -0
- package/dist/events/before-move.js +11 -0
- package/dist/events/before-open.d.ts +17 -0
- package/dist/events/before-open.js +11 -0
- package/dist/events/before-panel-resize.d.ts +13 -0
- package/dist/events/before-panel-resize.js +11 -0
- package/dist/events/before-pin.d.ts +6 -0
- package/dist/events/before-pin.js +11 -0
- package/dist/events/before-reconnect.d.ts +14 -0
- package/dist/events/before-reconnect.js +11 -0
- package/dist/events/before-relabel.d.ts +15 -0
- package/dist/events/before-relabel.js +11 -0
- package/dist/events/before-resize.d.ts +6 -0
- package/dist/events/before-resize.js +11 -0
- package/dist/events/before-split.d.ts +12 -0
- package/dist/events/before-split.js +11 -0
- package/dist/events/before-toggle.d.ts +23 -0
- package/dist/events/before-toggle.js +11 -0
- package/dist/events/canvas-edit.d.ts +16 -0
- package/dist/events/canvas-edit.js +11 -0
- package/dist/events/canvas-pan.d.ts +13 -0
- package/dist/events/canvas-pan.js +11 -0
- package/dist/events/canvas-view.d.ts +14 -0
- package/dist/events/canvas-view.js +11 -0
- package/dist/events/canvas-zoom.d.ts +6 -0
- package/dist/events/canvas-zoom.js +11 -0
- package/dist/events/caret.d.ts +17 -0
- package/dist/events/caret.js +11 -0
- package/dist/events/clear.d.ts +11 -0
- package/dist/events/clear.js +6 -0
- package/dist/events/collapse.d.ts +12 -0
- package/dist/events/collapse.js +11 -0
- package/dist/events/complete.d.ts +26 -0
- package/dist/events/complete.js +11 -0
- package/dist/events/connect.d.ts +14 -0
- package/dist/events/connect.js +11 -0
- package/dist/events/console.d.ts +13 -0
- package/dist/events/console.js +11 -0
- package/dist/events/copy-error.d.ts +9 -0
- package/dist/events/copy-error.js +6 -0
- package/dist/events/copy.d.ts +12 -0
- package/dist/events/copy.js +10 -0
- package/dist/events/create.d.ts +18 -0
- package/dist/events/create.js +11 -0
- package/dist/events/details.d.ts +459 -0
- package/dist/events/details.js +1 -0
- package/dist/events/dismiss.d.ts +16 -0
- package/dist/events/dismiss.js +11 -0
- package/dist/events/edit.d.ts +12 -0
- package/dist/events/edit.js +11 -0
- package/dist/events/end.d.ts +9 -0
- package/dist/events/end.js +6 -0
- package/dist/events/events.d.ts +113 -1478
- package/dist/events/events.js +93 -863
- package/dist/events/expand.d.ts +10 -0
- package/dist/events/expand.js +11 -0
- package/dist/events/facet.d.ts +17 -0
- package/dist/events/facet.js +11 -0
- package/dist/events/filter.d.ts +12 -0
- package/dist/events/filter.js +11 -0
- package/dist/events/filtered.d.ts +12 -0
- package/dist/events/filtered.js +11 -0
- package/dist/events/graph-filter.d.ts +10 -0
- package/dist/events/graph-filter.js +11 -0
- package/dist/events/graph-layout.d.ts +10 -0
- package/dist/events/graph-layout.js +11 -0
- package/dist/events/graph-pan.d.ts +9 -0
- package/dist/events/graph-pan.js +11 -0
- package/dist/events/graph-part-change.d.ts +10 -0
- package/dist/events/graph-part-change.js +11 -0
- package/dist/events/graph-ready.d.ts +8 -0
- package/dist/events/graph-ready.js +6 -0
- package/dist/events/graph-signal.d.ts +11 -0
- package/dist/events/graph-signal.js +11 -0
- package/dist/events/graph-zoom.d.ts +6 -0
- package/dist/events/graph-zoom.js +11 -0
- package/dist/events/history.d.ts +16 -0
- package/dist/events/history.js +11 -0
- package/dist/events/load-more.d.ts +12 -0
- package/dist/events/load-more.js +6 -0
- package/dist/events/load.d.ts +12 -0
- package/dist/events/load.js +6 -0
- package/dist/events/map-cluster.d.ts +15 -0
- package/dist/events/map-cluster.js +11 -0
- package/dist/events/map-pan.d.ts +18 -0
- package/dist/events/map-pan.js +11 -0
- package/dist/events/map-part-change.d.ts +16 -0
- package/dist/events/map-part-change.js +11 -0
- package/dist/events/map-ready.d.ts +15 -0
- package/dist/events/map-ready.js +6 -0
- package/dist/events/map-rotate.d.ts +9 -0
- package/dist/events/map-rotate.js +11 -0
- package/dist/events/map-tilt.d.ts +9 -0
- package/dist/events/map-tilt.js +11 -0
- package/dist/events/map-zoom.d.ts +13 -0
- package/dist/events/map-zoom.js +11 -0
- package/dist/events/move.d.ts +11 -0
- package/dist/events/move.js +11 -0
- package/dist/events/names.d.ts +18 -0
- package/dist/events/names.js +13 -0
- package/dist/events/navigate.d.ts +13 -0
- package/dist/events/navigate.js +11 -0
- package/dist/events/next.d.ts +23 -0
- package/dist/events/next.js +11 -0
- package/dist/events/panel-resize.d.ts +12 -0
- package/dist/events/panel-resize.js +11 -0
- package/dist/events/pin.d.ts +12 -0
- package/dist/events/pin.js +11 -0
- package/dist/events/press.d.ts +19 -0
- package/dist/events/press.js +11 -0
- package/dist/events/preview.d.ts +14 -0
- package/dist/events/preview.js +11 -0
- package/dist/events/previous.d.ts +6 -0
- package/dist/events/previous.js +11 -0
- package/dist/events/range-change.d.ts +10 -0
- package/dist/events/range-change.js +11 -0
- package/dist/events/read.d.ts +19 -0
- package/dist/events/read.js +11 -0
- package/dist/events/reconnect.d.ts +6 -0
- package/dist/events/reconnect.js +11 -0
- package/dist/events/reject.d.ts +13 -0
- package/dist/events/reject.js +11 -0
- package/dist/events/relabel.d.ts +6 -0
- package/dist/events/relabel.js +11 -0
- package/dist/events/remove.d.ts +12 -0
- package/dist/events/remove.js +11 -0
- package/dist/events/reorder.d.ts +18 -0
- package/dist/events/reorder.js +11 -0
- package/dist/events/reordered.d.ts +12 -0
- package/dist/events/reordered.js +11 -0
- package/dist/events/resize.d.ts +19 -0
- package/dist/events/resize.js +11 -0
- package/dist/events/resized.d.ts +16 -0
- package/dist/events/resized.js +11 -0
- package/dist/events/sample-end.d.ts +5 -0
- package/dist/events/sample-end.js +6 -0
- package/dist/events/sample-start.d.ts +18 -0
- package/dist/events/sample-start.js +6 -0
- package/dist/events/scrolled.d.ts +32 -0
- package/dist/events/scrolled.js +11 -0
- package/dist/events/select.d.ts +12 -0
- package/dist/events/select.js +11 -0
- package/dist/events/selected.d.ts +12 -0
- package/dist/events/selected.js +11 -0
- package/dist/events/send.d.ts +18 -0
- package/dist/events/send.js +11 -0
- package/dist/events/shortcut.d.ts +13 -0
- package/dist/events/shortcut.js +11 -0
- package/dist/events/sort.d.ts +17 -0
- package/dist/events/sort.js +11 -0
- package/dist/events/sorted.d.ts +15 -0
- package/dist/events/sorted.js +11 -0
- package/dist/events/split.d.ts +12 -0
- package/dist/events/split.js +11 -0
- package/dist/events/toggle.d.ts +15 -0
- package/dist/events/toggle.js +11 -0
- package/dist/events/tour-ask.d.ts +16 -0
- package/dist/events/tour-ask.js +11 -0
- package/dist/events/tour-status.d.ts +14 -0
- package/dist/events/tour-status.js +11 -0
- package/dist/events/typing.d.ts +10 -0
- package/dist/events/typing.js +11 -0
- package/dist/helix-element/helix-element.js +9 -43
- package/dist/helix-element/react-bridge.d.ts +23 -0
- package/dist/helix-element/react-bridge.js +2 -2
- package/dist/helix-form-element/helix-form-element.d.ts +5 -20
- package/dist/helix-form-element/helix-form-element.js +4 -56
- package/dist/index.d.ts +30 -9
- package/dist/index.js +30 -9
- package/dist/mixins/mixin-chart-source/mixin-chart-source.d.ts +24 -2
- package/dist/mixins/mixin-chart-source/mixin-chart-source.js +23 -1
- package/dist/mixins/mixin-controller-active/mixin-controller-active.js +4 -3
- package/dist/mixins/mixin-controller-checked/mixin-controller-checked.d.ts +5 -2
- package/dist/mixins/mixin-controller-checked/mixin-controller-checked.js +2 -1
- package/dist/mixins/mixin-controller-value/mixin-controller-value.d.ts +4 -2
- package/dist/mixins/mixin-controller-value/mixin-controller-value.js +7 -2
- package/dist/mixins/mixin-dismissible/mixin-dismissible.js +44 -7
- package/dist/mixins/mixin-field/mixin-field.js +2 -2
- package/dist/mixins/mixin-picker-feedback/mixin-picker-feedback.d.ts +42 -0
- package/dist/mixins/mixin-picker-feedback/mixin-picker-feedback.js +46 -0
- package/dist/mixins/mixin-picker-field/mixin-picker-field.d.ts +7 -4
- package/dist/mixins/mixin-picker-field/mixin-picker-field.js +6 -4
- package/dist/mixins/mixin-segmented-field/mixin-segmented-field.js +19 -9
- package/dist/utils/audit-name/audit-name-off.d.ts +10 -0
- package/dist/utils/audit-name/audit-name-off.js +1 -0
- package/dist/utils/audit-name/audit-name.d.ts +26 -8
- package/dist/utils/audit-name/audit-name.js +22 -30
- package/dist/utils/audit-source/audit-source-off.d.ts +10 -0
- package/dist/utils/audit-source/audit-source-off.js +1 -0
- package/dist/utils/audit-source/audit-source.d.ts +19 -0
- package/dist/utils/audit-source/audit-source.js +27 -0
- package/dist/utils/calendar/calendar.js +7 -7
- package/dist/utils/call-listener/call-listener.d.ts +16 -0
- package/dist/utils/call-listener/call-listener.js +17 -0
- package/dist/utils/chord/chord.d.ts +14 -0
- package/dist/utils/chord/chord.js +1 -0
- package/dist/utils/clamp/clamp.d.ts +7 -0
- package/dist/utils/clamp/clamp.js +1 -0
- package/dist/utils/css-color/css-color.js +1 -1
- package/dist/utils/draw-tooltip/draw-tooltip.d.ts +1 -1
- package/dist/utils/draw-tooltip/draw-tooltip.js +3 -1
- package/dist/utils/draw-tooltip/spoken-reading.d.ts +6 -2
- package/dist/utils/draw-tooltip/spoken-reading.js +5 -4
- package/dist/utils/elapsed-time/elapsed-time.d.ts +1 -1
- package/dist/utils/elapsed-time/elapsed-time.js +2 -5
- package/dist/utils/heading-level/heading-level.d.ts +8 -0
- package/dist/utils/heading-level/heading-level.js +4 -0
- package/dist/utils/host-words/host-words.d.ts +16 -0
- package/dist/utils/host-words/host-words.js +13 -0
- package/dist/utils/implicit-submit/implicit-submit.d.ts +25 -0
- package/dist/utils/implicit-submit/implicit-submit.js +52 -0
- package/dist/utils/load-more/load-more.d.ts +25 -0
- package/dist/utils/load-more/load-more.js +1 -0
- package/dist/utils/locale-of/locale-of.d.ts +18 -0
- package/dist/utils/locale-of/locale-of.js +26 -0
- package/dist/utils/name-text/name-text.d.ts +12 -0
- package/dist/utils/name-text/name-text.js +25 -0
- package/dist/utils/nearest/nearest.d.ts +9 -0
- package/dist/utils/nearest/nearest.js +9 -0
- package/dist/utils/number-format/number-format.d.ts +11 -1
- package/dist/utils/number-format/number-format.js +17 -5
- package/dist/utils/own-rule/own-rule.d.ts +16 -0
- package/dist/utils/own-rule/own-rule.js +7 -0
- package/dist/utils/plain-click/plain-click.d.ts +10 -0
- package/dist/utils/plain-click/plain-click.js +1 -0
- package/dist/utils/platform/platform.d.ts +8 -0
- package/dist/utils/platform/platform.js +1 -0
- package/dist/utils/press-type/press-type.d.ts +20 -0
- package/dist/utils/press-type/press-type.js +15 -0
- package/dist/utils/read-series/read-series.d.ts +14 -0
- package/dist/utils/read-series/read-series.js +15 -0
- package/dist/utils/relative-time/relative-time.d.ts +8 -0
- package/dist/utils/relative-time/relative-time.js +5 -2
- package/dist/utils/report-render/report-render.js +2 -14
- package/dist/utils/report-runtime/report-runtime.d.ts +11 -4
- package/dist/utils/report-runtime/report-runtime.js +2 -14
- package/dist/utils/report-usage/report-usage.js +2 -14
- package/dist/utils/row-data/row-data.d.ts +15 -0
- package/dist/utils/row-data/row-data.js +17 -0
- package/dist/utils/row-order/row-order.d.ts +141 -0
- package/dist/utils/row-order/row-order.js +76 -0
- package/dist/utils/scroll-item-into-view/scroll-item-into-view.d.ts +33 -0
- package/dist/utils/scroll-item-into-view/scroll-item-into-view.js +13 -3
- package/dist/utils/slotted-glyph/slotted-glyph.d.ts +33 -0
- package/dist/utils/slotted-glyph/slotted-glyph.js +27 -0
- package/dist/utils/tell-disclosure/tell-disclosure.d.ts +4 -0
- package/dist/utils/tree-arrow/tree-arrow.d.ts +23 -0
- package/dist/utils/tree-arrow/tree-arrow.js +9 -0
- package/dist/utils/typeahead/typeahead.d.ts +75 -0
- package/dist/utils/typeahead/typeahead.js +37 -0
- package/dist/utils/value-as/value-as.d.ts +9 -0
- package/dist/utils/value-as/value-as.js +9 -1
- package/dist/utils/verdict-flags/verdict-flags.d.ts +13 -0
- package/dist/utils/verdict-flags/verdict-flags.js +6 -0
- package/dist/utils/watch-labels/watch-labels.d.ts +16 -0
- package/dist/utils/watch-labels/watch-labels.js +34 -0
- package/dist/utils/words-converter/words-converter.d.ts +14 -0
- package/dist/utils/words-converter/words-converter.js +15 -0
- package/dist/utils/written-list/written-list.d.ts +60 -0
- package/dist/utils/written-list/written-list.js +46 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +29 -5
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Where a scrolling set stands, for the question of whether to ask for more. */
|
|
2
|
+
export interface EndInSight {
|
|
3
|
+
/** The length the set last asked for more at, or `-1` where it never has. */
|
|
4
|
+
askedAt: number;
|
|
5
|
+
/** The set's length now, which the answer is kept for. */
|
|
6
|
+
count: number;
|
|
7
|
+
/** How far below the bottom of the box the set goes, in pixels. */
|
|
8
|
+
remaining: number;
|
|
9
|
+
/** The box's own height, in pixels: one screen. */
|
|
10
|
+
screen: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Whether a reader has come within one screen of the end of a set, and the
|
|
14
|
+
* set has not already asked for more at this length: React Aria's
|
|
15
|
+
* `onLoadMore` rule.
|
|
16
|
+
*
|
|
17
|
+
* **Once for each length**, so a scroll that goes on asks again only after the
|
|
18
|
+
* next page arrived and the length moved. False while the box has no height or
|
|
19
|
+
* the set no items, so a list that has not been laid out asks for nothing.
|
|
20
|
+
* The caller keeps `askedAt`, setting it to `count` when this answers true.
|
|
21
|
+
*
|
|
22
|
+
* Listbox asks this of its own scroll, and `VirtualizeController.endInSight`
|
|
23
|
+
* of the rows it lays out, so the two lists ask on the same terms.
|
|
24
|
+
*/
|
|
25
|
+
export declare const endInSight: ({ askedAt, count, remaining, screen }: EndInSight) => boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const endInSight = ({ askedAt, count, remaining, screen }) => count > 0 && screen > 0 && askedAt !== count && remaining <= screen;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The locale an element speaks: `own`, the element's own `locale` property,
|
|
3
|
+
* where one is set, and otherwise the `lang` of the nearest element with one,
|
|
4
|
+
* read out through any shadow root the element is drawn in.
|
|
5
|
+
*
|
|
6
|
+
* **The page's language is the default a reader expects.** A date picker on a
|
|
7
|
+
* page written `lang="de"` that names its months in English and starts its
|
|
8
|
+
* weeks on Sunday is a widget that ignored the one place the page said what
|
|
9
|
+
* language it is in; Shoelace and Web Awesome read the same attribute.
|
|
10
|
+
* `lang=""` is the page saying it does not know, and answers empty.
|
|
11
|
+
*
|
|
12
|
+
* Empty where nothing says, which every `Intl` call here takes as the
|
|
13
|
+
* runtime's own locale, and empty for a bare language the runtime already
|
|
14
|
+
* speaks (see `usable`). Read when asked rather than watched, so a page that
|
|
15
|
+
* changes its `lang` is answered in the new one on the element's next render.
|
|
16
|
+
* A server shim with no `closest` answers `own`, or empty.
|
|
17
|
+
*/
|
|
18
|
+
export declare const localeOf: (element: Element, own?: string) => string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
let runtime;
|
|
2
|
+
const usable = (lang) => {
|
|
3
|
+
try {
|
|
4
|
+
const asked = new Intl.Locale(lang);
|
|
5
|
+
runtime ??= new Intl.Locale(new Intl.DateTimeFormat().resolvedOptions().locale);
|
|
6
|
+
return asked.region === undefined && asked.language === runtime.language ? '' : asked.toString();
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export const localeOf = (element, own = '') => {
|
|
13
|
+
if (own) {
|
|
14
|
+
return own;
|
|
15
|
+
}
|
|
16
|
+
let from = element;
|
|
17
|
+
while (from && typeof from.closest === 'function') {
|
|
18
|
+
const found = from.closest('[lang]');
|
|
19
|
+
if (found) {
|
|
20
|
+
return usable(found.getAttribute('lang') ?? '');
|
|
21
|
+
}
|
|
22
|
+
const root = from.getRootNode?.();
|
|
23
|
+
from = root?.host ?? null;
|
|
24
|
+
}
|
|
25
|
+
return '';
|
|
26
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The words a node gives a name computed from its content: its text, read
|
|
3
|
+
* through slots, and the `aria-label` or `alt` of a picture in it, such as an
|
|
4
|
+
* icon named by its own label. A node hidden from the reader gives none, and
|
|
5
|
+
* so does `shown`, the part where a control shows its value.
|
|
6
|
+
*
|
|
7
|
+
* **In every build.** `AriaForwardController` asks it whether a control's own
|
|
8
|
+
* label has words in it, which decides where the host's label goes, so it is
|
|
9
|
+
* kept apart from the missing-name warning, which only a development build
|
|
10
|
+
* carries.
|
|
11
|
+
*/
|
|
12
|
+
export declare const nameText: (node: Node, shown?: Element | null) => string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const nameText = (node, shown) => {
|
|
2
|
+
if (node === shown) {
|
|
3
|
+
return '';
|
|
4
|
+
}
|
|
5
|
+
if (node instanceof HTMLSlotElement) {
|
|
6
|
+
return node
|
|
7
|
+
.assignedNodes({ flatten: true })
|
|
8
|
+
.map((one) => nameText(one, shown))
|
|
9
|
+
.join('');
|
|
10
|
+
}
|
|
11
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
12
|
+
return node.textContent ?? '';
|
|
13
|
+
}
|
|
14
|
+
if (!(node instanceof Element)) {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
if ((node instanceof HTMLElement && node.hidden) || node.getAttribute('aria-hidden') === 'true') {
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
const said = node.getAttribute('aria-label') ?? node.getAttribute('alt');
|
|
21
|
+
if (said?.trim()) {
|
|
22
|
+
return said;
|
|
23
|
+
}
|
|
24
|
+
return [...node.childNodes].map((one) => nameText(one, shown)).join('');
|
|
25
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The value in `values` nearest `target`, the first of two at the same
|
|
3
|
+
* distance, or `undefined` for none.
|
|
4
|
+
*
|
|
5
|
+
* Drawer's `snapTo` and Rating's reading of a score between its steps each
|
|
6
|
+
* wrote this loop. Given in ascending order, a target halfway between two
|
|
7
|
+
* goes to the lower, which is the rule both kept.
|
|
8
|
+
*/
|
|
9
|
+
export declare const nearest: (values: Iterable<number>, target: number) => number | undefined;
|
|
@@ -9,13 +9,23 @@
|
|
|
9
9
|
*/
|
|
10
10
|
/** Writes a number in a locale with `Intl.NumberFormat` options. */
|
|
11
11
|
export declare const formatNumber: (value: number, locale?: string, options?: Intl.NumberFormatOptions) => string;
|
|
12
|
+
/**
|
|
13
|
+
* A reading in words: `value` written with `options` where they say another
|
|
14
|
+
* style, and otherwise `share`, from 0 to 1, as a percentage, whole unless
|
|
15
|
+
* `options` say more.
|
|
16
|
+
*
|
|
17
|
+
* Meter and Progress each wrote this, with the value each holds to its range
|
|
18
|
+
* and the share of it that is filled.
|
|
19
|
+
*/
|
|
20
|
+
export declare const readingText: (value: number, share: number, locale?: string, options?: Intl.NumberFormatOptions) => string;
|
|
12
21
|
/**
|
|
13
22
|
* Reads a number written in a locale with the same options it is shown with,
|
|
14
23
|
* or `null` where the text is no number.
|
|
15
24
|
*
|
|
16
25
|
* The locale's group separators are dropped and its decimal separator read as
|
|
17
26
|
* a point, so `1.234,5` in `de-DE` is 1234.5. A currency sign, a percent sign
|
|
18
|
-
* and a unit the options write are dropped too,
|
|
27
|
+
* and a unit the options write are dropped too, in the plural and the
|
|
28
|
+
* singular, and a percent is read back as
|
|
19
29
|
* the fraction it shows: `25 %` is 0.25. A point is read as a decimal point in
|
|
20
30
|
* a locale that groups with something else, which is what a decimal keypad
|
|
21
31
|
* types.
|
|
@@ -9,19 +9,31 @@ const formatter = (locale, options) => {
|
|
|
9
9
|
return found;
|
|
10
10
|
};
|
|
11
11
|
export const formatNumber = (value, locale = '', options) => formatter(locale, options).format(value);
|
|
12
|
+
const WHOLE_PERCENT = { maximumFractionDigits: 0, style: 'percent' };
|
|
13
|
+
export const readingText = (value, share, locale = '', options) => options && options.style !== 'percent'
|
|
14
|
+
? formatNumber(value, locale, options)
|
|
15
|
+
: formatNumber(share, locale, options ?? WHOLE_PERCENT);
|
|
12
16
|
const grouped = (text, separator, decimal) => {
|
|
13
17
|
const whole = (text.split(decimal)[0] ?? '').replace(/^[+-]/u, '');
|
|
14
18
|
return new RegExp(`^\\d{1,3}(${literal(separator)}\\d{3})+$`, 'u').test(whole);
|
|
15
19
|
};
|
|
16
20
|
const literal = (text) => text.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
17
21
|
export const parseNumber = (text, locale = '', options) => {
|
|
18
|
-
const
|
|
19
|
-
const
|
|
22
|
+
const format = formatter(locale, options);
|
|
23
|
+
const parts = format.formatToParts(-12345.6);
|
|
24
|
+
const one = format.formatToParts(1);
|
|
25
|
+
const of = (type, from = parts) => from.filter((part) => part.type === type).map((part) => part.value);
|
|
20
26
|
const group = of('group')[0] ?? ',';
|
|
21
27
|
const decimal = of('decimal')[0] ?? '.';
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
const named = (from) => [
|
|
29
|
+
...of('currency', from),
|
|
30
|
+
...of('percentSign', from),
|
|
31
|
+
...of('unit', from),
|
|
32
|
+
...of('literal', from),
|
|
33
|
+
];
|
|
34
|
+
const dropped = [...new Set([...named(parts), ...named(one)].map((word) => word.trim()))]
|
|
35
|
+
.filter(Boolean)
|
|
36
|
+
.sort((a, b) => b.length - a.length);
|
|
25
37
|
const percent = options?.style === 'percent' && /[%\u066a\u2030]/u.test(text);
|
|
26
38
|
let read = text.replace(/[\s\u00a0\u202f]/gu, '');
|
|
27
39
|
for (const one of dropped) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A page's own rule for a field's value: a message, a list of them, or `true`,
|
|
3
|
+
* `null` or nothing to accept the value. Input's and Textarea's `validate`.
|
|
4
|
+
*/
|
|
5
|
+
export type OwnRule = (value: string) => string | string[] | true | null | undefined;
|
|
6
|
+
/**
|
|
7
|
+
* Applies a page's own rule after the native verdict was copied, as React
|
|
8
|
+
* Aria's TextField `validate` does: only while the browser finds nothing
|
|
9
|
+
* wrong, so a required empty field says the browser's sentence first. A list
|
|
10
|
+
* of messages is joined with spaces, and the message is a `customError`
|
|
11
|
+
* anchored at the control, so the bubble points at the text.
|
|
12
|
+
*
|
|
13
|
+
* A function rather than a member of `MixinField`, so only the fields that
|
|
14
|
+
* take `validate` carry it.
|
|
15
|
+
*/
|
|
16
|
+
export declare const applyOwnRule: (internals: ElementInternals, control: HTMLInputElement | HTMLTextAreaElement, rule: OwnRule | undefined, value: string) => void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const applyOwnRule = (internals, control, rule, value) => {
|
|
2
|
+
const own = control.validity.valid ? rule?.(value) : undefined;
|
|
3
|
+
const message = Array.isArray(own) ? own.join(' ') : typeof own === 'string' ? own : '';
|
|
4
|
+
if (message !== '') {
|
|
5
|
+
internals.setValidity({ customError: true }, message, control);
|
|
6
|
+
}
|
|
7
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a click is a plain press of the main button, with no Command,
|
|
3
|
+
* Control, Shift or Alt held.
|
|
4
|
+
*
|
|
5
|
+
* A link pressed any other way opens where the browser opens it, a new tab or
|
|
6
|
+
* a new window, so an element that acts on a link's click first (a tab
|
|
7
|
+
* choosing itself, a skip link moving focus, an outline scrolling) leaves
|
|
8
|
+
* every other click to the browser.
|
|
9
|
+
*/
|
|
10
|
+
export declare const plainClick: (event: MouseEvent) => boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const plainClick = (event) => event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;
|
|
@@ -21,3 +21,11 @@ export declare const appleTouch: (platform: Platform | undefined) => boolean;
|
|
|
21
21
|
* `mod` as the key it names.
|
|
22
22
|
*/
|
|
23
23
|
export declare const onApple: (platform?: Platform | undefined) => boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Whether the browser runs on Android, where TalkBack reads no `aria-sort`.
|
|
26
|
+
*
|
|
27
|
+
* React Aria's table header describes its sort order in words there for the
|
|
28
|
+
* same reason, so a reader who cannot hear the state still hears which way a
|
|
29
|
+
* column is sorted. From the user agent; `false` on a server.
|
|
30
|
+
*/
|
|
31
|
+
export declare const onAndroid: (platform?: Platform | undefined) => boolean;
|
|
@@ -9,3 +9,4 @@ export const appleTouch = (platform) => {
|
|
|
9
9
|
return platform.platform === 'MacIntel' && (platform.maxTouchPoints ?? 0) > 1;
|
|
10
10
|
};
|
|
11
11
|
export const onApple = (platform = typeof navigator === 'undefined' ? undefined : navigator) => platform !== undefined && /mac|iphone|ipad|ipod/i.test(platform.userAgent ?? '');
|
|
12
|
+
export const onAndroid = (platform = typeof navigator === 'undefined' ? undefined : navigator) => platform !== undefined && /android/i.test(platform.userAgent ?? '');
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { PressPointerType } from '../../events/details.js';
|
|
2
|
+
/** What the control saw before the click, which the click does not carry everywhere. */
|
|
3
|
+
export interface RecentPress {
|
|
4
|
+
/** Whether Enter or Space started this press. */
|
|
5
|
+
key?: boolean;
|
|
6
|
+
/** The `pointerType` of the last `pointerdown` on the control. */
|
|
7
|
+
pointer?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* What a `click` came from, for `HelixPressEvent`.
|
|
11
|
+
*
|
|
12
|
+
* **Read in order.** The click's own pointer kind first, which Chromium and
|
|
13
|
+
* Firefox put on it. Then a key, which the caller saw start the press, because
|
|
14
|
+
* a keyboard press and a script's `click()` arrive alike. Then, for a click
|
|
15
|
+
* with a press count (`detail` above zero), the last pointer's kind, or
|
|
16
|
+
* `mouse` where none was seen, which is how Safari's click arrives. A click
|
|
17
|
+
* with none of these is `virtual`, as React Aria reads one: a screen reader's
|
|
18
|
+
* press or a script's `click()`.
|
|
19
|
+
*/
|
|
20
|
+
export declare const pressType: (click: MouseEvent, recent?: RecentPress) => PressPointerType;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const POINTERS = new Set(['mouse', 'pen', 'touch']);
|
|
2
|
+
export const pressType = (click, recent = {}) => {
|
|
3
|
+
const own = click.pointerType ?? '';
|
|
4
|
+
if (POINTERS.has(own)) {
|
|
5
|
+
return own;
|
|
6
|
+
}
|
|
7
|
+
if (recent.key === true) {
|
|
8
|
+
return 'keyboard';
|
|
9
|
+
}
|
|
10
|
+
if (click.detail > 0) {
|
|
11
|
+
const last = recent.pointer ?? '';
|
|
12
|
+
return POINTERS.has(last) ? last : 'mouse';
|
|
13
|
+
}
|
|
14
|
+
return 'virtual';
|
|
15
|
+
};
|
|
@@ -136,3 +136,17 @@ export declare const readRows: (table: Element) => Row[];
|
|
|
136
136
|
* name is written, in `lines`, `hidden-series` and `hide()` alike.
|
|
137
137
|
*/
|
|
138
138
|
export declare const seriesKey: (name: string) => string;
|
|
139
|
+
/** Where the highest and the lowest readings are, by place, or none. */
|
|
140
|
+
export interface Extremes {
|
|
141
|
+
/** The place of the highest reading, the first where several tie. */
|
|
142
|
+
high?: number;
|
|
143
|
+
/** The place of the lowest reading, the first where several tie. */
|
|
144
|
+
low?: number;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Where the highest and the lowest readings stand. A blank slot is passed
|
|
148
|
+
* over, and a list with nothing in it has neither.
|
|
149
|
+
*
|
|
150
|
+
* Sparkline's overview and Heatmap's busiest place each looked for these.
|
|
151
|
+
*/
|
|
152
|
+
export declare const extremesOf: (slots: readonly (number | undefined)[]) => Extremes;
|
|
@@ -139,3 +139,18 @@ export const readRows = (table) => {
|
|
|
139
139
|
return [...(element.tBodies[0]?.rows ?? [])].map((one) => row(one.cells[0], [...one.cells].slice(1), names));
|
|
140
140
|
};
|
|
141
141
|
export const seriesKey = (name) => name.trim().toLowerCase();
|
|
142
|
+
export const extremesOf = (slots) => {
|
|
143
|
+
const found = {};
|
|
144
|
+
slots.forEach((value, at) => {
|
|
145
|
+
if (value === undefined) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (found.high === undefined || value > slots[found.high]) {
|
|
149
|
+
found.high = at;
|
|
150
|
+
}
|
|
151
|
+
if (found.low === undefined || value < slots[found.low]) {
|
|
152
|
+
found.low = at;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
return found;
|
|
156
|
+
};
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How long each unit lasts, in milliseconds, largest last. `elapsedTime`
|
|
3
|
+
* reads its minute, hour and day from here.
|
|
4
|
+
*/
|
|
5
|
+
export declare const UNITS: Array<{
|
|
6
|
+
ms: number;
|
|
7
|
+
unit: Intl.RelativeTimeFormatUnit;
|
|
8
|
+
}>;
|
|
1
9
|
/** What one timestamp reads as, and when that stops being true. */
|
|
2
10
|
export interface Relative {
|
|
3
11
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const held = new Map();
|
|
2
|
-
const UNITS = [
|
|
2
|
+
export const UNITS = [
|
|
3
3
|
{ ms: 1000, unit: 'second' },
|
|
4
4
|
{ ms: 60_000, unit: 'minute' },
|
|
5
5
|
{ ms: 3_600_000, unit: 'hour' },
|
|
@@ -25,7 +25,10 @@ export const relativeTime = (locale, options = {}) => {
|
|
|
25
25
|
}
|
|
26
26
|
const size = Math.abs(elapsed);
|
|
27
27
|
if (size < 60_000) {
|
|
28
|
-
return {
|
|
28
|
+
return {
|
|
29
|
+
next: Math.max(1000, 60_000 - size),
|
|
30
|
+
text: found.format(elapsed > 0 ? 0 : -0, 'second'),
|
|
31
|
+
};
|
|
29
32
|
}
|
|
30
33
|
let chosen = UNITS[1];
|
|
31
34
|
for (const unit of UNITS) {
|
|
@@ -1,18 +1,6 @@
|
|
|
1
|
+
import { callListener } from '../call-listener/call-listener.js';
|
|
1
2
|
export const RENDER_SLOT = Symbol.for('fusion.dev/helix/render');
|
|
2
3
|
export const measuring = () => typeof globalThis[RENDER_SLOT] === 'function';
|
|
3
|
-
let told = false;
|
|
4
4
|
export const reportRender = (element, start, duration) => {
|
|
5
|
-
|
|
6
|
-
if (typeof listener !== 'function') {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
try {
|
|
10
|
-
listener(element, { duration, start });
|
|
11
|
-
}
|
|
12
|
-
catch (error) {
|
|
13
|
-
if (!told) {
|
|
14
|
-
told = true;
|
|
15
|
-
console.error('helix: a render listener threw, and the element rendered as usual. Later failures are not printed.', error);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
5
|
+
callListener(RENDER_SLOT, 'render', 'the element rendered as usual', element, { duration, start });
|
|
18
6
|
};
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
*/
|
|
19
19
|
/** What went wrong, stable across versions, so it can be counted. */
|
|
20
20
|
export type RuntimeKind =
|
|
21
|
+
/** A deprecated property, attribute or slot was used; the message names what replaces it. */
|
|
22
|
+
'deprecated'
|
|
21
23
|
/** Another class asked for a tag that is already registered: two copies of Helix. */
|
|
22
|
-
'duplicate-registration'
|
|
24
|
+
| 'duplicate-registration'
|
|
23
25
|
/** The browser refused fullscreen, usually for a frame without the permission. */
|
|
24
26
|
| 'fullscreen-refused'
|
|
25
|
-
/** An Avatar Group's `max` is past the number the fold is written for. */
|
|
26
|
-
| 'max-past-fold'
|
|
27
27
|
/** A rating's `min` is no score between 0 and its `max`. */
|
|
28
28
|
| 'min-out-of-range'
|
|
29
29
|
/** A Stat was given one of Trend's directions, `up`, `down` or `neutral`, which lay nothing out. */
|
|
@@ -34,12 +34,17 @@ export type RuntimeKind =
|
|
|
34
34
|
| 'missing-alt'
|
|
35
35
|
/** The three.js driver could not load its layout, so the notes stay where they started. */
|
|
36
36
|
| 'missing-layout'
|
|
37
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* A control has no accessible name, so a screen reader announces it by its role alone.
|
|
39
|
+
* Reported in development builds only (the `development` export condition).
|
|
40
|
+
*/
|
|
38
41
|
| 'missing-name'
|
|
39
42
|
/** A selectable Data Table has no `row-key`, so it knows each row by its place. */
|
|
40
43
|
| 'missing-row-key'
|
|
41
44
|
/** A stencil names parts the shape does not have. */
|
|
42
45
|
| 'missing-stencil-parts'
|
|
46
|
+
/** A chart, a legend or a sparkline names no table with `for`. Development builds only. */
|
|
47
|
+
| 'missing-table'
|
|
43
48
|
/** A Skip Link's `href` names no element in its tree, so a press moves focus nowhere. */
|
|
44
49
|
| 'missing-target'
|
|
45
50
|
/** A tooltip's `for` names no element in its own tree. */
|
|
@@ -64,6 +69,8 @@ export type RuntimeKind =
|
|
|
64
69
|
| 'too-many-rows'
|
|
65
70
|
/** A filter field marks more than one operator as its default. */
|
|
66
71
|
| 'two-default-operators'
|
|
72
|
+
/** A Quote's text starts or ends with a quotation mark, so the browser's marks double it. */
|
|
73
|
+
| 'typed-marks'
|
|
67
74
|
/** A React handler prop names an event nothing dispatches. */
|
|
68
75
|
| 'unknown-event'
|
|
69
76
|
/** An Icon's `name` is in no icon set it can read, so it draws nothing. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { callListener } from '../call-listener/call-listener.js';
|
|
1
2
|
export const RUNTIME_SLOT = Symbol.for('fusion.dev/helix/runtime');
|
|
2
3
|
export const RUNTIME_LOG = Symbol.for('fusion.dev/helix/runtime-log');
|
|
3
4
|
const KEPT = 200;
|
|
4
|
-
let told = false;
|
|
5
5
|
export const reportRuntime = (event) => {
|
|
6
6
|
const store = globalThis;
|
|
7
7
|
const log = Array.isArray(store[RUNTIME_LOG]) ? store[RUNTIME_LOG] : [];
|
|
@@ -9,19 +9,7 @@ export const reportRuntime = (event) => {
|
|
|
9
9
|
log.push(event);
|
|
10
10
|
}
|
|
11
11
|
store[RUNTIME_LOG] = log;
|
|
12
|
-
|
|
13
|
-
const listener = store[RUNTIME_SLOT];
|
|
14
|
-
if (typeof listener === 'function') {
|
|
15
|
-
try {
|
|
16
|
-
quiet = listener(event) === true;
|
|
17
|
-
}
|
|
18
|
-
catch (error) {
|
|
19
|
-
if (!told) {
|
|
20
|
-
told = true;
|
|
21
|
-
console.error('helix: a runtime listener threw, and the warning is printed here. Later failures are not printed.', error);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
12
|
+
const quiet = callListener(RUNTIME_SLOT, 'runtime', 'the warning is printed here', event) === true;
|
|
25
13
|
if (quiet) {
|
|
26
14
|
return;
|
|
27
15
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { VERSION } from '../../version.js';
|
|
2
|
+
import { callListener } from '../call-listener/call-listener.js';
|
|
2
3
|
export const USAGE_SLOT = Symbol.for('fusion.dev/helix/usage');
|
|
3
4
|
export const VERSIONS_SLOT = Symbol.for('fusion.dev/helix/versions');
|
|
4
5
|
export const noteVersion = () => {
|
|
@@ -9,19 +10,6 @@ export const noteVersion = () => {
|
|
|
9
10
|
}
|
|
10
11
|
store[VERSIONS_SLOT] = listed;
|
|
11
12
|
};
|
|
12
|
-
let told = false;
|
|
13
13
|
export const reportUsage = (element) => {
|
|
14
|
-
|
|
15
|
-
if (typeof listener !== 'function') {
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
try {
|
|
19
|
-
listener(element);
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
if (!told) {
|
|
23
|
-
told = true;
|
|
24
|
-
console.error('helix: a usage listener threw, and the element rendered as usual. Later failures are not printed.', error);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
14
|
+
callListener(USAGE_SLOT, 'usage', 'the element rendered as usual', element);
|
|
27
15
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The value at `path` in a row of data, or `undefined` where the path leads
|
|
3
|
+
* nowhere: the field a Table or Data Table column, a Data Table's `row-key`
|
|
4
|
+
* or a Virtual List's template hole names.
|
|
5
|
+
*
|
|
6
|
+
* A dot separates keys, so `author.name` reads `row.author.name`. A key that
|
|
7
|
+
* holds a dot itself is read whole first, so a flat record with a key such as
|
|
8
|
+
* `"v1.2"` keeps working. An empty path reads nothing, and so does a row that
|
|
9
|
+
* is no record. `undefined` is drawn as an empty cell: a missing key is a hole
|
|
10
|
+
* in the data, and drawing "undefined" tells a reader the software is broken.
|
|
11
|
+
*
|
|
12
|
+
* Written here rather than taken from a library, because the whole of what is
|
|
13
|
+
* needed is "walk the keys and stop at the first thing that is not an object".
|
|
14
|
+
*/
|
|
15
|
+
export declare const valueAt: (row: unknown, path: string) => unknown;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const valueAt = (row, path) => {
|
|
2
|
+
if (path === '' || row === null || typeof row !== 'object') {
|
|
3
|
+
return undefined;
|
|
4
|
+
}
|
|
5
|
+
const record = row;
|
|
6
|
+
if (path in record) {
|
|
7
|
+
return record[path];
|
|
8
|
+
}
|
|
9
|
+
let value = record;
|
|
10
|
+
for (const key of path.split('.')) {
|
|
11
|
+
if (value === null || typeof value !== 'object') {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
value = value[key];
|
|
15
|
+
}
|
|
16
|
+
return value;
|
|
17
|
+
};
|