@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.
Files changed (198) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/dist/AppShell/useCloseMobileDrawerOnActivate.d.ts +13 -0
  3. package/dist/AppShell/useCloseMobileDrawerOnActivate.d.ts.map +1 -0
  4. package/dist/AppShell/useCloseMobileDrawerOnActivate.js +45 -0
  5. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  6. package/dist/BottomSheet/BottomSheet.js +79 -9
  7. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  8. package/dist/BottomSheet/BottomSheetPanel.js +1 -1
  9. package/dist/BottomSheet/bottomSheetStack.d.ts.map +1 -1
  10. package/dist/BottomSheet/bottomSheetStack.js +5 -4
  11. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +2 -1
  12. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  13. package/dist/Breadcrumbs/BreadcrumbItem.js +7 -3
  14. package/dist/Button/Button.d.ts.map +1 -1
  15. package/dist/Button/Button.js +30 -2
  16. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  17. package/dist/CheckboxList/CheckboxList.js +7 -1
  18. package/dist/CheckboxList/CheckboxListContext.d.ts +6 -0
  19. package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
  20. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  21. package/dist/CheckboxList/CheckboxListItem.js +10 -2
  22. package/dist/DateInput/DateInput.d.ts.map +1 -1
  23. package/dist/DateInput/DateInput.js +5 -2
  24. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  25. package/dist/DateInput/MonthScroller.js +13 -27
  26. package/dist/DateInput/Wheel.d.ts.map +1 -1
  27. package/dist/DateInput/Wheel.js +22 -41
  28. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  29. package/dist/DateTimeInput/DateTimeInput.js +5 -2
  30. package/dist/Dialog/Dialog.d.ts.map +1 -1
  31. package/dist/Dialog/Dialog.js +4 -3
  32. package/dist/Drawer/Drawer.js +0 -1
  33. package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
  34. package/dist/Drawer/useDrawerDialogPresence.js +5 -1
  35. package/dist/Field/PanelSearchInput.d.ts +9 -1
  36. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  37. package/dist/Field/PanelSearchInput.js +3 -1
  38. package/dist/InfoTip/InfoTip.d.ts +2 -2
  39. package/dist/InfoTip/InfoTip.js +4 -4
  40. package/dist/Layer/layerAnimations.stylex.d.ts +7 -8
  41. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  42. package/dist/Layer/layerAnimations.stylex.js +25 -20
  43. package/dist/Layer/usePressPin.d.ts +3 -5
  44. package/dist/Layer/usePressPin.d.ts.map +1 -1
  45. package/dist/Layer/usePressPin.js +4 -6
  46. package/dist/MobileNav/MobileNav.js +0 -1
  47. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  48. package/dist/MultiSelector/hooks.js +2 -4
  49. package/dist/Outline/Outline.d.ts +2 -4
  50. package/dist/Outline/Outline.d.ts.map +1 -1
  51. package/dist/Outline/Outline.js +4 -52
  52. package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
  53. package/dist/Outline/useOutlineFromMarkdown.js +1 -0
  54. package/dist/Outline/useScrollSpy.js +3 -3
  55. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  56. package/dist/PowerSearch/PowerSearch.js +134 -179
  57. package/dist/RadioList/RadioList.d.ts.map +1 -1
  58. package/dist/RadioList/RadioList.js +5 -0
  59. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  60. package/dist/Resizable/ResizeHandle.js +118 -260
  61. package/dist/Resizable/resizeGesture.d.ts +91 -0
  62. package/dist/Resizable/resizeGesture.d.ts.map +1 -0
  63. package/dist/Resizable/resizeGesture.js +251 -0
  64. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  65. package/dist/SideNav/SideNavItem.js +3 -9
  66. package/dist/Token/Token.d.ts +2 -2
  67. package/dist/Token/Token.d.ts.map +1 -1
  68. package/dist/Token/Token.js +12 -4
  69. package/dist/Token/TokenNamingContext.d.ts +14 -0
  70. package/dist/Token/TokenNamingContext.d.ts.map +1 -0
  71. package/dist/Token/TokenNamingContext.js +23 -0
  72. package/dist/Tokenizer/Tokenizer.d.ts +46 -59
  73. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  74. package/dist/Tokenizer/Tokenizer.js +35 -58
  75. package/dist/Tokenizer/TokenizerBottomSheet.d.ts +25 -28
  76. package/dist/Tokenizer/TokenizerBottomSheet.d.ts.map +1 -1
  77. package/dist/Tokenizer/TokenizerBottomSheet.js +157 -54
  78. package/dist/Tokenizer/TokenizerItemRemovableContext.d.ts.map +1 -1
  79. package/dist/Tokenizer/TokenizerItemRemovableContext.js +5 -3
  80. package/dist/Tooltip/Tooltip.d.ts +25 -30
  81. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  82. package/dist/Tooltip/Tooltip.js +24 -5
  83. package/dist/Tooltip/index.d.ts +1 -1
  84. package/dist/Tooltip/index.d.ts.map +1 -1
  85. package/dist/Tooltip/useTooltip.d.ts +28 -29
  86. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  87. package/dist/Tooltip/useTooltip.js +20 -8
  88. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  89. package/dist/TopNav/TopNavItem.js +4 -7
  90. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  91. package/dist/TopNav/TopNavMegaMenuItem.js +4 -7
  92. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  93. package/dist/TopNav/TopNavMenu.js +4 -7
  94. package/dist/astryx.css +5 -5
  95. package/dist/gestures/GestureHost.d.ts +27 -1
  96. package/dist/gestures/GestureHost.d.ts.map +1 -1
  97. package/dist/gestures/GestureHost.js +90 -8
  98. package/dist/hooks/useHighlightedOptionScroll.d.ts +11 -1
  99. package/dist/hooks/useHighlightedOptionScroll.d.ts.map +1 -1
  100. package/dist/hooks/useHighlightedOptionScroll.js +103 -5
  101. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  102. package/dist/hooks/useMenuPress.js +4 -2
  103. package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.d.ts.map +1 -1
  104. package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.js +1 -0
  105. package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.d.ts.map +1 -1
  106. package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.js +7 -1
  107. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  108. package/dist/i18n/generated-locales/en.generated.js +1 -0
  109. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  110. package/dist/i18n/generated-locales/pseudo.generated.js +1 -0
  111. package/dist/internal/SheetConfirmation.d.ts +11 -0
  112. package/dist/internal/SheetConfirmation.d.ts.map +1 -0
  113. package/dist/internal/SheetConfirmation.js +92 -0
  114. package/dist/internal/sheetDraft.d.ts +35 -0
  115. package/dist/internal/sheetDraft.d.ts.map +1 -0
  116. package/dist/internal/sheetDraft.js +65 -0
  117. package/dist/internal/touch-sheet.d.ts +21 -0
  118. package/dist/internal/touch-sheet.d.ts.map +1 -0
  119. package/dist/internal/touch-sheet.js +19 -0
  120. package/dist/internal/useDismissSearchOnTouchDrag.d.ts +24 -0
  121. package/dist/internal/useDismissSearchOnTouchDrag.d.ts.map +1 -0
  122. package/dist/internal/useDismissSearchOnTouchDrag.js +56 -0
  123. package/dist/motion/reducedMotion.d.ts +24 -0
  124. package/dist/motion/reducedMotion.d.ts.map +1 -1
  125. package/dist/motion/reducedMotion.js +78 -1
  126. package/dist/utils/clickGuard.d.ts +8 -1
  127. package/dist/utils/clickGuard.d.ts.map +1 -1
  128. package/dist/utils/clickGuard.js +24 -1
  129. package/locales/en.json +4 -0
  130. package/locales/pseudo.json +3 -0
  131. package/package.json +9 -9
  132. package/src/AppShell/useCloseMobileDrawerOnActivate.ts +52 -0
  133. package/src/BottomSheet/BottomSheet.tsx +95 -10
  134. package/src/BottomSheet/BottomSheetPanel.tsx +7 -2
  135. package/src/BottomSheet/bottomSheetStack.ts +8 -4
  136. package/src/Breadcrumbs/BreadcrumbItem.tsx +13 -3
  137. package/src/Button/Button.tsx +37 -1
  138. package/src/CheckboxList/CheckboxList.doc.mjs +4 -2
  139. package/src/CheckboxList/CheckboxList.tsx +6 -0
  140. package/src/CheckboxList/CheckboxListContext.tsx +6 -0
  141. package/src/CheckboxList/CheckboxListItem.tsx +11 -2
  142. package/src/DateInput/DateInput.tsx +8 -2
  143. package/src/DateInput/MonthScroller.tsx +18 -22
  144. package/src/DateInput/Wheel.tsx +30 -32
  145. package/src/DateTimeInput/DateTimeInput.tsx +8 -2
  146. package/src/Dialog/Dialog.tsx +19 -4
  147. package/src/Drawer/Drawer.tsx +1 -1
  148. package/src/Drawer/useDrawerDialogPresence.ts +5 -1
  149. package/src/Field/PanelSearchInput.tsx +11 -0
  150. package/src/InfoTip/InfoTip.doc.mjs +3 -3
  151. package/src/InfoTip/InfoTip.tsx +5 -5
  152. package/src/Layer/layerAnimations.stylex.ts +24 -16
  153. package/src/Layer/usePressPin.ts +5 -11
  154. package/src/MobileNav/MobileNav.tsx +1 -1
  155. package/src/MultiSelector/hooks.ts +2 -4
  156. package/src/Outline/Outline.doc.mjs +177 -51
  157. package/src/Outline/Outline.tsx +5 -57
  158. package/src/Outline/useOutlineFromMarkdown.doc.mjs +157 -0
  159. package/src/Outline/useOutlineFromMarkdown.ts +1 -0
  160. package/src/Outline/useScrollSpy.ts +3 -3
  161. package/src/PowerSearch/PowerSearch.doc.mjs +3 -3
  162. package/src/PowerSearch/PowerSearch.tsx +196 -183
  163. package/src/RadioList/RadioList.doc.mjs +4 -2
  164. package/src/RadioList/RadioList.tsx +4 -0
  165. package/src/Resizable/ResizeHandle.tsx +133 -328
  166. package/src/Resizable/resizeGesture.ts +368 -0
  167. package/src/SideNav/SideNavItem.tsx +3 -7
  168. package/src/Token/Token.tsx +13 -4
  169. package/src/Token/TokenNamingContext.ts +28 -0
  170. package/src/Tokenizer/Tokenizer.doc.mjs +16 -0
  171. package/src/Tokenizer/Tokenizer.tsx +81 -86
  172. package/src/Tokenizer/TokenizerBottomSheet.tsx +219 -93
  173. package/src/Tokenizer/TokenizerItemRemovableContext.ts +5 -3
  174. package/src/Tooltip/Tooltip.doc.mjs +123 -54
  175. package/src/Tooltip/Tooltip.tsx +36 -39
  176. package/src/Tooltip/index.ts +0 -1
  177. package/src/Tooltip/useTooltip.doc.mjs +147 -33
  178. package/src/Tooltip/useTooltip.tsx +39 -32
  179. package/src/TopNav/TopNavItem.tsx +6 -5
  180. package/src/TopNav/TopNavMegaMenuItem.tsx +6 -5
  181. package/src/TopNav/TopNavMenu.tsx +6 -5
  182. package/src/gestures/GestureHost.ts +105 -10
  183. package/src/hooks/useHighlightedOptionScroll.ts +113 -9
  184. package/src/hooks/useMenuPress.ts +8 -2
  185. package/src/i18n/generated-english/PowerSearch/PowerSearch.generated.ts +1 -0
  186. package/src/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.ts +7 -1
  187. package/src/i18n/generated-locales/en.generated.ts +1 -0
  188. package/src/i18n/generated-locales/pseudo.generated.ts +1 -0
  189. package/src/internal/SheetConfirmation.tsx +101 -0
  190. package/src/internal/sheetDraft.ts +80 -0
  191. package/src/internal/touch-sheet.ts +21 -0
  192. package/src/internal/useDismissSearchOnTouchDrag.ts +69 -0
  193. package/src/motion/reducedMotion.ts +79 -1
  194. package/src/utils/clickGuard.ts +37 -1
  195. package/dist/internal/tokenizer-presentation.d.ts +0 -21
  196. package/dist/internal/tokenizer-presentation.d.ts.map +0 -1
  197. package/dist/internal/tokenizer-presentation.js +0 -21
  198. 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: "x1gg8mnh",
