@astryxdesign/core 0.7.7-canary.f9ac85f → 0.7.7
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/CHANGELOG.md +104 -0
- package/dist/AppShell/useCloseMobileDrawerOnActivate.d.ts +13 -0
- package/dist/AppShell/useCloseMobileDrawerOnActivate.d.ts.map +1 -0
- package/dist/AppShell/useCloseMobileDrawerOnActivate.js +45 -0
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +79 -9
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +1 -1
- package/dist/BottomSheet/bottomSheetStack.d.ts.map +1 -1
- package/dist/BottomSheet/bottomSheetStack.js +5 -4
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +2 -1
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +7 -3
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +30 -2
- package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxList.js +7 -1
- package/dist/CheckboxList/CheckboxListContext.d.ts +6 -0
- package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +10 -2
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +5 -2
- package/dist/DateInput/MonthScroller.d.ts.map +1 -1
- package/dist/DateInput/MonthScroller.js +13 -27
- package/dist/DateInput/Wheel.d.ts.map +1 -1
- package/dist/DateInput/Wheel.js +22 -41
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +5 -2
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +4 -3
- package/dist/Drawer/Drawer.js +0 -1
- package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
- package/dist/Drawer/useDrawerDialogPresence.js +5 -1
- package/dist/Field/PanelSearchInput.d.ts +9 -1
- package/dist/Field/PanelSearchInput.d.ts.map +1 -1
- package/dist/Field/PanelSearchInput.js +3 -1
- package/dist/InfoTip/InfoTip.d.ts +2 -2
- package/dist/InfoTip/InfoTip.js +4 -4
- package/dist/Layer/layerAnimations.stylex.d.ts +7 -8
- package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
- package/dist/Layer/layerAnimations.stylex.js +25 -20
- package/dist/Layer/usePressPin.d.ts +3 -5
- package/dist/Layer/usePressPin.d.ts.map +1 -1
- package/dist/Layer/usePressPin.js +4 -6
- package/dist/MobileNav/MobileNav.js +0 -1
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +2 -4
- package/dist/Outline/Outline.d.ts +2 -4
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +4 -52
- package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
- package/dist/Outline/useOutlineFromMarkdown.js +1 -0
- package/dist/Outline/useScrollSpy.js +3 -3
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +134 -179
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +5 -0
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +118 -260
- package/dist/Resizable/resizeGesture.d.ts +91 -0
- package/dist/Resizable/resizeGesture.d.ts.map +1 -0
- package/dist/Resizable/resizeGesture.js +251 -0
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +3 -9
- package/dist/Token/Token.d.ts +2 -2
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +12 -4
- package/dist/Token/TokenNamingContext.d.ts +14 -0
- package/dist/Token/TokenNamingContext.d.ts.map +1 -0
- package/dist/Token/TokenNamingContext.js +23 -0
- package/dist/Tokenizer/Tokenizer.d.ts +46 -59
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +35 -58
- package/dist/Tokenizer/TokenizerBottomSheet.d.ts +25 -28
- package/dist/Tokenizer/TokenizerBottomSheet.d.ts.map +1 -1
- package/dist/Tokenizer/TokenizerBottomSheet.js +157 -54
- package/dist/Tokenizer/TokenizerItemRemovableContext.d.ts.map +1 -1
- package/dist/Tokenizer/TokenizerItemRemovableContext.js +5 -3
- package/dist/Tooltip/Tooltip.d.ts +25 -30
- package/dist/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip/Tooltip.js +24 -5
- package/dist/Tooltip/index.d.ts +1 -1
- package/dist/Tooltip/index.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.d.ts +28 -29
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +20 -8
- package/dist/TopNav/TopNavItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavItem.js +4 -7
- package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuItem.js +4 -7
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +4 -7
- package/dist/astryx.css +5 -5
- package/dist/gestures/GestureHost.d.ts +27 -1
- package/dist/gestures/GestureHost.d.ts.map +1 -1
- package/dist/gestures/GestureHost.js +90 -8
- package/dist/hooks/useHighlightedOptionScroll.d.ts +11 -1
- package/dist/hooks/useHighlightedOptionScroll.d.ts.map +1 -1
- package/dist/hooks/useHighlightedOptionScroll.js +103 -5
- package/dist/hooks/useMenuPress.d.ts.map +1 -1
- package/dist/hooks/useMenuPress.js +4 -2
- package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.d.ts.map +1 -1
- package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.js +1 -0
- package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.d.ts.map +1 -1
- package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.js +7 -1
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +1 -0
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +1 -0
- package/dist/internal/SheetConfirmation.d.ts +11 -0
- package/dist/internal/SheetConfirmation.d.ts.map +1 -0
- package/dist/internal/SheetConfirmation.js +92 -0
- package/dist/internal/sheetDraft.d.ts +35 -0
- package/dist/internal/sheetDraft.d.ts.map +1 -0
- package/dist/internal/sheetDraft.js +65 -0
- package/dist/internal/touch-sheet.d.ts +21 -0
- package/dist/internal/touch-sheet.d.ts.map +1 -0
- package/dist/internal/touch-sheet.js +19 -0
- package/dist/internal/useDismissSearchOnTouchDrag.d.ts +24 -0
- package/dist/internal/useDismissSearchOnTouchDrag.d.ts.map +1 -0
- package/dist/internal/useDismissSearchOnTouchDrag.js +56 -0
- package/dist/motion/reducedMotion.d.ts +24 -0
- package/dist/motion/reducedMotion.d.ts.map +1 -1
- package/dist/motion/reducedMotion.js +78 -1
- package/dist/utils/clickGuard.d.ts +8 -1
- package/dist/utils/clickGuard.d.ts.map +1 -1
- package/dist/utils/clickGuard.js +24 -1
- package/locales/en.json +4 -0
- package/locales/pseudo.json +3 -0
- package/package.json +9 -9
- package/src/AppShell/useCloseMobileDrawerOnActivate.ts +52 -0
- package/src/BottomSheet/BottomSheet.tsx +95 -10
- package/src/BottomSheet/BottomSheetPanel.tsx +7 -2
- package/src/BottomSheet/bottomSheetStack.ts +8 -4
- package/src/Breadcrumbs/BreadcrumbItem.tsx +13 -3
- package/src/Button/Button.tsx +37 -1
- package/src/CheckboxList/CheckboxList.doc.mjs +4 -2
- package/src/CheckboxList/CheckboxList.tsx +6 -0
- package/src/CheckboxList/CheckboxListContext.tsx +6 -0
- package/src/CheckboxList/CheckboxListItem.tsx +11 -2
- package/src/DateInput/DateInput.tsx +8 -2
- package/src/DateInput/MonthScroller.tsx +18 -22
- package/src/DateInput/Wheel.tsx +30 -32
- package/src/DateTimeInput/DateTimeInput.tsx +8 -2
- package/src/Dialog/Dialog.tsx +19 -4
- package/src/Drawer/Drawer.tsx +1 -1
- package/src/Drawer/useDrawerDialogPresence.ts +5 -1
- package/src/Field/PanelSearchInput.tsx +11 -0
- package/src/InfoTip/InfoTip.doc.mjs +3 -3
- package/src/InfoTip/InfoTip.tsx +5 -5
- package/src/Layer/layerAnimations.stylex.ts +24 -16
- package/src/Layer/usePressPin.ts +5 -11
- package/src/MobileNav/MobileNav.tsx +1 -1
- package/src/MultiSelector/hooks.ts +2 -4
- package/src/Outline/Outline.doc.mjs +177 -51
- package/src/Outline/Outline.tsx +5 -57
- package/src/Outline/useOutlineFromMarkdown.doc.mjs +157 -0
- package/src/Outline/useOutlineFromMarkdown.ts +1 -0
- package/src/Outline/useScrollSpy.ts +3 -3
- package/src/PowerSearch/PowerSearch.doc.mjs +3 -3
- package/src/PowerSearch/PowerSearch.tsx +196 -183
- package/src/RadioList/RadioList.doc.mjs +4 -2
- package/src/RadioList/RadioList.tsx +4 -0
- package/src/Resizable/ResizeHandle.tsx +133 -328
- package/src/Resizable/resizeGesture.ts +368 -0
- package/src/SideNav/SideNavItem.tsx +3 -7
- package/src/Token/Token.tsx +13 -4
- package/src/Token/TokenNamingContext.ts +28 -0
- package/src/Tokenizer/Tokenizer.doc.mjs +16 -0
- package/src/Tokenizer/Tokenizer.tsx +81 -86
- package/src/Tokenizer/TokenizerBottomSheet.tsx +219 -93
- package/src/Tokenizer/TokenizerItemRemovableContext.ts +5 -3
- package/src/Tooltip/Tooltip.doc.mjs +123 -54
- package/src/Tooltip/Tooltip.tsx +36 -39
- package/src/Tooltip/index.ts +0 -1
- package/src/Tooltip/useTooltip.doc.mjs +147 -33
- package/src/Tooltip/useTooltip.tsx +39 -32
- package/src/TopNav/TopNavItem.tsx +6 -5
- package/src/TopNav/TopNavMegaMenuItem.tsx +6 -5
- package/src/TopNav/TopNavMenu.tsx +6 -5
- package/src/gestures/GestureHost.ts +105 -10
- package/src/hooks/useHighlightedOptionScroll.ts +113 -9
- package/src/hooks/useMenuPress.ts +8 -2
- package/src/i18n/generated-english/PowerSearch/PowerSearch.generated.ts +1 -0
- package/src/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.ts +7 -1
- package/src/i18n/generated-locales/en.generated.ts +1 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +1 -0
- package/src/internal/SheetConfirmation.tsx +101 -0
- package/src/internal/sheetDraft.ts +80 -0
- package/src/internal/touch-sheet.ts +21 -0
- package/src/internal/useDismissSearchOnTouchDrag.ts +69 -0
- package/src/motion/reducedMotion.ts +79 -1
- package/src/utils/clickGuard.ts +37 -1
- package/dist/internal/tokenizer-presentation.d.ts +0 -21
- package/dist/internal/tokenizer-presentation.d.ts.map +0 -1
- package/dist/internal/tokenizer-presentation.js +0 -21
- package/src/internal/tokenizer-presentation.ts +0 -25
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
import { useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
29
29
|
import { flushSync } from 'react-dom';
|
|
30
30
|
import * as stylex from '@stylexjs/stylex';
|
|
31
|
-
import { AlertDialog } from "../AlertDialog/AlertDialog.js";
|
|
32
31
|
import { BottomSheet } from "../BottomSheet/BottomSheet.js";
|
|
33
32
|
import { Button } from "../Button/Button.js";
|
|
34
33
|
import { EmptyState } from "../EmptyState/EmptyState.js";
|
|
@@ -41,9 +40,12 @@ import { useIsomorphicLayoutEffect } from "../hooks/useIsomorphicLayoutEffect.js
|
|
|
41
40
|
import { useAnnounce } from "../hooks/useAnnounce.js";
|
|
42
41
|
import { useAnnounceRenderedText } from "../hooks/useAnnounceRenderedText.js";
|
|
43
42
|
import { Text } from "../Text/Text.js";
|
|
43
|
+
import { SheetConfirmation } from "../internal/SheetConfirmation.js";
|
|
44
|
+
import { hasSameSelection, nameSheetDraftChange } from "../internal/sheetDraft.js";
|
|
45
|
+
import { useDismissSearchOnTouchDrag } from "../internal/useDismissSearchOnTouchDrag.js";
|
|
44
46
|
import { warnOnce } from "../utils/devWarning.js";
|
|
45
47
|
import "../theme/tokens.stylex.js";
|
|
46
|
-
import { colorVars, radiusVars, spacingVars } from "../theme/tokens.stylex.js";
|
|
48
|
+
import { colorVars, radiusVars, sizeVars, spacingVars } from "../theme/tokens.stylex.js";
|
|
47
49
|
import { registerEnglishFallback, useComponentTranslator } from "../i18n/useComponentTranslator.js";
|
|
48
50
|
import english from "../i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.js";
|
|
49
51
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -62,8 +64,8 @@ const EMPTY_RESULTS = [];
|
|
|
62
64
|
const LIST_LOAD_MORE_THRESHOLD_PX = 200;
|
|
63
65
|
const styles = {
|
|
64
66
|
searchField: {
|
|
65
|
-
kAzted: "
|
|
66
|
-
k8WAf4: "
|
|
67
|
+
kAzted: "x1xf4nls",
|
|
68
|
+
k8WAf4: "xu0wf1k",
|
|
67
69
|
$$css: true
|
|
68
70
|
},
|
|
69
71
|
rowLabel: {
|
|
@@ -93,22 +95,24 @@ const styles = {
|
|
|
93
95
|
/**
|
|
94
96
|
* The touch surface of Tokenizer's `bottom-sheet` presentation.
|
|
95
97
|
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
*
|
|
98
|
+
* One open sheet edits one draft that starts as `value`; rows, the create row
|
|
99
|
+
* and Clear all change the draft, and Save reports it once. Rows keep their
|
|
100
|
+
* position while the sheet is open: the items selected when it opened lead,
|
|
101
|
+
* in `value` order, then draft-selected items the results do not carry, then
|
|
102
|
+
* the results; the next open takes a fresh snapshot and regroups
|
|
103
|
+
* selected-first.
|
|
104
|
+
*
|
|
105
|
+
* The sheet is BottomSheet around the content, split in two so the content —
|
|
103
106
|
* search, rows, footer, and every announcement about them — is rendered
|
|
104
107
|
* inside the sheet's dialog, where `useAnnounce` routes into it while it is
|
|
105
|
-
* open
|
|
106
|
-
*
|
|
108
|
+
* open: a component that renders a modal and announces about its content is
|
|
109
|
+
* inside that modal only when the announcing code is.
|
|
107
110
|
*
|
|
108
111
|
* The outer part also tells the content how a close came about: a close the
|
|
109
|
-
* person made (
|
|
112
|
+
* person made (Save, swipe, scrim, Escape) clears the query so the next open
|
|
110
113
|
* lists the bootstrap set, while a close the field forced (becoming disabled
|
|
111
|
-
* while open) keeps it
|
|
114
|
+
* while open) keeps it. A swipe, scrim or Escape close of a changed draft is
|
|
115
|
+
* routed to the content first, which asks before discarding.
|
|
112
116
|
*/
|
|
113
117
|
export function TokenizerBottomSheet({
|
|
114
118
|
isOpen,
|
|
@@ -121,7 +125,9 @@ export function TokenizerBottomSheet({
|
|
|
121
125
|
// this handle, from the closing event, so a close the field forces by
|
|
122
126
|
// becoming disabled (which never comes through here) keeps it.
|
|
123
127
|
const clearQueryRef = useRef(null);
|
|
124
|
-
|
|
128
|
+
// Set by the content: a dismissal asks first while the draft is changed.
|
|
129
|
+
const requestDismissRef = useRef(null);
|
|
130
|
+
const closeSheet = () => {
|
|
125
131
|
clearQueryRef.current?.();
|
|
126
132
|
onOpenChange(false);
|
|
127
133
|
};
|
|
@@ -130,8 +136,10 @@ export function TokenizerBottomSheet({
|
|
|
130
136
|
onOpenChange: next => {
|
|
131
137
|
if (next) {
|
|
132
138
|
onOpenChange(true);
|
|
139
|
+
} else if (requestDismissRef.current != null) {
|
|
140
|
+
requestDismissRef.current();
|
|
133
141
|
} else {
|
|
134
|
-
|
|
142
|
+
closeSheet();
|
|
135
143
|
}
|
|
136
144
|
},
|
|
137
145
|
finalFocusRef: finalFocusRef,
|
|
@@ -143,7 +151,8 @@ export function TokenizerBottomSheet({
|
|
|
143
151
|
isOpen: isOpen,
|
|
144
152
|
label: label,
|
|
145
153
|
clearQueryRef: clearQueryRef,
|
|
146
|
-
|
|
154
|
+
requestDismissRef: requestDismissRef,
|
|
155
|
+
onCloseSheet: closeSheet
|
|
147
156
|
})
|
|
148
157
|
});
|
|
149
158
|
}
|
|
@@ -152,19 +161,18 @@ function TokenizerSheetContent({
|
|
|
152
161
|
isOpen,
|
|
153
162
|
initialQuery,
|
|
154
163
|
clearQueryRef,
|
|
155
|
-
|
|
164
|
+
requestDismissRef,
|
|
165
|
+
onCloseSheet,
|
|
156
166
|
label,
|
|
157
167
|
searchSource,
|
|
158
168
|
value,
|
|
159
|
-
|
|
169
|
+
maxEntries,
|
|
160
170
|
hasCreate,
|
|
161
171
|
maxMenuItems,
|
|
162
172
|
minQueryLength,
|
|
163
173
|
debounceMs,
|
|
164
174
|
emptySearchText,
|
|
165
|
-
|
|
166
|
-
onRemove,
|
|
167
|
-
onClearAll,
|
|
175
|
+
onCommit,
|
|
168
176
|
onChangeQuery
|
|
169
177
|
}) {
|
|
170
178
|
const t = useComponentTranslator();
|
|
@@ -192,6 +200,7 @@ function TokenizerSheetContent({
|
|
|
192
200
|
// sheet makes goes through `useAnnounce`, called inside the sheet's
|
|
193
201
|
// dialog, so FR14 routes the words into it while the sheet is open.
|
|
194
202
|
const [isClearConfirmationOpen, setIsClearConfirmationOpen] = useState(false);
|
|
203
|
+
const [isDiscardConfirmationOpen, setIsDiscardConfirmationOpen] = useState(false);
|
|
195
204
|
const clearAllRef = useRef(null);
|
|
196
205
|
const announce = useAnnounce();
|
|
197
206
|
const closeClearConfirmation = confirmed => {
|
|
@@ -204,7 +213,27 @@ function TokenizerSheetContent({
|
|
|
204
213
|
clearAllRef.current?.focus();
|
|
205
214
|
}
|
|
206
215
|
};
|
|
207
|
-
|
|
216
|
+
// Keep editing: the confirmation is gone, and focus returns to the search
|
|
217
|
+
// field, where the sheet's own reading order starts.
|
|
218
|
+
const closeDiscardConfirmation = () => {
|
|
219
|
+
// eslint-disable-next-line @eslint-react/dom-no-flush-sync -- the confirmation must be gone before focus moves back into the sheet
|
|
220
|
+
flushSync(() => setIsDiscardConfirmationOpen(false));
|
|
221
|
+
searchRef.current?.focus({
|
|
222
|
+
preventScroll: true
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
// ---- draft ----
|
|
227
|
+
// One open sheet edits one draft. The caller's `value` is unchanged until
|
|
228
|
+
// Save, so a dismissal can discard cleanly; `lastDraftChangeRef` is the
|
|
229
|
+
// edit Save names when it still holds.
|
|
230
|
+
const [valueAtOpen, setValueAtOpen] = useState(() => [...value]);
|
|
231
|
+
const [draftValue, setDraftValue] = useState(() => [...value]);
|
|
232
|
+
const lastDraftChangeRef = useRef(null);
|
|
233
|
+
const isDraftDirty = !hasSameSelection(valueAtOpen, draftValue);
|
|
234
|
+
const selectedIds = useMemo(() => new Set(draftValue.map(v => v.id)), [draftValue]);
|
|
235
|
+
const isAtMax = maxEntries != null && draftValue.length >= maxEntries;
|
|
236
|
+
const isDraftOverMax = maxEntries != null && draftValue.length > maxEntries;
|
|
208
237
|
|
|
209
238
|
// ---- sheet session ----
|
|
210
239
|
// Starts from the field's copy, which `onChangeQuery` keeps current, so the
|
|
@@ -256,7 +285,12 @@ function TokenizerSheetContent({
|
|
|
256
285
|
setWasOpen(isOpen);
|
|
257
286
|
if (isOpen) {
|
|
258
287
|
setSelectedItemsAtOpen(value);
|
|
288
|
+
setValueAtOpen([...value]);
|
|
289
|
+
setDraftValue([...value]);
|
|
290
|
+
lastDraftChangeRef.current = null;
|
|
259
291
|
setRenderedItemCount(LIST_RENDER_BATCH_SIZE);
|
|
292
|
+
setIsClearConfirmationOpen(false);
|
|
293
|
+
setIsDiscardConfirmationOpen(false);
|
|
260
294
|
// An open lists the bootstrap set, or searches a query kept across a
|
|
261
295
|
// close the field forced (FR18), and that load is pending; a kept
|
|
262
296
|
// query below the threshold leaves nothing pending, since no search
|
|
@@ -359,12 +393,12 @@ function TokenizerSheetContent({
|
|
|
359
393
|
const selectedAtOpenMatches = selectedItemsAtOpen.filter(matchesQuery);
|
|
360
394
|
const selectedAtOpenIds = new Set(selectedAtOpenMatches.map(item => item.id));
|
|
361
395
|
const resultIds = new Set(results.map(item => item.id));
|
|
362
|
-
const selectedItemsMissingFromResults =
|
|
396
|
+
const selectedItemsMissingFromResults = draftValue.filter(item => !selectedAtOpenIds.has(item.id) && !resultIds.has(item.id) && matchesQuery(item));
|
|
363
397
|
|
|
364
398
|
// Selection changes update checkbox state without moving an existing row.
|
|
365
399
|
// The next open snapshots the latest value and applies selected-first order.
|
|
366
400
|
return [...selectedAtOpenMatches, ...selectedItemsMissingFromResults, ...results.filter(item => !selectedAtOpenIds.has(item.id))];
|
|
367
|
-
}, [query, results, selectedItemsAtOpen,
|
|
401
|
+
}, [query, results, selectedItemsAtOpen, draftValue]);
|
|
368
402
|
const renderedItems = visibleItems.slice(0, renderedItemCount);
|
|
369
403
|
|
|
370
404
|
// A settled search may remove the row that holds focus: it was listed from
|
|
@@ -405,7 +439,7 @@ function TokenizerSheetContent({
|
|
|
405
439
|
return null;
|
|
406
440
|
}
|
|
407
441
|
const lowered = trimmedQuery.toLowerCase();
|
|
408
|
-
if (selectedIds.has(trimmedQuery) ||
|
|
442
|
+
if (selectedIds.has(trimmedQuery) || draftValue.some(item => item.label.toLowerCase() === lowered) || results.some(item => item.label.toLowerCase() === lowered)) {
|
|
409
443
|
return null;
|
|
410
444
|
}
|
|
411
445
|
return {
|
|
@@ -414,7 +448,7 @@ function TokenizerSheetContent({
|
|
|
414
448
|
value: trimmedQuery
|
|
415
449
|
})
|
|
416
450
|
};
|
|
417
|
-
}, [hasCreate, trimmedQuery, isAtMax, isPending, selectedIds,
|
|
451
|
+
}, [hasCreate, trimmedQuery, isAtMax, isPending, selectedIds, draftValue, results, t]);
|
|
418
452
|
const resetListWindow = () => {
|
|
419
453
|
lastLoadScrollHeightRef.current = null;
|
|
420
454
|
setRenderedItemCount(LIST_RENDER_BATCH_SIZE);
|
|
@@ -434,6 +468,29 @@ function TokenizerSheetContent({
|
|
|
434
468
|
setQuery(next);
|
|
435
469
|
onChangeQuery?.(next);
|
|
436
470
|
};
|
|
471
|
+
|
|
472
|
+
// A swipe, scrim or Escape close: asks first while the draft is changed.
|
|
473
|
+
useImperativeHandle(requestDismissRef, () => () => {
|
|
474
|
+
if (isDraftDirty) {
|
|
475
|
+
setIsDiscardConfirmationOpen(true);
|
|
476
|
+
} else {
|
|
477
|
+
onCloseSheet();
|
|
478
|
+
}
|
|
479
|
+
}, [isDraftDirty, onCloseSheet]);
|
|
480
|
+
const handleSave = () => {
|
|
481
|
+
if (isDraftOverMax) {
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
const change = isDraftDirty ? nameSheetDraftChange(valueAtOpen, draftValue, lastDraftChangeRef.current) : null;
|
|
485
|
+
if (change != null) {
|
|
486
|
+
onCommit([...draftValue], change);
|
|
487
|
+
}
|
|
488
|
+
onCloseSheet();
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
// Focus moves to the sheet's panel, not the page body behind the modal.
|
|
492
|
+
// The keyboard then leaves and the query stays.
|
|
493
|
+
const listDragProps = useDismissSearchOnTouchDrag(() => [searchRef.current], () => listRef.current?.closest('[tabindex="-1"]'));
|
|
437
494
|
const searchLabel = t('@astryx.tokenizer.search', {
|
|
438
495
|
label
|
|
439
496
|
});
|
|
@@ -495,6 +552,7 @@ function TokenizerSheetContent({
|
|
|
495
552
|
placeholder: t('@astryx.tokenizer.searchPlaceholder'),
|
|
496
553
|
value: query,
|
|
497
554
|
onValueChange: handleQueryChange,
|
|
555
|
+
hasInputBox: true,
|
|
498
556
|
fieldXstyle: styles.searchField
|
|
499
557
|
})
|
|
500
558
|
}), /*#__PURE__*/_jsxs("div", {
|
|
@@ -505,6 +563,7 @@ function TokenizerSheetContent({
|
|
|
505
563
|
"aria-busy": isPending || undefined,
|
|
506
564
|
"data-rendered-count": renderedItems.length,
|
|
507
565
|
"data-total-count": visibleItems.length,
|
|
566
|
+
...listDragProps,
|
|
508
567
|
onFocusCapture: event => {
|
|
509
568
|
isRowFocusedRef.current = event.target instanceof HTMLElement && event.target.getAttribute('role') === 'checkbox';
|
|
510
569
|
},
|
|
@@ -539,15 +598,21 @@ function TokenizerSheetContent({
|
|
|
539
598
|
variant: "secondary",
|
|
540
599
|
size: "lg",
|
|
541
600
|
onClick: () => {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
601
|
+
const base = {
|
|
602
|
+
id: trimmedQuery,
|
|
603
|
+
label: trimmedQuery
|
|
604
|
+
};
|
|
605
|
+
const createdItem = base;
|
|
606
|
+
setDraftValue(current => [...current, createdItem]);
|
|
607
|
+
lastDraftChangeRef.current = {
|
|
608
|
+
item: createdItem,
|
|
609
|
+
type: 'create'
|
|
610
|
+
};
|
|
611
|
+
// The created value, as the inline field announces it; the
|
|
612
|
+
// item's label is the row's caption ("Create …").
|
|
613
|
+
announce(t('@astryx.tokenizer.tokenAdded', {
|
|
614
|
+
label: trimmedQuery
|
|
615
|
+
}));
|
|
551
616
|
// The same path a typed change takes, so the bootstrap
|
|
552
617
|
// reload shows its pending state and reports the change.
|
|
553
618
|
handleQueryChange('');
|
|
@@ -631,16 +696,20 @@ function TokenizerSheetContent({
|
|
|
631
696
|
return;
|
|
632
697
|
}
|
|
633
698
|
if (isSelected) {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
699
|
+
setDraftValue(current => current.filter(selected => selected.id !== item.id));
|
|
700
|
+
lastDraftChangeRef.current = {
|
|
701
|
+
item,
|
|
702
|
+
type: 'remove'
|
|
703
|
+
};
|
|
704
|
+
announce(t('@astryx.tokenizer.tokenRemoved', {
|
|
705
|
+
label: item.label
|
|
706
|
+
}));
|
|
707
|
+
} else {
|
|
708
|
+
setDraftValue(current => [...current, item]);
|
|
709
|
+
lastDraftChangeRef.current = {
|
|
710
|
+
item,
|
|
711
|
+
type: 'add'
|
|
712
|
+
};
|
|
644
713
|
announce(t('@astryx.tokenizer.tokenAdded', {
|
|
645
714
|
label: item.label
|
|
646
715
|
}));
|
|
@@ -669,7 +738,7 @@ function TokenizerSheetContent({
|
|
|
669
738
|
}, item.id);
|
|
670
739
|
})
|
|
671
740
|
})]
|
|
672
|
-
}),
|
|
741
|
+
}), /*#__PURE__*/_jsxs("div", {
|
|
673
742
|
...{
|
|
674
743
|
className: "x78zum5 x6s0dn4 x1txdalj x1vlblms xr1yuqi"
|
|
675
744
|
},
|
|
@@ -677,25 +746,32 @@ function TokenizerSheetContent({
|
|
|
677
746
|
label: t('@astryx.tokenizer.clearAll'),
|
|
678
747
|
variant: "secondary",
|
|
679
748
|
size: "lg",
|
|
680
|
-
isDisabled:
|
|
749
|
+
isDisabled: draftValue.length === 0
|
|
681
750
|
// With a tooltip, Button's disabled mode is `aria-disabled`: the
|
|
682
751
|
// action keeps its focus order and says why it does nothing
|
|
683
752
|
// (`spec:AST-085` FR1), instead of leaving the tab order as a
|
|
684
753
|
// natively disabled button does — a confirmed Clear all returns
|
|
685
754
|
// focus here before the search field takes it (FR24).
|
|
686
755
|
,
|
|
687
|
-
tooltip:
|
|
756
|
+
tooltip: draftValue.length === 0 ? t('@astryx.tokenizer.nothingToClear') : undefined,
|
|
688
757
|
ref: clearAllRef,
|
|
689
758
|
onClick: () => setIsClearConfirmationOpen(true),
|
|
690
759
|
xstyle: styles.footerAction
|
|
691
760
|
}), /*#__PURE__*/_jsx(Button, {
|
|
692
|
-
label: t('@astryx.tokenizer.
|
|
761
|
+
label: t('@astryx.tokenizer.save'),
|
|
693
762
|
variant: "primary",
|
|
694
763
|
size: "lg",
|
|
695
|
-
|
|
764
|
+
isDisabled: isDraftOverMax
|
|
765
|
+
// Over the limit (a `value` already over it at open, or a lowered
|
|
766
|
+
// limit while open) Save keeps its tab stop and says why it waits.
|
|
767
|
+
,
|
|
768
|
+
tooltip: isDraftOverMax ? t('@astryx.tokenizer.selectionLimit', {
|
|
769
|
+
count: maxEntries ?? 0
|
|
770
|
+
}) : undefined,
|
|
771
|
+
onClick: handleSave,
|
|
696
772
|
xstyle: styles.footerAction
|
|
697
773
|
})]
|
|
698
|
-
}), isClearConfirmationOpen && /*#__PURE__*/_jsx(
|
|
774
|
+
}), isClearConfirmationOpen && /*#__PURE__*/_jsx(SheetConfirmation, {
|
|
699
775
|
isOpen: true,
|
|
700
776
|
onOpenChange: next => {
|
|
701
777
|
if (!next) {
|
|
@@ -706,11 +782,38 @@ function TokenizerSheetContent({
|
|
|
706
782
|
description: t('@astryx.tokenizer.clearAllDescription', {
|
|
707
783
|
label
|
|
708
784
|
}),
|
|
785
|
+
cancelLabel: t('@astryx.alertDialog.cancel'),
|
|
709
786
|
actionLabel: t('@astryx.tokenizer.clearSelection'),
|
|
710
787
|
onAction: () => {
|
|
711
|
-
|
|
788
|
+
// A clear is a removal of the draft's last item, for Save's
|
|
789
|
+
// `remove` when it is the last edit that holds.
|
|
790
|
+
const lastItem = draftValue[draftValue.length - 1];
|
|
791
|
+
if (lastItem != null) {
|
|
792
|
+
setDraftValue([]);
|
|
793
|
+
lastDraftChangeRef.current = {
|
|
794
|
+
item: lastItem,
|
|
795
|
+
type: 'remove'
|
|
796
|
+
};
|
|
797
|
+
}
|
|
712
798
|
closeClearConfirmation(true);
|
|
713
799
|
}
|
|
800
|
+
}), isDiscardConfirmationOpen && /*#__PURE__*/_jsx(SheetConfirmation, {
|
|
801
|
+
isOpen: true,
|
|
802
|
+
onOpenChange: next => {
|
|
803
|
+
if (!next) {
|
|
804
|
+
closeDiscardConfirmation();
|
|
805
|
+
}
|
|
806
|
+
},
|
|
807
|
+
title: t('@astryx.tokenizer.discardChangesTitle'),
|
|
808
|
+
description: t('@astryx.tokenizer.discardChangesDescription', {
|
|
809
|
+
label
|
|
810
|
+
}),
|
|
811
|
+
cancelLabel: t('@astryx.tokenizer.keepEditing'),
|
|
812
|
+
actionLabel: t('@astryx.tokenizer.discardChanges'),
|
|
813
|
+
onAction: () => {
|
|
814
|
+
setIsDiscardConfirmationOpen(false);
|
|
815
|
+
onCloseSheet();
|
|
816
|
+
}
|
|
714
817
|
})]
|
|
715
818
|
});
|
|
716
819
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenizerItemRemovableContext.d.ts","sourceRoot":"","sources":["../../src/Tokenizer/TokenizerItemRemovableContext.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TokenizerItemRemovableContext.d.ts","sourceRoot":"","sources":["../../src/Tokenizer/TokenizerItemRemovableContext.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAEvD,eAAO,MAAM,6BAA6B,kCAChC,cAAc,KAAK,OAAO,SAC7B,CAAC"}
|
|
@@ -8,9 +8,11 @@
|
|
|
8
8
|
* @output A context carrying a predicate that tells which tokens the user can
|
|
9
9
|
* remove
|
|
10
10
|
* @position Internal to Core: not exported from the Tokenizer barrel. A
|
|
11
|
-
* component that composes Tokenizer and locks some tokens (PowerSearch:
|
|
12
|
-
* filter of a read-only field) provides it.
|
|
13
|
-
*
|
|
11
|
+
* component that composes Tokenizer and locks some tokens (PowerSearch: its
|
|
12
|
+
* read-only filters, and every filter of a read-only field) provides it. In
|
|
13
|
+
* the popover presentation, Clear all then keeps a locked token, Backspace
|
|
14
|
+
* removes nothing while the last token is locked, and Clear all shows only
|
|
15
|
+
* while a removable token remains. Without it, every token is removable.
|
|
14
16
|
*/
|
|
15
17
|
import { createContext } from 'react';
|
|
16
18
|
export const TokenizerItemRemovableContext = /*#__PURE__*/createContext(null);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file Tooltip.tsx
|
|
3
3
|
* @input Uses React, useTooltip hook
|
|
4
|
-
* @output Exports Tooltip component for hover/focus triggered tooltips
|
|
4
|
+
* @output Exports Tooltip component for hover/focus triggered tooltips, and the
|
|
5
|
+
* module-only TooltipWithTriggerBehavior that InfoTip's press-to-pin uses
|
|
5
6
|
* @position Layer component; uses display:contents wrapper to avoid cloneElement
|
|
6
7
|
*
|
|
7
8
|
* SYNC: When modified, update these files to stay in sync:
|
|
@@ -10,9 +11,10 @@
|
|
|
10
11
|
* - /packages/cli/assets/templates/blocks/components/Tooltip/ (showcase blocks)
|
|
11
12
|
*/
|
|
12
13
|
import React, { type ReactElement, type ReactNode } from 'react';
|
|
13
|
-
import { type TooltipFocusTrigger, type
|
|
14
|
+
import { type TooltipFocusTrigger, type TooltipTouchTrigger } from './useTooltip.js';
|
|
15
|
+
import { type LayerTriggerBehavior } from '../Layer/usePressPin.js';
|
|
14
16
|
import type { LayerAlignment, LayerPlacement } from '../Layer/useLayer.js';
|
|
15
|
-
export type { TooltipFocusTrigger,
|
|
17
|
+
export type { TooltipFocusTrigger, TooltipTouchTrigger } from './useTooltip.js';
|
|
16
18
|
export interface TooltipProps {
|
|
17
19
|
/**
|
|
18
20
|
* The trigger element(s). Children refs are preserved.
|
|
@@ -70,35 +72,9 @@ export interface TooltipProps {
|
|
|
70
72
|
* - `tap`: tap always opens the tooltip, even on a trigger that acts
|
|
71
73
|
* - `none`: touch never opens the tooltip
|
|
72
74
|
*
|
|
73
|
-
* It decides only under `triggerBehavior="adaptive"`, the default.
|
|
74
|
-
*
|
|
75
75
|
* @default 'auto'
|
|
76
76
|
*/
|
|
77
77
|
touchTrigger?: TooltipTouchTrigger;
|
|
78
|
-
/**
|
|
79
|
-
* How the trigger opens the tooltip:
|
|
80
|
-
* - `adaptive` (the default): hover and focus preview it. A tap opens it
|
|
81
|
-
* unless the trigger performs an action of its own. While `touchTrigger`
|
|
82
|
-
* remains, it decides those taps.
|
|
83
|
-
* - `hover`: hover and focus preview it; no touch or pen tap opens it.
|
|
84
|
-
* - `toggle`: on a button trigger, a click, a tap, Enter, or Space pins the
|
|
85
|
-
* tooltip open, and the same press closes it. Hover and keyboard focus
|
|
86
|
-
* still preview it. A pinned tooltip stays until Escape, a second press,
|
|
87
|
-
* a press outside, or focus leaving. The press stops at the trigger. Its
|
|
88
|
-
* default action is prevented, and the trigger's own handlers still run.
|
|
89
|
-
* No clickable row or card around the trigger activates. With
|
|
90
|
-
* `anchorRef`, the anchor's own `onClick` runs, and a plain `onClick`
|
|
91
|
-
* element around it receives the press unless that `onClick` stops it.
|
|
92
|
-
* Astryx clickable rows, cards, and containers ignore it, except an Item
|
|
93
|
-
* row when the anchor is not a native button. The trigger reports
|
|
94
|
-
* `aria-expanded` and `aria-controls`, and the tooltip's text is
|
|
95
|
-
* announced once when it pins. Use it for a trigger whose information
|
|
96
|
-
* lives only in the tooltip, such as an info icon. `touchTrigger` is
|
|
97
|
-
* ignored.
|
|
98
|
-
*
|
|
99
|
-
* @default 'adaptive'
|
|
100
|
-
*/
|
|
101
|
-
triggerBehavior?: TooltipTriggerBehavior;
|
|
102
78
|
/**
|
|
103
79
|
* Whether the tooltip is enabled.
|
|
104
80
|
* When false, hover/focus triggers are disabled.
|
|
@@ -152,8 +128,27 @@ export interface TooltipProps {
|
|
|
152
128
|
* </Tooltip>
|
|
153
129
|
* ```
|
|
154
130
|
*/
|
|
155
|
-
export declare function Tooltip(
|
|
131
|
+
export declare function Tooltip(props: TooltipProps): ReactElement;
|
|
156
132
|
export declare namespace Tooltip {
|
|
157
133
|
var displayName: string;
|
|
158
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Module-only props for `TooltipWithTriggerBehavior`. Not exported from the
|
|
137
|
+
* package.
|
|
138
|
+
*/
|
|
139
|
+
export interface TooltipWithTriggerBehaviorProps extends TooltipProps {
|
|
140
|
+
/**
|
|
141
|
+
* How the trigger opens the tooltip. `toggle` pins it on a click, a tap,
|
|
142
|
+
* Enter, or Space on a button trigger, and stops that press at the trigger
|
|
143
|
+
* (see `useTooltipWithTriggerBehavior`). InfoTip uses it.
|
|
144
|
+
*
|
|
145
|
+
* @default 'adaptive'
|
|
146
|
+
*/
|
|
147
|
+
triggerBehavior?: LayerTriggerBehavior;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* `Tooltip` with a trigger behavior. Module-only: InfoTip's press-to-pin goes
|
|
151
|
+
* through it, and the package does not export it.
|
|
152
|
+
*/
|
|
153
|
+
export declare function TooltipWithTriggerBehavior({ children, anchorRef, content, placement, alignment, delay, hideDelay, focusTrigger, touchTrigger, triggerBehavior, isEnabled, onOpenChange, hasHoverIndication, isOpen, isDefaultOpen, }: TooltipWithTriggerBehaviorProps): ReactElement;
|
|
159
154
|
//# sourceMappingURL=Tooltip.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../src/Tooltip/Tooltip.tsx"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../src/Tooltip/Tooltip.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,EAGZ,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAC,cAAc,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAGtE,YAAY,EAAC,mBAAmB,EAAE,mBAAmB,EAAC,MAAM,cAAc,CAAC;AAiB3E,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAEhD;;;OAGG;IACH,OAAO,EAAE,SAAS,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAEnC;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAEnC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAEtC;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAiBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CAIzD;yBAJe,OAAO;;;AAMvB;;;GAGG;AACH,MAAM,WAAW,+BAAgC,SAAQ,YAAY;IACnE;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,oBAAoB,CAAC;CACxC;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,EACzC,QAAQ,EACR,SAAS,EACT,OAAO,EACP,SAAmB,EACnB,SAAoB,EACpB,KAAW,EACX,SAAa,EACb,YAAqB,EACrB,YAAqB,EACrB,eAA4B,EAC5B,SAAgB,EAChB,YAAY,EACZ,kBAA2B,EAC3B,MAAM,EACN,aAAa,GACd,EAAE,+BAA+B,GAAG,YAAY,CAkKhD"}
|
package/dist/Tooltip/Tooltip.js
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @file Tooltip.tsx
|
|
7
7
|
* @input Uses React, useTooltip hook
|
|
8
|
-
* @output Exports Tooltip component for hover/focus triggered tooltips
|
|
8
|
+
* @output Exports Tooltip component for hover/focus triggered tooltips, and the
|
|
9
|
+
* module-only TooltipWithTriggerBehavior that InfoTip's press-to-pin uses
|
|
9
10
|
* @position Layer component; uses display:contents wrapper to avoid cloneElement
|
|
10
11
|
*
|
|
11
12
|
* SYNC: When modified, update these files to stay in sync:
|
|
@@ -16,11 +17,11 @@
|
|
|
16
17
|
import React, { useCallback, useRef } from 'react';
|
|
17
18
|
import { useIsomorphicLayoutEffect } from "../hooks/useIsomorphicLayoutEffect.js";
|
|
18
19
|
import * as stylex from '@stylexjs/stylex';
|
|
19
|
-
import {
|
|
20
|
+
import { useTooltipWithTriggerBehavior } from "./useTooltip.js";
|
|
20
21
|
import { stopPressPinClick } from "../Layer/usePressPin.js";
|
|
21
22
|
import "../theme/tokens.stylex.js";
|
|
22
23
|
import { colorVars } from "../theme/tokens.stylex.js";
|
|
23
|
-
import {
|
|
24
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
24
25
|
/**
|
|
25
26
|
* Check if children are text-only (no React elements)
|
|
26
27
|
*/
|
|
@@ -50,7 +51,25 @@ function mergeIds(...ids) {
|
|
|
50
51
|
* </Tooltip>
|
|
51
52
|
* ```
|
|
52
53
|
*/
|
|
53
|
-
export function Tooltip({
|
|
54
|
+
export function Tooltip(props) {
|
|
55
|
+
// The option is fixed to `adaptive`, so a spread object that carries it at
|
|
56
|
+
// runtime cannot reach the press-to-pin path.
|
|
57
|
+
return /*#__PURE__*/_jsx(TooltipWithTriggerBehavior, {
|
|
58
|
+
...props,
|
|
59
|
+
triggerBehavior: "adaptive"
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Module-only props for `TooltipWithTriggerBehavior`. Not exported from the
|
|
65
|
+
* package.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* `Tooltip` with a trigger behavior. Module-only: InfoTip's press-to-pin goes
|
|
70
|
+
* through it, and the package does not export it.
|
|
71
|
+
*/
|
|
72
|
+
export function TooltipWithTriggerBehavior({
|
|
54
73
|
children,
|
|
55
74
|
anchorRef,
|
|
56
75
|
content,
|
|
@@ -80,7 +99,7 @@ export function Tooltip({
|
|
|
80
99
|
}, [onOpenChange]);
|
|
81
100
|
|
|
82
101
|
// Use the hook for all tooltip behavior
|
|
83
|
-
const tooltip =
|
|
102
|
+
const tooltip = useTooltipWithTriggerBehavior({
|
|
84
103
|
placement,
|
|
85
104
|
alignment,
|
|
86
105
|
delay,
|
package/dist/Tooltip/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* SYNC: When adding new Tooltip files, update exports here
|
|
8
8
|
*/
|
|
9
9
|
export { useTooltip } from './useTooltip.js';
|
|
10
|
-
export type { TooltipFocusTrigger,
|
|
10
|
+
export type { TooltipFocusTrigger, TooltipTouchTrigger, TooltipOptions, TooltipReturn, } from './useTooltip.js';
|
|
11
11
|
export { Tooltip } from './Tooltip.js';
|
|
12
12
|
export type { TooltipProps } from './Tooltip.js';
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Tooltip/index.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAGH,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,YAAY,EACV,mBAAmB,EACnB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Tooltip/index.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAGH,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,YAAY,EAAC,YAAY,EAAC,MAAM,WAAW,CAAC"}
|