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

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 (200) 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 +66 -0
  7. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -0
  8. package/dist/BottomSheet/BottomSheet.js +392 -0
  9. package/dist/BottomSheet/BottomSheetPanel.d.ts +60 -0
  10. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -0
  11. package/dist/BottomSheet/BottomSheetPanel.js +398 -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 +72 -0
  22. package/dist/BottomSheet/snapOffsets.d.ts.map +1 -0
  23. package/dist/BottomSheet/snapOffsets.js +130 -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 +180 -0
  28. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -0
  29. package/dist/BottomSheet/useSheetGestures.js +989 -0
  30. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  31. package/dist/Chat/ChatComposerInput.js +3 -4
  32. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  33. package/dist/ComplexSelector/ComplexSelector.js +12 -6
  34. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  35. package/dist/ContextMenu/ContextMenu.js +4 -2
  36. package/dist/DateInput/DateInput.d.ts.map +1 -1
  37. package/dist/DateInput/DateInput.js +9 -1
  38. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  39. package/dist/DateTimeInput/DateTimeInput.js +31 -1
  40. package/dist/Dialog/Dialog.d.ts.map +1 -1
  41. package/dist/Dialog/Dialog.js +2 -1
  42. package/dist/Field/InputClearButton.d.ts +2 -1
  43. package/dist/Field/InputClearButton.d.ts.map +1 -1
  44. package/dist/Field/InputClearButton.js +6 -1
  45. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  46. package/dist/Lightbox/Lightbox.js +9 -3
  47. package/dist/MobileNav/MobileNav.d.ts +12 -0
  48. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  49. package/dist/MobileNav/MobileNav.js +102 -30
  50. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  51. package/dist/MultiSelector/MultiSelector.js +21 -7
  52. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  53. package/dist/NumberInput/NumberInput.js +9 -1
  54. package/dist/PowerSearch/PowerSearchEditPopover.js +1 -1
  55. package/dist/Selector/Selector.d.ts.map +1 -1
  56. package/dist/Selector/Selector.js +14 -3
  57. package/dist/StatusDot/StatusDot.d.ts +43 -3
  58. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  59. package/dist/StatusDot/StatusDot.js +42 -5
  60. package/dist/Switch/Switch.d.ts.map +1 -1
  61. package/dist/Switch/Switch.js +5 -1
  62. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  63. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
  64. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  65. package/dist/TimeInput/TimeInput.js +8 -1
  66. package/dist/Tokenizer/Tokenizer.js +11 -5
  67. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  68. package/dist/Tooltip/useTooltip.js +4 -1
  69. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  70. package/dist/Typeahead/BaseTypeahead.js +5 -3
  71. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  72. package/dist/Typeahead/Typeahead.js +10 -1
  73. package/dist/astryx.css +21 -0
  74. package/dist/hooks/index.d.ts +8 -1
  75. package/dist/hooks/index.d.ts.map +1 -1
  76. package/dist/hooks/index.js +8 -1
  77. package/dist/hooks/useFocusTrap.d.ts +0 -11
  78. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  79. package/dist/hooks/useFocusTrap.js +1 -11
  80. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  81. package/dist/hooks/useInputStatusIcon.js +1 -0
  82. package/dist/index.d.ts +1 -0
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +1 -0
  85. package/dist/theme/defineTheme.d.ts +22 -4
  86. package/dist/theme/defineTheme.d.ts.map +1 -1
  87. package/dist/theme/expandColorScale.d.ts +17 -2
  88. package/dist/theme/expandColorScale.d.ts.map +1 -1
  89. package/dist/theme/expandColorScale.js +63 -33
  90. package/dist/utils/ime.d.ts +5 -0
  91. package/dist/utils/ime.d.ts.map +1 -0
  92. package/dist/utils/ime.js +63 -0
  93. package/dist/utils/index.d.ts +1 -0
  94. package/dist/utils/index.d.ts.map +1 -1
  95. package/dist/utils/index.js +2 -1
  96. package/locales/af-ZA.json +958 -0
  97. package/locales/ar-SA.json +998 -0
  98. package/locales/ca-ES.json +974 -0
  99. package/locales/cs-CZ.json +990 -0
  100. package/locales/da-DK.json +966 -0
  101. package/locales/de-DE.json +966 -0
  102. package/locales/el-GR.json +990 -0
  103. package/locales/en.json +48 -0
  104. package/locales/es-ES.json +978 -0
  105. package/locales/fi-FI.json +990 -0
  106. package/locales/fr-FR.json +928 -0
  107. package/locales/he-IL.json +990 -0
  108. package/locales/hu-HU.json +990 -0
  109. package/locales/it-IT.json +978 -0
  110. package/locales/ja-JP.json +998 -0
  111. package/locales/ko-KR.json +990 -0
  112. package/locales/nl-NL.json +954 -0
  113. package/locales/no-NO.json +978 -0
  114. package/locales/pl-PL.json +982 -0
  115. package/locales/pseudo.json +36 -0
  116. package/locales/pt-BR.json +982 -0
  117. package/locales/pt-PT.json +982 -0
  118. package/locales/ro-RO.json +982 -0
  119. package/locales/ru-RU.json +990 -0
  120. package/locales/sr-SP.json +990 -0
  121. package/locales/sv-SE.json +986 -0
  122. package/locales/tr-TR.json +990 -0
  123. package/locales/uk-UA.json +990 -0
  124. package/locales/vi-VN.json +986 -0
  125. package/locales/zh-CN.json +998 -0
  126. package/locales/zh-TW.json +998 -0
  127. package/package.json +9 -8
  128. package/src/Banner/Banner.doc.mjs +3 -3
  129. package/src/Banner/Banner.test.tsx +40 -0
  130. package/src/Banner/Banner.tsx +27 -2
  131. package/src/BottomSheet/BottomSheet.doc.mjs +266 -0
  132. package/src/BottomSheet/BottomSheet.test.tsx +2114 -0
  133. package/src/BottomSheet/BottomSheet.tsx +545 -0
  134. package/src/BottomSheet/BottomSheetPanel.test.tsx +240 -0
  135. package/src/BottomSheet/BottomSheetPanel.tsx +547 -0
  136. package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +219 -0
  137. package/src/BottomSheet/BottomSheetSwitcher.test.tsx +850 -0
  138. package/src/BottomSheet/BottomSheetSwitcher.tsx +628 -0
  139. package/src/BottomSheet/BottomSheetSwitcherContext.ts +51 -0
  140. package/src/BottomSheet/index.ts +15 -0
  141. package/src/BottomSheet/snapOffsets.test.ts +187 -0
  142. package/src/BottomSheet/snapOffsets.ts +159 -0
  143. package/src/BottomSheet/useMobileKeyboard.ts +499 -0
  144. package/src/BottomSheet/useSheetGestures.test.ts +1059 -0
  145. package/src/BottomSheet/useSheetGestures.ts +1459 -0
  146. package/src/Chat/ChatComposerInput.tsx +3 -4
  147. package/src/ComplexSelector/ComplexSelector.tsx +12 -5
  148. package/src/ContextMenu/ContextMenu.tsx +4 -2
  149. package/src/DateInput/DateInput.test.tsx +21 -0
  150. package/src/DateInput/DateInput.tsx +9 -1
  151. package/src/DateTimeInput/DateTimeInput.doc.mjs +4 -0
  152. package/src/DateTimeInput/DateTimeInput.test.tsx +137 -0
  153. package/src/DateTimeInput/DateTimeInput.tsx +39 -2
  154. package/src/Dialog/Dialog.tsx +2 -1
  155. package/src/Field/Field.doc.mjs +1 -0
  156. package/src/Field/InputClearButton.test.tsx +25 -0
  157. package/src/Field/InputClearButton.tsx +4 -1
  158. package/src/FileInput/FileInput.test.tsx +53 -9
  159. package/src/Lightbox/Lightbox.test.tsx +49 -28
  160. package/src/Lightbox/Lightbox.tsx +7 -3
  161. package/src/MobileNav/MobileNav.tsx +128 -37
  162. package/src/MobileNav/MobileNavCloseEdgeCases.test.tsx +426 -0
  163. package/src/MobileNav/MobileNavCloseTiming.test.ts +58 -0
  164. package/src/MobileNav/MobileNavCloseVisibility.test.tsx +172 -0
  165. package/src/MultiSelector/MultiSelector.test.tsx +195 -51
  166. package/src/MultiSelector/MultiSelector.tsx +22 -8
  167. package/src/NumberInput/NumberInput.test.tsx +18 -0
  168. package/src/NumberInput/NumberInput.tsx +9 -1
  169. package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
  170. package/src/Selector/Selector.test.tsx +85 -26
  171. package/src/Selector/Selector.tsx +13 -4
  172. package/src/StatusDot/StatusDot.doc.mjs +13 -0
  173. package/src/StatusDot/StatusDot.test.tsx +115 -8
  174. package/src/StatusDot/StatusDot.tsx +74 -9
  175. package/src/Switch/Switch.test.tsx +16 -0
  176. package/src/Switch/Switch.tsx +7 -0
  177. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +20 -2
  178. package/src/TimeInput/TimeInput.test.tsx +23 -0
  179. package/src/TimeInput/TimeInput.tsx +8 -0
  180. package/src/Tokenizer/Tokenizer.test.tsx +50 -32
  181. package/src/Tokenizer/Tokenizer.tsx +5 -5
  182. package/src/Tooltip/useTooltip.tsx +4 -1
  183. package/src/Typeahead/BaseTypeahead.tsx +10 -3
  184. package/src/Typeahead/Typeahead.test.tsx +116 -7
  185. package/src/Typeahead/Typeahead.tsx +10 -1
  186. package/src/__tests__/stubMatchMedia.test.ts +79 -0
  187. package/src/__tests__/stubMatchMedia.ts +95 -0
  188. package/src/hooks/index.ts +9 -5
  189. package/src/hooks/useFocusTrap.ts +1 -14
  190. package/src/hooks/useInputStatusIcon.test.tsx +19 -0
  191. package/src/hooks/useInputStatusIcon.tsx +7 -0
  192. package/src/index.ts +1 -0
  193. package/src/theme/defineTheme.ts +22 -4
  194. package/src/theme/expandColorScale.test.ts +138 -0
  195. package/src/theme/expandColorScale.ts +89 -44
  196. package/src/utils/ime.test.ts +32 -0
  197. package/src/utils/ime.ts +69 -0
  198. package/src/utils/index.ts +2 -0
  199. package/dist/astryx.umd.js +0 -147
  200. package/dist/astryx.umd.js.map +0 -7
