@astryxdesign/core 0.4.3 → 0.4.4-canary.0e8af82

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 (254) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +79 -45
  3. package/dist/Banner/Banner.d.ts +3 -0
  4. package/dist/Banner/Banner.d.ts.map +1 -1
  5. package/dist/Banner/Banner.js +13 -3
  6. package/dist/BottomSheet/BottomSheet.d.ts +75 -0
  7. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -0
  8. package/dist/BottomSheet/BottomSheet.js +396 -0
  9. package/dist/BottomSheet/BottomSheetPanel.d.ts +63 -0
  10. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -0
  11. package/dist/BottomSheet/BottomSheetPanel.js +441 -0
  12. package/dist/BottomSheet/BottomSheetSwitcher.d.ts +61 -0
  13. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -0
  14. package/dist/BottomSheet/BottomSheetSwitcher.js +410 -0
  15. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts +21 -0
  16. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts.map +1 -0
  17. package/dist/BottomSheet/BottomSheetSwitcherContext.js +13 -0
  18. package/dist/BottomSheet/index.d.ts +11 -0
  19. package/dist/BottomSheet/index.d.ts.map +1 -0
  20. package/dist/BottomSheet/index.js +12 -0
  21. package/dist/BottomSheet/snapOffsets.d.ts +109 -0
  22. package/dist/BottomSheet/snapOffsets.d.ts.map +1 -0
  23. package/dist/BottomSheet/snapOffsets.js +206 -0
  24. package/dist/BottomSheet/useMobileKeyboard.d.ts +35 -0
  25. package/dist/BottomSheet/useMobileKeyboard.d.ts.map +1 -0
  26. package/dist/BottomSheet/useMobileKeyboard.js +373 -0
  27. package/dist/BottomSheet/useSheetGestures.d.ts +185 -0
  28. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -0
  29. package/dist/BottomSheet/useSheetGestures.js +1038 -0
  30. package/dist/Calendar/Calendar.d.ts +17 -0
  31. package/dist/Calendar/Calendar.d.ts.map +1 -1
  32. package/dist/Calendar/Calendar.js +25 -1
  33. package/dist/Calendar/hooks/useCalendarConstraints.d.ts +22 -1
  34. package/dist/Calendar/hooks/useCalendarConstraints.d.ts.map +1 -1
  35. package/dist/Calendar/hooks/useCalendarConstraints.js +26 -4
  36. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  37. package/dist/Chat/ChatComposerInput.js +3 -4
  38. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  39. package/dist/CheckboxInput/CheckboxInput.js +9 -0
  40. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  41. package/dist/ComplexSelector/ComplexSelector.js +18 -7
  42. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  43. package/dist/ContextMenu/ContextMenu.js +4 -2
  44. package/dist/DateInput/DateInput.d.ts.map +1 -1
  45. package/dist/DateInput/DateInput.js +15 -2
  46. package/dist/DateRangeInput/DateRangeInput.d.ts +23 -1
  47. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  48. package/dist/DateRangeInput/DateRangeInput.js +38 -3
  49. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  50. package/dist/DateTimeInput/DateTimeInput.js +38 -3
  51. package/dist/Dialog/Dialog.d.ts.map +1 -1
  52. package/dist/Dialog/Dialog.js +2 -1
  53. package/dist/Field/FieldLabel.d.ts +2 -1
  54. package/dist/Field/FieldLabel.d.ts.map +1 -1
  55. package/dist/Field/FieldLabel.js +21 -3
  56. package/dist/Field/InputClearButton.d.ts +2 -1
  57. package/dist/Field/InputClearButton.d.ts.map +1 -1
  58. package/dist/Field/InputClearButton.js +6 -1
  59. package/dist/FormLayout/FormLayout.d.ts +24 -2
  60. package/dist/FormLayout/FormLayout.d.ts.map +1 -1
  61. package/dist/FormLayout/FormLayout.js +7 -2
  62. package/dist/FormLayout/FormLayoutContext.d.ts +15 -2
  63. package/dist/FormLayout/FormLayoutContext.d.ts.map +1 -1
  64. package/dist/FormLayout/FormLayoutContext.js +19 -4
  65. package/dist/FormLayout/index.d.ts +1 -1
  66. package/dist/FormLayout/index.d.ts.map +1 -1
  67. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  68. package/dist/Lightbox/Lightbox.js +9 -3
  69. package/dist/MobileNav/MobileNav.d.ts +12 -0
  70. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  71. package/dist/MobileNav/MobileNav.js +102 -30
  72. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  73. package/dist/MultiSelector/MultiSelector.js +27 -8
  74. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  75. package/dist/NumberInput/NumberInput.js +15 -2
  76. package/dist/PowerSearch/PowerSearchEditPopover.js +1 -1
  77. package/dist/RadioList/RadioList.d.ts.map +1 -1
  78. package/dist/RadioList/RadioList.js +12 -1
  79. package/dist/Selector/Selector.d.ts.map +1 -1
  80. package/dist/Selector/Selector.js +20 -4
  81. package/dist/StatusDot/StatusDot.d.ts +43 -3
  82. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  83. package/dist/StatusDot/StatusDot.js +42 -5
  84. package/dist/Switch/Switch.d.ts.map +1 -1
  85. package/dist/Switch/Switch.js +14 -1
  86. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  87. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
  88. package/dist/TextArea/TextArea.d.ts.map +1 -1
  89. package/dist/TextArea/TextArea.js +6 -1
  90. package/dist/TextInput/TextInput.d.ts.map +1 -1
  91. package/dist/TextInput/TextInput.js +6 -1
  92. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  93. package/dist/TimeInput/TimeInput.js +14 -2
  94. package/dist/Tokenizer/Tokenizer.js +11 -5
  95. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  96. package/dist/Tooltip/useTooltip.js +4 -1
  97. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  98. package/dist/Typeahead/BaseTypeahead.js +5 -3
  99. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  100. package/dist/Typeahead/Typeahead.js +10 -1
  101. package/dist/astryx.css +21 -0
  102. package/dist/hooks/index.d.ts +8 -1
  103. package/dist/hooks/index.d.ts.map +1 -1
  104. package/dist/hooks/index.js +8 -1
  105. package/dist/hooks/useFocusTrap.d.ts +0 -11
  106. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  107. package/dist/hooks/useFocusTrap.js +1 -11
  108. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  109. package/dist/hooks/useInputStatusIcon.js +1 -0
  110. package/dist/hooks/useResolvedRequired.d.ts +19 -0
  111. package/dist/hooks/useResolvedRequired.d.ts.map +1 -0
  112. package/dist/hooks/useResolvedRequired.js +40 -0
  113. package/dist/index.d.ts +1 -0
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.js +1 -0
  116. package/dist/theme/defineTheme.d.ts +22 -4
  117. package/dist/theme/defineTheme.d.ts.map +1 -1
  118. package/dist/theme/expandColorScale.d.ts +17 -2
  119. package/dist/theme/expandColorScale.d.ts.map +1 -1
  120. package/dist/theme/expandColorScale.js +63 -33
  121. package/dist/utils/ime.d.ts +5 -0
  122. package/dist/utils/ime.d.ts.map +1 -0
  123. package/dist/utils/ime.js +63 -0
  124. package/dist/utils/index.d.ts +1 -0
  125. package/dist/utils/index.d.ts.map +1 -1
  126. package/dist/utils/index.js +2 -1
  127. package/dist/utils/plainDate.d.ts +6 -0
  128. package/dist/utils/plainDate.d.ts.map +1 -1
  129. package/dist/utils/plainDate.js +12 -0
  130. package/locales/af-ZA.json +958 -0
  131. package/locales/ar-SA.json +998 -0
  132. package/locales/ca-ES.json +974 -0
  133. package/locales/cs-CZ.json +990 -0
  134. package/locales/da-DK.json +966 -0
  135. package/locales/de-DE.json +966 -0
  136. package/locales/el-GR.json +990 -0
  137. package/locales/en.json +52 -0
  138. package/locales/es-ES.json +978 -0
  139. package/locales/fi-FI.json +990 -0
  140. package/locales/fr-FR.json +928 -0
  141. package/locales/he-IL.json +990 -0
  142. package/locales/hu-HU.json +990 -0
  143. package/locales/it-IT.json +978 -0
  144. package/locales/ja-JP.json +998 -0
  145. package/locales/ko-KR.json +990 -0
  146. package/locales/nl-NL.json +954 -0
  147. package/locales/no-NO.json +978 -0
  148. package/locales/pl-PL.json +982 -0
  149. package/locales/pseudo.json +39 -0
  150. package/locales/pt-BR.json +982 -0
  151. package/locales/pt-PT.json +982 -0
  152. package/locales/ro-RO.json +982 -0
  153. package/locales/ru-RU.json +990 -0
  154. package/locales/sr-SP.json +990 -0
  155. package/locales/sv-SE.json +986 -0
  156. package/locales/tr-TR.json +990 -0
  157. package/locales/uk-UA.json +990 -0
  158. package/locales/vi-VN.json +986 -0
  159. package/locales/zh-CN.json +998 -0
  160. package/locales/zh-TW.json +998 -0
  161. package/package.json +9 -8
  162. package/src/Banner/Banner.doc.mjs +3 -3
  163. package/src/Banner/Banner.test.tsx +40 -0
  164. package/src/Banner/Banner.tsx +27 -2
  165. package/src/BottomSheet/BottomSheet.doc.mjs +299 -0
  166. package/src/BottomSheet/BottomSheet.test.tsx +2265 -0
  167. package/src/BottomSheet/BottomSheet.tsx +559 -0
  168. package/src/BottomSheet/BottomSheetPanel.test.tsx +240 -0
  169. package/src/BottomSheet/BottomSheetPanel.tsx +601 -0
  170. package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +219 -0
  171. package/src/BottomSheet/BottomSheetSwitcher.test.tsx +850 -0
  172. package/src/BottomSheet/BottomSheetSwitcher.tsx +628 -0
  173. package/src/BottomSheet/BottomSheetSwitcherContext.ts +51 -0
  174. package/src/BottomSheet/index.ts +19 -0
  175. package/src/BottomSheet/snapOffsets.test.ts +254 -0
  176. package/src/BottomSheet/snapOffsets.ts +245 -0
  177. package/src/BottomSheet/useMobileKeyboard.ts +499 -0
  178. package/src/BottomSheet/useSheetGestures.test.ts +1112 -0
  179. package/src/BottomSheet/useSheetGestures.ts +1503 -0
  180. package/src/Calendar/Calendar.doc.mjs +16 -0
  181. package/src/Calendar/Calendar.test.tsx +96 -0
  182. package/src/Calendar/Calendar.tsx +55 -0
  183. package/src/Calendar/hooks/useCalendarConstraints.ts +54 -3
  184. package/src/Chat/ChatComposerInput.tsx +3 -4
  185. package/src/CheckboxInput/CheckboxInput.tsx +6 -0
  186. package/src/ComplexSelector/ComplexSelector.tsx +15 -6
  187. package/src/ContextMenu/ContextMenu.tsx +4 -2
  188. package/src/DateInput/DateInput.test.tsx +21 -0
  189. package/src/DateInput/DateInput.tsx +12 -2
  190. package/src/DateRangeInput/DateRangeInput.doc.mjs +16 -0
  191. package/src/DateRangeInput/DateRangeInput.test.tsx +81 -1
  192. package/src/DateRangeInput/DateRangeInput.tsx +72 -1
  193. package/src/DateTimeInput/DateTimeInput.doc.mjs +4 -0
  194. package/src/DateTimeInput/DateTimeInput.test.tsx +137 -0
  195. package/src/DateTimeInput/DateTimeInput.tsx +43 -4
  196. package/src/Dialog/Dialog.tsx +2 -1
  197. package/src/Field/Field.doc.mjs +1 -0
  198. package/src/Field/FieldLabel.tsx +20 -4
  199. package/src/Field/InputClearButton.test.tsx +25 -0
  200. package/src/Field/InputClearButton.tsx +4 -1
  201. package/src/FileInput/FileInput.test.tsx +53 -9
  202. package/src/FormLayout/FormLayout.doc.mjs +13 -0
  203. package/src/FormLayout/FormLayout.test.tsx +181 -4
  204. package/src/FormLayout/FormLayout.tsx +33 -2
  205. package/src/FormLayout/FormLayoutContext.ts +22 -7
  206. package/src/FormLayout/index.ts +1 -1
  207. package/src/Lightbox/Lightbox.test.tsx +49 -28
  208. package/src/Lightbox/Lightbox.tsx +7 -3
  209. package/src/MobileNav/MobileNav.tsx +128 -37
  210. package/src/MobileNav/MobileNavCloseEdgeCases.test.tsx +426 -0
  211. package/src/MobileNav/MobileNavCloseTiming.test.ts +58 -0
  212. package/src/MobileNav/MobileNavCloseVisibility.test.tsx +172 -0
  213. package/src/MultiSelector/MultiSelector.test.tsx +195 -51
  214. package/src/MultiSelector/MultiSelector.tsx +25 -9
  215. package/src/NumberInput/NumberInput.test.tsx +18 -0
  216. package/src/NumberInput/NumberInput.tsx +12 -2
  217. package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
  218. package/src/RadioList/RadioList.tsx +9 -1
  219. package/src/Selector/Selector.test.tsx +85 -26
  220. package/src/Selector/Selector.tsx +16 -5
  221. package/src/StatusDot/StatusDot.doc.mjs +13 -0
  222. package/src/StatusDot/StatusDot.test.tsx +115 -8
  223. package/src/StatusDot/StatusDot.tsx +74 -9
  224. package/src/Switch/Switch.test.tsx +16 -0
  225. package/src/Switch/Switch.tsx +13 -0
  226. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +20 -2
  227. package/src/TextArea/TextArea.tsx +3 -1
  228. package/src/TextInput/TextInput.tsx +3 -1
  229. package/src/TimeInput/TimeInput.test.tsx +23 -0
  230. package/src/TimeInput/TimeInput.tsx +11 -1
  231. package/src/Tokenizer/Tokenizer.test.tsx +50 -32
  232. package/src/Tokenizer/Tokenizer.tsx +5 -5
  233. package/src/Tooltip/useTooltip.tsx +4 -1
  234. package/src/Typeahead/BaseTypeahead.tsx +10 -3
  235. package/src/Typeahead/Typeahead.test.tsx +116 -7
  236. package/src/Typeahead/Typeahead.tsx +10 -1
  237. package/src/__tests__/stubMatchMedia.test.ts +79 -0
  238. package/src/__tests__/stubMatchMedia.ts +95 -0
  239. package/src/hooks/index.ts +9 -5
  240. package/src/hooks/useFocusTrap.ts +1 -14
  241. package/src/hooks/useInputStatusIcon.test.tsx +19 -0
  242. package/src/hooks/useInputStatusIcon.tsx +7 -0
  243. package/src/hooks/useResolvedRequired.ts +42 -0
  244. package/src/index.ts +1 -0
  245. package/src/theme/defineTheme.ts +22 -4
  246. package/src/theme/expandColorScale.test.ts +138 -0
  247. package/src/theme/expandColorScale.ts +89 -44
  248. package/src/utils/ime.test.ts +32 -0
  249. package/src/utils/ime.ts +69 -0
  250. package/src/utils/index.ts +2 -0
  251. package/src/utils/plainDate.test.ts +50 -0
  252. package/src/utils/plainDate.ts +12 -0
  253. package/dist/astryx.umd.js +0 -147
  254. package/dist/astryx.umd.js.map +0 -7
