@astryxdesign/lab 0.4.1-canary.f4868b2 → 0.4.2-canary.356d2f9

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 (48) hide show
  1. package/dist/BottomSheet/BottomSheet.d.ts +35 -104
  2. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  3. package/dist/BottomSheet/BottomSheet.js +258 -264
  4. package/dist/BottomSheet/BottomSheetPanel.d.ts +56 -0
  5. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -0
  6. package/dist/BottomSheet/BottomSheetPanel.js +342 -0
  7. package/dist/BottomSheet/BottomSheetSwitcher.d.ts +60 -0
  8. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -0
  9. package/dist/BottomSheet/BottomSheetSwitcher.js +373 -0
  10. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts +19 -0
  11. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts.map +1 -0
  12. package/dist/BottomSheet/BottomSheetSwitcherContext.js +13 -0
  13. package/dist/BottomSheet/index.d.ts +5 -3
  14. package/dist/BottomSheet/index.d.ts.map +1 -1
  15. package/dist/BottomSheet/index.js +6 -4
  16. package/dist/BottomSheet/snapOffsets.d.ts +5 -5
  17. package/dist/BottomSheet/snapOffsets.d.ts.map +1 -1
  18. package/dist/BottomSheet/useMobileKeyboard.d.ts +25 -0
  19. package/dist/BottomSheet/useMobileKeyboard.d.ts.map +1 -0
  20. package/dist/BottomSheet/useMobileKeyboard.js +384 -0
  21. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  22. package/dist/BottomSheet/useSheetGestures.js +10 -6
  23. package/dist/ListInput/ListInput.d.ts.map +1 -1
  24. package/dist/ListInput/ListInput.js +76 -29
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/lab.css +5 -1
  29. package/package.json +6 -5
  30. package/src/BottomSheet/BottomSheet.doc.mjs +80 -36
  31. package/src/BottomSheet/BottomSheet.test.tsx +882 -18
  32. package/src/BottomSheet/BottomSheet.tsx +342 -384
  33. package/src/BottomSheet/BottomSheetPanel.test.tsx +240 -0
  34. package/src/BottomSheet/BottomSheetPanel.tsx +478 -0
  35. package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +107 -0
  36. package/src/BottomSheet/BottomSheetSwitcher.test.tsx +738 -0
  37. package/src/BottomSheet/BottomSheetSwitcher.tsx +593 -0
  38. package/src/BottomSheet/BottomSheetSwitcherContext.ts +46 -0
  39. package/src/BottomSheet/index.ts +7 -3
  40. package/src/BottomSheet/snapOffsets.ts +5 -5
  41. package/src/BottomSheet/useMobileKeyboard.ts +566 -0
  42. package/src/BottomSheet/useSheetGestures.test.ts +6 -4
  43. package/src/BottomSheet/useSheetGestures.ts +10 -6
  44. package/src/ListInput/ListInput.test.tsx +48 -22
  45. package/src/ListInput/ListInput.tsx +76 -34
  46. package/src/TransferList/TransferList.doc.mjs +2 -2
  47. package/src/index.ts +7 -1
  48. package/src/BottomSheet/useSheetGestures.doc.mjs +0 -32