66
- k8WAf4: "xce4md1",
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
- * Rows keep their position while the sheet is open: the items selected when it
97
- * opened lead, in `value` order, then selected items the results do not carry,
98
- * then the results. Toggling a row changes its checkbox and nothing else; the
99
- * next open takes a fresh snapshot and regroups selected-first.
100
- */
101
- /**
102
- * The sheet: BottomSheet around the content. Split in two so the content —
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 (`spec:AST-086` FR14): a component that renders a modal and announces
106
- * about its content is inside that modal only when the announcing code is.
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 (Done, swipe, scrim, Escape) clears the query so the next open
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 (`component:Tokenizer` FR18).
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
- const requestClose = () => {
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
- requestClose();
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
- onRequestClose: requestClose
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
- onRequestClose,
164
+ requestDismissRef,
165
+ onCloseSheet,
156
166
  label,
157
167
  searchSource,
158
168
  value,
159
- isAtMax,
169
+ maxEntries,
160
170
  hasCreate,
161
171
  maxMenuItems,
162
172
  minQueryLength,
163
173
  debounceMs,
164
174
  emptySearchText,
165
- onAdd,
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
- const selectedIds = useMemo(() => new Set(value.map(v => v.id)), [value]);
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 = value.filter(item => !selectedAtOpenIds.has(item.id) && !resultIds.has(item.id) && matchesQuery(item));
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, value]);
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) || value.some(item => item.label.toLowerCase() === lowered) || results.some(item => item.label.toLowerCase() === lowered)) {
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, value, results, t]);
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
- if (onAdd(createItem, {
543
- silent: true
544
- })) {
545
- // The created value, as the inline field announces it; the
546
- // item's label is the row's caption ("Create …").
547
- announce(t('@astryx.tokenizer.tokenAdded', {
548
- label: trimmedQuery
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
- if (onRemove(item, {
635
- silent: true
636
- })) {
637
- announce(t('@astryx.tokenizer.tokenRemoved', {
638
- label: item.label
639
- }));
640
- }
641
- } else if (onAdd(item, {
642
- silent: true
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
- }), isQueryEmpty && /*#__PURE__*/_jsxs("div", {
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: value.length === 0
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: value.length === 0 ? t('@astryx.tokenizer.nothingToClear') : undefined,
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.done'),
761
+ label: t('@astryx.tokenizer.save'),
693
762
  variant: "primary",
694
763
  size: "lg",
695
- onClick: onRequestClose,
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(AlertDialog, {
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
- onClearAll();
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":"AAgBA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAEvD,eAAO,MAAM,6BAA6B,kCAChC,cAAc,KAAK,OAAO,SAC7B,CAAC"}
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: every
12
- * filter of a read-only field) provides it. Backspace then removes nothing
13
- * while the last token is locked. Without it, every token is removable.
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 TooltipTriggerBehavior, type TooltipTouchTrigger } from './useTooltip.js';
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, TooltipTriggerBehavior, TooltipTouchTrigger, } from './useTooltip.js';
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({ children, anchorRef, content, placement, alignment, delay, hideDelay, focusTrigger, touchTrigger, triggerBehavior, isEnabled, onOpenChange, hasHoverIndication, isOpen, isDefaultOpen, }: TooltipProps): ReactElement;
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;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,EAGZ,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACzB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAC,cAAc,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAGtE,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAiBtB,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;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAEnC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,eAAe,CAAC,EAAE,sBAAsB,CAAC;IAEzC;;;;;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,EACtB,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,YAAY,GAAG,YAAY,CAkK7B;yBAlLe,OAAO"}
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"}
@@ -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 { useTooltip } from "./useTooltip.js";
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 { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
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 = useTooltip({
102
+ const tooltip = useTooltipWithTriggerBehavior({
84
103
  placement,
85
104
  alignment,
86
105
  delay,
@@ -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, TooltipTriggerBehavior, TooltipTouchTrigger, TooltipOptions, TooltipReturn, } from './useTooltip.js';
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,sBAAsB,EACtB,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"}
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"}