@@ -0,0 +1,410 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file BottomSheetSwitcher.tsx
7
+ * @input Uses React context, StyleX, theme tokens, focus/scroll-lock hooks, BottomSheetSwitcherContext
8
+ * @output Exports BottomSheetSwitcher and BottomSheetSwitcherProps
9
+ * @position Core switcher for mutually exclusive BottomSheet flows
10
+ *
11
+ * The switcher turns a set of declaratively nested BottomSheets into a
12
+ * controlled single-selection group: `activeSheet` names the one interactive
13
+ * child, or is null when the flow is closed. During a handoff the new sheet
14
+ * enters above the previous sheet. If it is shorter, the previous sheet moves
15
+ * down at the same time until their top edges align; otherwise it stays
16
+ * stationary. The previous sheet fades only after both motions complete.
17
+ *
18
+ * All child sheets render as panels inside one switcher-owned `<dialog>`. A
19
+ * scrim flow calls showModal() once and keeps that native top-layer dialog open
20
+ * across every handoff. A no-scrim flow calls show() on the same non-modal shell.
21
+ * This keeps one modal boundary and one native ::backdrop without a portal.
22
+ *
23
+ * SYNC: When modified, update these files to stay in sync:
24
+ * - /packages/core/src/BottomSheet/BottomSheet.tsx
25
+ * - /packages/core/src/BottomSheet/BottomSheetSwitcher.doc.mjs
26
+ * - /packages/core/src/BottomSheet/BottomSheetSwitcher.test.tsx
27
+ * - /packages/core/src/BottomSheet/index.ts
28
+ * - /apps/storybook/stories/BottomSheetSwitcher.stories.tsx
29
+ * - /packages/cli/assets/templates/blocks/components/BottomSheet/BottomSheetSwitcherShowcase.tsx
30
+ */
31
+ import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
32
+ import * as stylex from '@stylexjs/stylex';
33
+ import "../theme/tokens.stylex.js";
34
+ import { colorVars, durationVars, easeVars } from "../theme/tokens.stylex.js";
35
+ import { hasActiveFocusTrapEscape, isImeKeyEvent, useFocusTrap, useScrollLock } from "../hooks/index.js";
36
+ import { composeEventHandlers, mergeProps, mergeRefs } from "../utils/index.js";
37
+ import { BottomSheetSwitcherContext } from "./BottomSheetSwitcherContext.js";
38
+ import { jsx as _jsx } from "react/jsx-runtime";
39
+ const styles = {
40
+ dialog: {
41
+ kVAEAm: "xixxii4",
42
+ kpwlN0: "x10a8y8t",
43
+ kzqmXN: "x1o6l61p",
44
+ kZKoxP: "xtdtrs8",
45
+ ks0D6T: "x1x1rfll",
46
+ kskxy: "x7ab17h",
47
+ kogj98: "x1ghz6dp",
48
+ kmVPX3: "x1717udv",
49
+ kWkggS: "xjbqb8w",
50
+ kVQacm: "x1rea2x4",
51
+ k1xSpc: "x1s85apg",
52
+ kI3sdo: "x1a2a7pz",
53
+ $$css: true
54
+ },
55
+ dialogOpen: {
56
+ k1xSpc: "x1lliihq",
57
+ $$css: true
58
+ },
59
+ dialogNonModal: {
60
+ kfzvcC: "x47corl",
61
+ kY2c9j: "xfo81ep",
62
+ kzqmXN: "xh8yej3",
63
+ kZKoxP: "x5yr21d",
64
+ $$css: true
65
+ },
66
+ scrim: {
67
+ kGyWv1: "xnixb3f",
68
+ k5sjJv: "xni466t xxiuuzi",
69
+ kND0Po: "xc0dz0a",
70
+ k9an0g: "xft5bk6",
71
+ kb4ib: "x15h3t91",
72
+ kwHxkk: "x142juwg",
73
+ k4oj2o: "x1viac0w",
74
+ $$css: true
75
+ }
76
+ };
77
+ const IDLE_TRANSITION = {
78
+ enteringSheet: null,
79
+ retainedSheet: null,
80
+ retainedPhase: null,
81
+ alignmentOffset: 0,
82
+ isAlignmentComplete: false
83
+ };
84
+ const ALIGNMENT_THRESHOLD_PX = 1;
85
+ function transitionForActiveSheetChange(previousSheet, nextSheet) {
86
+ if (previousSheet == null) {
87
+ return IDLE_TRANSITION;
88
+ }
89
+ if (nextSheet == null) {
90
+ return {
91
+ enteringSheet: null,
92
+ retainedSheet: previousSheet,
93
+ retainedPhase: 'exiting',
94
+ alignmentOffset: 0,
95
+ isAlignmentComplete: false
96
+ };
97
+ }
98
+ return {
99
+ enteringSheet: nextSheet,
100
+ retainedSheet: previousSheet,
101
+ retainedPhase: 'covered',
102
+ alignmentOffset: 0,
103
+ isAlignmentComplete: false
104
+ };
105
+ }
106
+ function alignmentOffsetForElements(enteringElement, retainedElement) {
107
+ if (enteringElement == null || retainedElement == null) {
108
+ return 0;
109
+ }
110
+ const enteringPositioner = enteringElement.parentElement;
111
+ const enteringTop = enteringPositioner?.getBoundingClientRect().top ?? enteringElement.getBoundingClientRect().top;
112
+ return Math.max(0, enteringTop - retainedElement.getBoundingClientRect().top);
113
+ }
114
+ /**
115
+ * Coordinates a set of BottomSheets so zero or one is active at a time inside
116
+ * one shared native dialog. During a handoff the previous panel stays visible
117
+ * and inert beneath the entering panel, then fades after motion completes.
118
+ */
119
+ export function BottomSheetSwitcher({
120
+ activeSheet,
121
+ onActiveSheetChange,
122
+ hasScrim = true,
123
+ children,
124
+ ref,
125
+ xstyle,
126
+ className,
127
+ style,
128
+ onCancel,
129
+ onClick,
130
+ onKeyDown,
131
+ ...props
132
+ }) {
133
+ const dialogRef = useRef(null);
134
+ const dialogModeRef = useRef(null);
135
+ const triggerRef = useRef(null);
136
+ const sheetElementsRef = useRef(new Map());
137
+ const committedActiveSheetRef = useRef(activeSheet);
138
+ const [sheetLabels, setSheetLabels] = useState(() => new Map());
139
+ const [sheetPurposes, setSheetPurposes] = useState(() => new Map());
140
+ const [unmountedSheetIds, setUnmountedSheetIds] = useState(() => new Set());
141
+ const [transition, setTransition] = useState(IDLE_TRANSITION);
142
+ const activeSheetChanged = committedActiveSheetRef.current !== activeSheet;
143
+ const visibleTransition = activeSheetChanged ? transitionForActiveSheetChange(committedActiveSheetRef.current, activeSheet) : transition;
144
+ const isFlowVisible = activeSheet != null && !unmountedSheetIds.has(activeSheet) || visibleTransition.retainedSheet != null && !unmountedSheetIds.has(visibleTransition.retainedSheet);
145
+ const isModal = hasScrim && isFlowVisible;
146
+ const activeSheetPurpose = (activeSheet == null ? null : sheetPurposes.get(activeSheet)) ?? 'info';
147
+ const allowsEscapeDismiss = activeSheetPurpose !== 'required';
148
+ const allowsLightDismiss = activeSheetPurpose === 'info';
149
+ useLayoutEffect(() => {
150
+ const previousActiveSheet = committedActiveSheetRef.current;
151
+ if (previousActiveSheet === activeSheet) {
152
+ return;
153
+ }
154
+ committedActiveSheetRef.current = activeSheet;
155
+ const nextTransition = transitionForActiveSheetChange(previousActiveSheet, activeSheet);
156
+ setTransition(nextTransition.retainedSheet != null && !sheetElementsRef.current.has(nextTransition.retainedSheet) ? IDLE_TRANSITION : nextTransition);
157
+ }, [activeSheet]);
158
+ const dismissOnEscape = useCallback(() => {
159
+ if (allowsEscapeDismiss) {
160
+ onActiveSheetChange(null);
161
+ }
162
+ }, [allowsEscapeDismiss, onActiveSheetChange]);
163
+ const dismissOnLightInteraction = useCallback(() => {
164
+ if (allowsLightDismiss) {
165
+ onActiveSheetChange(null);
166
+ }
167
+ }, [allowsLightDismiss, onActiveSheetChange]);
168
+ const {
169
+ containerRef
170
+ } = useFocusTrap({
171
+ isActive: isModal,
172
+ onEscape: dismissOnEscape
173
+ });
174
+ useScrollLock(isModal);
175
+
176
+ // Open one shared shell for the complete flow. Modal flows enter the native
177
+ // top layer once; handoffs only swap panels inside it. The final panel owns
178
+ // the exit timing, so isFlowVisible becomes false only when it is safe to
179
+ // close the dialog and restore focus.
180
+ useLayoutEffect(() => {
181
+ const dialog = dialogRef.current;
182
+ if (dialog == null) {
183
+ return;
184
+ }
185
+ if (isFlowVisible) {
186
+ const nextMode = hasScrim ? 'modal' : 'non-modal';
187
+ if (dialog.open && dialogModeRef.current !== nextMode) {
188
+ dialog.close();
189
+ }
190
+ if (!dialog.open) {
191
+ if (hasScrim && triggerRef.current == null) {
192
+ triggerRef.current = document.activeElement;
193
+ }
194
+ if (hasScrim) {
195
+ dialog.showModal();
196
+ } else {
197
+ dialog.show();
198
+ }
199
+ }
200
+ dialogModeRef.current = nextMode;
201
+ return;
202
+ }
203
+ if (dialog.open) {
204
+ dialog.close();
205
+ }
206
+ if (dialogModeRef.current === 'modal') {
207
+ triggerRef.current?.focus();
208
+ }
209
+ triggerRef.current = null;
210
+ dialogModeRef.current = null;
211
+ }, [hasScrim, isFlowVisible]);
212
+ const getSheetPhase = useCallback(sheetId => {
213
+ if (sheetId === activeSheet) {
214
+ return sheetId === visibleTransition.enteringSheet ? 'entering' : 'active';
215
+ }
216
+ if (sheetId === visibleTransition.retainedSheet) {
217
+ return visibleTransition.retainedPhase ?? 'hidden';
218
+ }
219
+ return 'hidden';
220
+ }, [activeSheet, visibleTransition]);
221
+ const getSheetAlignmentOffset = useCallback(sheetId => visibleTransition.retainedSheet === sheetId ? visibleTransition.alignmentOffset : 0, [visibleTransition]);
222
+ const registerSheetElement = useCallback((sheetId, element) => {
223
+ if (element == null) {
224
+ sheetElementsRef.current.delete(sheetId);
225
+ setUnmountedSheetIds(current => {
226
+ if (current.has(sheetId)) {
227
+ return current;
228
+ }
229
+ const next = new Set(current);
230
+ next.add(sheetId);
231
+ return next;
232
+ });
233
+ setTransition(current => current.retainedSheet === sheetId ? IDLE_TRANSITION : current);
234
+ } else {
235
+ sheetElementsRef.current.set(sheetId, element);
236
+ setUnmountedSheetIds(current => {
237
+ if (!current.has(sheetId)) {
238
+ return current;
239
+ }
240
+ const next = new Set(current);
241
+ next.delete(sheetId);
242
+ return next;
243
+ });
244
+ }
245
+ }, []);
246
+ const registerSheetLabel = useCallback((sheetId, label) => {
247
+ setSheetLabels(current => {
248
+ if (label == null) {
249
+ if (!current.has(sheetId)) {
250
+ return current;
251
+ }
252
+ const next = new Map(current);
253
+ next.delete(sheetId);
254
+ return next;
255
+ }
256
+ if (current.get(sheetId) === label) {
257
+ return current;
258
+ }
259
+ const next = new Map(current);
260
+ next.set(sheetId, label);
261
+ return next;
262
+ });
263
+ }, []);
264
+ const registerSheetPurpose = useCallback((sheetId, purpose) => {
265
+ setSheetPurposes(current => {
266
+ if (purpose == null) {
267
+ if (!current.has(sheetId)) {
268
+ return current;
269
+ }
270
+ const next = new Map(current);
271
+ next.delete(sheetId);
272
+ return next;
273
+ }
274
+ if (current.get(sheetId) === purpose) {
275
+ return current;
276
+ }
277
+ const next = new Map(current);
278
+ next.set(sheetId, purpose);
279
+ return next;
280
+ });
281
+ }, []);
282
+ useLayoutEffect(() => {
283
+ // eslint-disable-next-line @eslint-react/set-state-in-effect -- clear a retained sheet after its panel unmounts
284
+ setTransition(current => current.retainedSheet != null && unmountedSheetIds.has(current.retainedSheet) ? IDLE_TRANSITION : current);
285
+ }, [unmountedSheetIds]);
286
+ const onSheetEnterStart = useCallback(sheetId => {
287
+ setTransition(current => {
288
+ if (current.enteringSheet !== sheetId || current.retainedSheet == null || current.retainedPhase !== 'covered') {
289
+ return current;
290
+ }
291
+ const alignmentOffset = alignmentOffsetForElements(sheetElementsRef.current.get(sheetId), sheetElementsRef.current.get(current.retainedSheet));
292
+ if (alignmentOffset <= ALIGNMENT_THRESHOLD_PX) {
293
+ return current;
294
+ }
295
+ return {
296
+ ...current,
297
+ retainedPhase: 'aligning',
298
+ alignmentOffset,
299
+ isAlignmentComplete: false
300
+ };
301
+ });
302
+ }, []);
303
+ const onSheetTransitionComplete = useCallback(({
304
+ sheetId,
305
+ phase
306
+ }) => {
307
+ setTransition(current => {
308
+ if (phase === 'entering') {
309
+ if (current.enteringSheet !== sheetId) {
310
+ return current;
311
+ }
312
+ if (current.retainedSheet == null) {
313
+ return IDLE_TRANSITION;
314
+ }
315
+ if (current.retainedPhase === 'aligning' && !current.isAlignmentComplete) {
316
+ return {
317
+ ...current,
318
+ enteringSheet: null
319
+ };
320
+ }
321
+ return {
322
+ ...current,
323
+ enteringSheet: null,
324
+ retainedPhase: 'fading'
325
+ };
326
+ }
327
+ if (phase === 'aligning' && current.retainedSheet === sheetId && current.retainedPhase === 'aligning') {
328
+ return current.enteringSheet == null ? {
329
+ ...current,
330
+ retainedPhase: 'fading'
331
+ } : {
332
+ ...current,
333
+ isAlignmentComplete: true
334
+ };
335
+ }
336
+ if ((phase === 'fading' || phase === 'exiting') && current.retainedSheet === sheetId && current.retainedPhase === phase) {
337
+ return IDLE_TRANSITION;
338
+ }
339
+ return current;
340
+ });
341
+ }, []);
342
+ const setScrimOpacity = useCallback(opacity => {
343
+ dialogRef.current?.style.setProperty('--_sheet-scrim-opacity', String(opacity));
344
+ }, []);
345
+ const onSheetScrimOpacityChange = useCallback((sheetId, opacity) => {
346
+ // A pointer captured by the outgoing sheet can keep delivering gesture
347
+ // events after a handoff. Only the currently committed sheet owns the
348
+ // shared backdrop, so stale gesture updates must not reach the dialog.
349
+ if (sheetId !== committedActiveSheetRef.current) {
350
+ return;
351
+ }
352
+ setScrimOpacity(opacity);
353
+ }, [setScrimOpacity]);
354
+ useLayoutEffect(() => {
355
+ setScrimOpacity(activeSheet == null ? 0 : 1);
356
+ }, [activeSheet, setScrimOpacity]);
357
+ const contextValue = useMemo(() => ({
358
+ activeSheet,
359
+ hasScrim,
360
+ onActiveSheetChange,
361
+ getSheetPhase,
362
+ getSheetAlignmentOffset,
363
+ registerSheetElement,
364
+ registerSheetLabel,
365
+ registerSheetPurpose,
366
+ onSheetEnterStart,
367
+ onSheetTransitionComplete,
368
+ onSheetScrimOpacityChange
369
+ }), [activeSheet, getSheetAlignmentOffset, getSheetPhase, hasScrim, onActiveSheetChange, onSheetEnterStart, onSheetScrimOpacityChange, onSheetTransitionComplete, registerSheetElement, registerSheetLabel, registerSheetPurpose]);
370
+ const activeLabel = (activeSheet == null ? null : sheetLabels.get(activeSheet)) ?? (visibleTransition.retainedSheet == null ? undefined : sheetLabels.get(visibleTransition.retainedSheet));
371
+ const handleCancel = useCallback(event => {
372
+ event.preventDefault();
373
+ dismissOnEscape();
374
+ }, [dismissOnEscape]);
375
+ const handleKeyDown = useCallback(event => {
376
+ // Modal Escape is owned by useFocusTrap so nested traps can win. A
377
+ // non-modal switcher has no outer trap, so retain local dismissal while
378
+ // deferring to an active nested layer and ignoring IME cancellation.
379
+ if (!isModal && event.key === 'Escape' && !isImeKeyEvent(event.nativeEvent) && !hasActiveFocusTrapEscape()) {
380
+ event.preventDefault();
381
+ dismissOnEscape();
382
+ }
383
+ }, [dismissOnEscape, isModal]);
384
+ const handleClick = useCallback(event => {
385
+ if (hasScrim && event.target === event.currentTarget) {
386
+ dismissOnLightInteraction();
387
+ }
388
+ }, [dismissOnLightInteraction, hasScrim]);
389
+ const dialogStyleProps = stylex.props(styles.dialog, isFlowVisible && styles.dialogOpen, hasScrim && styles.scrim, !hasScrim && styles.dialogNonModal, xstyle);
390
+ const dialogPresentationProps = mergeProps(dialogStyleProps, className, style);
391
+ const ariaLabel = props['aria-label'] ?? (props['aria-labelledby'] == null ? activeLabel : undefined);
392
+ return /*#__PURE__*/_jsx(BottomSheetSwitcherContext, {
393
+ value: contextValue,
394
+ children: /*#__PURE__*/_jsx("dialog", {
395
+ ...props,
396
+ ...dialogPresentationProps,
397
+ ref: mergeRefs(ref, dialogRef, containerRef),
398
+ "aria-label": ariaLabel,
399
+ "aria-modal": isModal ? 'true' : undefined,
400
+ onCancel: composeEventHandlers(onCancel, handleCancel),
401
+ onClick: composeEventHandlers(onClick, handleClick),
402
+ onKeyDown: composeEventHandlers(onKeyDown, handleKeyDown),
403
+ ...(activeSheetPurpose === 'required' ? {
404
+ role: 'alertdialog'
405
+ } : undefined),
406
+ children: children
407
+ })
408
+ });
409
+ }
410
+ BottomSheetSwitcher.displayName = 'BottomSheetSwitcher';
@@ -0,0 +1,21 @@
1
+ import type { DialogPurpose } from '../Dialog';
2
+ export type BottomSheetSwitcherPhase = 'entering' | 'active' | 'covered' | 'aligning' | 'fading' | 'exiting' | 'hidden';
3
+ export interface BottomSheetSwitcherTransitionEvent {
4
+ sheetId: string;
5
+ phase: 'entering' | 'aligning' | 'fading' | 'exiting';
6
+ }
7
+ export interface BottomSheetSwitcherContextValue {
8
+ activeSheet: string | null;
9
+ hasScrim: boolean;
10
+ onActiveSheetChange: (sheetId: string | null) => void;
11
+ getSheetPhase: (sheetId: string) => BottomSheetSwitcherPhase;
12
+ getSheetAlignmentOffset: (sheetId: string) => number;
13
+ registerSheetElement: (sheetId: string, element: HTMLElement | null) => void;
14
+ registerSheetLabel: (sheetId: string, label: string | null) => void;
15
+ registerSheetPurpose: (sheetId: string, purpose: DialogPurpose | null) => void;
16
+ onSheetEnterStart: (sheetId: string) => void;
17
+ onSheetTransitionComplete: (event: BottomSheetSwitcherTransitionEvent) => void;
18
+ onSheetScrimOpacityChange: (sheetId: string, opacity: number) => void;
19
+ }
20
+ export declare const BottomSheetSwitcherContext: import("react").Context<BottomSheetSwitcherContextValue | null>;
21
+ //# sourceMappingURL=BottomSheetSwitcherContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BottomSheetSwitcherContext.d.ts","sourceRoot":"","sources":["../../src/BottomSheet/BottomSheetSwitcherContext.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,WAAW,CAAC;AAE7C,MAAM,MAAM,wBAAwB,GAChC,UAAU,GACV,QAAQ,GACR,SAAS,GACT,UAAU,GACV,QAAQ,GACR,SAAS,GACT,QAAQ,CAAC;AAEb,MAAM,WAAW,kCAAkC;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;CACvD;AAED,MAAM,WAAW,+BAA+B;IAC9C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,mBAAmB,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACtD,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,wBAAwB,CAAC;IAC7D,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACrD,oBAAoB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7E,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACpE,oBAAoB,EAAE,CACpB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,GAAG,IAAI,KAC1B,IAAI,CAAC;IACV,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,yBAAyB,EAAE,CACzB,KAAK,EAAE,kCAAkC,KACtC,IAAI,CAAC;IACV,yBAAyB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvE;AAED,eAAO,MAAM,0BAA0B,iEACsB,CAAC"}
@@ -0,0 +1,13 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file BottomSheetSwitcherContext.ts
7
+ * @input Uses React context
8
+ * @output Internal phase and lifecycle context shared by BottomSheetSwitcher and BottomSheet
9
+ * @position Private coordination layer for mutually exclusive BottomSheets
10
+ */
11
+ import { createContext } from 'react';
12
+ export const BottomSheetSwitcherContext = /*#__PURE__*/createContext(null);
13
+ BottomSheetSwitcherContext.displayName = 'BottomSheetSwitcherContext';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @file index.ts
3
+ * @input BottomSheet.tsx, BottomSheetSwitcher.tsx
4
+ * @output Re-exports the BottomSheet public API
5
+ * @position Component entry point; re-exported by /packages/core/src/index.ts
6
+ */
7
+ export { BottomSheet } from './BottomSheet';
8
+ export type { BottomSheetHeight, BottomSheetProps, BottomSheetSnapPoint, } from './BottomSheet';
9
+ export { BottomSheetSwitcher } from './BottomSheetSwitcher';
10
+ export type { BottomSheetSwitcherProps } from './BottomSheetSwitcher';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/BottomSheet/index.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAC1D,YAAY,EAAC,wBAAwB,EAAC,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,12 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file index.ts
7
+ * @input BottomSheet.tsx, BottomSheetSwitcher.tsx
8
+ * @output Re-exports the BottomSheet public API
9
+ * @position Component entry point; re-exported by /packages/core/src/index.ts
10
+ */
11
+ export { BottomSheet } from "./BottomSheet.js";
12
+ export { BottomSheetSwitcher } from "./BottomSheetSwitcher.js";
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @file snapOffsets.ts
3
+ * @input Pure geometry helpers — no React, no DOM.
4
+ * @output Resolves snap points and converts them to translateY offsets.
5
+ * @position Internal to BottomSheet; consumed by useSheetGestures and
6
+ * BottomSheetPanel, tested by snapOffsets.test.ts.
7
+ *
8
+ * A detent is represented as an offset in px from the fully-open position
9
+ * (0 = fully open, larger = more collapsed). The panel may render that offset
10
+ * as a translate or as a reduction in layout height. These
11
+ * helpers turn snap points into the shared offset list; they are pure so the
12
+ * geometry can be unit-tested without a DOM.
13
+ */
14
+ /**
15
+ * A height the sheet can rest at, expressed as the sheet's VISIBLE height:
16
+ *
17
+ * - a number in `(0, 1]` — a fraction of the viewport (`0.5` is half the
18
+ * screen), so the stop tracks rotation and window resizes;
19
+ * - a `'<n>%'` string — the same thing spelled in CSS;
20
+ * - a `'<n>px'` string — an absolute height that does not scale.
21
+ *
22
+ * Anything else — a unitless string, `calc()`, `vh`, `rem`, a number outside
23
+ * `(0, 1]` — is ignored with a dev warning. Percentages resolve against the
24
+ * layout viewport (`window.innerHeight`), the same box the height budgets are
25
+ * written against, so the mobile keyboard never moves a stop.
26
+ */
27
+ export type BottomSheetSnapPoint = number | string;
28
+ /**
29
+ * Detents whose resting offsets land within this many px of each other are
30
+ * treated as the same stop (the taller one wins). Stops the sheet from having
31
+ * two near-identical rest positions — e.g. when a content-hugging height sits
32
+ * a hair away from a fractional snap point.
33
+ */
34
+ export declare const DETENT_DEDUP_PX = 48;
35
+ /**
36
+ * Largest share of the fully open sheet the shortest stop may fill and still
37
+ * be a peek. Above it the stop is a working surface — it lays its content out
38
+ * and keeps a full scrim — so a two-stop sheet like `[0.5]` behaves like the
39
+ * half-height panel it asks for rather than like a glance.
40
+ */
41
+ export declare const PEEK_MAX_HEIGHT_RATIO = 0.25;
42
+ /**
43
+ * Whether a snap point can be resolved at all. The viewport only scales the
44
+ * result, so validity is independent of it.
45
+ */
46
+ export declare function isValidSnapPoint(point: BottomSheetSnapPoint): boolean;
47
+ /**
48
+ * Resolve snap points to candidate visible heights in px, dropping the ones
49
+ * this sheet cannot honor. Callers warn about those separately — this stays
50
+ * silent because it runs on every drag frame.
51
+ */
52
+ export declare function resolveSnapPoints(points: ReadonlyArray<BottomSheetSnapPoint>, viewportPx: number): number[];
53
+ /**
54
+ * Given the sheet's full height (px, as rendered fully open) and a set of
55
+ * candidate detent *visible heights* (px), return the resting offsets from
56
+ * fully-open, ascending and de-duplicated.
57
+ *
58
+ * - `0` (fully open) is always the first detent.
59
+ * - Only heights strictly shorter than the sheet become collapsed detents; a
60
+ * height >= the sheet is already covered by the fully-open stop.
61
+ * - Offsets closer than `dedupPx` collapse to the smaller (taller) offset, so
62
+ * near-identical detents — e.g. a hug height ≈ a snap point — become one stop.
63
+ */
64
+ export declare function computeDetentOffsets(sheetHeight: number, detentHeights: ReadonlyArray<number>, dedupPx?: number): number[];
65
+ /** Nearest value in `offsets` to `value` (offsets must be non-empty). */
66
+ export declare function nearestOffset(value: number, offsets: ReadonlyArray<number>): number;
67
+ /**
68
+ * Minimum scrim opacity at the peek detent. The scrim thins to a glance state
69
+ * but never fully vanishes, because a modal sheet keeps the background inert —
70
+ * a fully clear backdrop would read as "interactive" when it isn't. (For a
71
+ * genuinely interactive, undimmed peek, use a non-modal sheet, `hasScrim=false`.)
72
+ */
73
+ export declare const MIN_PEEK_SCRIM_OPACITY = 0.3;
74
+ /**
75
+ * The peek detent's offset, or `null` when this sheet has no peek.
76
+ *
77
+ * A peek is the shortest stop AND a sliver — at most `PEEK_MAX_HEIGHT_RATIO`
78
+ * of the fully open sheet. It is the one detent the sheet does NOT express as
79
+ * layout height: at a sliver there is nothing useful to lay out, and reflowing
80
+ * the content into it (then back out on the way up) is churn the user sees, so
81
+ * it keeps the full layout height and slides below the viewport instead. It is
82
+ * also the only stop that thins the scrim.
83
+ *
84
+ * A sheet whose shortest stop is a working height — `[0.5]`, say — has no
85
+ * peek: half a screen of content deserves to be laid out at half a screen, and
86
+ * a scrim that thinned there would read as a dismissed sheet.
87
+ */
88
+ export declare function peekOffsetFor(offsets: ReadonlyArray<number>, visibleSheetHeight: number): number | null;
89
+ /**
90
+ * Scrim opacity (1 = fully visible) for a drag/settle `offset`.
91
+ *
92
+ * The scrim is full down to the shortest stop that is still a working surface,
93
+ * and only thins past it — onto a peek, where it holds at
94
+ * `MIN_PEEK_SCRIM_OPACITY` (a glance state, and the sheet is still modal), or
95
+ * out through the dismiss overshoot toward `dismissOffset`, where it clears
96
+ * completely because the sheet is leaving.
97
+ *
98
+ * So a sheet whose stops are all working heights keeps a full scrim at every
99
+ * one of them; only the sliver of a peek, or a sheet on its way out, dims less.
100
+ */
101
+ export declare function scrimOpacityForOffset(offset: number, offsets: ReadonlyArray<number>, dismissOffset: number, peekOffset: number | null): number;
102
+ /**
103
+ * Settle target for a released drag. Restricts candidates to the drag
104
+ * direction so a committed drag never snaps *back past* where it started
105
+ * (a down-drag settles at/below the start, an up-drag at/above), then picks
106
+ * the nearest remaining detent. `dir`: 1 = dragged down, -1 = up, 0 = neither.
107
+ */
108
+ export declare function resolveSettleOffset(value: number, offsets: ReadonlyArray<number>, dir: number, baseOffset: number): number;
109
+ //# sourceMappingURL=snapOffsets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapOffsets.d.ts","sourceRoot":"","sources":["../../src/BottomSheet/snapOffsets.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAkC1C;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAErE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,aAAa,CAAC,oBAAoB,CAAC,EAC3C,UAAU,EAAE,MAAM,GACjB,MAAM,EAAE,CASV;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,EACpC,OAAO,GAAE,MAAwB,GAChC,MAAM,EAAE,CAcV;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAC7B,MAAM,CAKR;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,kBAAkB,EAAE,MAAM,GACzB,MAAM,GAAG,IAAI,CASf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,CAgBR;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GACjB,MAAM,CAcR"}