@astryxdesign/core 0.4.3 → 0.4.4-canary.2022d94

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 (156) 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/Lightbox/Lightbox.d.ts.map +1 -1
  43. package/dist/Lightbox/Lightbox.js +9 -3
  44. package/dist/MobileNav/MobileNav.d.ts +12 -0
  45. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  46. package/dist/MobileNav/MobileNav.js +102 -30
  47. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  48. package/dist/MultiSelector/MultiSelector.js +21 -7
  49. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  50. package/dist/NumberInput/NumberInput.js +9 -1
  51. package/dist/PowerSearch/PowerSearchEditPopover.js +1 -1
  52. package/dist/Selector/Selector.d.ts.map +1 -1
  53. package/dist/Selector/Selector.js +14 -3
  54. package/dist/Switch/Switch.d.ts.map +1 -1
  55. package/dist/Switch/Switch.js +5 -1
  56. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  57. package/dist/TimeInput/TimeInput.js +8 -1
  58. package/dist/Tokenizer/Tokenizer.js +11 -5
  59. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  60. package/dist/Tooltip/useTooltip.js +4 -1
  61. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  62. package/dist/Typeahead/BaseTypeahead.js +5 -3
  63. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  64. package/dist/Typeahead/Typeahead.js +10 -1
  65. package/dist/astryx.css +21 -0
  66. package/dist/hooks/index.d.ts +8 -1
  67. package/dist/hooks/index.d.ts.map +1 -1
  68. package/dist/hooks/index.js +8 -1
  69. package/dist/hooks/useFocusTrap.d.ts +0 -11
  70. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  71. package/dist/hooks/useFocusTrap.js +1 -11
  72. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  73. package/dist/hooks/useInputStatusIcon.js +1 -0
  74. package/dist/index.d.ts +1 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +1 -0
  77. package/dist/theme/defineTheme.d.ts +22 -4
  78. package/dist/theme/defineTheme.d.ts.map +1 -1
  79. package/dist/theme/expandColorScale.d.ts +17 -2
  80. package/dist/theme/expandColorScale.d.ts.map +1 -1
  81. package/dist/theme/expandColorScale.js +63 -33
  82. package/dist/utils/ime.d.ts +5 -0
  83. package/dist/utils/ime.d.ts.map +1 -0
  84. package/dist/utils/ime.js +63 -0
  85. package/dist/utils/index.d.ts +1 -0
  86. package/dist/utils/index.d.ts.map +1 -1
  87. package/dist/utils/index.js +2 -1
  88. package/locales/en.json +48 -0
  89. package/locales/pseudo.json +36 -0
  90. package/package.json +9 -8
  91. package/src/Banner/Banner.doc.mjs +3 -3
  92. package/src/Banner/Banner.test.tsx +40 -0
  93. package/src/Banner/Banner.tsx +27 -2
  94. package/src/BottomSheet/BottomSheet.doc.mjs +266 -0
  95. package/src/BottomSheet/BottomSheet.test.tsx +2114 -0
  96. package/src/BottomSheet/BottomSheet.tsx +545 -0
  97. package/src/BottomSheet/BottomSheetPanel.test.tsx +240 -0
  98. package/src/BottomSheet/BottomSheetPanel.tsx +547 -0
  99. package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +219 -0
  100. package/src/BottomSheet/BottomSheetSwitcher.test.tsx +850 -0
  101. package/src/BottomSheet/BottomSheetSwitcher.tsx +628 -0
  102. package/src/BottomSheet/BottomSheetSwitcherContext.ts +51 -0
  103. package/src/BottomSheet/index.ts +15 -0
  104. package/src/BottomSheet/snapOffsets.test.ts +187 -0
  105. package/src/BottomSheet/snapOffsets.ts +159 -0
  106. package/src/BottomSheet/useMobileKeyboard.ts +499 -0
  107. package/src/BottomSheet/useSheetGestures.test.ts +1059 -0
  108. package/src/BottomSheet/useSheetGestures.ts +1459 -0
  109. package/src/Chat/ChatComposerInput.tsx +3 -4
  110. package/src/ComplexSelector/ComplexSelector.tsx +12 -5
  111. package/src/ContextMenu/ContextMenu.tsx +4 -2
  112. package/src/DateInput/DateInput.test.tsx +21 -0
  113. package/src/DateInput/DateInput.tsx +9 -1
  114. package/src/DateTimeInput/DateTimeInput.doc.mjs +4 -0
  115. package/src/DateTimeInput/DateTimeInput.test.tsx +137 -0
  116. package/src/DateTimeInput/DateTimeInput.tsx +39 -2
  117. package/src/Dialog/Dialog.tsx +2 -1
  118. package/src/FileInput/FileInput.test.tsx +53 -9
  119. package/src/Lightbox/Lightbox.test.tsx +49 -28
  120. package/src/Lightbox/Lightbox.tsx +7 -3
  121. package/src/MobileNav/MobileNav.tsx +128 -37
  122. package/src/MobileNav/MobileNavCloseEdgeCases.test.tsx +426 -0
  123. package/src/MobileNav/MobileNavCloseTiming.test.ts +58 -0
  124. package/src/MobileNav/MobileNavCloseVisibility.test.tsx +172 -0
  125. package/src/MultiSelector/MultiSelector.test.tsx +195 -51
  126. package/src/MultiSelector/MultiSelector.tsx +22 -8
  127. package/src/NumberInput/NumberInput.test.tsx +18 -0
  128. package/src/NumberInput/NumberInput.tsx +9 -1
  129. package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
  130. package/src/Selector/Selector.test.tsx +85 -26
  131. package/src/Selector/Selector.tsx +13 -4
  132. package/src/Switch/Switch.test.tsx +16 -0
  133. package/src/Switch/Switch.tsx +7 -0
  134. package/src/TimeInput/TimeInput.test.tsx +23 -0
  135. package/src/TimeInput/TimeInput.tsx +8 -0
  136. package/src/Tokenizer/Tokenizer.test.tsx +50 -32
  137. package/src/Tokenizer/Tokenizer.tsx +5 -5
  138. package/src/Tooltip/useTooltip.tsx +4 -1
  139. package/src/Typeahead/BaseTypeahead.tsx +10 -3
  140. package/src/Typeahead/Typeahead.test.tsx +116 -7
  141. package/src/Typeahead/Typeahead.tsx +10 -1
  142. package/src/__tests__/stubMatchMedia.test.ts +79 -0
  143. package/src/__tests__/stubMatchMedia.ts +95 -0
  144. package/src/hooks/index.ts +9 -5
  145. package/src/hooks/useFocusTrap.ts +1 -14
  146. package/src/hooks/useInputStatusIcon.test.tsx +19 -0
  147. package/src/hooks/useInputStatusIcon.tsx +7 -0
  148. package/src/index.ts +1 -0
  149. package/src/theme/defineTheme.ts +22 -4
  150. package/src/theme/expandColorScale.test.ts +138 -0
  151. package/src/theme/expandColorScale.ts +89 -44
  152. package/src/utils/ime.test.ts +32 -0
  153. package/src/utils/ime.ts +69 -0
  154. package/src/utils/index.ts +2 -0
  155. package/dist/astryx.umd.js +0 -147
  156. 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
+ });