@@ -1,125 +1,56 @@
1
1
  /**
2
2
  * @file BottomSheet.tsx
3
- * @input Uses React, StyleX, theme tokens, core hooks (useScrollLock), utils, useSheetGestures
3
+ * @input Uses React, StyleX, core hooks/utils, BottomSheetPanel, BottomSheetSwitcherContext
4
4
  * @output Exports BottomSheet component and BottomSheetProps
5
- * @position Lab implementation; consumed by index.ts, tested by BottomSheet.test.tsx, demonstrated in Storybook
5
+ * @position Public BottomSheet router plus private standalone/switcher hosts
6
6
  *
7
- * A mobile touch surface that rises from the bottom edge: grab handle, snap
8
- * points, and swipe-to-dismiss. It owns a native `<dialog>` directly and
9
- * composes core primitives (`useScrollLock`, `<dialog>.showModal()` for the
10
- * top layer + focus trap, a `::backdrop` scrim) rather than delegating to a
11
- * heavier overlay component — so it controls its own sizing and can render a
12
- * full-height transparent shell with the visible sheet bottom-anchored inside.
13
- * That shell is what lets the sheet translate freely (including a little past
14
- * fully-open) without clipping against a fixed dialog edge.
15
- *
16
- * `hasScrim` picks the presentation: `true` (default) uses `showModal()` (top
17
- * layer, focus trap, scrim, scroll lock, background inert); `false` uses
18
- * `show()` for a non-modal sheet with no scrim, leaving the page behind
19
- * interactive and scrollable (the transparent shell is pointer-events:none so
20
- * taps pass through). Both modes keep the native dialog presented but inert
21
- * until the slide-out transition ends.
22
- *
23
- * The drag/snap/dismiss machinery lives in `useSheetGestures`; the offset
24
- * geometry lives in the pure, tested `snapOffsets` module. Both are internal
25
- * to BottomSheet and not exported from the lab entry point.
7
+ * BottomSheet selects one of two focused hosts. A standalone host owns its
8
+ * native dialog lifecycle; a switcher item participates in the parent's shared
9
+ * dialog and transition state machine. Both render the same BottomSheetPanel,
10
+ * which owns sheet presentation, gestures, mobile-keyboard accommodation, and
11
+ * motion completion.
26
12
  *
27
13
  * SYNC: When modified, update these files to stay in sync:
28
- * - /packages/lab/src/BottomSheet/BottomSheet.doc.mjs (props table, features, usage)
29
- * - /packages/lab/src/BottomSheet/BottomSheet.test.tsx (tests for new/changed behavior)
30
- * - /packages/lab/src/BottomSheet/index.ts (exports if types change)
31
- * - /apps/storybook/stories/BottomSheet.stories.tsx (examples and visual coverage)
14
+ * - /packages/lab/src/BottomSheet/BottomSheetPanel.tsx
15
+ * - /packages/lab/src/BottomSheet/BottomSheet.doc.mjs
16
+ * - /packages/lab/src/BottomSheet/BottomSheet.test.tsx
17
+ * - /packages/lab/src/BottomSheet/BottomSheetSwitcher.tsx
18
+ * - /packages/lab/src/BottomSheet/BottomSheetSwitcher.test.tsx
19
+ * - /apps/storybook/stories/BottomSheet.stories.tsx
32
20
  */
33
21
  import { type ReactNode } from 'react';
34
22
  import type { BaseProps } from '@astryxdesign/core';
