@expofp/ui 0.0.0-experimental.2d6c681

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 (192) hide show
  1. package/README.md +30 -0
  2. package/dist/components/Alert/Alert.d.ts +20 -0
  3. package/dist/components/Alert/Alert.js +23 -0
  4. package/dist/components/Alert/index.d.ts +3 -0
  5. package/dist/components/Alert/index.js +1 -0
  6. package/dist/components/Autocomplete/Autocomplete.d.ts +28 -0
  7. package/dist/components/Autocomplete/Autocomplete.js +292 -0
  8. package/dist/components/Autocomplete/index.d.ts +3 -0
  9. package/dist/components/Autocomplete/index.js +1 -0
  10. package/dist/components/Badge/Badge.d.ts +14 -0
  11. package/dist/components/Badge/Badge.js +15 -0
  12. package/dist/components/Badge/index.d.ts +3 -0
  13. package/dist/components/Badge/index.js +1 -0
  14. package/dist/components/Button/Button.d.ts +30 -0
  15. package/dist/components/Button/Button.js +41 -0
  16. package/dist/components/Button/index.d.ts +3 -0
  17. package/dist/components/Button/index.js +1 -0
  18. package/dist/components/Checkbox/Checkbox.d.ts +19 -0
  19. package/dist/components/Checkbox/Checkbox.js +19 -0
  20. package/dist/components/Checkbox/index.d.ts +3 -0
  21. package/dist/components/Checkbox/index.js +1 -0
  22. package/dist/components/CheckboxButton/CheckboxButton.d.ts +12 -0
  23. package/dist/components/CheckboxButton/CheckboxButton.js +19 -0
  24. package/dist/components/CheckboxButton/index.d.ts +3 -0
  25. package/dist/components/CheckboxButton/index.js +1 -0
  26. package/dist/components/DownloadList/DownloadList.d.ts +15 -0
  27. package/dist/components/DownloadList/DownloadList.js +9 -0
  28. package/dist/components/DownloadList/index.d.ts +3 -0
  29. package/dist/components/DownloadList/index.js +2 -0
  30. package/dist/components/Draggable/Draggable.d.ts +9 -0
  31. package/dist/components/Draggable/Draggable.js +92 -0
  32. package/dist/components/Draggable/index.d.ts +3 -0
  33. package/dist/components/Draggable/index.js +2 -0
  34. package/dist/components/EntityItem/EntityItem.d.ts +46 -0
  35. package/dist/components/EntityItem/EntityItem.js +29 -0
  36. package/dist/components/EntityItem/index.d.ts +3 -0
  37. package/dist/components/EntityItem/index.js +1 -0
  38. package/dist/components/EventBadge/EventBadge.d.ts +13 -0
  39. package/dist/components/EventBadge/EventBadge.js +10 -0
  40. package/dist/components/EventBadge/index.d.ts +3 -0
  41. package/dist/components/EventBadge/index.js +1 -0
  42. package/dist/components/Gallery/Gallery.d.ts +24 -0
  43. package/dist/components/Gallery/Gallery.js +28 -0
  44. package/dist/components/Gallery/GalleryBadges/GalleryBadges.d.ts +8 -0
  45. package/dist/components/Gallery/GalleryBadges/GalleryBadges.js +5 -0
  46. package/dist/components/Gallery/GalleryControls/GalleryControls.d.ts +11 -0
  47. package/dist/components/Gallery/GalleryControls/GalleryControls.js +5 -0
  48. package/dist/components/Gallery/GalleryImg/GalleryImg.d.ts +13 -0
  49. package/dist/components/Gallery/GalleryImg/GalleryImg.js +37 -0
  50. package/dist/components/Gallery/GalleryItem/GalleryItem.d.ts +14 -0
  51. package/dist/components/Gallery/GalleryItem/GalleryItem.js +6 -0
  52. package/dist/components/Gallery/GalleryModal/GalleryModal.d.ts +20 -0
  53. package/dist/components/Gallery/GalleryModal/GalleryModal.js +90 -0
  54. package/dist/components/Gallery/GalleryPreLoader.d.ts +7 -0
  55. package/dist/components/Gallery/GalleryPreLoader.js +29 -0
  56. package/dist/components/Gallery/TransformImg/TransformImg.d.ts +10 -0
  57. package/dist/components/Gallery/TransformImg/TransformImg.js +15 -0
  58. package/dist/components/Gallery/index.d.ts +4 -0
  59. package/dist/components/Gallery/index.js +1 -0
  60. package/dist/components/Gallery/types.d.ts +6 -0
  61. package/dist/components/Gallery/types.js +1 -0
  62. package/dist/components/HeatmapLegend/HeatmapLegend.d.ts +15 -0
  63. package/dist/components/HeatmapLegend/HeatmapLegend.js +11 -0
  64. package/dist/components/HeatmapLegend/index.d.ts +3 -0
  65. package/dist/components/HeatmapLegend/index.js +2 -0
  66. package/dist/components/HighlightText/HighlightText.d.ts +7 -0
  67. package/dist/components/HighlightText/HighlightText.js +14 -0
  68. package/dist/components/HighlightText/index.d.ts +2 -0
  69. package/dist/components/HighlightText/index.js +1 -0
  70. package/dist/components/LevelBadge/LevelBadge.d.ts +9 -0
  71. package/dist/components/LevelBadge/LevelBadge.js +10 -0
  72. package/dist/components/LevelBadge/index.d.ts +3 -0
  73. package/dist/components/LevelBadge/index.js +2 -0
  74. package/dist/components/LevelSelector/LevelSelector.d.ts +18 -0
  75. package/dist/components/LevelSelector/LevelSelector.js +91 -0
  76. package/dist/components/LevelSelector/index.d.ts +3 -0
  77. package/dist/components/LevelSelector/index.js +2 -0
  78. package/dist/components/MapControls/MapControls.d.ts +33 -0
  79. package/dist/components/MapControls/MapControls.js +38 -0
  80. package/dist/components/MapControls/index.d.ts +3 -0
  81. package/dist/components/MapControls/index.js +2 -0
  82. package/dist/components/MobileToggleButton/MobileToggleButton.d.ts +11 -0
  83. package/dist/components/MobileToggleButton/MobileToggleButton.js +8 -0
  84. package/dist/components/MobileToggleButton/index.d.ts +3 -0
  85. package/dist/components/MobileToggleButton/index.js +1 -0
  86. package/dist/components/Modal/Modal.d.ts +34 -0
  87. package/dist/components/Modal/Modal.js +103 -0
  88. package/dist/components/Modal/index.d.ts +3 -0
  89. package/dist/components/Modal/index.js +1 -0
  90. package/dist/components/MultiSelectGroups/MultiSelectGroups.d.ts +37 -0
  91. package/dist/components/MultiSelectGroups/MultiSelectGroups.js +80 -0
  92. package/dist/components/MultiSelectGroups/index.d.ts +3 -0
  93. package/dist/components/MultiSelectGroups/index.js +1 -0
  94. package/dist/components/Overlay/Overlay.d.ts +30 -0
  95. package/dist/components/Overlay/Overlay.js +250 -0
  96. package/dist/components/Overlay/OverlayHeaderContext.d.ts +7 -0
  97. package/dist/components/Overlay/OverlayHeaderContext.js +7 -0
  98. package/dist/components/Overlay/OverlayKeyboardInsetContext.d.ts +7 -0
  99. package/dist/components/Overlay/OverlayKeyboardInsetContext.js +7 -0
  100. package/dist/components/Overlay/OverlayScrollContext.d.ts +7 -0
  101. package/dist/components/Overlay/OverlayScrollContext.js +7 -0
  102. package/dist/components/Overlay/index.d.ts +5 -0
  103. package/dist/components/Overlay/index.js +3 -0
  104. package/dist/components/OverlayGrip/OverlayGrip.d.ts +11 -0
  105. package/dist/components/OverlayGrip/OverlayGrip.js +8 -0
  106. package/dist/components/OverlayGrip/index.d.ts +3 -0
  107. package/dist/components/OverlayGrip/index.js +2 -0
  108. package/dist/components/PermissionNotice/PermissionNotice.d.ts +16 -0
  109. package/dist/components/PermissionNotice/PermissionNotice.js +11 -0
  110. package/dist/components/PermissionNotice/index.d.ts +3 -0
  111. package/dist/components/PermissionNotice/index.js +2 -0
  112. package/dist/components/PlanSelector/PlanSelector.d.ts +13 -0
  113. package/dist/components/PlanSelector/PlanSelector.js +10 -0
  114. package/dist/components/PlanSelector/index.d.ts +3 -0
  115. package/dist/components/PlanSelector/index.js +2 -0
  116. package/dist/components/Radio/Radio.d.ts +15 -0
  117. package/dist/components/Radio/Radio.js +13 -0
  118. package/dist/components/Radio/index.d.ts +3 -0
  119. package/dist/components/Radio/index.js +1 -0
  120. package/dist/components/RebookingNotes/RebookingNotes.d.ts +11 -0
  121. package/dist/components/RebookingNotes/RebookingNotes.js +18 -0
  122. package/dist/components/RebookingNotes/index.d.ts +3 -0
  123. package/dist/components/RebookingNotes/index.js +1 -0
  124. package/dist/components/RebookingRadioGroup/RebookingRadioGroup.d.ts +17 -0
  125. package/dist/components/RebookingRadioGroup/RebookingRadioGroup.js +13 -0
  126. package/dist/components/RebookingRadioGroup/index.d.ts +3 -0
  127. package/dist/components/RebookingRadioGroup/index.js +1 -0
  128. package/dist/components/ScrollableRow/ScrollableRow.d.ts +21 -0
  129. package/dist/components/ScrollableRow/ScrollableRow.js +155 -0
  130. package/dist/components/ScrollableRow/index.d.ts +3 -0
  131. package/dist/components/ScrollableRow/index.js +2 -0
  132. package/dist/components/Share/Share.d.ts +22 -0
  133. package/dist/components/Share/Share.js +24 -0
  134. package/dist/components/Share/index.d.ts +3 -0
  135. package/dist/components/Share/index.js +1 -0
  136. package/dist/components/ShowMoreButton/ShowMoreButton.d.ts +11 -0
  137. package/dist/components/ShowMoreButton/ShowMoreButton.js +7 -0
  138. package/dist/components/ShowMoreButton/index.d.ts +3 -0
  139. package/dist/components/ShowMoreButton/index.js +1 -0
  140. package/dist/components/SidebarActions/SidebarActions.d.ts +26 -0
  141. package/dist/components/SidebarActions/SidebarActions.js +32 -0
  142. package/dist/components/SidebarActions/index.d.ts +3 -0
  143. package/dist/components/SidebarActions/index.js +2 -0
  144. package/dist/components/SimpleRow/SimpleRow.d.ts +15 -0
  145. package/dist/components/SimpleRow/SimpleRow.js +11 -0
  146. package/dist/components/SimpleRow/index.d.ts +3 -0
  147. package/dist/components/SimpleRow/index.js +2 -0
  148. package/dist/components/Spinner/Spinner.d.ts +9 -0
  149. package/dist/components/Spinner/Spinner.js +8 -0
  150. package/dist/components/Spinner/index.d.ts +3 -0
  151. package/dist/components/Spinner/index.js +1 -0
  152. package/dist/components/ToggleButton/ToggleButton.d.ts +17 -0
  153. package/dist/components/ToggleButton/ToggleButton.js +8 -0
  154. package/dist/components/ToggleButton/index.d.ts +3 -0
  155. package/dist/components/ToggleButton/index.js +1 -0
  156. package/dist/components/ToggleSwitch/ToggleSwitch.d.ts +12 -0
  157. package/dist/components/ToggleSwitch/ToggleSwitch.js +10 -0
  158. package/dist/components/ToggleSwitch/index.d.ts +3 -0
  159. package/dist/components/ToggleSwitch/index.js +1 -0
  160. package/dist/components/TouchHand/TouchHand.d.ts +5 -0
  161. package/dist/components/TouchHand/TouchHand.js +7 -0
  162. package/dist/components/TouchHand/index.d.ts +2 -0
  163. package/dist/components/TouchHand/index.js +1 -0
  164. package/dist/components/VenuePicker/VenuePicker.d.ts +23 -0
  165. package/dist/components/VenuePicker/VenuePicker.js +70 -0
  166. package/dist/components/VenuePicker/index.d.ts +3 -0
  167. package/dist/components/VenuePicker/index.js +2 -0
  168. package/dist/components/WayfindingFloorSelector/WayfindingFloorSelector.d.ts +24 -0
  169. package/dist/components/WayfindingFloorSelector/WayfindingFloorSelector.js +27 -0
  170. package/dist/components/WayfindingFloorSelector/index.d.ts +3 -0
  171. package/dist/components/WayfindingFloorSelector/index.js +1 -0
  172. package/dist/index.d.ts +74 -0
  173. package/dist/index.js +77 -0
  174. package/dist/shared/activeElement.d.ts +7 -0
  175. package/dist/shared/activeElement.js +14 -0
  176. package/dist/shared/debounce.d.ts +2 -0
  177. package/dist/shared/debounce.js +9 -0
  178. package/dist/shared/hooks/useKeyboardInset.d.ts +9 -0
  179. package/dist/shared/hooks/useKeyboardInset.js +84 -0
  180. package/dist/shared/hooks/useOnClickOutside.d.ts +14 -0
  181. package/dist/shared/hooks/useOnClickOutside.js +43 -0
  182. package/dist/shared/hooks/useOnEscape.d.ts +14 -0
  183. package/dist/shared/hooks/useOnEscape.js +31 -0
  184. package/dist/shared/hooks/useSheetDrag.d.ts +28 -0
  185. package/dist/shared/hooks/useSheetDrag.js +274 -0
  186. package/dist/shared/hooks/useWindowSize.d.ts +5 -0
  187. package/dist/shared/hooks/useWindowSize.js +38 -0
  188. package/dist/shared/interactive.d.ts +2 -0
  189. package/dist/shared/interactive.js +4 -0
  190. package/dist/shared/selector-option.d.ts +7 -0
  191. package/dist/shared/selector-option.js +1 -0
  192. package/package.json +73 -0
