@astryxdesign/core 0.7.3 → 0.7.4-canary.10b832e

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 (131) hide show
  1. package/dist/BottomSheet/BottomSheet.d.ts +18 -6
  2. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  3. package/dist/BottomSheet/BottomSheet.js +268 -58
  4. package/dist/BottomSheet/BottomSheetSwitcher.d.ts +41 -12
  5. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  6. package/dist/BottomSheet/BottomSheetSwitcher.js +294 -165
  7. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts +51 -1
  8. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts.map +1 -1
  9. package/dist/BottomSheet/BottomSheetSwitcherContext.js +13 -1
  10. package/dist/Carousel/Carousel.d.ts.map +1 -1
  11. package/dist/Carousel/Carousel.js +7 -11
  12. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  13. package/dist/Chat/ChatMessageList.js +8 -1
  14. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  15. package/dist/Chat/useTriggerMenu.js +46 -7
  16. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  17. package/dist/CheckboxInput/CheckboxInput.js +6 -0
  18. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  19. package/dist/ComplexSelector/ComplexSelector.js +6 -1
  20. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  21. package/dist/ContextMenu/ContextMenu.js +12 -0
  22. package/dist/DateInput/DateInput.d.ts.map +1 -1
  23. package/dist/DateInput/DateInput.js +6 -1
  24. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  25. package/dist/DateInput/NativeDateField.js +6 -1
  26. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  27. package/dist/DateInput/TouchDateField.js +9 -1
  28. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  29. package/dist/DateRangeInput/DateRangeInput.js +6 -1
  30. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  31. package/dist/DateTimeInput/DateTimeInput.js +6 -1
  32. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  33. package/dist/DateTimeInput/TouchDateTimeField.js +9 -1
  34. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  35. package/dist/DropdownMenu/DropdownMenuSubMenu.js +7 -1
  36. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  37. package/dist/MultiSelector/MultiSelector.js +6 -1
  38. package/dist/Selector/Selector.d.ts.map +1 -1
  39. package/dist/Selector/Selector.js +6 -1
  40. package/dist/TextArea/TextArea.d.ts.map +1 -1
  41. package/dist/TextArea/TextArea.js +6 -1
  42. package/dist/TextInput/TextInput.d.ts.map +1 -1
  43. package/dist/TextInput/TextInput.js +6 -1
  44. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  45. package/dist/Thumbnail/Thumbnail.js +9 -2
  46. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  47. package/dist/TimeInput/TimeInput.js +6 -1
  48. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  49. package/dist/TimeInput/TouchTimeField.js +9 -1
  50. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  51. package/dist/Tokenizer/Tokenizer.js +9 -1
  52. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  53. package/dist/Typeahead/BaseTypeahead.js +7 -1
  54. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  55. package/dist/Typeahead/Typeahead.js +9 -1
  56. package/dist/astryx.css +2 -0
  57. package/dist/hooks/useBusyAnnouncement.d.ts +22 -0
  58. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -0
  59. package/dist/hooks/useBusyAnnouncement.js +87 -0
  60. package/dist/hooks/useMenuPress.d.ts +2 -2
  61. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  62. package/dist/hooks/useMenuPress.js +5 -1
  63. package/dist/hooks/useTypeahead.d.ts.map +1 -1
  64. package/dist/hooks/useTypeahead.js +7 -2
  65. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  66. package/dist/i18n/generated-locales/en.generated.js +1 -0
  67. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  68. package/dist/i18n/generated-locales/pseudo.generated.js +1 -0
  69. package/locales/en.json +6 -2
  70. package/locales/pseudo.json +3 -0
  71. package/package.json +4 -4
  72. package/src/BottomSheet/BottomSheet.doc.mjs +2 -2
  73. package/src/BottomSheet/BottomSheet.spec.md +2 -5
  74. package/src/BottomSheet/BottomSheet.tsx +260 -47
  75. package/src/BottomSheet/BottomSheetEdgeTint.test.tsx +4 -2
  76. package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +11 -10
  77. package/src/BottomSheet/BottomSheetSwitcher.spec.md +28 -35
  78. package/src/BottomSheet/BottomSheetSwitcher.test.tsx +830 -48
  79. package/src/BottomSheet/BottomSheetSwitcher.tsx +396 -215
  80. package/src/BottomSheet/BottomSheetSwitcherContext.ts +57 -2
  81. package/src/Carousel/Carousel.test.tsx +8 -12
  82. package/src/Carousel/Carousel.tsx +6 -13
  83. package/src/Chat/ChatComposerInput.test.tsx +167 -1
  84. package/src/Chat/ChatMessageList.test.tsx +6 -2
  85. package/src/Chat/ChatMessageList.tsx +7 -1
  86. package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +20 -12
  87. package/src/Chat/useTriggerMenu.tsx +55 -6
  88. package/src/CheckboxInput/CheckboxInput.tsx +6 -0
  89. package/src/ComplexSelector/ComplexSelector.tsx +5 -1
  90. package/src/ContextMenu/ContextMenu.test.tsx +34 -0
  91. package/src/ContextMenu/ContextMenu.tsx +13 -1
  92. package/src/DateInput/DateInput.tsx +5 -1
  93. package/src/DateInput/DateInputTouch.test.tsx +45 -0
  94. package/src/DateInput/NativeDateField.test.tsx +10 -2
  95. package/src/DateInput/NativeDateField.tsx +5 -1
  96. package/src/DateInput/TouchDateField.tsx +14 -2
  97. package/src/DateRangeInput/DateRangeInput.tsx +5 -1
  98. package/src/DateTimeInput/DateTimeInput.tsx +5 -1
  99. package/src/DateTimeInput/TouchDateTimeField.tsx +14 -2
  100. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +10 -1
  101. package/src/MultiSelector/MultiSelector.test.tsx +18 -4
  102. package/src/MultiSelector/MultiSelector.tsx +5 -1
  103. package/src/ProgressBar/ProgressBar.test.tsx +4 -21
  104. package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +114 -0
  105. package/src/ProgressBar/__tests__/ProgressBar.a11y.known-failures.ts +12 -0
  106. package/src/ProgressBar/__tests__/ProgressBar.a11y.renders.tsx +38 -0
  107. package/src/ProgressBar/__tests__/ProgressBar.a11y.states.ts +123 -0
  108. package/src/ProgressBar/__tests__/ProgressBar.a11y.test.tsx +107 -0
  109. package/src/Selector/Selector.test.tsx +22 -5
  110. package/src/Selector/Selector.tsx +5 -1
  111. package/src/TextArea/TextArea.test.tsx +9 -1
  112. package/src/TextArea/TextArea.tsx +5 -1
  113. package/src/TextInput/TextInput.tsx +5 -1
  114. package/src/Thumbnail/Thumbnail.test.tsx +6 -1
  115. package/src/Thumbnail/Thumbnail.tsx +12 -3
  116. package/src/TimeInput/TimeInput.tsx +5 -1
  117. package/src/TimeInput/TouchTimeField.tsx +12 -2
  118. package/src/Tokenizer/Tokenizer.test.tsx +17 -12
  119. package/src/Tokenizer/Tokenizer.tsx +10 -1
  120. package/src/Typeahead/BaseTypeahead.tsx +14 -1
  121. package/src/Typeahead/Typeahead.test.tsx +32 -41
  122. package/src/Typeahead/Typeahead.tsx +10 -1
  123. package/src/__tests__/BusyOwnerAnnouncement.test.tsx +576 -0
  124. package/src/hooks/__tests__/MenuPressShadowRoot.a11y.chromium.spec.ts +50 -0
  125. package/src/hooks/useBusyAnnouncement.ts +100 -0
  126. package/src/hooks/useMenuPress.test.tsx +27 -1
  127. package/src/hooks/useMenuPress.ts +12 -3
  128. package/src/hooks/useTypeahead.test.tsx +42 -1
  129. package/src/hooks/useTypeahead.ts +7 -2
  130. package/src/i18n/generated-locales/en.generated.ts +1 -0
  131. 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 participates in the parent's shared dialog, transition state