35
- /**
36
- * Height budget for each named size, as a fraction of the viewport:
37
- * - `hug` — fits its content, never taller than 92%.
38
- * - `capped` — a scrolling mid-height panel (62%).
39
- * - `tall` — a pinned near-full panel (92%); use when content streams in so
40
- * the sheet doesn't resize under the user.
41
- */
42
- declare const HEIGHT_BUDGETS: {
43
- readonly hug: "92dvh";
44
- readonly capped: "62dvh";
45
- readonly tall: "92dvh";
46
- };
47
- export type BottomSheetHeight = keyof typeof HEIGHT_BUDGETS;
48
- export interface BottomSheetProps extends BaseProps<HTMLDialogElement> {
49
- /** Ref forwarded to the underlying <dialog> element. */
50
- ref?: React.Ref<HTMLDialogElement>;
51
- /** Whether the sheet is open. Fully controlled — pair with `onOpenChange`. */
52
- isOpen: boolean;
53
- /**
54
- * Called when the sheet opens or closes. The boolean is the requested next
55
- * state (`false` on Escape, scrim click, or a swipe past the dismiss
56
- * threshold). The caller owns the open state.
57
- */
58
- onOpenChange: (isOpen: boolean) => void;
59
- /**
60
- * Accessible label for the sheet (required — the sheet has no built-in
61
- * heading to derive a name from).
62
- */
23
+ export type { BottomSheetHeight } from './BottomSheetPanel';
24
+ import type { BottomSheetHeight } from './BottomSheetPanel';
25
+ interface BottomSheetSharedProps extends BaseProps<HTMLDivElement> {
26
+ /** Ref forwarded to the visual sheet panel <div>. */
27
+ ref?: React.Ref<HTMLDivElement>;
28
+ /** Accessible label for the sheet. */
63
29
  label: string;
64
30
  /** Sheet content, rendered below the grab handle in a scrollable area. */
65
31
  children: ReactNode;
66
- /**
67
- * How tall the sheet is. A named budget, or any explicit height:
68
- * - `'hug'` — fits its content, never taller than 92% of the viewport.
69
- * - `'capped'` — a scrolling mid-height panel (~62%).
70
- * - `'tall'` — a pinned near-full panel (~92%); use when content streams in
71
- * so the sheet doesn't resize under the user.
72
- * - a `number` (px) or CSS length string (e.g. `'70dvh'`, `480`) for a
73
- * custom budget.
74
- *
75
- * The user can still drag between snap points regardless of the starting
76
- * height. On viewports shorter than the budget the sheet fills the
77
- * available height.
78
- * @default 'capped'
79
- */
32
+ /** Height budget or custom CSS length. Only fully expanded Tall is keyboard-aware. @default 'capped' */
80
33
  height?: BottomSheetHeight | number | string;
81
- /**
82
- * Whether to render a modal scrim behind the sheet.
83
- * - `true` (default) — `showModal()`: renders in the top layer with a focus
84
- * trap, a `::backdrop` scrim, body scroll lock, and tap-scrim-to-dismiss.
85
- * The background is inert. Use for focused tasks (filters, forms).
86
- * - `false`: `show()` renders a viewport-anchored overlay with **no scrim**. It is
87
- * still layered above the page, not rendered inline, but the page behind
88
- * stays interactive and scrollable (like Material's *standard* bottom
89
- * sheet or an iOS undimmed detent). Escape still closes while focus is
90
- * inside the sheet, and drag/flick-to-dismiss still work. Use for a peek
91
- * surface that coexists with the page (e.g. a panel over a live map).
92
- * @default true
93
- */
34
+ }
35
+ interface StandaloneBottomSheetProps extends BottomSheetSharedProps {
36
+ isOpen: boolean;
37
+ onOpenChange: (isOpen: boolean) => void;
94
38
  hasScrim?: boolean;
95
- /** Test ID for the root element. */
96
- 'data-testid'?: string;
39
+ sheetId?: never;
97
40
  }
41
+ interface SwitcherBottomSheetProps extends BottomSheetSharedProps {
42
+ sheetId: string;
43
+ isOpen?: never;
44
+ onOpenChange?: never;
45
+ hasScrim?: never;
46
+ }
47
+ export type BottomSheetProps = StandaloneBottomSheetProps | SwitcherBottomSheetProps;
98
48
  /**
99
- * A mobile touch sheet that rises from the bottom edge, with a grab handle,
100
- * drag-to-resize snap points, and swipe-to-dismiss. It owns a native
101
- * `<dialog>` and, by default (`hasScrim`), enters the top layer with a focus
102
- * trap + `::backdrop` scrim and locks body scroll; a slow drag settles to the
103
- * nearest snap point, a flick down dismisses, and Escape closes — so the swipe
104
- * always has a keyboard equivalent.
105
- *
106
- * With `hasScrim={false}` it opens non-modally (`show()`, no scrim), leaving
107
- * the page behind interactive and scrollable.
108
- *
109
- * @example
110
- * ```
111
- * const [isOpen, setIsOpen] = useState(false);
112
- * <BottomSheet
113
- * isOpen={isOpen}
114
- * onOpenChange={setIsOpen}
115
- * label="Filters">
116
- * <FilterControls />
117
- * </BottomSheet>
118
- * ```
49
+ * A mobile touch sheet that either owns a native dialog or participates in a
50
+ * BottomSheetSwitcher shared dialog when given a sheetId inside that context.
119
51
  */
120
- export declare function BottomSheet({ ref, isOpen, onOpenChange, label, children, height, hasScrim, xstyle, ...props }: BottomSheetProps): import("react").JSX.Element;
52
+ export declare function BottomSheet(props: BottomSheetProps): import("react").JSX.Element;
121
53
  export declare namespace BottomSheet {
122
54
  var displayName: string;
123
55
  }
124
- export {};
125
56
  //# sourceMappingURL=BottomSheet.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BottomSheet.d.ts","sourceRoot":"","sources":["../../src/BottomSheet/BottomSheet.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAA2C,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAE/E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AA2BlD;;;;;;GAMG;AACH,QAAA,MAAM,cAAc;;;;CAIV,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,cAAc,CAAC;AAoL5D,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IACpE,wDAAwD;IACxD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAEnC,8EAA8E;IAC9E,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;OAIG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAExC;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd,0EAA0E;IAC1E,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,EAAE,iBAAiB,GAAG,MAAM,GAAG,MAAM,CAAC;IAE7C;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,GAAG,EACH,MAAM,EACN,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,MAAiB,EACjB,QAAe,EACf,MAAM,EACN,GAAG,KAAK,EACT,EAAE,gBAAgB,+BAoMlB;yBA9Me,WAAW"}
1
+ {"version":3,"file":"BottomSheet.d.ts","sourceRoot":"","sources":["../../src/BottomSheet/BottomSheet.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAkBlD,YAAY,EAAC,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;AA2D1D,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,wGAAwG;IACxG,MAAM,CAAC,EAAE,iBAAiB,GAAG,MAAM,GAAG,MAAM,CAAC;CAC9C;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,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;AAwUxD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,+BA6BlD;yBA7Be,WAAW"}