@@ -0,0 +1,274 @@
1
+ import { useCallback, useEffect, useLayoutEffect, useRef, } from 'react';
2
+ /**
3
+ * Bottom-sheet drag physics ported from `vaul` v1.1.2 (not a dependency: it
4
+ * injects styles into `document.head`, which never reaches our shadow root).
5
+ * At rest the sheet is height-driven; during a gesture it is frozen at its
6
+ * tallest point and moved with `translate3d`, off the React/layout path.
7
+ */
8
+ /** px/ms: above this the sheet flies to the far end regardless of distance. */
9
+ const FLING_VELOCITY = 2;
10
+ /** px/ms: above this a short drag steps exactly one snap point. */
11
+ const STEP_VELOCITY = 0.4;
12
+ const STEP_DISTANCE_RATIO = 0.4;
13
+ const SCROLL_LOCK_TIMEOUT = 100;
14
+ const OPEN_LOCK_TIMEOUT = 500;
15
+ const MOVE_TOLERANCE = 2;
16
+ /** Matches SHEET_TRANSITION, with room for a `transitionend` that may not come. */
17
+ const SETTLE_TIMEOUT = 550;
18
+ const SHEET_TRANSITION = 'transform 0.5s cubic-bezier(0.32, 0.72, 0, 1)';
19
+ /** Resistance past the end stops (vaul's curve). */
20
+ const dampen = (distance) => Math.max(8 * (Math.log(distance + 1) - 2), 0);
21
+ const readOffset = (panel) => {
22
+ if (!panel || typeof DOMMatrixReadOnly !== 'function')
23
+ return null;
24
+ const { transform } = getComputedStyle(panel);
25
+ if (!transform || transform === 'none')
26
+ return null;
27
+ try {
28
+ return new DOMMatrixReadOnly(transform).m42;
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ };
34
+ /** Whether a horizontal scroller — a chip row, a gallery strip — sits under the finger. */
35
+ const scrollsSideways = (target, panel) => {
36
+ let element = target instanceof Element ? target : null;
37
+ while (element && panel?.contains(element)) {
38
+ if (element.scrollWidth > element.clientWidth) {
39
+ const { overflowX } = getComputedStyle(element);
40
+ if (overflowX === 'auto' || overflowX === 'scroll')
41
+ return true;
42
+ }
43
+ element = element.parentElement;
44
+ }
45
+ return false;
46
+ };
47
+ export function useSheetDrag({ enabled, panelRef, scrollElement, snapPoints, current, openedAtRef, onDragStart, onSnap, onSettle, onHandleTap, }) {
48
+ const gestureRef = useRef(null);
49
+ const scrollBlockedAtRef = useRef(0);
50
+ const settleRef = useRef(null);
51
+ // Detaches the window listeners of a gesture still in flight, without snapping.
52
+ const stopGestureRef = useRef(null);
53
+ // Mirrored after paint so a concurrent re-render cannot observe a torn value.
54
+ const stateRef = useRef({ enabled, snapPoints, current });
55
+ useLayoutEffect(() => {
56
+ stateRef.current = { enabled, snapPoints, current };
57
+ }, [enabled, snapPoints, current]);
58
+ const callbacksRef = useRef({ onDragStart, onSnap, onSettle, onHandleTap });
59
+ useLayoutEffect(() => {
60
+ callbacksRef.current = { onDragStart, onSnap, onSettle, onHandleTap };
61
+ }, [onDragStart, onSnap, onSettle, onHandleTap]);
62
+ const offsetOf = useCallback((name) => {
63
+ const { snapPoints } = stateRef.current;
64
+ const tallest = snapPoints[snapPoints.length - 1].height;
65
+ const point = snapPoints.find((snapPoint) => snapPoint.name === name);
66
+ return tallest - (point?.height ?? tallest);
67
+ }, []);
68
+ const writeOffset = useCallback((offset, transition) => {
69
+ const panel = panelRef.current;
70
+ if (!panel)
71
+ return;
72
+ panel.style.transition = transition;
73
+ panel.style.transform = `translate3d(0, ${offset}px, 0)`;
74
+ }, [panelRef]);
75
+ /** Vaul's `shouldDrag`; runs on the first move — the answer depends on direction. */
76
+ const shouldDrag = useCallback((target, draggingDown) => {
77
+ const now = performance.now();
78
+ const openedAt = openedAtRef.current;
79
+ if (openedAt !== undefined && now - openedAt < OPEN_LOCK_TIMEOUT)
80
+ return false;
81
+ if (now - scrollBlockedAtRef.current < SCROLL_LOCK_TIMEOUT)
82
+ return false;
83
+ if (window.getSelection()?.toString())
84
+ return false;
85
+ let element = target instanceof Element ? target : null;
86
+ if (element?.closest('[data-no-drag]'))
87
+ return false;
88
+ const { snapPoints, current } = stateRef.current;
89
+ if (!draggingDown && current === snapPoints[snapPoints.length - 1].name) {
90
+ scrollBlockedAtRef.current = now;
91
+ return false;
92
+ }
93
+ const panel = panelRef.current;
94
+ while (element && panel?.contains(element)) {
95
+ if (element.scrollHeight > element.clientHeight && element.scrollTop !== 0) {
96
+ scrollBlockedAtRef.current = now;
97
+ return false;
98
+ }
99
+ element = element.parentElement;
100
+ }
101
+ return true;
102
+ }, [openedAtRef, panelRef]);
103
+ const resolveTarget = useCallback((offset, distance, velocity) => {
104
+ const { snapPoints, current } = stateRef.current;
105
+ const draggedUp = distance > 0;
106
+ if (velocity > FLING_VELOCITY) {
107
+ return draggedUp ? snapPoints[snapPoints.length - 1].name : snapPoints[0].name;
108
+ }
109
+ if (velocity > STEP_VELOCITY &&
110
+ Math.abs(distance) < window.innerHeight * STEP_DISTANCE_RATIO) {
111
+ const index = snapPoints.findIndex((snapPoint) => snapPoint.name === current);
112
+ const stepped = index + (draggedUp ? 1 : -1);
113
+ return snapPoints[Math.min(Math.max(stepped, 0), snapPoints.length - 1)].name;
114
+ }
115
+ return snapPoints.reduce((closest, snapPoint) => Math.abs(offsetOf(snapPoint.name) - offset) < Math.abs(offsetOf(closest.name) - offset)
116
+ ? snapPoint
117
+ : closest).name;
118
+ }, [offsetOf]);
119
+ const flushSettle = useCallback(() => {
120
+ settleRef.current?.flush();
121
+ }, []);
122
+ const scheduleSettle = useCallback(() => {
123
+ const panel = panelRef.current;
124
+ const cancel = () => {
125
+ settleRef.current = null;
126
+ clearTimeout(timer);
127
+ panel?.removeEventListener('transitionend', onTransitionEnd);
128
+ };
129
+ const flush = () => {
130
+ cancel();
131
+ callbacksRef.current.onSettle();
132
+ };
133
+ const onTransitionEnd = (event) => {
134
+ if (event.target === panel && event.propertyName === 'transform')
135
+ flush();
136
+ };
137
+ // No `transitionend` when the sheet is released where it started.
138
+ const timer = setTimeout(flush, SETTLE_TIMEOUT);
139
+ panel?.addEventListener('transitionend', onTransitionEnd);
140
+ settleRef.current = { flush, cancel };
141
+ }, [panelRef]);
142
+ // A sheet unmounted mid-gesture takes its timers and window listeners with
143
+ // it, silently — no onSnap/onSettle into a dead tree.
144
+ useEffect(() => () => {
145
+ settleRef.current?.cancel();
146
+ stopGestureRef.current?.();
147
+ }, []);
148
+ const onPointerDown = useCallback((event) => {
149
+ if (!stateRef.current.enabled || gestureRef.current)
150
+ return;
151
+ if (event.pointerType === 'mouse' && event.button !== 0)
152
+ return;
153
+ const liveOffset = settleRef.current ? readOffset(panelRef.current) : null;
154
+ flushSettle();
155
+ const startOffset = liveOffset ?? offsetOf(stateRef.current.current);
156
+ const gesture = {
157
+ pointerId: event.pointerId,
158
+ startX: event.clientX,
159
+ startY: event.clientY,
160
+ lastY: event.clientY,
161
+ startTime: performance.now(),
162
+ startOffset,
163
+ offset: startOffset,
164
+ committed: false,
165
+ commit: (clientX, clientY) => {
166
+ if (gesture.committed)
167
+ return true;
168
+ const deltaX = clientX - gesture.startX;
169
+ const deltaY = clientY - gesture.startY;
170
+ if (Math.hypot(deltaX, deltaY) < MOVE_TOLERANCE)
171
+ return false;
172
+ if (Math.abs(deltaX) > Math.abs(deltaY)) {
173
+ // A sideways move belongs to a chip row or gallery strip under the finger. Anywhere
174
+ // else it is the finger settling, which says nothing about the direction yet.
175
+ if (scrollsSideways(event.target, panelRef.current))
176
+ stop();
177
+ return false;
178
+ }
179
+ if (!shouldDrag(event.target, deltaY > 0)) {
180
+ stop();
181
+ return false;
182
+ }
183
+ gesture.committed = true;
184
+ try {
185
+ panelRef.current?.setPointerCapture(gesture.pointerId);
186
+ }
187
+ catch {
188
+ // Throws when the pointer is already gone; the window listeners
189
+ // below carry the gesture either way.
190
+ }
191
+ if (scrollElement)
192
+ scrollElement.style.overflow = 'hidden';
193
+ callbacksRef.current.onDragStart();
194
+ return true;
195
+ },
196
+ };
197
+ gestureRef.current = gesture;
198
+ const stop = () => {
199
+ window.removeEventListener('pointermove', handleMove);
200
+ window.removeEventListener('pointerup', finish);
201
+ window.removeEventListener('pointercancel', finish);
202
+ gestureRef.current = null;
203
+ stopGestureRef.current = null;
204
+ };
205
+ const finish = (endEvent) => {
206
+ // A second finger releasing must not end the first finger's gesture.
207
+ if (endEvent.pointerId !== gesture.pointerId)
208
+ return;
209
+ stop();
210
+ if (scrollElement)
211
+ scrollElement.style.removeProperty('overflow');
212
+ if (!gesture.committed) {
213
+ const target = event.target;
214
+ if (target instanceof Element && target.closest('[data-sheet-handle]')) {
215
+ callbacksRef.current.onHandleTap();
216
+ }
217
+ return;
218
+ }
219
+ const distance = gesture.startY - gesture.lastY;
220
+ const elapsed = Math.max(performance.now() - gesture.startTime, 1);
221
+ const velocity = Math.abs(distance) / elapsed;
222
+ const target = resolveTarget(gesture.offset, distance, velocity);
223
+ writeOffset(offsetOf(target), SHEET_TRANSITION);
224
+ scheduleSettle();
225
+ callbacksRef.current.onSnap(target);
226
+ };
227
+ const handleMove = (moveEvent) => {
228
+ if (moveEvent.pointerId !== gesture.pointerId)
229
+ return;
230
+ gesture.lastY = moveEvent.clientY;
231
+ if (!gesture.commit(moveEvent.clientX, moveEvent.clientY))
232
+ return;
233
+ const delta = moveEvent.clientY - gesture.startY;
234
+ const limit = offsetOf(stateRef.current.snapPoints[0].name);
235
+ const raw = gesture.startOffset + delta;
236
+ const offset = raw < 0 ? -dampen(-raw) : raw > limit ? limit + dampen(raw - limit) : raw;
237
+ gesture.offset = offset;
238
+ writeOffset(offset, 'none');
239
+ };
240
+ window.addEventListener('pointermove', handleMove);
241
+ window.addEventListener('pointerup', finish);
242
+ window.addEventListener('pointercancel', finish);
243
+ stopGestureRef.current = stop;
244
+ }, [
245
+ flushSettle,
246
+ offsetOf,
247
+ panelRef,
248
+ resolveTarget,
249
+ scheduleSettle,
250
+ scrollElement,
251
+ shouldDrag,
252
+ writeOffset,
253
+ ]);
254
+ // Non-passive, so bound natively (React's touch listeners are passive), and in place before the
255
+ // touch starts. A drag that starts on the content must keep the browser from scrolling it: a
256
+ // native scroll takes the touch over and cancels the pointer mid-drag (#1686). Once that scroll
257
+ // starts, touchmoves are no longer cancelable, and a pointermove can arrive a frame after its
258
+ // touchmove, so the drag is decided here as well.
259
+ useEffect(() => {
260
+ if (!scrollElement || !enabled)
261
+ return;
262
+ const handleTouchMove = (event) => {
263
+ const gesture = gestureRef.current;
264
+ const touch = event.targetTouches[0];
265
+ if (!gesture || !touch || !event.cancelable)
266
+ return;
267
+ if (gesture.commit(touch.clientX, touch.clientY))
268
+ event.preventDefault();
269
+ };
270
+ scrollElement.addEventListener('touchmove', handleTouchMove, { passive: false });
271
+ return () => scrollElement.removeEventListener('touchmove', handleTouchMove);
272
+ }, [scrollElement, enabled]);
273
+ return { onPointerDown };
274
+ }
@@ -0,0 +1,5 @@
1
+ export declare const useWindowSize: () => {
2
+ width: number;
3
+ height: number;
4
+ };
5
+ //# sourceMappingURL=useWindowSize.d.ts.map
@@ -0,0 +1,38 @@
1
+ import { useEffect, useState } from 'react';
2
+ /**
3
+ * How long the window size must hold still before consumers see it. A live window drag fires
4
+ * `resize` on every frame, and a state update per frame re-renders every consumer's subtree for
5
+ * the whole drag — for layout breakpoints, one update once the drag settles is enough.
6
+ */
7
+ const RESIZE_DEBOUNCE_MS = 200;
8
+ const measure = () => {
9
+ const isInIframe = window !== window.top;
10
+ if (isInIframe) {
11
+ return {
12
+ width: document.documentElement.clientWidth || window.innerWidth,
13
+ height: document.documentElement.clientHeight || window.innerHeight,
14
+ };
15
+ }
16
+ return {
17
+ width: window.innerWidth,
18
+ height: window.innerHeight,
19
+ };
20
+ };
21
+ export const useWindowSize = () => {
22
+ const [windowSize, setWindowSize] = useState(measure);
23
+ useEffect(() => {
24
+ let timeoutId;
25
+ const handleResize = () => {
26
+ clearTimeout(timeoutId);
27
+ timeoutId = setTimeout(() => setWindowSize(measure()), RESIZE_DEBOUNCE_MS);
28
+ };
29
+ window.addEventListener('resize', handleResize);
30
+ window.addEventListener('orientationchange', handleResize);
31
+ return () => {
32
+ clearTimeout(timeoutId);
33
+ window.removeEventListener('resize', handleResize);
34
+ window.removeEventListener('orientationchange', handleResize);
35
+ };
36
+ }, []);
37
+ return windowSize;
38
+ };
@@ -0,0 +1,2 @@
1
+ export declare function isInteractiveTarget(target: Element | null): boolean;
2
+ //# sourceMappingURL=interactive.d.ts.map
@@ -0,0 +1,4 @@
1
+ const INTERACTIVE_SELECTOR = 'button, input, select, textarea, a, [contenteditable="true"], [draggable="false"]';
2
+ export function isInteractiveTarget(target) {
3
+ return Boolean(target?.closest(INTERACTIVE_SELECTOR));
4
+ }
@@ -0,0 +1,7 @@
1
+ export interface SelectorOption {
2
+ id: string;
3
+ label: string;
4
+ active: boolean;
5
+ disabled: boolean;
6
+ }
7
+ //# sourceMappingURL=selector-option.d.ts.map
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@expofp/ui",
3
+ "version": "0.0.0-experimental.2d6c681",
4
+ "type": "module",
5
+ "description": "ExpoFP SDK internal: shared pure React UI components",
6
+ "homepage": "https://developer.expofp.com/",
7
+ "license": "MIT",
8
+ "sideEffects": [
9
+ "**/*.scss",
10
+ "**/*.css"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "main": "./dist/index.js",
16
+ "module": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ "./package.json": "./package.json",
20
+ ".": {
21
+ "@expofp/source": "./src/index.ts",
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js",
24
+ "default": "./dist/index.js"
25
+ }
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "!**/*.tsbuildinfo",
30
+ "!**/*.map"
31
+ ],
32
+ "dependencies": {
33
+ "classnames": "^2.2.6",
34
+ "copy-to-clipboard": "^3.2.0",
35
+ "react-virtuoso": "^4.18.7",
36
+ "react-zoom-pan-pinch-sr": "^0.2.0",
37
+ "resize-observer": "^1.0.4",
38
+ "swiper": "^9.4.1",
39
+ "tslib": "^2.3.0"
40
+ },
41
+ "peerDependencies": {
42
+ "react": "^19.2.8",
43
+ "react-dom": "^19.2.8"
44
+ },
45
+ "devDependencies": {
46
+ "@storybook/addon-vitest": "10.4.6",
47
+ "@storybook/react": "10.4.6",
48
+ "@storybook/react-vite": "10.4.6",
49
+ "@types/react": "^19.2.17",
50
+ "@types/react-dom": "^19.2.3",
51
+ "@vitejs/plugin-react": "^6.0.3",
52
+ "@vitest/browser-playwright": "^4.1.9",
53
+ "playwright": "^1.61.1",
54
+ "react": "^19.2.8",
55
+ "react-dom": "^19.2.8",
56
+ "sass-embedded": "^1.100.0",
57
+ "storybook": "10.4.6"
58
+ },
59
+ "nx": {
60
+ "targets": {
61
+ "test-storybook": {
62
+ "dependsOn": [
63
+ "^build"
64
+ ],
65
+ "command": "vitest run --config vitest.storybook.config.mts",
66
+ "options": {
67
+ "cwd": "packages/ui"
68
+ },
69
+ "cache": true
70
+ }
71
+ }
72
+ }
73
+ }