@tensor_1/react 2.47.0 → 2.49.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/README.md +540 -2
- package/dist/{SchedulingCalendar-B6TakO2h.d.ts → SchedulingCalendar-WWyFL3Eo.d.ts} +51 -2
- package/dist/announce.d.ts +10 -0
- package/dist/announce.js +30 -0
- package/dist/chart-analytic.cjs +33 -25
- package/dist/chart-preset.cjs +23 -15
- package/dist/chart.cjs +23 -15
- package/dist/combobox-model.d.ts +10 -1
- package/dist/combobox-model.js +15 -0
- package/dist/command-palette-model.d.ts +44 -0
- package/dist/command-palette-model.js +36 -0
- package/dist/components/AccountMenu.d.ts +44 -0
- package/dist/components/AccountMenu.js +43 -0
- package/dist/components/AppShell.d.ts +45 -2
- package/dist/components/AppShell.js +116 -5
- package/dist/components/AuditLog.d.ts +128 -0
- package/dist/components/AuditLog.js +196 -0
- package/dist/components/BrandProfiles.js +4 -3
- package/dist/components/Breadcrumbs.d.ts +9 -2
- package/dist/components/Breadcrumbs.js +3 -2
- package/dist/components/Button.d.ts +12 -5
- package/dist/components/Button.js +7 -3
- package/dist/components/Card.d.ts +18 -1
- package/dist/components/Card.js +5 -1
- package/dist/components/ChangeHighlight.d.ts +30 -0
- package/dist/components/ChangeHighlight.js +21 -0
- package/dist/components/ChartCore.js +2 -1
- package/dist/components/Checkbox.d.ts +27 -1
- package/dist/components/Checkbox.js +31 -2
- package/dist/components/Chip.d.ts +7 -3
- package/dist/components/Chip.js +2 -2
- package/dist/components/CodeDisplay.d.ts +65 -0
- package/dist/components/CodeDisplay.js +124 -0
- package/dist/components/Combobox.d.ts +27 -6
- package/dist/components/Combobox.js +195 -58
- package/dist/components/CommandPalette.d.ts +36 -1
- package/dist/components/CommandPalette.js +254 -2
- package/dist/components/ContactCard.d.ts +66 -0
- package/dist/components/ContactCard.js +74 -0
- package/dist/components/Count.d.ts +24 -0
- package/dist/components/Count.js +32 -0
- package/dist/components/DashboardCanvas.js +14 -0
- package/dist/components/DataWorkspace.d.ts +167 -0
- package/dist/components/DataWorkspace.js +380 -0
- package/dist/components/DateFieldParts.d.ts +2 -1
- package/dist/components/DateFieldParts.js +7 -0
- package/dist/components/DatePicker.d.ts +9 -2
- package/dist/components/DatePicker.js +67 -28
- package/dist/components/DateRangePicker.d.ts +12 -2
- package/dist/components/DateRangePicker.js +13 -12
- package/dist/components/DetailPage.d.ts +7 -1
- package/dist/components/DetailPage.js +2 -1
- package/dist/components/Dialogs.d.ts +71 -10
- package/dist/components/Dialogs.js +130 -30
- package/dist/components/DiffViewer.d.ts +23 -3
- package/dist/components/DiffViewer.js +26 -12
- package/dist/components/DiscardPrompt.js +16 -0
- package/dist/components/DisplayPreferences.d.ts +83 -0
- package/dist/components/DisplayPreferences.js +185 -0
- package/dist/components/EditorialHome.d.ts +23 -3
- package/dist/components/EditorialHome.js +16 -11
- package/dist/components/EntityPicker.d.ts +20 -3
- package/dist/components/EntityPicker.js +32 -13
- package/dist/components/FilterEditor.d.ts +18 -4
- package/dist/components/FilterEditor.js +141 -19
- package/dist/components/FocusOnMount.d.ts +282 -0
- package/dist/components/FocusOnMount.js +12 -0
- package/dist/components/InfoTip.js +11 -12
- package/dist/components/InlineEdit.d.ts +87 -20
- package/dist/components/InlineEdit.js +197 -54
- package/dist/components/Input.d.ts +12 -2
- package/dist/components/Input.js +5 -3
- package/dist/components/Kanban.d.ts +14 -3
- package/dist/components/Kanban.js +9 -4
- package/dist/components/Kbd.d.ts +6 -1
- package/dist/components/Kbd.js +6 -6
- package/dist/components/Lightbox.d.ts +41 -5
- package/dist/components/Lightbox.js +95 -9
- package/dist/components/MatchReview.d.ts +40 -1
- package/dist/components/MatchReview.js +130 -4
- package/dist/components/MetricInput.js +3 -2
- package/dist/components/Modal.d.ts +2 -1
- package/dist/components/Modal.js +13 -4
- package/dist/components/MotionList.d.ts +303 -0
- package/dist/components/MotionList.js +175 -0
- package/dist/components/NavFavourites.d.ts +5 -0
- package/dist/components/NavFavourites.js +7 -7
- package/dist/components/OtpInput.d.ts +33 -0
- package/dist/components/OtpInput.js +123 -0
- package/dist/components/PageHeader.d.ts +7 -1
- package/dist/components/PageHeader.js +2 -2
- package/dist/components/Pagination.js +6 -5
- package/dist/components/PasswordInput.d.ts +34 -0
- package/dist/components/PasswordInput.js +101 -0
- package/dist/components/Peek.js +3 -3
- package/dist/components/Popover.js +11 -0
- package/dist/components/PrintLayout.d.ts +63 -0
- package/dist/components/PrintLayout.js +114 -0
- package/dist/components/QrCode.d.ts +47 -0
- package/dist/components/QrCode.js +55 -0
- package/dist/components/QrScanner.d.ts +95 -0
- package/dist/components/QrScanner.js +266 -0
- package/dist/components/RelationshipGraph.d.ts +32 -1
- package/dist/components/RelationshipGraph.js +22 -6
- package/dist/components/RelationshipGraphLayered.d.ts +1 -1
- package/dist/components/RelationshipGraphLayered.js +268 -118
- package/dist/components/RelationshipGraphList.js +33 -6
- package/dist/components/RuleBuilder.js +39 -7
- package/dist/components/SchedulingAgenda.d.ts +3 -1
- package/dist/components/SchedulingCalendar.d.ts +3 -1
- package/dist/components/SchedulingCalendar.js +43 -4
- package/dist/components/SchedulingResourceDay.d.ts +57 -0
- package/dist/components/SchedulingResourceDay.js +287 -0
- package/dist/components/SchedulingTimeGrid.d.ts +3 -1
- package/dist/components/SchedulingTimeline.d.ts +3 -1
- package/dist/components/SearchSuggest.d.ts +23 -3
- package/dist/components/SearchSuggest.js +56 -18
- package/dist/components/Segmented.d.ts +39 -4
- package/dist/components/Segmented.js +39 -5
- package/dist/components/Select.d.ts +3 -2
- package/dist/components/Select.js +7 -1
- package/dist/components/ShortcutHint.d.ts +11 -10
- package/dist/components/ShortcutHint.js +44 -38
- package/dist/components/Sidebar.d.ts +36 -4
- package/dist/components/Sidebar.js +37 -12
- package/dist/components/SortableList.d.ts +45 -0
- package/dist/components/SortableList.js +147 -0
- package/dist/components/Stat.d.ts +28 -3
- package/dist/components/Stat.js +13 -3
- package/dist/components/States.d.ts +33 -1
- package/dist/components/States.js +43 -1
- package/dist/components/StatusPill.d.ts +14 -3
- package/dist/components/StatusPill.js +11 -3
- package/dist/components/Steps.js +2 -1
- package/dist/components/Table.d.ts +9 -2
- package/dist/components/Table.js +4 -2
- package/dist/components/TableControls.js +18 -58
- package/dist/components/TableOverflowProbe.d.ts +12 -0
- package/dist/components/TableOverflowProbe.js +27 -0
- package/dist/components/Tabs.d.ts +2 -1
- package/dist/components/Tabs.js +10 -2
- package/dist/components/TagInput.d.ts +67 -0
- package/dist/components/TagInput.js +342 -0
- package/dist/components/Textarea.d.ts +5 -0
- package/dist/components/Textarea.js +2 -2
- package/dist/components/TimePicker.d.ts +80 -0
- package/dist/components/TimePicker.js +347 -0
- package/dist/components/Toast.d.ts +1 -1
- package/dist/components/Toast.js +109 -4
- package/dist/components/Tooltip.d.ts +8 -4
- package/dist/components/Tooltip.js +86 -28
- package/dist/components/Tree.d.ts +8 -0
- package/dist/components/Tree.js +11 -5
- package/dist/display-preferences-model.d.ts +53 -0
- package/dist/display-preferences-model.js +64 -0
- package/dist/emoji.cjs +143 -49
- package/dist/filter-model.d.ts +59 -3
- package/dist/filter-model.js +67 -2
- package/dist/hooks/useAnchoredPosition.js +14 -2
- package/dist/hooks/useChangeHighlight.d.ts +33 -0
- package/dist/hooks/useChangeHighlight.js +44 -0
- package/dist/hooks/useDeferredReorder.d.ts +32 -0
- package/dist/hooks/useDeferredReorder.js +47 -0
- package/dist/hooks/useDialog.d.ts +5 -0
- package/dist/hooks/useDialog.js +17 -3
- package/dist/hooks/useKeyboardGrab.d.ts +58 -0
- package/dist/hooks/useKeyboardGrab.js +118 -0
- package/dist/hooks/useOptimisticValue.d.ts +51 -0
- package/dist/hooks/useOptimisticValue.js +61 -0
- package/dist/hooks/useReducedMotion.d.ts +4 -1
- package/dist/hooks/useReducedMotion.js +7 -1
- package/dist/hooks/useResolvedFilterLabels.d.ts +15 -0
- package/dist/hooks/useResolvedFilterLabels.js +34 -0
- package/dist/hooks/useSlidingIndicator.d.ts +18 -0
- package/dist/hooks/useSlidingIndicator.js +80 -0
- package/dist/hooks/useVirtualRows.d.ts +21 -2
- package/dist/hooks/useVirtualRows.js +30 -3
- package/dist/icons/Icon.d.ts +1 -1
- package/dist/index.cjs +19687 -13423
- package/dist/index.d.cts +3419 -651
- package/dist/index.d.ts +48 -18
- package/dist/index.js +153 -9
- package/dist/labels-context.d.ts +93 -3
- package/dist/motion.d.ts +11 -0
- package/dist/motion.js +35 -0
- package/dist/overlay-stack.d.ts +6 -0
- package/dist/overlay-stack.js +13 -0
- package/dist/qr-model.d.ts +65 -0
- package/dist/qr-model.js +323 -0
- package/dist/relationship-graph-model.d.ts +92 -3
- package/dist/relationship-graph-model.js +134 -15
- package/dist/reorder.d.ts +30 -0
- package/dist/reorder.js +74 -0
- package/dist/rich-text.cjs +46 -4
- package/dist/scheduling-resource-model.d.ts +76 -0
- package/dist/scheduling-resource-model.js +74 -0
- package/dist/search-suggest-model.js +3 -1
- package/dist/shell-context.d.ts +11 -0
- package/dist/shell-context.js +7 -0
- package/dist/time-field-model.d.ts +46 -0
- package/dist/time-field-model.js +152 -0
- package/dist/toast-store.d.ts +22 -3
- package/dist/toast-store.js +26 -9
- package/package.json +2 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { TextFilterOperator, NumberFilterOperator, FilterField, FilterValue } from '../filter-model.js';
|
|
2
|
+
import { TextFilterOperator, NumberFilterOperator, DateFilterOperator, FilterField, FilterValue } from '../filter-model.js';
|
|
3
3
|
|
|
4
4
|
interface FilterEditorLabels {
|
|
5
5
|
apply: string;
|
|
@@ -26,7 +26,15 @@ interface FilterEditorLabels {
|
|
|
26
26
|
remove: string;
|
|
27
27
|
/** Names the row of `field.presets` chips. Optional so existing label objects still type-check; default "Presets". */
|
|
28
28
|
presets?: string;
|
|
29
|
+
/** `tags` (HAR-1832): the field that takes a new value, and its hint. Optional, like `presets`. */
|
|
30
|
+
addTag?: string;
|
|
31
|
+
/** `tags`: how to add one, read with the field. */
|
|
32
|
+
addTagHint?: string;
|
|
33
|
+
/** `date` (HAR-1832): the date of on / before / after. Optional, like `presets`. */
|
|
34
|
+
date?: string;
|
|
29
35
|
operators: Record<TextFilterOperator | NumberFilterOperator, string>;
|
|
36
|
+
/** `date` conditions (HAR-1832). Optional, like `presets`. */
|
|
37
|
+
dateOperators?: Partial<Record<DateFilterOperator, string>>;
|
|
30
38
|
}
|
|
31
39
|
declare const DEFAULT_FILTER_EDITOR_LABELS: FilterEditorLabels;
|
|
32
40
|
interface FilterEditorProps {
|
|
@@ -34,7 +42,12 @@ interface FilterEditorProps {
|
|
|
34
42
|
/** Undefined means "not filtered yet". */
|
|
35
43
|
value: FilterValue | undefined;
|
|
36
44
|
onValueChange: (value: FilterValue) => void;
|
|
37
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Apply the filter: the Apply button, or Enter in any field (HAR-1832). Gets the value to
|
|
47
|
+
* apply, which already holds a tag still being typed: read it rather than your state, which
|
|
48
|
+
* has not caught up when Enter applies in the same event.
|
|
49
|
+
*/
|
|
50
|
+
onApply: (value: FilterValue) => void;
|
|
38
51
|
onClear: () => void;
|
|
39
52
|
labels?: Partial<FilterEditorLabels>;
|
|
40
53
|
/** Show an option filter above an enum list once it has more options than this. Default 8. */
|
|
@@ -44,8 +57,9 @@ interface FilterEditorProps {
|
|
|
44
57
|
}
|
|
45
58
|
/**
|
|
46
59
|
* Editor content for one typed column filter (HAR-1365; TENSOR C6, MOTUS C-1): an enum
|
|
47
|
-
* multi-select, text or number with a condition, a date range,
|
|
48
|
-
*
|
|
60
|
+
* multi-select, text or number with a condition, a date range, a date with a condition
|
|
61
|
+
* (on / before / after / between), yes/no, free-text tags, or records found by an async search
|
|
62
|
+
* (restored ids get their labels from `field.resolveLabels`). Enter applies in every kind. The product owns the popover trigger and the query; `summarizeFilter`
|
|
49
63
|
* turns the applied value into the chip text. `FilterPopover` stays for the one-string case.
|
|
50
64
|
* An enum field's `presets` (HAR-1505) render as toggle chips above its options. Words come
|
|
51
65
|
* from `labels`, or from `UixLabelsProvider`'s `filterEditor` entry.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useEffect, useId, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { Fragment as Fragment2, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { Button } from "./Button.js";
|
|
5
5
|
import { Checkbox } from "./Checkbox.js";
|
|
6
6
|
import { Input } from "./Input.js";
|
|
@@ -8,9 +8,11 @@ import { Radio, RadioGroup } from "./Radio.js";
|
|
|
8
8
|
import { Select } from "./Select.js";
|
|
9
9
|
import { Chip } from "./Chip.js";
|
|
10
10
|
import { fillLabel } from "../fill-label.js";
|
|
11
|
+
import { cx } from "../cx.js";
|
|
11
12
|
import { useUixLabels } from "../labels-context.js";
|
|
13
|
+
import { useDelayedPending } from "../hooks/useDelayedPending.js";
|
|
12
14
|
import { foldForSearch } from "../search-suggest-model.js";
|
|
13
|
-
import { NUMBER_FILTER_OPERATORS, TEXT_FILTER_OPERATORS, emptyFilterValue, matchFilterPreset } from "../filter-model.js";
|
|
15
|
+
import { DATE_FILTER_OPERATORS, NUMBER_FILTER_OPERATORS, TEXT_FILTER_OPERATORS, emptyFilterValue, isUnresolvedChoice, matchFilterPreset, orderFilterRange } from "../filter-model.js";
|
|
14
16
|
const DEFAULT_FILTER_EDITOR_LABELS = {
|
|
15
17
|
apply: "Apply",
|
|
16
18
|
clear: "Clear",
|
|
@@ -32,6 +34,10 @@ const DEFAULT_FILTER_EDITOR_LABELS = {
|
|
|
32
34
|
selected: "{count} selected",
|
|
33
35
|
remove: "Remove {label}",
|
|
34
36
|
presets: "Presets",
|
|
37
|
+
addTag: "Add a value",
|
|
38
|
+
addTagHint: "Enter or a comma adds it.",
|
|
39
|
+
date: "Date",
|
|
40
|
+
dateOperators: { on: "on", before: "before", after: "after", between: "between" },
|
|
35
41
|
operators: {
|
|
36
42
|
contains: "contains",
|
|
37
43
|
"not-contains": "does not contain",
|
|
@@ -53,10 +59,21 @@ function FilterEditor({ field, value: valueProp, onValueChange, onApply, onClear
|
|
|
53
59
|
...DEFAULT_FILTER_EDITOR_LABELS,
|
|
54
60
|
...provided,
|
|
55
61
|
...labelOverrides,
|
|
56
|
-
operators: { ...DEFAULT_FILTER_EDITOR_LABELS.operators, ...provided?.operators, ...labelOverrides?.operators }
|
|
62
|
+
operators: { ...DEFAULT_FILTER_EDITOR_LABELS.operators, ...provided?.operators, ...labelOverrides?.operators },
|
|
63
|
+
dateOperators: { ...DEFAULT_FILTER_EDITOR_LABELS.dateOperators, ...provided?.dateOperators, ...labelOverrides?.dateOperators }
|
|
57
64
|
};
|
|
58
65
|
const id = useId();
|
|
59
|
-
|
|
66
|
+
let value = valueProp?.kind === field.kind ? valueProp : emptyFilterValue(field.kind);
|
|
67
|
+
if (value.kind === "date" && field.dateOperators?.length && !field.dateOperators.includes(value.operator)) value = { ...value, operator: field.dateOperators[0] };
|
|
68
|
+
const pendingTag = useRef(() => void 0);
|
|
69
|
+
const apply = () => onApply(orderFilterRange((value.kind === "tags" ? pendingTag.current() : void 0) ?? value));
|
|
70
|
+
const onKeyDown = (event) => {
|
|
71
|
+
if (event.key !== "Enter" || event.defaultPrevented || event.nativeEvent.isComposing || event.keyCode === 229) return;
|
|
72
|
+
const target = event.target;
|
|
73
|
+
if (target.closest('button, a, textarea, [role="option"], [role="listbox"], [aria-expanded="true"]')) return;
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
apply();
|
|
76
|
+
};
|
|
60
77
|
let body = null;
|
|
61
78
|
switch (value.kind) {
|
|
62
79
|
case "enum":
|
|
@@ -65,13 +82,31 @@ function FilterEditor({ field, value: valueProp, onValueChange, onApply, onClear
|
|
|
65
82
|
case "reference":
|
|
66
83
|
body = /* @__PURE__ */ jsx(ReferenceBody, { field, value, onChange: onValueChange, labels, delay: searchDelay });
|
|
67
84
|
break;
|
|
85
|
+
case "tags":
|
|
86
|
+
body = /* @__PURE__ */ jsx(TagsBody, { value, onChange: onValueChange, labels, pending: pendingTag, id });
|
|
87
|
+
break;
|
|
88
|
+
case "date": {
|
|
89
|
+
const ops = field.dateOperators ?? DATE_FILTER_OPERATORS;
|
|
90
|
+
const words = labels.dateOperators ?? {};
|
|
91
|
+
const between = value.operator === "between";
|
|
92
|
+
body = /* @__PURE__ */ jsxs("div", { className: "uix-filter-editor__row", children: [
|
|
93
|
+
ops.length > 1 && /* @__PURE__ */ jsx(Select, { size: "sm", "aria-label": labels.operator, value: value.operator, onChange: (e) => onValueChange({ ...value, operator: e.currentTarget.value, ...e.currentTarget.value === "between" ? {} : { to: void 0 } }), children: ops.map((op) => /* @__PURE__ */ jsx("option", { value: op, children: words[op] ?? DEFAULT_FILTER_EDITOR_LABELS.dateOperators[op] }, op)) }),
|
|
94
|
+
/* @__PURE__ */ jsxs("label", { className: "uix-filter-editor__date", children: [
|
|
95
|
+
/* @__PURE__ */ jsx("span", { children: between ? labels.from : labels.date ?? DEFAULT_FILTER_EDITOR_LABELS.date }),
|
|
96
|
+
/* @__PURE__ */ jsx(Input, { type: "date", value: value.from ?? "", max: between ? value.to : void 0, onChange: (e) => onValueChange({ ...value, from: e.currentTarget.value || void 0 }), autoFocus: true })
|
|
97
|
+
] }),
|
|
98
|
+
between && /* @__PURE__ */ jsxs("label", { className: "uix-filter-editor__date", children: [
|
|
99
|
+
/* @__PURE__ */ jsx("span", { children: labels.to }),
|
|
100
|
+
/* @__PURE__ */ jsx(Input, { type: "date", value: value.to ?? "", min: value.from, onChange: (e) => onValueChange({ ...value, to: e.currentTarget.value || void 0 }) })
|
|
101
|
+
] })
|
|
102
|
+
] });
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
68
105
|
case "text": {
|
|
69
106
|
const ops = field.operators ?? TEXT_FILTER_OPERATORS;
|
|
70
107
|
body = /* @__PURE__ */ jsxs("div", { className: "uix-filter-editor__row", children: [
|
|
71
108
|
ops.length > 1 && /* @__PURE__ */ jsx(Select, { size: "sm", "aria-label": labels.operator, value: value.operator, onChange: (e) => onValueChange({ ...value, operator: e.currentTarget.value }), children: ops.map((op) => /* @__PURE__ */ jsx("option", { value: op, children: labels.operators[op] }, op)) }),
|
|
72
|
-
/* @__PURE__ */ jsx(Input, { "aria-label": labels.value, value: value.text, onChange: (e) => onValueChange({ ...value, text: e.currentTarget.value }),
|
|
73
|
-
if (e.key === "Enter") onApply();
|
|
74
|
-
}, autoFocus: true })
|
|
109
|
+
/* @__PURE__ */ jsx(Input, { "aria-label": labels.value, value: value.text, onChange: (e) => onValueChange({ ...value, text: e.currentTarget.value }), autoFocus: true })
|
|
75
110
|
] });
|
|
76
111
|
break;
|
|
77
112
|
}
|
|
@@ -111,12 +146,12 @@ function FilterEditor({ field, value: valueProp, onValueChange, onApply, onClear
|
|
|
111
146
|
break;
|
|
112
147
|
}
|
|
113
148
|
}
|
|
114
|
-
return /* @__PURE__ */ jsxs("div", { className: "uix-filter-popover uix-filter-editor", role: "group", "aria-labelledby": `${id}-label`, "data-kind": field.kind, children: [
|
|
149
|
+
return /* @__PURE__ */ jsxs("div", { className: "uix-filter-popover uix-filter-editor", role: "group", "aria-labelledby": `${id}-label`, "data-kind": field.kind, onKeyDown, children: [
|
|
115
150
|
/* @__PURE__ */ jsx("div", { id: `${id}-label`, className: "uix-filter-editor__label", children: field.label }),
|
|
116
|
-
body,
|
|
151
|
+
/* @__PURE__ */ jsx(Fragment2, { children: body }, `${field.kind}:${field.id}`),
|
|
117
152
|
/* @__PURE__ */ jsxs("div", { className: "uix-filter-popover__actions", children: [
|
|
118
153
|
/* @__PURE__ */ jsx(Button, { type: "button", size: "sm", onClick: onClear, children: labels.clear }),
|
|
119
|
-
/* @__PURE__ */ jsx(Button, { type: "button", size: "sm", variant: "primary", onClick:
|
|
154
|
+
/* @__PURE__ */ jsx(Button, { type: "button", size: "sm", variant: "primary", onClick: apply, children: labels.apply })
|
|
120
155
|
] })
|
|
121
156
|
] });
|
|
122
157
|
}
|
|
@@ -146,13 +181,18 @@ function ReferenceBody({ field, value, onChange, labels, delay }) {
|
|
|
146
181
|
const [query, setQuery] = useState("");
|
|
147
182
|
const [state, setState] = useState({ status: "idle", results: [] });
|
|
148
183
|
const [attempt, setAttempt] = useState(0);
|
|
184
|
+
const slow = useDelayedPending(state.status === "loading");
|
|
149
185
|
const latest = useRef(0);
|
|
186
|
+
const search = useRef(field.onSearch);
|
|
187
|
+
search.current = field.onSearch;
|
|
188
|
+
const resolve = useRef(field.resolveLabels);
|
|
189
|
+
resolve.current = field.resolveLabels;
|
|
150
190
|
useEffect(() => {
|
|
151
|
-
if (!
|
|
191
|
+
if (!search.current) return;
|
|
152
192
|
const run = ++latest.current;
|
|
153
193
|
const timer = window.setTimeout(() => {
|
|
154
194
|
setState((s) => ({ ...s, status: "loading" }));
|
|
155
|
-
|
|
195
|
+
search.current(query.trim()).then(
|
|
156
196
|
(results) => {
|
|
157
197
|
if (run === latest.current) setState({ status: "done", results });
|
|
158
198
|
},
|
|
@@ -162,22 +202,104 @@ function ReferenceBody({ field, value, onChange, labels, delay }) {
|
|
|
162
202
|
);
|
|
163
203
|
}, delay);
|
|
164
204
|
return () => window.clearTimeout(timer);
|
|
165
|
-
}, [query, attempt, field, delay]);
|
|
166
|
-
const
|
|
167
|
-
const
|
|
205
|
+
}, [query, attempt, field.id, delay]);
|
|
206
|
+
const [known, setKnown] = useState(/* @__PURE__ */ new Map());
|
|
207
|
+
const answered = useRef(/* @__PURE__ */ new Set());
|
|
208
|
+
const requests = useRef(/* @__PURE__ */ new Map());
|
|
209
|
+
const unresolved = value.values.filter((v) => isUnresolvedChoice(v) && !known.has(v.value) && !answered.current.has(v.value)).map((v) => v.value);
|
|
210
|
+
const unresolvedKey = unresolved.join("\0");
|
|
211
|
+
useEffect(() => {
|
|
212
|
+
if (!unresolvedKey || !resolve.current) return;
|
|
213
|
+
let live = true;
|
|
214
|
+
const ids = unresolvedKey.split("\0");
|
|
215
|
+
let request = requests.current.get(unresolvedKey);
|
|
216
|
+
if (!request) {
|
|
217
|
+
request = resolve.current(ids);
|
|
218
|
+
requests.current.set(unresolvedKey, request);
|
|
219
|
+
}
|
|
220
|
+
const settle = (choices) => {
|
|
221
|
+
for (const id of ids) answered.current.add(id);
|
|
222
|
+
if (live) setKnown((prev) => new Map([...prev, ...choices.map((c) => [c.value, c.label])]));
|
|
223
|
+
};
|
|
224
|
+
request.then(settle, () => settle([]));
|
|
225
|
+
return () => {
|
|
226
|
+
live = false;
|
|
227
|
+
};
|
|
228
|
+
}, [unresolvedKey, field.id]);
|
|
229
|
+
const labelled = (v) => isUnresolvedChoice(v) && known.has(v.value) ? { value: v.value, label: known.get(v.value) } : v;
|
|
230
|
+
const values = value.values.map(labelled);
|
|
231
|
+
const chosen = new Map(values.map((v) => [v.value, v]));
|
|
232
|
+
const toggle = (choice, on) => onChange({ kind: "reference", values: on ? [...values, choice] : values.filter((v) => v.value !== choice.value) });
|
|
233
|
+
const showResults = state.status === "done" || state.status === "loading" && state.results.length > 0;
|
|
168
234
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
169
|
-
|
|
235
|
+
values.length > 0 && /* @__PURE__ */ jsx("div", { className: "uix-chip-group", role: "group", "aria-label": fillLabel(labels.selected, { count: values.length }), children: values.map((v) => /* @__PURE__ */ jsx(Chip, { removeLabel: fillLabel(labels.remove, { label: v.label }), onRemove: () => toggle(v, false), children: v.label }, v.value)) }),
|
|
170
236
|
/* @__PURE__ */ jsx(Input, { type: "search", size: "sm", "aria-label": labels.search, placeholder: labels.search, value: query, onChange: (e) => setQuery(e.currentTarget.value), autoFocus: true }),
|
|
171
237
|
/* @__PURE__ */ jsxs("div", { className: "uix-filter-editor__list", "aria-busy": state.status === "loading" || void 0, children: [
|
|
172
|
-
state.status === "loading" && /* @__PURE__ */ jsx("p", { className: "uix-filter-editor__note", role: "status", children: labels.searching }),
|
|
173
238
|
state.status === "error" && /* @__PURE__ */ jsxs("p", { className: "uix-filter-editor__note", role: "alert", children: [
|
|
174
239
|
labels.searchFailed,
|
|
175
240
|
" ",
|
|
176
241
|
/* @__PURE__ */ jsx(Button, { type: "button", variant: "link", size: "sm", onClick: () => setAttempt((n) => n + 1), children: labels.retry })
|
|
177
242
|
] }),
|
|
178
243
|
state.status === "done" && state.results.length === 0 && /* @__PURE__ */ jsx("p", { className: "uix-filter-editor__note", children: labels.noMatches }),
|
|
179
|
-
|
|
180
|
-
] })
|
|
244
|
+
showResults && state.results.map((r) => /* @__PURE__ */ jsx(Checkbox, { label: r.label, checked: chosen.has(r.value), onChange: (e) => toggle(r, e.currentTarget.checked) }, r.value))
|
|
245
|
+
] }),
|
|
246
|
+
/* @__PURE__ */ jsx("p", { className: cx("uix-filter-editor__note", "uix-filter-editor__searching", !slow && "uix-visually-hidden"), role: "status", "data-shown": slow || void 0, children: slow ? labels.searching : "" })
|
|
247
|
+
] });
|
|
248
|
+
}
|
|
249
|
+
const splitTags = (text) => text.split(/[,\n]/).map((t) => t.trim()).filter(Boolean);
|
|
250
|
+
function TagsBody({ value, onChange, labels, pending, id }) {
|
|
251
|
+
const [draft, setDraft] = useState("");
|
|
252
|
+
const field = useRef(null);
|
|
253
|
+
const withTags = (tags) => ({ kind: "tags", values: [...value.values, ...tags.filter((t, i) => !value.values.includes(t) && tags.indexOf(t) === i)] });
|
|
254
|
+
pending.current = () => splitTags(draft).length ? withTags(splitTags(draft)) : void 0;
|
|
255
|
+
const commit = (text) => {
|
|
256
|
+
const tags = splitTags(text);
|
|
257
|
+
if (tags.length) onChange(withTags(tags));
|
|
258
|
+
setDraft("");
|
|
259
|
+
};
|
|
260
|
+
const remove = (tag) => {
|
|
261
|
+
onChange({ kind: "tags", values: value.values.filter((t) => t !== tag) });
|
|
262
|
+
field.current?.focus();
|
|
263
|
+
};
|
|
264
|
+
const onKeyDown = (event) => {
|
|
265
|
+
if (event.nativeEvent.isComposing || event.keyCode === 229) return;
|
|
266
|
+
if ((event.key === "Enter" || event.key === ",") && draft.trim()) {
|
|
267
|
+
event.preventDefault();
|
|
268
|
+
commit(draft);
|
|
269
|
+
} else if (event.key === ",") {
|
|
270
|
+
event.preventDefault();
|
|
271
|
+
} else if (event.key === "Backspace" && draft === "" && value.values.length > 0) {
|
|
272
|
+
onChange({ kind: "tags", values: value.values.slice(0, -1) });
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
const onPaste = (event) => {
|
|
276
|
+
const text = event.clipboardData.getData("text");
|
|
277
|
+
if (!/[,\n]/.test(text)) return;
|
|
278
|
+
event.preventDefault();
|
|
279
|
+
commit(`${draft}${text}`);
|
|
280
|
+
};
|
|
281
|
+
return /* @__PURE__ */ jsxs("div", { className: "uix-taginput uix-filter-editor__tags", children: [
|
|
282
|
+
value.values.map((tag) => /* @__PURE__ */ jsxs("span", { className: "uix-tag", children: [
|
|
283
|
+
tag,
|
|
284
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "uix-tag__remove", "aria-label": fillLabel(labels.remove, { label: tag }), onClick: () => remove(tag), children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) })
|
|
285
|
+
] }, tag)),
|
|
286
|
+
/* @__PURE__ */ jsx(
|
|
287
|
+
"input",
|
|
288
|
+
{
|
|
289
|
+
ref: field,
|
|
290
|
+
className: "uix-taginput__field",
|
|
291
|
+
"aria-label": labels.addTag ?? DEFAULT_FILTER_EDITOR_LABELS.addTag,
|
|
292
|
+
"aria-describedby": `${id}-tags-hint`,
|
|
293
|
+
placeholder: labels.addTag ?? DEFAULT_FILTER_EDITOR_LABELS.addTag,
|
|
294
|
+
value: draft,
|
|
295
|
+
enterKeyHint: "enter",
|
|
296
|
+
onChange: (e) => setDraft(e.currentTarget.value),
|
|
297
|
+
onKeyDown,
|
|
298
|
+
onPaste,
|
|
299
|
+
autoFocus: true
|
|
300
|
+
}
|
|
301
|
+
),
|
|
302
|
+
/* @__PURE__ */ jsx("span", { id: `${id}-tags-hint`, className: "uix-visually-hidden", children: labels.addTagHint ?? DEFAULT_FILTER_EDITOR_LABELS.addTagHint })
|
|
181
303
|
] });
|
|
182
304
|
}
|
|
183
305
|
export {
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, HTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A heading (or any element) that takes focus once, when it mounts — so a page that replaces
|
|
6
|
+
* a form with its outcome (SuccessState) reads the outcome first. `tabIndex={-1}`: focusable
|
|
7
|
+
* by script, not a tab stop. The client half of server-renderable states.
|
|
8
|
+
*/
|
|
9
|
+
declare function FocusOnMount({ as, enabled, children, ...props }: {
|
|
10
|
+
as: keyof HTMLElementTagNameMap;
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
children?: ReactNode;
|
|
13
|
+
} & HTMLAttributes<HTMLElement>): react.DetailedReactHTMLElement<{
|
|
14
|
+
ref: react.RefObject<HTMLElement>;
|
|
15
|
+
tabIndex: number;
|
|
16
|
+
defaultChecked?: boolean | undefined;
|
|
17
|
+
defaultValue?: string | number | readonly string[] | undefined;
|
|
18
|
+
suppressContentEditableWarning?: boolean | undefined;
|
|
19
|
+
suppressHydrationWarning?: boolean | undefined;
|
|
20
|
+
accessKey?: string | undefined;
|
|
21
|
+
autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {});
|
|
22
|
+
autoFocus?: boolean | undefined;
|
|
23
|
+
className?: string | undefined;
|
|
24
|
+
contentEditable?: (boolean | "false" | "true") | "inherit" | "plaintext-only" | undefined;
|
|
25
|
+
contextMenu?: string | undefined;
|
|
26
|
+
dir?: string | undefined;
|
|
27
|
+
draggable?: (boolean | "false" | "true") | undefined;
|
|
28
|
+
enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined;
|
|
29
|
+
hidden?: boolean | undefined;
|
|
30
|
+
id?: string | undefined;
|
|
31
|
+
lang?: string | undefined;
|
|
32
|
+
nonce?: string | undefined;
|
|
33
|
+
slot?: string | undefined;
|
|
34
|
+
spellCheck?: (boolean | "false" | "true") | undefined;
|
|
35
|
+
style?: react.CSSProperties | undefined;
|
|
36
|
+
title?: string | undefined;
|
|
37
|
+
translate?: "yes" | "no" | undefined;
|
|
38
|
+
radioGroup?: string | undefined;
|
|
39
|
+
role?: react.AriaRole | undefined;
|
|
40
|
+
about?: string | undefined;
|
|
41
|
+
content?: string | undefined;
|
|
42
|
+
datatype?: string | undefined;
|
|
43
|
+
inlist?: any;
|
|
44
|
+
prefix?: string | undefined;
|
|
45
|
+
property?: string | undefined;
|
|
46
|
+
rel?: string | undefined;
|
|
47
|
+
resource?: string | undefined;
|
|
48
|
+
rev?: string | undefined;
|
|
49
|
+
typeof?: string | undefined;
|
|
50
|
+
vocab?: string | undefined;
|
|
51
|
+
autoCorrect?: string | undefined;
|
|
52
|
+
autoSave?: string | undefined;
|
|
53
|
+
color?: string | undefined;
|
|
54
|
+
itemProp?: string | undefined;
|
|
55
|
+
itemScope?: boolean | undefined;
|
|
56
|
+
itemType?: string | undefined;
|
|
57
|
+
itemID?: string | undefined;
|
|
58
|
+
itemRef?: string | undefined;
|
|
59
|
+
results?: number | undefined;
|
|
60
|
+
security?: string | undefined;
|
|
61
|
+
unselectable?: "on" | "off" | undefined;
|
|
62
|
+
inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined;
|
|
63
|
+
is?: string | undefined;
|
|
64
|
+
exportparts?: string | undefined;
|
|
65
|
+
part?: string | undefined;
|
|
66
|
+
"aria-activedescendant"?: string | undefined;
|
|
67
|
+
"aria-atomic"?: (boolean | "false" | "true") | undefined;
|
|
68
|
+
"aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined;
|
|
69
|
+
"aria-braillelabel"?: string | undefined;
|
|
70
|
+
"aria-brailleroledescription"?: string | undefined;
|
|
71
|
+
"aria-busy"?: (boolean | "false" | "true") | undefined;
|
|
72
|
+
"aria-checked"?: boolean | "false" | "mixed" | "true" | undefined;
|
|
73
|
+
"aria-colcount"?: number | undefined;
|
|
74
|
+
"aria-colindex"?: number | undefined;
|
|
75
|
+
"aria-colindextext"?: string | undefined;
|
|
76
|
+
"aria-colspan"?: number | undefined;
|
|
77
|
+
"aria-controls"?: string | undefined;
|
|
78
|
+
"aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined;
|
|
79
|
+
"aria-describedby"?: string | undefined;
|
|
80
|
+
"aria-description"?: string | undefined;
|
|
81
|
+
"aria-details"?: string | undefined;
|
|
82
|
+
"aria-disabled"?: (boolean | "false" | "true") | undefined;
|
|
83
|
+
"aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined;
|
|
84
|
+
"aria-errormessage"?: string | undefined;
|
|
85
|
+
"aria-expanded"?: (boolean | "false" | "true") | undefined;
|
|
86
|
+
"aria-flowto"?: string | undefined;
|
|
87
|
+
"aria-grabbed"?: (boolean | "false" | "true") | undefined;
|
|
88
|
+
"aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined;
|
|
89
|
+
"aria-hidden"?: (boolean | "false" | "true") | undefined;
|
|
90
|
+
"aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined;
|
|
91
|
+
"aria-keyshortcuts"?: string | undefined;
|
|
92
|
+
"aria-label"?: string | undefined;
|
|
93
|
+
"aria-labelledby"?: string | undefined;
|
|
94
|
+
"aria-level"?: number | undefined;
|
|
95
|
+
"aria-live"?: "off" | "assertive" | "polite" | undefined;
|
|
96
|
+
"aria-modal"?: (boolean | "false" | "true") | undefined;
|
|
97
|
+
"aria-multiline"?: (boolean | "false" | "true") | undefined;
|
|
98
|
+
"aria-multiselectable"?: (boolean | "false" | "true") | undefined;
|
|
99
|
+
"aria-orientation"?: "horizontal" | "vertical" | undefined;
|
|
100
|
+
"aria-owns"?: string | undefined;
|
|
101
|
+
"aria-placeholder"?: string | undefined;
|
|
102
|
+
"aria-posinset"?: number | undefined;
|
|
103
|
+
"aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined;
|
|
104
|
+
"aria-readonly"?: (boolean | "false" | "true") | undefined;
|
|
105
|
+
"aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined;
|
|
106
|
+
"aria-required"?: (boolean | "false" | "true") | undefined;
|
|
107
|
+
"aria-roledescription"?: string | undefined;
|
|
108
|
+
"aria-rowcount"?: number | undefined;
|
|
109
|
+
"aria-rowindex"?: number | undefined;
|
|
110
|
+
"aria-rowindextext"?: string | undefined;
|
|
111
|
+
"aria-rowspan"?: number | undefined;
|
|
112
|
+
"aria-selected"?: (boolean | "false" | "true") | undefined;
|
|
113
|
+
"aria-setsize"?: number | undefined;
|
|
114
|
+
"aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined;
|
|
115
|
+
"aria-valuemax"?: number | undefined;
|
|
116
|
+
"aria-valuemin"?: number | undefined;
|
|
117
|
+
"aria-valuenow"?: number | undefined;
|
|
118
|
+
"aria-valuetext"?: string | undefined;
|
|
119
|
+
dangerouslySetInnerHTML?: {
|
|
120
|
+
__html: string | TrustedHTML;
|
|
121
|
+
} | undefined;
|
|
122
|
+
onCopy?: react.ClipboardEventHandler<HTMLElement> | undefined;
|
|
123
|
+
onCopyCapture?: react.ClipboardEventHandler<HTMLElement> | undefined;
|
|
124
|
+
onCut?: react.ClipboardEventHandler<HTMLElement> | undefined;
|
|
125
|
+
onCutCapture?: react.ClipboardEventHandler<HTMLElement> | undefined;
|
|
126
|
+
onPaste?: react.ClipboardEventHandler<HTMLElement> | undefined;
|
|
127
|
+
onPasteCapture?: react.ClipboardEventHandler<HTMLElement> | undefined;
|
|
128
|
+
onCompositionEnd?: react.CompositionEventHandler<HTMLElement> | undefined;
|
|
129
|
+
onCompositionEndCapture?: react.CompositionEventHandler<HTMLElement> | undefined;
|
|
130
|
+
onCompositionStart?: react.CompositionEventHandler<HTMLElement> | undefined;
|
|
131
|
+
onCompositionStartCapture?: react.CompositionEventHandler<HTMLElement> | undefined;
|
|
132
|
+
onCompositionUpdate?: react.CompositionEventHandler<HTMLElement> | undefined;
|
|
133
|
+
onCompositionUpdateCapture?: react.CompositionEventHandler<HTMLElement> | undefined;
|
|
134
|
+
onFocus?: react.FocusEventHandler<HTMLElement> | undefined;
|
|
135
|
+
onFocusCapture?: react.FocusEventHandler<HTMLElement> | undefined;
|
|
136
|
+
onBlur?: react.FocusEventHandler<HTMLElement> | undefined;
|
|
137
|
+
onBlurCapture?: react.FocusEventHandler<HTMLElement> | undefined;
|
|
138
|
+
onChange?: react.FormEventHandler<HTMLElement> | undefined;
|
|
139
|
+
onChangeCapture?: react.FormEventHandler<HTMLElement> | undefined;
|
|
140
|
+
onBeforeInput?: react.InputEventHandler<HTMLElement> | undefined;
|
|
141
|
+
onBeforeInputCapture?: react.FormEventHandler<HTMLElement> | undefined;
|
|
142
|
+
onInput?: react.FormEventHandler<HTMLElement> | undefined;
|
|
143
|
+
onInputCapture?: react.FormEventHandler<HTMLElement> | undefined;
|
|
144
|
+
onReset?: react.FormEventHandler<HTMLElement> | undefined;
|
|
145
|
+
onResetCapture?: react.FormEventHandler<HTMLElement> | undefined;
|
|
146
|
+
onSubmit?: react.FormEventHandler<HTMLElement> | undefined;
|
|
147
|
+
onSubmitCapture?: react.FormEventHandler<HTMLElement> | undefined;
|
|
148
|
+
onInvalid?: react.FormEventHandler<HTMLElement> | undefined;
|
|
149
|
+
onInvalidCapture?: react.FormEventHandler<HTMLElement> | undefined;
|
|
150
|
+
onLoad?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
151
|
+
onLoadCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
152
|
+
onError?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
153
|
+
onErrorCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
154
|
+
onKeyDown?: react.KeyboardEventHandler<HTMLElement> | undefined;
|
|
155
|
+
onKeyDownCapture?: react.KeyboardEventHandler<HTMLElement> | undefined;
|
|
156
|
+
onKeyPress?: react.KeyboardEventHandler<HTMLElement> | undefined;
|
|
157
|
+
onKeyPressCapture?: react.KeyboardEventHandler<HTMLElement> | undefined;
|
|
158
|
+
onKeyUp?: react.KeyboardEventHandler<HTMLElement> | undefined;
|
|
159
|
+
onKeyUpCapture?: react.KeyboardEventHandler<HTMLElement> | undefined;
|
|
160
|
+
onAbort?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
161
|
+
onAbortCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
162
|
+
onCanPlay?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
163
|
+
onCanPlayCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
164
|
+
onCanPlayThrough?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
165
|
+
onCanPlayThroughCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
166
|
+
onDurationChange?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
167
|
+
onDurationChangeCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
168
|
+
onEmptied?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
169
|
+
onEmptiedCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
170
|
+
onEncrypted?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
171
|
+
onEncryptedCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
172
|
+
onEnded?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
173
|
+
onEndedCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
174
|
+
onLoadedData?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
175
|
+
onLoadedDataCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
176
|
+
onLoadedMetadata?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
177
|
+
onLoadedMetadataCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
178
|
+
onLoadStart?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
179
|
+
onLoadStartCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
180
|
+
onPause?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
181
|
+
onPauseCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
182
|
+
onPlay?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
183
|
+
onPlayCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
184
|
+
onPlaying?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
185
|
+
onPlayingCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
186
|
+
onProgress?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
187
|
+
onProgressCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
188
|
+
onRateChange?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
189
|
+
onRateChangeCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
190
|
+
onSeeked?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
191
|
+
onSeekedCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
192
|
+
onSeeking?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
193
|
+
onSeekingCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
194
|
+
onStalled?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
195
|
+
onStalledCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
196
|
+
onSuspend?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
197
|
+
onSuspendCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
198
|
+
onTimeUpdate?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
199
|
+
onTimeUpdateCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
200
|
+
onVolumeChange?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
201
|
+
onVolumeChangeCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
202
|
+
onWaiting?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
203
|
+
onWaitingCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
204
|
+
onAuxClick?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
205
|
+
onAuxClickCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
206
|
+
onClick?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
207
|
+
onClickCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
208
|
+
onContextMenu?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
209
|
+
onContextMenuCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
210
|
+
onDoubleClick?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
211
|
+
onDoubleClickCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
212
|
+
onDrag?: react.DragEventHandler<HTMLElement> | undefined;
|
|
213
|
+
onDragCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
214
|
+
onDragEnd?: react.DragEventHandler<HTMLElement> | undefined;
|
|
215
|
+
onDragEndCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
216
|
+
onDragEnter?: react.DragEventHandler<HTMLElement> | undefined;
|
|
217
|
+
onDragEnterCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
218
|
+
onDragExit?: react.DragEventHandler<HTMLElement> | undefined;
|
|
219
|
+
onDragExitCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
220
|
+
onDragLeave?: react.DragEventHandler<HTMLElement> | undefined;
|
|
221
|
+
onDragLeaveCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
222
|
+
onDragOver?: react.DragEventHandler<HTMLElement> | undefined;
|
|
223
|
+
onDragOverCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
224
|
+
onDragStart?: react.DragEventHandler<HTMLElement> | undefined;
|
|
225
|
+
onDragStartCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
226
|
+
onDrop?: react.DragEventHandler<HTMLElement> | undefined;
|
|
227
|
+
onDropCapture?: react.DragEventHandler<HTMLElement> | undefined;
|
|
228
|
+
onMouseDown?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
229
|
+
onMouseDownCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
230
|
+
onMouseEnter?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
231
|
+
onMouseLeave?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
232
|
+
onMouseMove?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
233
|
+
onMouseMoveCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
234
|
+
onMouseOut?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
235
|
+
onMouseOutCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
236
|
+
onMouseOver?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
237
|
+
onMouseOverCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
238
|
+
onMouseUp?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
239
|
+
onMouseUpCapture?: react.MouseEventHandler<HTMLElement> | undefined;
|
|
240
|
+
onSelect?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
241
|
+
onSelectCapture?: react.ReactEventHandler<HTMLElement> | undefined;
|
|
242
|
+
onTouchCancel?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
243
|
+
onTouchCancelCapture?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
244
|
+
onTouchEnd?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
245
|
+
onTouchEndCapture?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
246
|
+
onTouchMove?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
247
|
+
onTouchMoveCapture?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
248
|
+
onTouchStart?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
249
|
+
onTouchStartCapture?: react.TouchEventHandler<HTMLElement> | undefined;
|
|
250
|
+
onPointerDown?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
251
|
+
onPointerDownCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
252
|
+
onPointerMove?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
253
|
+
onPointerMoveCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
254
|
+
onPointerUp?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
255
|
+
onPointerUpCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
256
|
+
onPointerCancel?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
257
|
+
onPointerCancelCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
258
|
+
onPointerEnter?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
259
|
+
onPointerLeave?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
260
|
+
onPointerOver?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
261
|
+
onPointerOverCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
262
|
+
onPointerOut?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
263
|
+
onPointerOutCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
264
|
+
onGotPointerCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
265
|
+
onGotPointerCaptureCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
266
|
+
onLostPointerCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
267
|
+
onLostPointerCaptureCapture?: react.PointerEventHandler<HTMLElement> | undefined;
|
|
268
|
+
onScroll?: react.UIEventHandler<HTMLElement> | undefined;
|
|
269
|
+
onScrollCapture?: react.UIEventHandler<HTMLElement> | undefined;
|
|
270
|
+
onWheel?: react.WheelEventHandler<HTMLElement> | undefined;
|
|
271
|
+
onWheelCapture?: react.WheelEventHandler<HTMLElement> | undefined;
|
|
272
|
+
onAnimationStart?: react.AnimationEventHandler<HTMLElement> | undefined;
|
|
273
|
+
onAnimationStartCapture?: react.AnimationEventHandler<HTMLElement> | undefined;
|
|
274
|
+
onAnimationEnd?: react.AnimationEventHandler<HTMLElement> | undefined;
|
|
275
|
+
onAnimationEndCapture?: react.AnimationEventHandler<HTMLElement> | undefined;
|
|
276
|
+
onAnimationIteration?: react.AnimationEventHandler<HTMLElement> | undefined;
|
|
277
|
+
onAnimationIterationCapture?: react.AnimationEventHandler<HTMLElement> | undefined;
|
|
278
|
+
onTransitionEnd?: react.TransitionEventHandler<HTMLElement> | undefined;
|
|
279
|
+
onTransitionEndCapture?: react.TransitionEventHandler<HTMLElement> | undefined;
|
|
280
|
+
}, HTMLElement>;
|
|
281
|
+
|
|
282
|
+
export { FocusOnMount };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createElement, useEffect, useRef } from "react";
|
|
3
|
+
function FocusOnMount({ as, enabled = true, children, ...props }) {
|
|
4
|
+
const ref = useRef(null);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
if (enabled) ref.current?.focus({ preventScroll: false });
|
|
7
|
+
}, [enabled]);
|
|
8
|
+
return createElement(as, { ...props, ref, tabIndex: -1 }, children);
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
FocusOnMount
|
|
12
|
+
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useEffect, useId, useRef, useState } from "react";
|
|
3
|
+
import { useEffect, useId, useLayoutEffect, useRef, useState } from "react";
|
|
4
4
|
import { cx } from "../cx.js";
|
|
5
5
|
import { helpParagraphs } from "../info-tip-model.js";
|
|
6
6
|
import { Popover } from "./Popover.js";
|
|
7
7
|
const OPEN_DELAY = 300;
|
|
8
8
|
const CLOSE_DELAY = 100;
|
|
9
|
+
const useIsomorphicLayoutEffect = typeof document !== "undefined" ? useLayoutEffect : useEffect;
|
|
9
10
|
const QuestionMark = () => /* @__PURE__ */ jsx("svg", { viewBox: "262 -840 436 760", fill: "currentColor", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx("path", { d: "M424-320q0-81 14.5-116.5T500-514q41-36 62.5-62.5T584-637q0-41-27.5-68T480-732q-51 0-77.5 31T365-638l-103-44q21-64 77-111t141-47q105 0 161.5 58.5T698-641q0 50-21.5 85.5T609-475q-49 47-59.5 71.5T539-320H424Zm56 240q-33 0-56.5-23.5T400-160q0-33 23.5-56.5T480-240q33 0 56.5 23.5T560-160q0 33-23.5 56.5T480-80Z" }) });
|
|
10
11
|
const isShown = (el) => {
|
|
11
12
|
try {
|
|
@@ -93,18 +94,21 @@ function InfoTipControl({
|
|
|
93
94
|
refocusing.current = false;
|
|
94
95
|
}
|
|
95
96
|
};
|
|
96
|
-
|
|
97
|
-
if (!open) return;
|
|
97
|
+
useIsomorphicLayoutEffect(() => {
|
|
98
|
+
if (!open) return void 0;
|
|
98
99
|
const onKey = (e) => {
|
|
99
|
-
if (e.key
|
|
100
|
+
if (e.key !== "Escape" || !openRef.current) return;
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
e.stopPropagation();
|
|
103
|
+
escape();
|
|
100
104
|
};
|
|
101
105
|
const onPointer = (e) => {
|
|
102
106
|
if (!wrapRef.current?.contains(e.target)) hide();
|
|
103
107
|
};
|
|
104
|
-
document.addEventListener("keydown", onKey);
|
|
108
|
+
document.addEventListener("keydown", onKey, true);
|
|
105
109
|
document.addEventListener("pointerdown", onPointer, true);
|
|
106
110
|
return () => {
|
|
107
|
-
document.removeEventListener("keydown", onKey);
|
|
111
|
+
document.removeEventListener("keydown", onKey, true);
|
|
108
112
|
document.removeEventListener("pointerdown", onPointer, true);
|
|
109
113
|
};
|
|
110
114
|
}, [open]);
|
|
@@ -148,13 +152,8 @@ function InfoTipControl({
|
|
|
148
152
|
pinned.current = true;
|
|
149
153
|
}
|
|
150
154
|
},
|
|
151
|
-
onKeyDown: (
|
|
155
|
+
onKeyDown: () => {
|
|
152
156
|
pressing.current = false;
|
|
153
|
-
if (e.key === "Escape" && openRef.current) {
|
|
154
|
-
e.preventDefault();
|
|
155
|
-
e.stopPropagation();
|
|
156
|
-
hide();
|
|
157
|
-
}
|
|
158
157
|
},
|
|
159
158
|
children: /* @__PURE__ */ jsx(QuestionMark, {})
|
|
160
159
|
}
|