@astryxdesign/core 0.7.3 → 0.7.4-canary.1a552f2
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.
- package/dist/BottomSheet/BottomSheet.d.ts +18 -6
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +268 -58
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts +41 -12
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.js +294 -165
- package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts +51 -1
- package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcherContext.js +13 -1
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +7 -11
- package/dist/Chat/ChatMessageList.d.ts.map +1 -1
- package/dist/Chat/ChatMessageList.js +8 -1
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +46 -7
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +6 -0
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +6 -11
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +7 -1
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +6 -1
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +12 -0
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +6 -1
- package/dist/DateInput/NativeDateField.d.ts.map +1 -1
- package/dist/DateInput/NativeDateField.js +6 -1
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +9 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +6 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +6 -1
- package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
- package/dist/DateTimeInput/TouchDateTimeField.js +9 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +7 -1
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +16 -2
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +6 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +6 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +6 -1
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +6 -1
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +9 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +6 -1
- package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
- package/dist/TimeInput/TouchTimeField.js +9 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +9 -1
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +7 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +9 -1
- package/dist/astryx.css +2 -0
- package/dist/hooks/useBusyAnnouncement.d.ts +22 -0
- package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -0
- package/dist/hooks/useBusyAnnouncement.js +87 -0
- package/dist/hooks/useMenuPress.d.ts +2 -2
- package/dist/hooks/useMenuPress.d.ts.map +1 -1
- package/dist/hooks/useMenuPress.js +5 -1
- package/dist/hooks/useTypeahead.d.ts.map +1 -1
- package/dist/hooks/useTypeahead.js +7 -2
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +1 -0
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +1 -0
- package/locales/en.json +6 -2
- package/locales/pseudo.json +3 -0
- package/package.json +4 -4
- package/src/BottomSheet/BottomSheet.doc.mjs +2 -2
- package/src/BottomSheet/BottomSheet.spec.md +3 -5
- package/src/BottomSheet/BottomSheet.tsx +260 -47
- package/src/BottomSheet/BottomSheetEdgeTint.test.tsx +29 -4
- package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +11 -10
- package/src/BottomSheet/BottomSheetSwitcher.spec.md +35 -41
- package/src/BottomSheet/BottomSheetSwitcher.test.tsx +1051 -49
- package/src/BottomSheet/BottomSheetSwitcher.tsx +396 -215
- package/src/BottomSheet/BottomSheetSwitcherContext.ts +57 -2
- package/src/BottomSheet/__tests__/BottomSheetNativeModal.a11y.browser.spec.ts +461 -0
- package/src/Carousel/Carousel.test.tsx +8 -12
- package/src/Carousel/Carousel.tsx +6 -13
- package/src/Chat/ChatComposerInput.test.tsx +167 -1
- package/src/Chat/ChatMessageList.test.tsx +6 -2
- package/src/Chat/ChatMessageList.tsx +7 -1
- package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +20 -12
- package/src/Chat/useTriggerMenu.tsx +55 -6
- package/src/CheckboxInput/CheckboxInput.tsx +6 -0
- package/src/CommandPalette/CommandPalette.test.tsx +4 -2
- package/src/CommandPalette/CommandPalette.tsx +6 -11
- package/src/CommandPalette/CommandPaletteInput.test.tsx +3 -1
- package/src/CommandPalette/CommandPaletteInput.tsx +10 -1
- package/src/ComplexSelector/ComplexSelector.tsx +5 -1
- package/src/ContextMenu/ContextMenu.test.tsx +34 -0
- package/src/ContextMenu/ContextMenu.tsx +13 -1
- package/src/DateInput/DateInput.tsx +5 -1
- package/src/DateInput/DateInputTouch.test.tsx +45 -0
- package/src/DateInput/NativeDateField.test.tsx +10 -2
- package/src/DateInput/NativeDateField.tsx +5 -1
- package/src/DateInput/TouchDateField.tsx +14 -2
- package/src/DateRangeInput/DateRangeInput.tsx +5 -1
- package/src/DateTimeInput/DateTimeInput.tsx +5 -1
- package/src/DateTimeInput/TouchDateTimeField.tsx +14 -2
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +10 -1
- package/src/FileInput/FileInput.tsx +18 -2
- package/src/MultiSelector/MultiSelector.test.tsx +18 -4
- package/src/MultiSelector/MultiSelector.tsx +5 -1
- package/src/ProgressBar/ProgressBar.test.tsx +4 -21
- package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +114 -0
- package/src/ProgressBar/__tests__/ProgressBar.a11y.known-failures.ts +12 -0
- package/src/ProgressBar/__tests__/ProgressBar.a11y.renders.tsx +38 -0
- package/src/ProgressBar/__tests__/ProgressBar.a11y.states.ts +123 -0
- package/src/ProgressBar/__tests__/ProgressBar.a11y.test.tsx +107 -0
- package/src/Selector/Selector.test.tsx +22 -5
- package/src/Selector/Selector.tsx +5 -1
- package/src/TextArea/TextArea.test.tsx +9 -1
- package/src/TextArea/TextArea.tsx +5 -1
- package/src/TextInput/TextInput.tsx +5 -1
- package/src/Thumbnail/Thumbnail.test.tsx +6 -1
- package/src/Thumbnail/Thumbnail.tsx +12 -3
- package/src/TimeInput/TimeInput.tsx +5 -1
- package/src/TimeInput/TouchTimeField.tsx +12 -2
- package/src/Tokenizer/Tokenizer.test.tsx +17 -12
- package/src/Tokenizer/Tokenizer.tsx +10 -1
- package/src/Typeahead/BaseTypeahead.tsx +14 -1
- package/src/Typeahead/Typeahead.test.tsx +32 -41
- package/src/Typeahead/Typeahead.tsx +10 -1
- package/src/__tests__/BusyOwnerAnnouncement.test.tsx +792 -0
- package/src/hooks/__tests__/MenuPressShadowRoot.a11y.chromium.spec.ts +50 -0
- package/src/hooks/useBusyAnnouncement.ts +100 -0
- package/src/hooks/useMenuPress.test.tsx +27 -1
- package/src/hooks/useMenuPress.ts +12 -3
- package/src/hooks/useTypeahead.test.tsx +42 -1
- package/src/hooks/useTypeahead.ts +7 -2
- package/src/i18n/generated-locales/en.generated.ts +1 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +1 -0
|
@@ -6,10 +6,22 @@
|
|
|
6
6
|
*
|
|
7
7
|
* BottomSheet selects one of two focused hosts. A standalone host owns its
|
|
8
8
|
* native dialog lifecycle and joins the shared layer dismissal stack; a
|
|
9
|
-
* switcher item
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* switcher item owns a native dialog of its own too, but hands its lifecycle
|
|
10
|
+
* to the parent's transition state machine, scrim ownership, and dismissal
|
|
11
|
+
* registration. Both render the same BottomSheetPanel, which owns sheet
|
|
12
|
+
* presentation, content padding, gestures, mobile-keyboard accommodation,
|
|
13
|
+
* and motion completion.
|
|
14
|
+
*
|
|
15
|
+
* Every sheet dialog is native first. A scrim-backed sheet is presented with
|
|
16
|
+
* showModal(): the browser makes the page inert and keeps focus inside the
|
|
17
|
+
* dialog, delivers Escape and the platform close as `cancel`, paints the
|
|
18
|
+
* scrim as `::backdrop`, and returns focus to the opener on close(). Page
|
|
19
|
+
* scroll is locked by the shared useScrollLock hook, as for Dialog: a
|
|
20
|
+
* standalone sheet holds it while presented, a switcher holds one for the
|
|
21
|
+
* whole modal flow. The remaining script is what no single dialog can
|
|
22
|
+
* decide: gating `cancel` by `purpose` and the shared dismissal stack, and,
|
|
23
|
+
* in a switcher, handing one scrim between two dialogs and keeping focus in
|
|
24
|
+
* the active sheet when a retained dialog closes.
|
|
13
25
|
*
|
|
14
26
|
* SYNC: When modified, update these files to stay in sync:
|
|
15
27
|
* - /packages/core/src/BottomSheet/BottomSheetPanel.tsx
|
|
@@ -82,8 +94,8 @@ interface SwitcherBottomSheetProps extends BottomSheetSharedProps {
|
|
|
82
94
|
}
|
|
83
95
|
export type BottomSheetProps = StandaloneBottomSheetProps | SwitcherBottomSheetProps;
|
|
84
96
|
/**
|
|
85
|
-
* A mobile touch sheet that
|
|
86
|
-
* BottomSheetSwitcher
|
|
97
|
+
* A mobile touch sheet that owns a native dialog. Given a sheetId inside a
|
|
98
|
+
* BottomSheetSwitcher, that switcher coordinates the dialog's lifecycle.
|
|
87
99
|
*/
|
|
88
100
|
export declare function BottomSheet(props: BottomSheetProps): import("react").JSX.Element;
|
|
89
101
|
export declare namespace BottomSheet {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheet.d.ts","sourceRoot":"","sources":["../../src/BottomSheet/BottomSheet.tsx"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"BottomSheet.d.ts","sourceRoot":"","sources":["../../src/BottomSheet/BottomSheet.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,EAOL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAoBhD,YAAY,EAAC,iBAAiB,EAAE,oBAAoB,EAAC,MAAM,oBAAoB,CAAC;AAChF,OAAO,KAAK,EAAC,iBAAiB,EAAE,oBAAoB,EAAC,MAAM,oBAAoB,CAAC;AA2FhF,UAAU,sBAAuB,SAAQ,SAAS,CAAC,cAAc,CAAC;IAChE,qDAAqD;IACrD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEhC,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IAEd,0EAA0E;IAC1E,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB,wGAAwG;IACxG,MAAM,CAAC,EAAE,iBAAiB,GAAG,MAAM,GAAG,MAAM,CAAC;IAE7C;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IAEjD;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,UAAU,0BAA2B,SAAQ,sBAAsB;IACjE,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0DAA0D;IAC1D,aAAa,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,KAAK,CAAC;CACjB;AAED,UAAU,wBAAyB,SAAQ,sBAAsB;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB;AAED,MAAM,MAAM,gBAAgB,GAC1B,0BAA0B,GAAG,wBAAwB,CAAC;AAikBxD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,+BA6BlD;yBA7Be,WAAW"}
|
|
@@ -10,10 +10,22 @@
|
|
|
10
10
|
*
|
|
11
11
|
* BottomSheet selects one of two focused hosts. A standalone host owns its
|
|
12
12
|
* native dialog lifecycle and joins the shared layer dismissal stack; a
|
|
13
|
-
* switcher item
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* switcher item owns a native dialog of its own too, but hands its lifecycle
|
|
14
|
+
* to the parent's transition state machine, scrim ownership, and dismissal
|
|
15
|
+
* registration. Both render the same BottomSheetPanel, which owns sheet
|
|
16
|
+
* presentation, content padding, gestures, mobile-keyboard accommodation,
|
|
17
|
+
* and motion completion.
|
|
18
|
+
*
|
|
19
|
+
* Every sheet dialog is native first. A scrim-backed sheet is presented with
|
|
20
|
+
* showModal(): the browser makes the page inert and keeps focus inside the
|
|
21
|
+
* dialog, delivers Escape and the platform close as `cancel`, paints the
|
|
22
|
+
* scrim as `::backdrop`, and returns focus to the opener on close(). Page
|
|
23
|
+
* scroll is locked by the shared useScrollLock hook, as for Dialog: a
|
|
24
|
+
* standalone sheet holds it while presented, a switcher holds one for the
|
|
25
|
+
* whole modal flow. The remaining script is what no single dialog can
|
|
26
|
+
* decide: gating `cancel` by `purpose` and the shared dismissal stack, and,
|
|
27
|
+
* in a switcher, handing one scrim between two dialogs and keeping focus in
|
|
28
|
+
* the active sheet when a retained dialog closes.
|
|
17
29
|
*
|
|
18
30
|
* SYNC: When modified, update these files to stay in sync:
|
|
19
31
|
* - /packages/core/src/BottomSheet/BottomSheetPanel.tsx
|
|
@@ -32,6 +44,7 @@ import * as stylex from '@stylexjs/stylex';
|
|
|
32
44
|
import "../theme/tokens.stylex.js";
|
|
33
45
|
import { colorVars, durationVars, easeVars } from "../theme/tokens.stylex.js";
|
|
34
46
|
import { useDevWarning, useScrollLock } from "../hooks/index.js";
|
|
47
|
+
import { mergeProps } from "../utils/index.js";
|
|
35
48
|
import { LayerDepthProvider } from "../Layer/LayerDepthContext.js";
|
|
36
49
|
import { useLayerDismissal } from "../Layer/useLayerDismissal.js";
|
|
37
50
|
import { focusForLastInput } from "../utils/focusReturn.js";
|
|
@@ -40,6 +53,53 @@ import { BottomSheetPanel } from "./BottomSheetPanel.js";
|
|
|
40
53
|
import { BottomSheetEdgeTint } from "./BottomSheetEdgeTint.js";
|
|
41
54
|
import { BottomSheetSwitcherContext } from "./BottomSheetSwitcherContext.js";
|
|
42
55
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
56
|
+
const styles = {
|
|
57
|
+
dialog: {
|
|
58
|
+
kVAEAm: "xixxii4",
|
|
59
|
+
kpwlN0: "x10a8y8t",
|
|
60
|
+
kzqmXN: "x1o6l61p",
|
|
61
|
+
kZKoxP: "xtdtrs8",
|
|
62
|
+
ks0D6T: "x1x1rfll",
|
|
63
|
+
kskxy: "x7ab17h",
|
|
64
|
+
kogj98: "x1ghz6dp",
|
|
65
|
+
kmVPX3: "x1717udv",
|
|
66
|
+
kMzoRj: "xc342km",
|
|
67
|
+
ksu8eU: "xng3xce",
|
|
68
|
+
kWkggS: "xjbqb8w",
|
|
69
|
+
kVQacm: "x1rea2x4",
|
|
70
|
+
k1xSpc: "x1s85apg",
|
|
71
|
+
kI3sdo: "x1a2a7pz",
|
|
72
|
+
$$css: true
|
|
73
|
+
},
|
|
74
|
+
dialogOpen: {
|
|
75
|
+
k1xSpc: "x1lliihq",
|
|
76
|
+
$$css: true
|
|
77
|
+
},
|
|
78
|
+
scrim: {
|
|
79
|
+
kGyWv1: "xnixb3f",
|
|
80
|
+
k5sjJv: "xni466t xxiuuzi",
|
|
81
|
+
kND0Po: "xc0dz0a",
|
|
82
|
+
k9an0g: "x10buo38",
|
|
83
|
+
kb4ib: "x15h3t91",
|
|
84
|
+
kwHxkk: "x142juwg",
|
|
85
|
+
k4oj2o: "x15l12jy",
|
|
86
|
+
$$css: true
|
|
87
|
+
},
|
|
88
|
+
dialogNonModalItem: {
|
|
89
|
+
kfzvcC: "x47corl",
|
|
90
|
+
kzqmXN: "xh8yej3",
|
|
91
|
+
kZKoxP: "x5yr21d",
|
|
92
|
+
$$css: true
|
|
93
|
+
},
|
|
94
|
+
dialogNonModalItemTop: {
|
|
95
|
+
kY2c9j: "x1vjfegm",
|
|
96
|
+
$$css: true
|
|
97
|
+
},
|
|
98
|
+
scrimClosing: {
|
|
99
|
+
kb4ib: "x1cz9k3x",
|
|
100
|
+
$$css: true
|
|
101
|
+
}
|
|
102
|
+
};
|
|
43
103
|
function panelStateForSwitcherPhase(phase, alignmentOffset) {
|
|
44
104
|
switch (phase) {
|
|
45
105
|
case 'active':
|
|
@@ -91,6 +151,43 @@ function focusPanel(panel, isModal) {
|
|
|
91
151
|
});
|
|
92
152
|
}
|
|
93
153
|
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Present a switcher step's dialog modally with no focus to return to.
|
|
157
|
+
* showModal() records the element focused at that moment and close() moves
|
|
158
|
+
* focus back to it, in Chromium and WebKit even when focus is in another
|
|
159
|
+
* dialog by then. For a step that element is the control that advanced the
|
|
160
|
+
* flow (Continue, Back) or the flow's opener, and the dialog closes a fade
|
|
161
|
+
* later, while the user is in the next step: the return would pull focus
|
|
162
|
+
* off the active panel with no user action. Blurring first leaves nothing
|
|
163
|
+
* recorded, so the close moves nothing; the entering step then focuses its
|
|
164
|
+
* own panel, and the switcher returns focus to the opener itself when the
|
|
165
|
+
* flow ends. The blur happens in the same task as the present, so no frame
|
|
166
|
+
* paints without focus.
|
|
167
|
+
*/
|
|
168
|
+
function presentStepModally(dialog) {
|
|
169
|
+
const focused = dialog.ownerDocument.activeElement;
|
|
170
|
+
if (focused instanceof HTMLElement && focused !== dialog.ownerDocument.body) {
|
|
171
|
+
focused.blur();
|
|
172
|
+
}
|
|
173
|
+
dialog.showModal();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Present a switcher dialog whose backdrop must start, and stay, clear: the
|
|
178
|
+
* opacity is set with the scrim transition pinned to 0s, the dialog is
|
|
179
|
+
* presented, and the pin is lifted only after a style flush has applied the
|
|
180
|
+
* clear backdrop, so no frame eases from a previous backdrop value.
|
|
181
|
+
*/
|
|
182
|
+
function presentWithClearScrim(dialog) {
|
|
183
|
+
dialog.style.setProperty('--_sheet-scrim-duration', '0s');
|
|
184
|
+
dialog.style.setProperty('--_sheet-scrim-opacity', '0');
|
|
185
|
+
presentStepModally(dialog);
|
|
186
|
+
if (typeof getComputedStyle === 'function') {
|
|
187
|
+
void getComputedStyle(dialog, '::backdrop').opacity;
|
|
188
|
+
}
|
|
189
|
+
dialog.style.removeProperty('--_sheet-scrim-duration');
|
|
190
|
+
}
|
|
94
191
|
function StandaloneBottomSheet({
|
|
95
192
|
ref,
|
|
96
193
|
isOpen,
|
|
@@ -231,10 +328,10 @@ function StandaloneBottomSheet({
|
|
|
231
328
|
className: "xixxii4 x10a8y8t x1o6l61p xtdtrs8 x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1a2a7pz x1lliihq"
|
|
232
329
|
},
|
|
233
330
|
4: {
|
|
234
|
-
className: "xixxii4 x10a8y8t x1o6l61p xtdtrs8 x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1s85apg x1a2a7pz xnixb3f xni466t xxiuuzi xc0dz0a
|
|
331
|
+
className: "xixxii4 x10a8y8t x1o6l61p xtdtrs8 x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1s85apg x1a2a7pz xnixb3f xni466t xxiuuzi xc0dz0a x10buo38 x15h3t91 x142juwg x15l12jy"
|
|
235
332
|
},
|
|
236
333
|
12: {
|
|
237
|
-
className: "xixxii4 x10a8y8t x1o6l61p xtdtrs8 x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1a2a7pz x1lliihq xnixb3f xni466t xxiuuzi xc0dz0a
|
|
334
|
+
className: "xixxii4 x10a8y8t x1o6l61p xtdtrs8 x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1a2a7pz x1lliihq xnixb3f xni466t xxiuuzi xc0dz0a x10buo38 x15h3t91 x142juwg x15l12jy"
|
|
238
335
|
},
|
|
239
336
|
2: {
|
|
240
337
|
className: "xixxii4 x10a8y8t x1o6l61p xtdtrs8 x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1s85apg x1a2a7pz x1cz9k3x"
|
|
@@ -243,10 +340,10 @@ function StandaloneBottomSheet({
|
|
|
243
340
|
className: "xixxii4 x10a8y8t x1o6l61p xtdtrs8 x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1a2a7pz x1lliihq x1cz9k3x"
|
|
244
341
|
},
|
|
245
342
|
6: {
|
|
246
|
-
className: "xixxii4 x10a8y8t x1o6l61p xtdtrs8 x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1s85apg x1a2a7pz xnixb3f xni466t xxiuuzi xc0dz0a
|
|
343
|
+
className: "xixxii4 x10a8y8t x1o6l61p xtdtrs8 x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1s85apg x1a2a7pz xnixb3f xni466t xxiuuzi xc0dz0a x10buo38 x142juwg x15l12jy x1cz9k3x"
|
|
247
344
|
},
|
|
248
345
|
14: {
|
|
249
|
-
className: "xixxii4 x10a8y8t x1o6l61p xtdtrs8 x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1a2a7pz x1lliihq xnixb3f xni466t xxiuuzi xc0dz0a
|
|
346
|
+
className: "xixxii4 x10a8y8t x1o6l61p xtdtrs8 x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1a2a7pz x1lliihq xnixb3f xni466t xxiuuzi xc0dz0a x10buo38 x142juwg x15l12jy x1cz9k3x"
|
|
250
347
|
},
|
|
251
348
|
1: {
|
|
252
349
|
className: "xixxii4 x10a8y8t x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1s85apg x1a2a7pz x47corl xfo81ep xh8yej3 x5yr21d"
|
|
@@ -255,10 +352,10 @@ function StandaloneBottomSheet({
|
|
|
255
352
|
className: "xixxii4 x10a8y8t x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1a2a7pz x1lliihq x47corl xfo81ep xh8yej3 x5yr21d"
|
|
256
353
|
},
|
|
257
354
|
5: {
|
|
258
|
-
className: "xixxii4 x10a8y8t x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1s85apg x1a2a7pz xnixb3f xni466t xxiuuzi xc0dz0a
|
|
355
|
+
className: "xixxii4 x10a8y8t x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1s85apg x1a2a7pz xnixb3f xni466t xxiuuzi xc0dz0a x10buo38 x15h3t91 x142juwg x15l12jy x47corl xfo81ep xh8yej3 x5yr21d"
|
|
259
356
|
},
|
|
260
357
|
13: {
|
|
261
|
-
className: "xixxii4 x10a8y8t x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1a2a7pz x1lliihq xnixb3f xni466t xxiuuzi xc0dz0a
|
|
358
|
+
className: "xixxii4 x10a8y8t x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1a2a7pz x1lliihq xnixb3f xni466t xxiuuzi xc0dz0a x10buo38 x15h3t91 x142juwg x15l12jy x47corl xfo81ep xh8yej3 x5yr21d"
|
|
262
359
|
},
|
|
263
360
|
3: {
|
|
264
361
|
className: "xixxii4 x10a8y8t x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1s85apg x1a2a7pz x1cz9k3x x47corl xfo81ep xh8yej3 x5yr21d"
|
|
@@ -267,10 +364,10 @@ function StandaloneBottomSheet({
|
|
|
267
364
|
className: "xixxii4 x10a8y8t x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1a2a7pz x1lliihq x1cz9k3x x47corl xfo81ep xh8yej3 x5yr21d"
|
|
268
365
|
},
|
|
269
366
|
7: {
|
|
270
|
-
className: "xixxii4 x10a8y8t x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1s85apg x1a2a7pz xnixb3f xni466t xxiuuzi xc0dz0a
|
|
367
|
+
className: "xixxii4 x10a8y8t x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1s85apg x1a2a7pz xnixb3f xni466t xxiuuzi xc0dz0a x10buo38 x142juwg x15l12jy x1cz9k3x x47corl xfo81ep xh8yej3 x5yr21d"
|
|
271
368
|
},
|
|
272
369
|
15: {
|
|
273
|
-
className: "xixxii4 x10a8y8t x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1a2a7pz x1lliihq xnixb3f xni466t xxiuuzi xc0dz0a
|
|
370
|
+
className: "xixxii4 x10a8y8t x1x1rfll x7ab17h x1ghz6dp x1717udv xc342km xng3xce xjbqb8w x1rea2x4 x1a2a7pz x1lliihq xnixb3f xni466t xxiuuzi xc0dz0a x10buo38 x142juwg x15l12jy x1cz9k3x x47corl xfo81ep xh8yej3 x5yr21d"
|
|
274
371
|
}
|
|
275
372
|
}[!!shouldPresent << 3 | !!hasScrim << 2 | !!(hasScrim && !isOpen && isPresented) << 1 | !!!hasScrim << 0],
|
|
276
373
|
ref: dialogRef,
|
|
@@ -324,12 +421,21 @@ function SwitcherBottomSheetItem({
|
|
|
324
421
|
onActiveSheetChange,
|
|
325
422
|
getSheetPhase,
|
|
326
423
|
getSheetAlignmentOffset,
|
|
424
|
+
hostSheet,
|
|
425
|
+
isScrimOwner,
|
|
426
|
+
isFlowClosing,
|
|
327
427
|
registerSheetElement,
|
|
328
|
-
|
|
428
|
+
registerSheetDialog,
|
|
329
429
|
registerSheetPurpose,
|
|
430
|
+
onBeforeSheetPresent,
|
|
431
|
+
isCoveredInTopLayer,
|
|
330
432
|
onSheetEnterStart,
|
|
331
433
|
onSheetTransitionComplete,
|
|
332
|
-
onSheetScrimOpacityChange
|
|
434
|
+
onSheetScrimOpacityChange,
|
|
435
|
+
dialogProps,
|
|
436
|
+
onDialogCancel,
|
|
437
|
+
onDialogClick,
|
|
438
|
+
onDialogKeyDown
|
|
333
439
|
} = switcher;
|
|
334
440
|
const hasValidSheetId = typeof sheetId === 'string' && sheetId.length > 0;
|
|
335
441
|
const phase = hasValidSheetId ? getSheetPhase(sheetId) : 'hidden';
|
|
@@ -339,6 +445,10 @@ function SwitcherBottomSheetItem({
|
|
|
339
445
|
const isInactive = phase === 'covered' || phase === 'aligning' || phase === 'fading' || phase === 'exiting';
|
|
340
446
|
const isPresented = phase !== 'hidden';
|
|
341
447
|
const isTopSheet = phase === 'active' || phase === 'entering';
|
|
448
|
+
const ownsScrim = hasValidSheetId && isScrimOwner(sheetId);
|
|
449
|
+
const isHostSheet = hasValidSheetId && hostSheet === sheetId;
|
|
450
|
+
const dialogRef = useRef(null);
|
|
451
|
+
const dialogModeRef = useRef(null);
|
|
342
452
|
const panelRef = useRef(null);
|
|
343
453
|
const previousPhaseRef = useRef(phase);
|
|
344
454
|
const previousPhase = previousPhaseRef.current;
|
|
@@ -357,6 +467,12 @@ function SwitcherBottomSheetItem({
|
|
|
357
467
|
registerSheetElement(sheetId, element);
|
|
358
468
|
}
|
|
359
469
|
}, [hasValidSheetId, registerSheetElement, sheetId]);
|
|
470
|
+
const handleDialogElementChange = useCallback(element => {
|
|
471
|
+
dialogRef.current = element;
|
|
472
|
+
if (hasValidSheetId) {
|
|
473
|
+
registerSheetDialog(sheetId, element);
|
|
474
|
+
}
|
|
475
|
+
}, [hasValidSheetId, registerSheetDialog, sheetId]);
|
|
360
476
|
const handleMotionStart = useCallback(motion => {
|
|
361
477
|
if (motion === 'entering' && hasValidSheetId) {
|
|
362
478
|
onSheetEnterStart(sheetId);
|
|
@@ -375,13 +491,6 @@ function SwitcherBottomSheetItem({
|
|
|
375
491
|
onSheetScrimOpacityChange(sheetId, opacity);
|
|
376
492
|
}
|
|
377
493
|
}, [hasValidSheetId, onSheetScrimOpacityChange, sheetId]);
|
|
378
|
-
useLayoutEffect(() => {
|
|
379
|
-
if (!hasValidSheetId) {
|
|
380
|
-
return;
|
|
381
|
-
}
|
|
382
|
-
registerSheetLabel(sheetId, label);
|
|
383
|
-
return () => registerSheetLabel(sheetId, null);
|
|
384
|
-
}, [hasValidSheetId, label, registerSheetLabel, sheetId]);
|
|
385
494
|
useLayoutEffect(() => {
|
|
386
495
|
if (!hasValidSheetId) {
|
|
387
496
|
return;
|
|
@@ -389,6 +498,70 @@ function SwitcherBottomSheetItem({
|
|
|
389
498
|
registerSheetPurpose(sheetId, purpose);
|
|
390
499
|
return () => registerSheetPurpose(sheetId, null);
|
|
391
500
|
}, [hasValidSheetId, purpose, registerSheetPurpose, sheetId]);
|
|
501
|
+
|
|
502
|
+
// Present this sheet's own dialog while the switcher keeps the sheet on
|
|
503
|
+
// screen, and close it once the sheet is hidden. A scrim flow presents
|
|
504
|
+
// modally: an entering dialog is shown above the retained one in the top
|
|
505
|
+
// layer, and the retained dialog closes only after its panel has faded. A
|
|
506
|
+
// modal dialog that is still open beneath a newer one -- the user went back
|
|
507
|
+
// to a sheet that was still fading -- re-presents to become topmost again:
|
|
508
|
+
// the document is blocked by the topmost modal dialog, so a lower one is
|
|
509
|
+
// inert whatever the switcher calls it.
|
|
510
|
+
//
|
|
511
|
+
// Every present blurs first, so no step dialog records an element to
|
|
512
|
+
// return focus to: a close while another sheet is active moves nothing,
|
|
513
|
+
// and when the flow ends the switcher focuses the flow's opener itself.
|
|
514
|
+
useLayoutEffect(() => {
|
|
515
|
+
const dialog = dialogRef.current;
|
|
516
|
+
if (dialog == null || !hasValidSheetId) {
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
if (!isPresented) {
|
|
520
|
+
if (dialog.open) {
|
|
521
|
+
dialog.close();
|
|
522
|
+
}
|
|
523
|
+
dialogModeRef.current = null;
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
const nextMode = hasScrim ? 'modal' : 'non-modal';
|
|
527
|
+
if (dialog.open && dialogModeRef.current !== nextMode) {
|
|
528
|
+
dialog.close();
|
|
529
|
+
}
|
|
530
|
+
if (dialog.open && hasScrim && isInteractive && isCoveredInTopLayer(sheetId)) {
|
|
531
|
+
dialog.close();
|
|
532
|
+
}
|
|
533
|
+
if (!dialog.open) {
|
|
534
|
+
if (hasScrim) {
|
|
535
|
+
onBeforeSheetPresent(sheetId);
|
|
536
|
+
if (ownsScrim) {
|
|
537
|
+
presentStepModally(dialog);
|
|
538
|
+
} else {
|
|
539
|
+
// Entering above a retained dialog whose backdrop already dims the
|
|
540
|
+
// page: present with a clear backdrop so the page is not dimmed
|
|
541
|
+
// twice and the previous panel stays undimmed beneath this one.
|
|
542
|
+
// Pinned to 0s across the present: a dialog re-presented from the
|
|
543
|
+
// retained position (the user went back while it was fading)
|
|
544
|
+
// closed with its backdrop at 1, and would otherwise ease it down
|
|
545
|
+
// over the scrim duration on top of the new owner's backdrop.
|
|
546
|
+
presentWithClearScrim(dialog);
|
|
547
|
+
}
|
|
548
|
+
} else {
|
|
549
|
+
dialog.show();
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
dialogModeRef.current = nextMode;
|
|
553
|
+
}, [hasScrim, hasValidSheetId, isCoveredInTopLayer, isInteractive, isPresented, onBeforeSheetPresent, ownsScrim, sheetId]);
|
|
554
|
+
|
|
555
|
+
// A sheet removed while presented -- a consumer unmounts the closing sheet
|
|
556
|
+
// in the same update that closes the flow -- takes its dialog out of the
|
|
557
|
+
// top layer with it, but the element would keep its `open` state. Close it
|
|
558
|
+
// while it is still attached so the native lifecycle ends cleanly.
|
|
559
|
+
useLayoutEffect(() => () => {
|
|
560
|
+
const dialog = dialogRef.current;
|
|
561
|
+
if (dialog?.open) {
|
|
562
|
+
dialog.close();
|
|
563
|
+
}
|
|
564
|
+
}, []);
|
|
392
565
|
useEffect(() => {
|
|
393
566
|
if (isInteractive) {
|
|
394
567
|
const wasInteractive = previousPhase === 'active' || previousPhase === 'entering';
|
|
@@ -401,50 +574,87 @@ function SwitcherBottomSheetItem({
|
|
|
401
574
|
}
|
|
402
575
|
}, [hasScrim, isInteractive, phase, previousPhase]);
|
|
403
576
|
useDevWarning('BottomSheet', 'requires a non-empty `label` for an accessible name; the open sheet ' + 'has no built-in heading to derive one from.', isInteractive && !label);
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
577
|
+
|
|
578
|
+
// The switcher's dialog surface applies to every sheet dialog, except the
|
|
579
|
+
// attributes that identify one element: those render on the host dialog
|
|
580
|
+
// only, the one the switcher's ref resolves to. Of the attributes set
|
|
581
|
+
// explicitly below, only `role` has a consumer value to keep: a required
|
|
582
|
+
// step forces `alertdialog`, otherwise the switcher's `role` stands, as on
|
|
583
|
+
// a shared dialog. `aria-label`/`aria-labelledby` keep consumer precedence
|
|
584
|
+
// above; `aria-modal`, `aria-hidden`, and `inert` are the host's own state.
|
|
585
|
+
const {
|
|
586
|
+
className: switcherClassName,
|
|
587
|
+
style: switcherStyle,
|
|
588
|
+
xstyle: switcherXstyle,
|
|
589
|
+
'aria-label': switcherAriaLabel,
|
|
590
|
+
'aria-labelledby': switcherAriaLabelledBy,
|
|
591
|
+
id: switcherId,
|
|
592
|
+
'data-testid': switcherTestId,
|
|
593
|
+
...switcherDialogProps
|
|
594
|
+
} = dialogProps;
|
|
595
|
+
const dialogPresentationProps = mergeProps(stylex.props(styles.dialog, isPresented && styles.dialogOpen, hasScrim && styles.scrim, hasScrim && ownsScrim && isFlowClosing && styles.scrimClosing, !hasScrim && styles.dialogNonModalItem, !hasScrim && isTopSheet && styles.dialogNonModalItemTop, switcherXstyle), switcherClassName, switcherStyle);
|
|
596
|
+
return /*#__PURE__*/_jsxs("dialog", {
|
|
597
|
+
...switcherDialogProps,
|
|
598
|
+
...dialogPresentationProps,
|
|
599
|
+
id: isHostSheet ? switcherId : undefined,
|
|
600
|
+
"data-testid": isHostSheet ? switcherTestId : undefined,
|
|
601
|
+
ref: handleDialogElementChange,
|
|
602
|
+
"aria-label": switcherAriaLabel ?? (switcherAriaLabelledBy == null ? label : undefined),
|
|
603
|
+
"aria-labelledby": switcherAriaLabelledBy,
|
|
604
|
+
"aria-modal": hasScrim && isInteractive ? 'true' : undefined,
|
|
420
605
|
"aria-hidden": isInactive ? 'true' : undefined,
|
|
421
606
|
inert: isInactive ? true : undefined,
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
607
|
+
role: purpose === 'required' ? 'alertdialog' : switcherDialogProps.role,
|
|
608
|
+
onCancel: onDialogCancel,
|
|
609
|
+
onClick: onDialogClick,
|
|
610
|
+
onKeyDown: onDialogKeyDown,
|
|
611
|
+
children: [/*#__PURE__*/_jsx("div", {
|
|
612
|
+
...{
|
|
613
|
+
0: {
|
|
614
|
+
className: "x10l6tqk x17y0mx6 x1ey2m1c x78zum5 xl56j7k x47corl"
|
|
615
|
+
},
|
|
616
|
+
2: {
|
|
617
|
+
className: "x10l6tqk x17y0mx6 x1ey2m1c xl56j7k x47corl x1s85apg"
|
|
618
|
+
},
|
|
619
|
+
1: {
|
|
620
|
+
className: "x10l6tqk x17y0mx6 x1ey2m1c x78zum5 xl56j7k x47corl x1vjfegm"
|
|
621
|
+
},
|
|
622
|
+
3: {
|
|
623
|
+
className: "x10l6tqk x17y0mx6 x1ey2m1c xl56j7k x47corl x1s85apg x1vjfegm"
|
|
624
|
+
}
|
|
625
|
+
}[!!!isPresented << 1 | !!isTopSheet << 0],
|
|
626
|
+
hidden: !isPresented,
|
|
627
|
+
"aria-hidden": isInactive ? 'true' : undefined,
|
|
628
|
+
inert: isInactive ? true : undefined,
|
|
629
|
+
children: /*#__PURE__*/_jsx(BottomSheetPanel, {
|
|
630
|
+
...props,
|
|
631
|
+
ref: ref,
|
|
632
|
+
state: panelState,
|
|
633
|
+
height: height,
|
|
634
|
+
label: label,
|
|
635
|
+
snapPoints: snapPoints,
|
|
636
|
+
isSwipeDismissAllowed: purpose === 'info',
|
|
637
|
+
isPageScrollLocked: hasScrim,
|
|
638
|
+
xstyle: xstyle,
|
|
639
|
+
onDismiss: dismissOnSwipe,
|
|
640
|
+
onScrimOpacity: handleScrimOpacity,
|
|
641
|
+
onElementChange: handlePanelElementChange,
|
|
642
|
+
onMotionStart: handleMotionStart,
|
|
643
|
+
onMotionComplete: handleMotionComplete,
|
|
644
|
+
children: /*#__PURE__*/_jsx(BottomSheetSwitcherContext, {
|
|
645
|
+
value: null,
|
|
646
|
+
children: /*#__PURE__*/_jsx(LayerDepthProvider, {
|
|
647
|
+
children: children
|
|
648
|
+
})
|
|
649
|
+
})
|
|
440
650
|
})
|
|
441
|
-
})
|
|
651
|
+
}), isPresented && /*#__PURE__*/_jsx(BottomSheetEdgeTint, {})]
|
|
442
652
|
});
|
|
443
653
|
}
|
|
444
654
|
|
|
445
655
|
/**
|
|
446
|
-
* A mobile touch sheet that
|
|
447
|
-
* BottomSheetSwitcher
|
|
656
|
+
* A mobile touch sheet that owns a native dialog. Given a sheetId inside a
|
|
657
|
+
* BottomSheetSwitcher, that switcher coordinates the dialog's lifecycle.
|
|
448
658
|
*/
|
|
449
659
|
export function BottomSheet(props) {
|
|
450
660
|
const switcher = use(BottomSheetSwitcherContext);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file BottomSheetSwitcher.tsx
|
|
3
|
-
* @input Uses React context, StyleX,
|
|
3
|
+
* @input Uses React context, StyleX, shared layer dismissal, BottomSheetSwitcherContext
|
|
4
4
|
* @output Exports BottomSheetSwitcher and BottomSheetSwitcherProps
|
|
5
5
|
* @position Core switcher for mutually exclusive BottomSheet flows
|
|
6
6
|
*
|
|
@@ -11,14 +11,37 @@
|
|
|
11
11
|
* down at the same time until their top edges align; otherwise it stays
|
|
12
12
|
* stationary. The previous sheet fades only after both motions complete.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
* scrim flow
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* Every child sheet owns a native `<dialog>`, exactly like a standalone
|
|
15
|
+
* sheet: a scrim flow presents each sheet with showModal(), a no-scrim flow
|
|
16
|
+
* with show(). The browser then does what a modal dialog does -- the page is
|
|
17
|
+
* inert, focus stays in the top-layer dialog, Escape and the platform close
|
|
18
|
+
* arrive as `cancel`. The switcher is the coordinator: it decides which
|
|
19
|
+
* sheet dialog is presented, retained, or hidden, keeps one scrim painted
|
|
20
|
+
* across a handoff (the retained sheet's backdrop until it fades, then the
|
|
21
|
+
* new sheet's, swapped without a fade), holds the flow's one page scroll
|
|
22
|
+
* lock (the shared useScrollLock, as Dialog uses, acquired once while the
|
|
23
|
+
* flow is presented and released after its exit, never per step) and the
|
|
24
|
+
* one layer-dismissal registration, and returns focus to the flow's opener
|
|
25
|
+
* when the flow ends, which no single dialog can know.
|
|
26
|
+
*
|
|
27
|
+
* The switcher's one element is a flow wrapper. In a scrim flow it has no box
|
|
28
|
+
* (`display: contents`): the dialogs sit in the top layer. In a no-scrim flow
|
|
29
|
+
* it is the isolated surface that orders the sheet dialogs locally, the way
|
|
30
|
+
* the shared shell once did, so no sheet needs a page-level value of its own.
|
|
31
|
+
*
|
|
32
|
+
* Its `ref` resolves to the host dialog: the one presenting the active sheet,
|
|
33
|
+
* the exiting sheet's through its exit, and the last host's (or the first
|
|
34
|
+
* mounted sheet's) while the flow is closed, so the ref is never null while a
|
|
35
|
+
* sheet is mounted. `id` and `data-testid` render on the host dialog only:
|
|
36
|
+
* a flow that mounts open carries them on the active sheet's dialog in server
|
|
37
|
+
* markup too; a flow that mounts closed carries them from the first commit's
|
|
38
|
+
* synchronous re-render on, and its server markup carries them on no element.
|
|
39
|
+
* Every other dialog prop and handler, `onCancel` included, applies to every
|
|
40
|
+
* sheet dialog; the browser raises `cancel` on the dialog it presents.
|
|
18
41
|
*
|
|
19
42
|
* SYNC: When modified, update these files to stay in sync:
|
|
20
43
|
* - /packages/core/src/BottomSheet/BottomSheet.tsx
|
|
21
|
-
* - /packages/core/src/BottomSheet/
|
|
44
|
+
* - /packages/core/src/BottomSheet/BottomSheetSwitcherContext.ts
|
|
22
45
|
* - /packages/core/src/BottomSheet/BottomSheetSwitcher.doc.mjs
|
|
23
46
|
* - /packages/core/src/BottomSheet/BottomSheetSwitcher.spec.md
|
|
24
47
|
* - /packages/core/src/BottomSheet/BottomSheetSwitcher.test.tsx
|
|
@@ -29,9 +52,15 @@
|
|
|
29
52
|
import { type ReactNode, type SyntheticEvent } from 'react';
|
|
30
53
|
import type { BaseProps } from '../BaseProps';
|
|
31
54
|
export interface BottomSheetSwitcherProps extends BaseProps<HTMLDialogElement> {
|
|
32
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* Ref resolved to the native dialog hosting the flow: the active sheet's
|
|
57
|
+
* dialog, which changes on a handoff; the exiting sheet's through its exit;
|
|
58
|
+
* and, while the flow is closed, the dialog that hosted it last (or the
|
|
59
|
+
* first mounted sheet's), so it is never null while a sheet is mounted,
|
|
60
|
+
* from the first commit on.
|
|
61
|
+
*/
|
|
33
62
|
ref?: React.Ref<HTMLDialogElement>;
|
|
34
|
-
/** Called when the
|
|
63
|
+
/** Called when the active sheet's native dialog receives a cancel event. */
|
|
35
64
|
onCancel?: (event: SyntheticEvent<HTMLDialogElement>) => void;
|
|
36
65
|
/**
|
|
37
66
|
* ID of the interactive BottomSheet, or null when the flow should close.
|
|
@@ -43,7 +72,7 @@ export interface BottomSheetSwitcherProps extends BaseProps<HTMLDialogElement> {
|
|
|
43
72
|
/** Called with null when the active sheet requests dismissal. */
|
|
44
73
|
onActiveSheetChange: (sheetId: string | null) => void;
|
|
45
74
|
/**
|
|
46
|
-
* Whether
|
|
75
|
+
* Whether each sheet dialog opens modally with a native ::backdrop.
|
|
47
76
|
* Disable for a viewport-anchored, non-modal flow over an interactive page.
|
|
48
77
|
* @default true
|
|
49
78
|
*/
|
|
@@ -52,8 +81,8 @@ export interface BottomSheetSwitcherProps extends BaseProps<HTMLDialogElement> {
|
|
|
52
81
|
children: ReactNode;
|
|
53
82
|
}
|
|
54
83
|
/**
|
|
55
|
-
* Coordinates a set of BottomSheets so zero or one is active at a time
|
|
56
|
-
*
|
|
84
|
+
* Coordinates a set of BottomSheets so zero or one is active at a time, each
|
|
85
|
+
* in its own native dialog. During a handoff the previous panel stays visible
|
|
57
86
|
* and inert beneath the entering panel, then fades after motion completes.
|
|
58
87
|
*
|
|
59
88
|
* @example
|
|
@@ -66,7 +95,7 @@ export interface BottomSheetSwitcherProps extends BaseProps<HTMLDialogElement> {
|
|
|
66
95
|
* </BottomSheetSwitcher>
|
|
67
96
|
* ```
|
|
68
97
|
*/
|
|
69
|
-
export declare function BottomSheetSwitcher({ activeSheet, onActiveSheetChange, hasScrim, children, ref,
|
|
98
|
+
export declare function BottomSheetSwitcher({ activeSheet, onActiveSheetChange, hasScrim, children, ref, onCancel, onClick, onKeyDown, className, style, xstyle, ...restDialogProps }: BottomSheetSwitcherProps): import("react").JSX.Element;
|
|
70
99
|
export declare namespace BottomSheetSwitcher {
|
|
71
100
|
var displayName: string;
|
|
72
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheetSwitcher.d.ts","sourceRoot":"","sources":["../../src/BottomSheet/BottomSheetSwitcher.tsx"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"BottomSheetSwitcher.d.ts","sourceRoot":"","sources":["../../src/BottomSheet/BottomSheetSwitcher.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH,OAAO,EAQL,KAAK,SAAS,EACd,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAyI5C,MAAM,WAAW,wBAAyB,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC5E;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAEnC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IAE9D;;;;;OAKG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B,iEAAiE;IACjE,mBAAmB,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAEtD;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,0DAA0D;IAC1D,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,WAAW,EACX,mBAAmB,EACnB,QAAe,EACf,QAAQ,EACR,GAAG,EACH,QAAQ,EACR,OAAO,EACP,SAAS,EACT,SAAS,EACT,KAAK,EACL,MAAM,EACN,GAAG,eAAe,EACnB,EAAE,wBAAwB,+BAgkB1B;yBA7kBe,mBAAmB"}
|