10
- * machine, and dismissal registration. Both render the same BottomSheetPanel,
11
- * which owns sheet presentation, content padding, gestures, mobile-keyboard
12
- * accommodation, and motion completion.
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 either owns a native dialog or participates in a
86
- * BottomSheetSwitcher shared dialog when given a sheetId inside that context.
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;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;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;AAmBhD,YAAY,EAAC,iBAAiB,EAAE,oBAAoB,EAAC,MAAM,oBAAoB,CAAC;AAChF,OAAO,KAAK,EAAC,iBAAiB,EAAE,oBAAoB,EAAC,MAAM,oBAAoB,CAAC;AA0EhF,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;AA0YxD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,+BA6BlD;yBA7Be,WAAW"}
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 participates in the parent's shared dialog, transition state
14
- * machine, and dismissal registration. Both render the same BottomSheetPanel,
15
- * which owns sheet presentation, content padding, gestures, mobile-keyboard
16
- * accommodation, and motion completion.
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 xft5bk6 x15h3t91 x142juwg x1viac0w"
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 xft5bk6 x15h3t91 x142juwg x1viac0w"
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 xft5bk6 x142juwg x1viac0w x1cz9k3x"
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 xft5bk6 x142juwg x1viac0w x1cz9k3x"
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 xft5bk6 x15h3t91 x142juwg x1viac0w x47corl xfo81ep xh8yej3 x5yr21d"
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 xft5bk6 x15h3t91 x142juwg x1viac0w x47corl xfo81ep xh8yej3 x5yr21d"
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 xft5bk6 x142juwg x1viac0w x1cz9k3x x47corl xfo81ep xh8yej3 x5yr21d"
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 xft5bk6 x142juwg x1viac0w x1cz9k3x x47corl xfo81ep xh8yej3 x5yr21d"
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
- registerSheetLabel,
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
- return /*#__PURE__*/_jsx("div", {
405
- ...{
406
- 0: {
407
- className: "x10l6tqk x17y0mx6 x1ey2m1c x78zum5 xl56j7k x47corl"
408
- },
409
- 2: {
410
- className: "x10l6tqk x17y0mx6 x1ey2m1c xl56j7k x47corl x1s85apg"
411
- },
412
- 1: {
413
- className: "x10l6tqk x17y0mx6 x1ey2m1c x78zum5 xl56j7k x47corl x1vjfegm"
414
- },
415
- 3: {
416
- className: "x10l6tqk x17y0mx6 x1ey2m1c xl56j7k x47corl x1s85apg x1vjfegm"
417
- }
418
- }[!!!isPresented << 1 | !!isTopSheet << 0],
419
- hidden: !isPresented,
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
- children: /*#__PURE__*/_jsx(BottomSheetPanel, {
423
- ...props,
424
- ref: ref,
425
- state: panelState,
426
- height: height,
427
- label: label,
428
- snapPoints: snapPoints,
429
- isSwipeDismissAllowed: purpose === 'info',
430
- isPageScrollLocked: hasScrim,
431
- xstyle: xstyle,
432
- onDismiss: dismissOnSwipe,
433
- onScrimOpacity: handleScrimOpacity,
434
- onElementChange: handlePanelElementChange,
435
- onMotionStart: handleMotionStart,
436
- onMotionComplete: handleMotionComplete,
437
- children: /*#__PURE__*/_jsx(BottomSheetSwitcherContext, {
438
- value: null,
439
- children: children
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 either owns a native dialog or participates in a
447
- * BottomSheetSwitcher shared dialog when given a sheetId inside that context.
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, theme tokens, shared layer dismissal, focus/scroll-lock hooks, BottomSheetSwitcherContext
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
- * All child sheets render as panels inside one switcher-owned `<dialog>`. A
15
- * scrim flow calls showModal() once and keeps that native top-layer dialog open
16
- * across every handoff. A no-scrim flow calls show() on the same non-modal shell.
17
- * This keeps one modal boundary and one native ::backdrop without a portal.
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/BottomSheetEdgeTint.tsx
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
- /** Ref forwarded to the shared native dialog. */
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 shared native dialog receives a cancel event. */
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 to open the shared dialog modally with its native ::backdrop.
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 inside
56
- * one shared native dialog. During a handoff the previous panel stays visible
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, xstyle, className, style, onCancel, onClick, onKeyDown, ...props }: BottomSheetSwitcherProps): import("react").JSX.Element;
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;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAQL,KAAK,SAAS,EACd,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAwI5C,MAAM,WAAW,wBAAyB,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC5E,iDAAiD;IACjD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAEnC,oEAAoE;IACpE,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,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,OAAO,EACP,SAAS,EACT,GAAG,KAAK,EACT,EAAE,wBAAwB,+BAya1B;yBAtbe,mBAAmB"}
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"}