@astryxdesign/core 0.4.2 → 0.4.3-canary.00bed29

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 (214) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +79 -45
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +3 -19
  5. package/dist/Banner/Banner.d.ts +9 -2
  6. package/dist/Banner/Banner.d.ts.map +1 -1
  7. package/dist/Banner/Banner.js +84 -33
  8. package/dist/Banner/index.d.ts +14 -12
  9. package/dist/Banner/index.d.ts.map +1 -1
  10. package/dist/Banner/index.js +10 -8
  11. package/dist/BottomSheet/BottomSheet.d.ts +66 -0
  12. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -0
  13. package/dist/BottomSheet/BottomSheet.js +392 -0
  14. package/dist/BottomSheet/BottomSheetPanel.d.ts +60 -0
  15. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -0
  16. package/dist/BottomSheet/BottomSheetPanel.js +398 -0
  17. package/dist/BottomSheet/BottomSheetSwitcher.d.ts +61 -0
  18. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -0
  19. package/dist/BottomSheet/BottomSheetSwitcher.js +410 -0
  20. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts +21 -0
  21. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts.map +1 -0
  22. package/dist/BottomSheet/BottomSheetSwitcherContext.js +13 -0
  23. package/dist/BottomSheet/index.d.ts +11 -0
  24. package/dist/BottomSheet/index.d.ts.map +1 -0
  25. package/dist/BottomSheet/index.js +12 -0
  26. package/dist/BottomSheet/snapOffsets.d.ts +72 -0
  27. package/dist/BottomSheet/snapOffsets.d.ts.map +1 -0
  28. package/dist/BottomSheet/snapOffsets.js +130 -0
  29. package/dist/BottomSheet/useMobileKeyboard.d.ts +35 -0
  30. package/dist/BottomSheet/useMobileKeyboard.d.ts.map +1 -0
  31. package/dist/BottomSheet/useMobileKeyboard.js +373 -0
  32. package/dist/BottomSheet/useSheetGestures.d.ts +180 -0
  33. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -0
  34. package/dist/BottomSheet/useSheetGestures.js +942 -0
  35. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  36. package/dist/Chat/ChatComposerInput.js +3 -4
  37. package/dist/Chat/ChatTokenizedText.js +1 -1
  38. package/dist/ComplexSelector/ComplexSelector.d.ts +38 -4
  39. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  40. package/dist/ComplexSelector/ComplexSelector.js +98 -31
  41. package/dist/ComplexSelector/index.d.ts +2 -2
  42. package/dist/ComplexSelector/index.d.ts.map +1 -1
  43. package/dist/ComplexSelector/index.js +1 -1
  44. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  45. package/dist/ContextMenu/ContextMenu.js +4 -2
  46. package/dist/DateInput/DateInput.d.ts.map +1 -1
  47. package/dist/DateInput/DateInput.js +9 -1
  48. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  49. package/dist/DateTimeInput/DateTimeInput.js +31 -1
  50. package/dist/Dialog/Dialog.d.ts.map +1 -1
  51. package/dist/Dialog/Dialog.js +2 -1
  52. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  53. package/dist/Lightbox/Lightbox.js +9 -3
  54. package/dist/Markdown/parser.d.ts.map +1 -1
  55. package/dist/Markdown/parser.js +55 -12
  56. package/dist/MobileNav/MobileNav.d.ts +12 -0
  57. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  58. package/dist/MobileNav/MobileNav.js +102 -30
  59. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  60. package/dist/MultiSelector/MultiSelector.js +21 -7
  61. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  62. package/dist/NumberInput/NumberInput.js +9 -1
  63. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  64. package/dist/PowerSearch/PowerSearch.js +4 -1
  65. package/dist/PowerSearch/PowerSearchEditPopover.js +1 -1
  66. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  67. package/dist/PowerSearch/formatFilterValue.js +2 -4
  68. package/dist/Selector/Selector.d.ts.map +1 -1
  69. package/dist/Selector/Selector.js +14 -3
  70. package/dist/Switch/Switch.d.ts.map +1 -1
  71. package/dist/Switch/Switch.js +5 -1
  72. package/dist/Table/columnUtils.d.ts.map +1 -1
  73. package/dist/Table/columnUtils.js +4 -1
  74. package/dist/TextArea/TextArea.d.ts +6 -3
  75. package/dist/TextArea/TextArea.d.ts.map +1 -1
  76. package/dist/TextArea/TextArea.js +17 -6
  77. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  78. package/dist/TimeInput/TimeInput.js +8 -1
  79. package/dist/Tokenizer/Tokenizer.js +11 -5
  80. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  81. package/dist/Tooltip/useTooltip.js +4 -1
  82. package/dist/TreeList/TreeList.js +2 -1
  83. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  84. package/dist/Typeahead/BaseTypeahead.js +5 -3
  85. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  86. package/dist/Typeahead/Typeahead.js +10 -1
  87. package/dist/astryx.css +25 -2
  88. package/dist/hooks/index.d.ts +8 -1
  89. package/dist/hooks/index.d.ts.map +1 -1
  90. package/dist/hooks/index.js +8 -1
  91. package/dist/hooks/useFocusTrap.d.ts +0 -11
  92. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  93. package/dist/hooks/useFocusTrap.js +1 -11
  94. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  95. package/dist/hooks/useInputStatusIcon.js +1 -0
  96. package/dist/index.d.ts +1 -0
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +1 -0
  99. package/dist/theme/defineTheme.d.ts +30 -7
  100. package/dist/theme/defineTheme.d.ts.map +1 -1
  101. package/dist/theme/defineTheme.js +36 -47
  102. package/dist/theme/expandColorScale.d.ts +17 -2
  103. package/dist/theme/expandColorScale.d.ts.map +1 -1
  104. package/dist/theme/expandColorScale.js +63 -33
  105. package/dist/theme/mergeComponents.d.ts +20 -0
  106. package/dist/theme/mergeComponents.d.ts.map +1 -0
  107. package/dist/theme/mergeComponents.js +56 -0
  108. package/dist/theme/onMediaTokens.d.ts +6 -1
  109. package/dist/theme/onMediaTokens.d.ts.map +1 -1
  110. package/dist/theme/onMediaTokens.js +11 -3
  111. package/dist/utils/characters.d.ts +27 -0
  112. package/dist/utils/characters.d.ts.map +1 -0
  113. package/dist/utils/characters.js +83 -0
  114. package/dist/utils/ime.d.ts +5 -0
  115. package/dist/utils/ime.d.ts.map +1 -0
  116. package/dist/utils/ime.js +63 -0
  117. package/dist/utils/index.d.ts +2 -0
  118. package/dist/utils/index.d.ts.map +1 -1
  119. package/dist/utils/index.js +3 -1
  120. package/locales/en.json +48 -0
  121. package/locales/pseudo.json +36 -0
  122. package/package.json +9 -8
  123. package/src/Avatar/Avatar.test.tsx +6 -1
  124. package/src/Avatar/Avatar.tsx +3 -21
  125. package/src/Banner/Banner.doc.mjs +12 -10
  126. package/src/Banner/Banner.test.tsx +108 -0
  127. package/src/Banner/Banner.tsx +124 -38
  128. package/src/Banner/index.ts +15 -13
  129. package/src/BottomSheet/BottomSheet.doc.mjs +266 -0
  130. package/src/BottomSheet/BottomSheet.test.tsx +2114 -0
  131. package/src/BottomSheet/BottomSheet.tsx +545 -0
  132. package/src/BottomSheet/BottomSheetPanel.test.tsx +240 -0
  133. package/src/BottomSheet/BottomSheetPanel.tsx +547 -0
  134. package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +219 -0
  135. package/src/BottomSheet/BottomSheetSwitcher.test.tsx +850 -0
  136. package/src/BottomSheet/BottomSheetSwitcher.tsx +628 -0
  137. package/src/BottomSheet/BottomSheetSwitcherContext.ts +51 -0
  138. package/src/BottomSheet/index.ts +15 -0
  139. package/src/BottomSheet/snapOffsets.test.ts +187 -0
  140. package/src/BottomSheet/snapOffsets.ts +159 -0
  141. package/src/BottomSheet/useMobileKeyboard.ts +499 -0
  142. package/src/BottomSheet/useSheetGestures.test.ts +1014 -0
  143. package/src/BottomSheet/useSheetGestures.ts +1407 -0
  144. package/src/Chat/ChatComposerInput.tsx +3 -4
  145. package/src/Chat/ChatTokenizedText.tsx +1 -1
  146. package/src/ComplexSelector/ComplexSelector.doc.mjs +55 -6
  147. package/src/ComplexSelector/ComplexSelector.test.tsx +197 -6
  148. package/src/ComplexSelector/ComplexSelector.tsx +156 -28
  149. package/src/ComplexSelector/index.ts +3 -1
  150. package/src/ContextMenu/ContextMenu.tsx +4 -2
  151. package/src/DateInput/DateInput.test.tsx +21 -0
  152. package/src/DateInput/DateInput.tsx +9 -1
  153. package/src/DateTimeInput/DateTimeInput.doc.mjs +4 -0
  154. package/src/DateTimeInput/DateTimeInput.test.tsx +137 -0
  155. package/src/DateTimeInput/DateTimeInput.tsx +39 -2
  156. package/src/Dialog/Dialog.tsx +2 -1
  157. package/src/FileInput/FileInput.test.tsx +53 -9
  158. package/src/Lightbox/Lightbox.test.tsx +49 -28
  159. package/src/Lightbox/Lightbox.tsx +7 -3
  160. package/src/Markdown/parser.test.ts +53 -0
  161. package/src/Markdown/parser.ts +53 -12
  162. package/src/MobileNav/MobileNav.tsx +128 -37
  163. package/src/MobileNav/MobileNavCloseEdgeCases.test.tsx +426 -0
  164. package/src/MobileNav/MobileNavCloseTiming.test.ts +58 -0
  165. package/src/MobileNav/MobileNavCloseVisibility.test.tsx +172 -0
  166. package/src/MultiSelector/MultiSelector.test.tsx +195 -51
  167. package/src/MultiSelector/MultiSelector.tsx +22 -8
  168. package/src/NumberInput/NumberInput.test.tsx +18 -0
  169. package/src/NumberInput/NumberInput.tsx +9 -1
  170. package/src/PowerSearch/PowerSearch.test.tsx +48 -3
  171. package/src/PowerSearch/PowerSearch.tsx +4 -1
  172. package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
  173. package/src/PowerSearch/formatFilterValue.test.ts +22 -0
  174. package/src/PowerSearch/formatFilterValue.ts +2 -4
  175. package/src/Selector/Selector.test.tsx +85 -26
  176. package/src/Selector/Selector.tsx +13 -4
  177. package/src/Switch/Switch.test.tsx +16 -0
  178. package/src/Switch/Switch.tsx +7 -0
  179. package/src/Table/Table.test.tsx +6 -0
  180. package/src/Table/columnUtils.ts +3 -1
  181. package/src/TextArea/TextArea.doc.mjs +1 -1
  182. package/src/TextArea/TextArea.test.tsx +72 -0
  183. package/src/TextArea/TextArea.tsx +26 -8
  184. package/src/TimeInput/TimeInput.test.tsx +23 -0
  185. package/src/TimeInput/TimeInput.tsx +8 -0
  186. package/src/Tokenizer/Tokenizer.test.tsx +50 -32
  187. package/src/Tokenizer/Tokenizer.tsx +5 -5
  188. package/src/Tooltip/useTooltip.tsx +4 -1
  189. package/src/TreeList/TreeList.doc.mjs +2 -2
  190. package/src/TreeList/TreeList.tsx +1 -1
  191. package/src/Typeahead/BaseTypeahead.tsx +10 -3
  192. package/src/Typeahead/Typeahead.test.tsx +116 -7
  193. package/src/Typeahead/Typeahead.tsx +10 -1
  194. package/src/__tests__/stubMatchMedia.test.ts +79 -0
  195. package/src/__tests__/stubMatchMedia.ts +95 -0
  196. package/src/hooks/index.ts +9 -5
  197. package/src/hooks/useFocusTrap.ts +1 -14
  198. package/src/hooks/useInputStatusIcon.test.tsx +19 -0
  199. package/src/hooks/useInputStatusIcon.tsx +7 -0
  200. package/src/index.ts +1 -0
  201. package/src/theme/defineTheme.test.ts +127 -0
  202. package/src/theme/defineTheme.ts +70 -55
  203. package/src/theme/expandColorScale.test.ts +138 -0
  204. package/src/theme/expandColorScale.ts +89 -44
  205. package/src/theme/extensibleAxes.test.ts +365 -0
  206. package/src/theme/mergeComponents.ts +59 -0
  207. package/src/theme/onMediaTokens.ts +9 -2
  208. package/src/utils/characters.test.ts +141 -0
  209. package/src/utils/characters.ts +88 -0
  210. package/src/utils/ime.test.ts +32 -0
  211. package/src/utils/ime.ts +69 -0
  212. package/src/utils/index.ts +4 -0
  213. package/dist/astryx.umd.js +0 -147
  214. 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
+ });