@@ -0,0 +1,240 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file BottomSheetPanel.test.tsx
5
+ * @input Uses vitest, Testing Library, BottomSheetPanel
6
+ * @output Tests the shared sheet surface motion contract
7
+ * @position Internal presentation tests shared by standalone and switcher modes
8
+ */
9
+
10
+ import {act, fireEvent, render, screen} from '@testing-library/react';
11
+ import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
12
+ import {
13
+ BottomSheetPanel,
14
+ type BottomSheetPanelMotion,
15
+ type BottomSheetPanelState,
16
+ } from './BottomSheetPanel';
17
+
18
+ const panelTransitionStyle = {
19
+ transitionProperty: 'transform, opacity',
20
+ transitionDuration: '410ms',
21
+ transitionDelay: '0ms',
22
+ };
23
+
24
+ beforeEach(() => {
25
+ vi.stubGlobal(
26
+ 'matchMedia',
27
+ vi.fn().mockReturnValue({
28
+ matches: false,
29
+ media: '',
30
+ onchange: null,
31
+ addEventListener: vi.fn(),
32
+ removeEventListener: vi.fn(),
33
+ addListener: vi.fn(),
34
+ removeListener: vi.fn(),
35
+ dispatchEvent: vi.fn(),
36
+ }),
37
+ );
38
+ });
39
+
40
+ afterEach(() => {
41
+ vi.unstubAllGlobals();
42
+ });
43
+
44
+ function renderPanel(
45
+ state: BottomSheetPanelState,
46
+ callbacks: {
47
+ onMotionStart?: (motion: BottomSheetPanelMotion) => void;
48
+ onMotionComplete?: (motion: BottomSheetPanelMotion) => void;
49
+ } = {},
50
+ ) {
51
+ return render(
52
+ <BottomSheetPanel
53
+ state={state}
54
+ height="hug"
55
+ style={panelTransitionStyle}
56
+ onDismiss={() => {}}
57
+ onScrimOpacity={() => {}}
58
+ onMotionStart={callbacks.onMotionStart}
59
+ onMotionComplete={callbacks.onMotionComplete}>
60
+ Panel content
61
+ </BottomSheetPanel>,
62
+ );
63
+ }
64
+
65
+ function getPanel(): HTMLElement {
66
+ const panel = screen
67
+ .getByText('Panel content')
68
+ .closest<HTMLElement>('.astryx-bottom-sheet');
69
+ if (panel == null) {
70
+ throw new Error('BottomSheetPanel surface not found');
71
+ }
72
+ return panel;
73
+ }
74
+
75
+ describe('BottomSheetPanel', () => {
76
+ it('reports entrance completion only for the surface transform', () => {
77
+ const onMotionStart = vi.fn();
78
+ const onMotionComplete = vi.fn();
79
+ renderPanel(
80
+ {kind: 'open', entering: true},
81
+ {onMotionStart, onMotionComplete},
82
+ );
83
+
84
+ expect(onMotionStart).toHaveBeenCalledWith('entering');
85
+ fireEvent.transitionEnd(getPanel(), {propertyName: 'opacity'});
86
+ expect(onMotionComplete).not.toHaveBeenCalled();
87
+ fireEvent.transitionEnd(getPanel(), {propertyName: 'transform'});
88
+ expect(onMotionComplete).toHaveBeenCalledWith('entering');
89
+ });
90
+
91
+ it('completes a retained-sheet reactivation without waiting for a new entrance', () => {
92
+ const onMotionComplete = vi.fn();
93
+ const {rerender} = render(
94
+ <BottomSheetPanel
95
+ state={{kind: 'retained', motion: 'covered', alignmentOffset: 0}}
96
+ height="hug"
97
+ style={panelTransitionStyle}
98
+ onDismiss={() => {}}
99
+ onScrimOpacity={() => {}}
100
+ onMotionComplete={onMotionComplete}>
101
+ Panel content
102
+ </BottomSheetPanel>,
103
+ );
104
+
105
+ rerender(
106
+ <BottomSheetPanel
107
+ state={{kind: 'open', entering: true}}
108
+ height="hug"
109
+ style={panelTransitionStyle}
110
+ onDismiss={() => {}}
111
+ onScrimOpacity={() => {}}
112
+ onMotionComplete={onMotionComplete}>
113
+ Panel content
114
+ </BottomSheetPanel>,
115
+ );
116
+
117
+ expect(onMotionComplete).toHaveBeenCalledWith('entering');
118
+ });
119
+
120
+ it('applies the switcher alignment offset to a retained surface', () => {
121
+ renderPanel({
122
+ kind: 'retained',
123
+ motion: 'aligning',
124
+ alignmentOffset: 120,
125
+ });
126
+
127
+ expect(getPanel()).toHaveStyle({transform: 'translateY(120px)'});
128
+ });
129
+
130
+ it('maps exit and fade completion to their respective CSS properties', () => {
131
+ const onMotionComplete = vi.fn();
132
+ const {rerender} = renderPanel(
133
+ {kind: 'retained', motion: 'fading', alignmentOffset: 0},
134
+ {onMotionComplete},
135
+ );
136
+
137
+ fireEvent.transitionEnd(getPanel(), {propertyName: 'opacity'});
138
+ expect(onMotionComplete).toHaveBeenLastCalledWith('fading');
139
+
140
+ rerender(
141
+ <BottomSheetPanel
142
+ state={{kind: 'exiting'}}
143
+ height="hug"
144
+ style={panelTransitionStyle}
145
+ onDismiss={() => {}}
146
+ onScrimOpacity={() => {}}
147
+ onMotionComplete={onMotionComplete}>
148
+ Panel content
149
+ </BottomSheetPanel>,
150
+ );
151
+ fireEvent.transitionEnd(getPanel(), {propertyName: 'transform'});
152
+ expect(onMotionComplete).toHaveBeenLastCalledWith('exiting');
153
+ });
154
+
155
+ it('completes immediately when the rendered transition is disabled', () => {
156
+ vi.mocked(matchMedia).mockReturnValue({
157
+ matches: true,
158
+ media: '(prefers-reduced-motion: reduce)',
159
+ onchange: null,
160
+ addEventListener: vi.fn(),
161
+ removeEventListener: vi.fn(),
162
+ addListener: vi.fn(),
163
+ removeListener: vi.fn(),
164
+ dispatchEvent: vi.fn(),
165
+ });
166
+ const onMotionComplete = vi.fn();
167
+ render(
168
+ <BottomSheetPanel
169
+ state={{kind: 'open', entering: true}}
170
+ height="hug"
171
+ onDismiss={() => {}}
172
+ onScrimOpacity={() => {}}
173
+ onMotionComplete={onMotionComplete}>
174
+ Panel content
175
+ </BottomSheetPanel>,
176
+ );
177
+
178
+ expect(onMotionComplete).toHaveBeenCalledWith('entering');
179
+ });
180
+
181
+ it('derives its transition backstop from the rendered timing', () => {
182
+ vi.useFakeTimers();
183
+ try {
184
+ const onMotionComplete = vi.fn();
185
+ render(
186
+ <BottomSheetPanel
187
+ state={{kind: 'open', entering: true}}
188
+ height="hug"
189
+ style={{
190
+ transitionProperty: 'transform, opacity',
191
+ transitionDuration: '0.5s, 200ms',
192
+ transitionDelay: '100ms, 0ms',
193
+ }}
194
+ onDismiss={() => {}}
195
+ onScrimOpacity={() => {}}
196
+ onMotionComplete={onMotionComplete}>
197
+ Panel content
198
+ </BottomSheetPanel>,
199
+ );
200
+
201
+ void act(() => vi.advanceTimersByTime(649));
202
+ expect(onMotionComplete).not.toHaveBeenCalled();
203
+ void act(() => vi.advanceTimersByTime(1));
204
+ expect(onMotionComplete).toHaveBeenCalledWith('entering');
205
+ } finally {
206
+ vi.useRealTimers();
207
+ }
208
+ });
209
+
210
+ it('does not detach a stable public ref during an ordinary rerender', () => {
211
+ const panelRef = vi.fn();
212
+ const {rerender, unmount} = render(
213
+ <BottomSheetPanel
214
+ ref={panelRef}
215
+ state={{kind: 'open', entering: false}}
216
+ height="hug"
217
+ onDismiss={() => {}}
218
+ onScrimOpacity={() => {}}>
219
+ First render
220
+ </BottomSheetPanel>,
221
+ );
222
+
223
+ expect(panelRef).toHaveBeenCalledTimes(1);
224
+ rerender(
225
+ <BottomSheetPanel
226
+ ref={panelRef}
227
+ state={{kind: 'open', entering: false}}
228
+ height="hug"
229
+ onDismiss={() => {}}
230
+ onScrimOpacity={() => {}}>
231
+ Second render
232
+ </BottomSheetPanel>,
233
+ );
234
+ expect(panelRef).toHaveBeenCalledTimes(1);
235
+
236
+ unmount();
237
+ expect(panelRef).toHaveBeenLastCalledWith(null);
238
+ expect(panelRef).toHaveBeenCalledTimes(2);
239
+ });
240
+ });