@astryxdesign/lab 0.4.4-canary.eb069fd → 0.4.5-canary.013e728
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/Chat/ChatEmojiPicker.js +1 -1
- package/dist/Chat/ChatReactionBar.js +3 -3
- package/dist/Drawer/Drawer.d.ts +46 -44
- package/dist/Drawer/Drawer.d.ts.map +1 -1
- package/dist/Drawer/Drawer.js +86 -170
- package/dist/InfoTip/InfoTip.d.ts +2 -2
- package/dist/InfoTip/InfoTip.d.ts.map +1 -1
- package/dist/InfoTip/InfoTip.js +10 -4
- package/dist/ListInput/ListInput.d.ts.map +1 -1
- package/dist/ListInput/ListInput.js +3 -1
- package/dist/LogStream/LogStream.d.ts.map +1 -1
- package/dist/LogStream/LogStream.js +4 -4
- package/dist/Stepper/Step.js +2 -2
- package/dist/TransferList/TransferList.d.ts.map +1 -1
- package/dist/TransferList/TransferList.js +32 -15
- package/dist/lab.css +19 -27
- package/package.json +3 -3
- package/src/Chat/ChatEmojiPicker.tsx +1 -1
- package/src/Chat/ChatReactionBar.tsx +3 -3
- package/src/Drawer/Drawer.doc.mjs +171 -59
- package/src/Drawer/Drawer.test.tsx +162 -196
- package/src/Drawer/Drawer.tsx +140 -273
- package/src/InfoTip/InfoTip.doc.mjs +6 -3
- package/src/InfoTip/InfoTip.test.tsx +64 -0
- package/src/InfoTip/InfoTip.tsx +8 -3
- package/src/ListInput/ListInput.test.tsx +217 -0
- package/src/ListInput/ListInput.tsx +10 -4
- package/src/LogStream/LogStream.tsx +12 -4
- package/src/Stepper/Step.tsx +2 -2
- package/src/TransferList/TransferList.doc.mjs +23 -0
- package/src/TransferList/TransferList.test.tsx +19 -15
- package/src/TransferList/TransferList.tsx +27 -20
|
@@ -99,10 +99,10 @@ export function ChatReactionBar({
|
|
|
99
99
|
onClick: () => onToggle?.(reaction.emoji),
|
|
100
100
|
...{
|
|
101
101
|
0: {
|
|
102
|
-
className: "x3nfvp2 x6s0dn4 xzye2dw xxk0z11 xf314gf xjspbzw xmkeg23 x1y0btm7 x9r1u3d
|
|
102
|
+
className: "x3nfvp2 x6s0dn4 xzye2dw xxk0z11 xf314gf xjspbzw xmkeg23 x1y0btm7 x9r1u3d xs8to0k x1xwh4np xwmxj5m x1ypdohk x9ynric x9f619 xq90yva xuedmi6 x12w9bfk xlr8y92"
|
|
103
103
|
},
|
|
104
104
|
1: {
|
|
105
|
-
className: "x3nfvp2 x6s0dn4 xzye2dw xxk0z11 xf314gf xjspbzw xmkeg23 x1y0btm7 x1ypdohk x9ynric x9f619 xq90yva xuedmi6 x12w9bfk xlr8y92 xgcxg3y xad5do
|
|
105
|
+
className: "x3nfvp2 x6s0dn4 xzye2dw xxk0z11 xf314gf xjspbzw xmkeg23 x1y0btm7 x1ypdohk x9ynric x9f619 xq90yva xuedmi6 x12w9bfk xlr8y92 xgcxg3y xad5do xz7zccy xmhmdd9"
|
|
106
106
|
}
|
|
107
107
|
}[!!isSelected << 0],
|
|
108
108
|
children: [/*#__PURE__*/_jsx("span", {
|
|
@@ -137,7 +137,7 @@ export function ChatReactionBar({
|
|
|
137
137
|
type: "button",
|
|
138
138
|
"aria-label": addLabel,
|
|
139
139
|
...{
|
|
140
|
-
className: "x3nfvp2 x6s0dn4 xl56j7k x1td3qas xxk0z11 xjspbzw xmkeg23 x1y0btm7 x9r1u3d
|
|
140
|
+
className: "x3nfvp2 x6s0dn4 xl56j7k x1td3qas xxk0z11 xjspbzw xmkeg23 x1y0btm7 x9r1u3d xs8to0k x1xwh4np xwmxj5m xv9yike x1ypdohk x9f619 x1jvydc1 x1ltkj2j x1717udv"
|
|
141
141
|
},
|
|
142
142
|
children: "+"
|
|
143
143
|
})
|
package/dist/Drawer/Drawer.d.ts
CHANGED
|
@@ -4,10 +4,17 @@
|
|
|
4
4
|
* @output Exports Drawer component and DrawerProps
|
|
5
5
|
* @position Lab implementation; consumed by index.ts, tested by Drawer.test.tsx, demonstrated in Storybook
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* the
|
|
10
|
-
* (
|
|
7
|
+
* Overlay panel for inspectors and detail views — the "click a table row,
|
|
8
|
+
* see its details" pattern. Slides in from the inline start or end edge and
|
|
9
|
+
* floats above the page content: unlike a docked panel it never reflows the
|
|
10
|
+
* layout underneath, it overlays it (with or without a scrim).
|
|
11
|
+
*
|
|
12
|
+
* Inline axis only (start/end). Block-axis sheets are BottomSheet's job;
|
|
13
|
+
* a drawer is always a full-height side panel.
|
|
14
|
+
*
|
|
15
|
+
* Sizing is viewport-aware: `width` is the desktop budget, and below
|
|
16
|
+
* the mobile breakpoint it preserves a 56px reveal of the page behind, capped
|
|
17
|
+
* by the requested width (or fills the viewport with `isFullWidthOnMobile`).
|
|
11
18
|
*
|
|
12
19
|
* Uses the native `<dialog>` element (same precedent as Dialog/MobileNav):
|
|
13
20
|
* - `showModal()` when `hasScrim` (default) — top-layer rendering, focus
|
|
@@ -36,36 +43,42 @@ export interface DrawerProps extends BaseProps<HTMLDialogElement> {
|
|
|
36
43
|
/** Ref forwarded to the root <dialog> element */
|
|
37
44
|
ref?: React.Ref<HTMLDialogElement>;
|
|
38
45
|
/**
|
|
39
|
-
* Whether the drawer is open. Fully controlled — pair with `
|
|
46
|
+
* Whether the drawer is open. Fully controlled — pair with `onOpenChange`.
|
|
40
47
|
*/
|
|
41
48
|
isOpen: boolean;
|
|
42
49
|
/**
|
|
43
|
-
* Called when the drawer requests
|
|
44
|
-
*
|
|
45
|
-
* open state. When sibling drawers are open, Escape only closes the
|
|
46
|
-
*
|
|
50
|
+
* Called when the drawer requests an open-state change. Escape, scrim
|
|
51
|
+
* click, and the built-in close button call it with `false`. The caller owns
|
|
52
|
+
* the open state. When sibling drawers are open, Escape only closes the top
|
|
53
|
+
* (last-opened) drawer.
|
|
47
54
|
*/
|
|
48
|
-
|
|
55
|
+
onOpenChange: (isOpen: boolean) => void;
|
|
49
56
|
/**
|
|
50
57
|
* Which edge the drawer slides from.
|
|
51
58
|
* - `'end'` — inline-end edge (right in LTR) — the inspector convention
|
|
52
59
|
* - `'start'` — inline-start edge (left in LTR)
|
|
53
|
-
* - `'top'` / `'bottom'` — full-width sheets on the block axis
|
|
54
60
|
* @default 'end'
|
|
55
61
|
*/
|
|
56
|
-
side?: 'start' | 'end'
|
|
62
|
+
side?: 'start' | 'end';
|
|
57
63
|
/**
|
|
58
|
-
*
|
|
59
|
-
* `
|
|
60
|
-
*
|
|
61
|
-
*
|
|
64
|
+
* Desktop width budget. A number is pixels; a string is any CSS length
|
|
65
|
+
* (`'50%'`, `'32rem'`). Below the mobile breakpoint (640px), this
|
|
66
|
+
* remains the maximum while the drawer preserves a 56px reveal of the page
|
|
67
|
+
* behind — see `isFullWidthOnMobile`.
|
|
62
68
|
* @default 400
|
|
63
69
|
*/
|
|
64
|
-
|
|
70
|
+
width?: number | string;
|
|
71
|
+
/**
|
|
72
|
+
* Whether the drawer covers the full viewport width on mobile
|
|
73
|
+
* (below 640px) instead of preserving the default 56px reveal of the page
|
|
74
|
+
* behind. The reveal makes the drawer read as an overlay rather than a
|
|
75
|
+
* navigation.
|
|
76
|
+
* @default false
|
|
77
|
+
*/
|
|
78
|
+
isFullWidthOnMobile?: boolean;
|
|
65
79
|
/**
|
|
66
80
|
* Accessible label for the drawer (required — the drawer has no
|
|
67
|
-
* built-in heading to derive a name from).
|
|
68
|
-
* collapse/expand affordances.
|
|
81
|
+
* built-in heading to derive a name from).
|
|
69
82
|
*/
|
|
70
83
|
label: string;
|
|
71
84
|
/**
|
|
@@ -79,24 +92,11 @@ export interface DrawerProps extends BaseProps<HTMLDialogElement> {
|
|
|
79
92
|
hasScrim?: boolean;
|
|
80
93
|
/**
|
|
81
94
|
* Whether to render the built-in close button in the top-trailing
|
|
82
|
-
* corner.
|
|
83
|
-
*
|
|
84
|
-
* @default
|
|
95
|
+
* corner. Enabled by default for both modal and non-modal drawers so every
|
|
96
|
+
* overlay has an obvious dismissal affordance.
|
|
97
|
+
* @default true
|
|
85
98
|
*/
|
|
86
99
|
hasCloseButton?: boolean;
|
|
87
|
-
/**
|
|
88
|
-
* Collapse the drawer to a narrow click-to-expand rail. Only supported
|
|
89
|
-
* for non-modal (`hasScrim={false}`) drawers with `side="start"/"end"`;
|
|
90
|
-
* ignored (with a dev warning) otherwise. Controlled — pair with
|
|
91
|
-
* `onCollapsedChange`.
|
|
92
|
-
*/
|
|
93
|
-
isCollapsed?: boolean;
|
|
94
|
-
/**
|
|
95
|
-
* Called when the built-in collapse/expand affordances are used.
|
|
96
|
-
* Providing it renders a collapse toggle next to the close button while
|
|
97
|
-
* expanded; the collapsed rail always expands on click.
|
|
98
|
-
*/
|
|
99
|
-
onCollapsedChange?: (collapsed: boolean) => void;
|
|
100
100
|
/**
|
|
101
101
|
* Drawer content. Rendered inside a full-height scrollable area.
|
|
102
102
|
* Focus the element with `data-autofocus` on open, if present.
|
|
@@ -108,27 +108,29 @@ export interface DrawerProps extends BaseProps<HTMLDialogElement> {
|
|
|
108
108
|
'data-testid'?: string;
|
|
109
109
|
}
|
|
110
110
|
/**
|
|
111
|
-
* An
|
|
111
|
+
* An overlay panel for inspectors and detail views.
|
|
112
112
|
*
|
|
113
|
-
* Slides in from the logical start
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* `
|
|
113
|
+
* Slides in from the logical start or end edge and floats above the page
|
|
114
|
+
* using the native `<dialog>` element: modal with a scrim by default, or a
|
|
115
|
+
* non-modal overlay with `hasScrim={false}` that leaves the page behind
|
|
116
|
+
* interactive. `width` is the desktop budget; below 640px the panel preserves
|
|
117
|
+
* a 56px page reveal without exceeding that budget (or fills the viewport
|
|
118
|
+
* with `isFullWidthOnMobile`). Escape
|
|
119
|
+
* closes the top-most open drawer; focus returns to the element that
|
|
120
|
+
* opened it.
|
|
119
121
|
*
|
|
120
122
|
* @example
|
|
121
123
|
* ```
|
|
122
124
|
* const [selected, setSelected] = useState(null);
|
|
123
125
|
* <Drawer
|
|
124
126
|
* isOpen={selected != null}
|
|
125
|
-
*
|
|
127
|
+
* onOpenChange={isOpen => !isOpen && setSelected(null)}
|
|
126
128
|
* label={`Details: ${selected?.name}`}>
|
|
127
129
|
* <HostDetails host={selected} />
|
|
128
130
|
* </Drawer>
|
|
129
131
|
* ```
|
|
130
132
|
*/
|
|
131
|
-
export declare function Drawer({ isOpen,
|
|
133
|
+
export declare function Drawer({ isOpen, onOpenChange, side, width, isFullWidthOnMobile, label, hasScrim, hasCloseButton, children, xstyle, className, style, onClick: onClickProp, onKeyDown: onKeyDownProp, ref, ...props }: DrawerProps): import("react").JSX.Element;
|
|
132
134
|
export declare namespace Drawer {
|
|
133
135
|
var displayName: string;
|
|
134
136
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../src/Drawer/Drawer.tsx"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../src/Drawer/Drawer.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAsOlD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC/D,iDAAiD;IACjD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAEnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;OAKG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAExC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAEvB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,YAAY,EACZ,IAAY,EACZ,KAAW,EACX,mBAA2B,EAC3B,KAAK,EACL,QAAe,EACf,cAAqB,EACrB,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,+BAmMb;yBApNe,MAAM"}
|
package/dist/Drawer/Drawer.js
CHANGED
|
@@ -8,10 +8,17 @@
|
|
|
8
8
|
* @output Exports Drawer component and DrawerProps
|
|
9
9
|
* @position Lab implementation; consumed by index.ts, tested by Drawer.test.tsx, demonstrated in Storybook
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* the
|
|
14
|
-
* (
|
|
11
|
+
* Overlay panel for inspectors and detail views — the "click a table row,
|
|
12
|
+
* see its details" pattern. Slides in from the inline start or end edge and
|
|
13
|
+
* floats above the page content: unlike a docked panel it never reflows the
|
|
14
|
+
* layout underneath, it overlays it (with or without a scrim).
|
|
15
|
+
*
|
|
16
|
+
* Inline axis only (start/end). Block-axis sheets are BottomSheet's job;
|
|
17
|
+
* a drawer is always a full-height side panel.
|
|
18
|
+
*
|
|
19
|
+
* Sizing is viewport-aware: `width` is the desktop budget, and below
|
|
20
|
+
* the mobile breakpoint it preserves a 56px reveal of the page behind, capped
|
|
21
|
+
* by the requested width (or fills the viewport with `isFullWidthOnMobile`).
|
|
15
22
|
*
|
|
16
23
|
* Uses the native `<dialog>` element (same precedent as Dialog/MobileNav):
|
|
17
24
|
* - `showModal()` when `hasScrim` (default) — top-layer rendering, focus
|
|
@@ -37,11 +44,12 @@
|
|
|
37
44
|
import { useCallback, useEffect, useId, useRef, useState } from 'react';
|
|
38
45
|
import * as stylex from '@stylexjs/stylex';
|
|
39
46
|
import '@astryxdesign/core/theme/tokens.stylex';
|
|
40
|
-
import { borderVars, colorVars, durationVars, easeVars, shadowVars, spacingVars
|
|
47
|
+
import { borderVars, colorVars, durationVars, easeVars, shadowVars, spacingVars } from '@astryxdesign/core/theme/tokens.stylex';
|
|
41
48
|
import { Icon } from '@astryxdesign/core/Icon';
|
|
42
49
|
import { IconButton } from '@astryxdesign/core/IconButton';
|
|
43
|
-
import { useScrollLock
|
|
44
|
-
import { mergeProps, mergeRefs, themeProps } from '@astryxdesign/core/utils';
|
|
50
|
+
import { useScrollLock } from '@astryxdesign/core/hooks';
|
|
51
|
+
import { composeEventHandlers, mergeProps, mergeRefs, themeProps } from '@astryxdesign/core/utils';
|
|
52
|
+
import { overlayPaddingReset } from '@astryxdesign/core/Layout';
|
|
45
53
|
|
|
46
54
|
// =============================================================================
|
|
47
55
|
// LIFO stacking registry (internal)
|
|
@@ -85,14 +93,22 @@ function isTopDrawer(id) {
|
|
|
85
93
|
// Styles
|
|
86
94
|
// =============================================================================
|
|
87
95
|
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
|
|
96
|
+
// Below this viewport width the drawer preserves a fixed reveal of the page
|
|
97
|
+
// behind instead of growing proportionally with the viewport. 640px is the
|
|
98
|
+
// repo's mobile breakpoint.
|
|
99
|
+
const MOBILE_BREAKPOINT = 640;
|
|
100
|
+
|
|
101
|
+
// Material's established mobile drawer pattern leaves a 56dp reveal. Using
|
|
102
|
+
// the same value in CSS pixels gives the overlay a stable visual relationship
|
|
103
|
+
// to the page behind while the requested width remains an upper bound.
|
|
104
|
+
const MOBILE_PAGE_REVEAL = 56;
|
|
105
|
+
const MOBILE_WIDTH_FULL = '100dvw';
|
|
91
106
|
const styles = {
|
|
92
107
|
dialog: {
|
|
93
108
|
kVAEAm: "xixxii4",
|
|
94
109
|
kogj98: "x1ghz6dp",
|
|
95
110
|
kmVPX3: "x1717udv",
|
|
111
|
+
kaIpWk: "x2u8bby",
|
|
96
112
|
ks0D6T: "x1x1rfll",
|
|
97
113
|
kskxy: "x7ab17h",
|
|
98
114
|
kB7OPa: "x9f619",
|
|
@@ -102,8 +118,11 @@ const styles = {
|
|
|
102
118
|
kVQacm: "xb3r6kr",
|
|
103
119
|
kZeWKH: "xish69e",
|
|
104
120
|
kI3sdo: "x1a2a7pz",
|
|
121
|
+
k87sOh: "x13vifvy",
|
|
122
|
+
krVfgx: "x1ey2m1c",
|
|
123
|
+
kZKoxP: "xtdtrs8",
|
|
105
124
|
k1xSpc: "x1s85apg",
|
|
106
|
-
k1ekBW: "
|
|
125
|
+
k1ekBW: "xayqnl7",
|
|
107
126
|
kIyJzY: "x80gvsz",
|
|
108
127
|
kAMwcw: "xlr8y92",
|
|
109
128
|
kzIqYQ: "xd00j3c",
|
|
@@ -115,11 +134,8 @@ const styles = {
|
|
|
115
134
|
$$css: true
|
|
116
135
|
},
|
|
117
136
|
end: {
|
|
118
|
-
k87sOh: "x13vifvy",
|
|
119
|
-
krVfgx: "x1ey2m1c",
|
|
120
137
|
kt4wiu: "xtijo5x",
|
|
121
138
|
kLqNvP: "xhi6v0a",
|
|
122
|
-
kZKoxP: "xtdtrs8",
|
|
123
139
|
k2ei4v: "xgbv0en",
|
|
124
140
|
kVhnKS: "x1t7ytsu",
|
|
125
141
|
kGJrpR: "x1j92z86",
|
|
@@ -131,11 +147,8 @@ const styles = {
|
|
|
131
147
|
$$css: true
|
|
132
148
|
},
|
|
133
149
|
start: {
|
|
134
|
-
k87sOh: "x13vifvy",
|
|
135
|
-
krVfgx: "x1ey2m1c",
|
|
136
150
|
kLqNvP: "x1o0tod",
|
|
137
151
|
kt4wiu: "x1woyocn",
|
|
138
|
-
kZKoxP: "xtdtrs8",
|
|
139
152
|
ke9TFa: "xw8tdv1",
|
|
140
153
|
k8ry5P: "x18b5jzi",
|
|
141
154
|
kBCPoo: "x1gejf6u",
|
|
@@ -146,38 +159,6 @@ const styles = {
|
|
|
146
159
|
k3aq6I: "xbryuvx x6mt36l x14gflnl",
|
|
147
160
|
$$css: true
|
|
148
161
|
},
|
|
149
|
-
top: {
|
|
150
|
-
kzqmXN: "x1o6l61p",
|
|
151
|
-
kLqNvP: "x1o0tod",
|
|
152
|
-
kt4wiu: "xtijo5x",
|
|
153
|
-
k87sOh: "x13vifvy",
|
|
154
|
-
krVfgx: "xdd4er5",
|
|
155
|
-
kt9PQ7: "x92x3c3",
|
|
156
|
-
kfdmCh: "x1q0q8m5",
|
|
157
|
-
kL6WhQ: "xw8gpjh",
|
|
158
|
-
k3aq6I: "x105ttfm",
|
|
159
|
-
$$css: true
|
|
160
|
-
},
|
|
161
|
-
topOpen: {
|
|
162
|
-
k3aq6I: "xnn1q72 xub2912",
|
|
163
|
-
$$css: true
|
|
164
|
-
},
|
|
165
|
-
bottom: {
|
|
166
|
-
kzqmXN: "x1o6l61p",
|
|
167
|
-
kLqNvP: "x1o0tod",
|
|
168
|
-
kt4wiu: "xtijo5x",
|
|
169
|
-
krVfgx: "x1ey2m1c",
|
|
170
|
-
k87sOh: "x80663w",
|
|
171
|
-
kEafiO: "x11xkdxz",
|
|
172
|
-
kPef9Z: "x13fuv20",
|
|
173
|
-
kLZC3w: "x1pc3f07",
|
|
174
|
-
k3aq6I: "x1weeur4",
|
|
175
|
-
$$css: true
|
|
176
|
-
},
|
|
177
|
-
bottomOpen: {
|
|
178
|
-
k3aq6I: "xnn1q72 xhbqy3z",
|
|
179
|
-
$$css: true
|
|
180
|
-
},
|
|
181
162
|
scrim: {
|
|
182
163
|
kGyWv1: "xnixb3f",
|
|
183
164
|
kba3nw: "x1abwkk1",
|
|
@@ -191,32 +172,19 @@ const styles = {
|
|
|
191
172
|
scrimOpen: {
|
|
192
173
|
k5sjJv: "xb3n6bw xxiuuzi",
|
|
193
174
|
$$css: true
|
|
194
|
-
},
|
|
195
|
-
collapsedRail: {
|
|
196
|
-
ks0D6T: "x1k2d6hx",
|
|
197
|
-
$$css: true
|
|
198
175
|
}
|
|
199
176
|
};
|
|
200
177
|
const _temp = {
|
|
201
|
-
|
|
202
|
-
"$$css": true
|
|
203
|
-
};
|
|
204
|
-
const _temp2 = {
|
|
205
|
-
kZKoxP: "xtdtrs8",
|
|
178
|
+
ks0D6T: "xlbgzzq",
|
|
206
179
|
"$$css": true
|
|
207
180
|
};
|
|
208
181
|
const dynamicStyles = {
|
|
209
|
-
inlineSize:
|
|
210
|
-
|
|
182
|
+
inlineSize: (desktopWidth, mobileWidth) => [_temp, {
|
|
183
|
+
kzqmXN: (desktopWidth != null ? "x11ymkkh " : desktopWidth) + (mobileWidth != null ? "xci7e5a" : mobileWidth),
|
|
211
184
|
$$css: true
|
|
212
185
|
}, {
|
|
213
|
-
"--x-
|
|
214
|
-
|
|
215
|
-
blockSize: s => [_temp2, {
|
|
216
|
-
kskxy: s != null ? "x1jols5v" : s,
|
|
217
|
-
$$css: true
|
|
218
|
-
}, {
|
|
219
|
-
"--x-maxHeight": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(s)
|
|
186
|
+
"--x-1xmrurk": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(desktopWidth),
|
|
187
|
+
"--x-fqzwsx": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(mobileWidth)
|
|
220
188
|
}],
|
|
221
189
|
stackZ: z => [{
|
|
222
190
|
kY2c9j: z != null ? "xr3buco" : z,
|
|
@@ -235,21 +203,23 @@ const dynamicStyles = {
|
|
|
235
203
|
// =============================================================================
|
|
236
204
|
|
|
237
205
|
/**
|
|
238
|
-
* An
|
|
206
|
+
* An overlay panel for inspectors and detail views.
|
|
239
207
|
*
|
|
240
|
-
* Slides in from the logical start
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
* `
|
|
208
|
+
* Slides in from the logical start or end edge and floats above the page
|
|
209
|
+
* using the native `<dialog>` element: modal with a scrim by default, or a
|
|
210
|
+
* non-modal overlay with `hasScrim={false}` that leaves the page behind
|
|
211
|
+
* interactive. `width` is the desktop budget; below 640px the panel preserves
|
|
212
|
+
* a 56px page reveal without exceeding that budget (or fills the viewport
|
|
213
|
+
* with `isFullWidthOnMobile`). Escape
|
|
214
|
+
* closes the top-most open drawer; focus returns to the element that
|
|
215
|
+
* opened it.
|
|
246
216
|
*
|
|
247
217
|
* @example
|
|
248
218
|
* ```
|
|
249
219
|
* const [selected, setSelected] = useState(null);
|
|
250
220
|
* <Drawer
|
|
251
221
|
* isOpen={selected != null}
|
|
252
|
-
*
|
|
222
|
+
* onOpenChange={isOpen => !isOpen && setSelected(null)}
|
|
253
223
|
* label={`Details: ${selected?.name}`}>
|
|
254
224
|
* <HostDetails host={selected} />
|
|
255
225
|
* </Drawer>
|
|
@@ -257,18 +227,19 @@ const dynamicStyles = {
|
|
|
257
227
|
*/
|
|
258
228
|
export function Drawer({
|
|
259
229
|
isOpen,
|
|
260
|
-
|
|
230
|
+
onOpenChange,
|
|
261
231
|
side = 'end',
|
|
262
|
-
|
|
232
|
+
width = 400,
|
|
233
|
+
isFullWidthOnMobile = false,
|
|
263
234
|
label,
|
|
264
235
|
hasScrim = true,
|
|
265
|
-
hasCloseButton,
|
|
266
|
-
isCollapsed,
|
|
267
|
-
onCollapsedChange,
|
|
236
|
+
hasCloseButton = true,
|
|
268
237
|
children,
|
|
269
238
|
xstyle,
|
|
270
239
|
className,
|
|
271
240
|
style,
|
|
241
|
+
onClick: onClickProp,
|
|
242
|
+
onKeyDown: onKeyDownProp,
|
|
272
243
|
ref,
|
|
273
244
|
...props
|
|
274
245
|
}) {
|
|
@@ -276,23 +247,15 @@ export function Drawer({
|
|
|
276
247
|
const closeTimeoutRef = useRef(null);
|
|
277
248
|
// Element focused when the drawer opened — restored on close.
|
|
278
249
|
const triggerElementRef = useRef(null);
|
|
279
|
-
// Registry identity + latest
|
|
280
|
-
// registration effect doesn't churn on every
|
|
250
|
+
// Registry identity + latest onOpenChange (stable across re-renders so the
|
|
251
|
+
// registration effect doesn't churn on every onOpenChange identity change).
|
|
281
252
|
const drawerId = useId();
|
|
282
|
-
const
|
|
253
|
+
const onOpenChangeRef = useRef(onOpenChange);
|
|
283
254
|
useEffect(() => {
|
|
284
|
-
|
|
285
|
-
}, [
|
|
255
|
+
onOpenChangeRef.current = onOpenChange;
|
|
256
|
+
}, [onOpenChange]);
|
|
286
257
|
// z-index assigned by the registry on open (non-modal stacking only).
|
|
287
258
|
const [stackZ, setStackZ] = useState(NON_MODAL_BASE_Z);
|
|
288
|
-
const isSheet = side === 'top' || side === 'bottom';
|
|
289
|
-
// Collapse only makes sense for a persistent (non-modal) side panel.
|
|
290
|
-
const canCollapse = !hasScrim && !isSheet;
|
|
291
|
-
const collapsed = canCollapse && isCollapsed === true;
|
|
292
|
-
const showCloseButton = hasCloseButton ?? hasScrim;
|
|
293
|
-
|
|
294
|
-
// Dev warning for unsupported collapse combinations.
|
|
295
|
-
useDevWarning('Drawer', '`isCollapsed` is only supported for non-modal drawers ' + '(hasScrim={false}) with side="start" or side="end". The prop is ' + 'ignored.', isCollapsed != null && !canCollapse);
|
|
296
259
|
|
|
297
260
|
// Open/close the native dialog. close() is delayed so the slide-out
|
|
298
261
|
// transition can play; focus restore happens after close() because a
|
|
@@ -364,7 +327,7 @@ export function Drawer({
|
|
|
364
327
|
if (!isOpen) {
|
|
365
328
|
return;
|
|
366
329
|
}
|
|
367
|
-
const z = registerDrawer(drawerId, () =>
|
|
330
|
+
const z = registerDrawer(drawerId, () => onOpenChangeRef.current(false));
|
|
368
331
|
setStackZ(z);
|
|
369
332
|
return () => unregisterDrawer(drawerId);
|
|
370
333
|
}, [isOpen, drawerId]);
|
|
@@ -373,57 +336,40 @@ export function Drawer({
|
|
|
373
336
|
useScrollLock(isOpen && hasScrim);
|
|
374
337
|
|
|
375
338
|
// Escape closes. The native `cancel` event only fires for showModal();
|
|
376
|
-
// this keydown handler covers the non-modal show() path too. Only the
|
|
339
|
+
// this React keydown handler covers the non-modal show() path too. Only the
|
|
377
340
|
// top of the drawer stack closes, so stacked siblings peel off
|
|
378
341
|
// innermost-first.
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
const handleKeyDown = event => {
|
|
385
|
-
if (event.key === 'Escape') {
|
|
386
|
-
event.preventDefault();
|
|
387
|
-
if (isTopDrawer(drawerId)) {
|
|
388
|
-
onClose();
|
|
389
|
-
}
|
|
342
|
+
const handleKeyDown = useCallback(event => {
|
|
343
|
+
if (event.key === 'Escape') {
|
|
344
|
+
event.preventDefault();
|
|
345
|
+
if (isTopDrawer(drawerId)) {
|
|
346
|
+
onOpenChange(false);
|
|
390
347
|
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
return () => dialog.removeEventListener('keydown', handleKeyDown);
|
|
394
|
-
}, [isOpen, onClose, drawerId]);
|
|
348
|
+
}
|
|
349
|
+
}, [onOpenChange, drawerId]);
|
|
395
350
|
|
|
396
351
|
// Native cancel event (browser Escape handling) — prevent the browser
|
|
397
|
-
// from closing the dialog directly and route through
|
|
352
|
+
// from closing the dialog directly and route through onOpenChange so the
|
|
398
353
|
// caller's state stays the source of truth. Same top-of-stack rule as
|
|
399
354
|
// the keydown path.
|
|
400
355
|
const handleCancel = useCallback(event => {
|
|
401
356
|
event.preventDefault();
|
|
402
357
|
if (isTopDrawer(drawerId)) {
|
|
403
|
-
|
|
358
|
+
onOpenChange(false);
|
|
404
359
|
}
|
|
405
|
-
}, [
|
|
360
|
+
}, [onOpenChange, drawerId]);
|
|
406
361
|
|
|
407
362
|
// Clicks on the ::backdrop target the <dialog> element itself; clicks on
|
|
408
363
|
// drawer content always target a child (the content area fills the panel).
|
|
409
364
|
const handleClick = useCallback(event => {
|
|
410
365
|
if (event.target === event.currentTarget && hasScrim) {
|
|
411
|
-
|
|
366
|
+
onOpenChange(false);
|
|
412
367
|
}
|
|
413
|
-
}, [hasScrim,
|
|
414
|
-
const
|
|
415
|
-
const
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
top: styles.top,
|
|
419
|
-
bottom: styles.bottom
|
|
420
|
-
}[side];
|
|
421
|
-
const sideOpenStyle = {
|
|
422
|
-
start: styles.startOpen,
|
|
423
|
-
end: styles.endOpen,
|
|
424
|
-
top: styles.topOpen,
|
|
425
|
-
bottom: styles.bottomOpen
|
|
426
|
-
}[side];
|
|
368
|
+
}, [hasScrim, onOpenChange]);
|
|
369
|
+
const widthValue = typeof width === 'number' ? `${width}px` : width;
|
|
370
|
+
const mobileWidth = isFullWidthOnMobile ? MOBILE_WIDTH_FULL : `min(${widthValue}, calc(100dvw - ${MOBILE_PAGE_REVEAL}px))`;
|
|
371
|
+
const sideStyle = side === 'start' ? styles.start : styles.end;
|
|
372
|
+
const sideOpenStyle = side === 'start' ? styles.startOpen : styles.endOpen;
|
|
427
373
|
|
|
428
374
|
// Filter out native `open` to prevent InvalidStateError when passed
|
|
429
375
|
const {
|
|
@@ -432,56 +378,26 @@ export function Drawer({
|
|
|
432
378
|
} = props;
|
|
433
379
|
return /*#__PURE__*/_jsxs("dialog", {
|
|
434
380
|
ref: mergeRefs(ref, dialogRef),
|
|
435
|
-
"aria-label": label,
|
|
436
|
-
"aria-modal": hasScrim ? 'true' : undefined,
|
|
437
|
-
onClick: handleClick,
|
|
438
|
-
onCancel: handleCancel,
|
|
439
381
|
...mergeProps(themeProps('drawer', {
|
|
440
382
|
side
|
|
441
|
-
}), stylex.props(styles.dialog, sideStyle,
|
|
383
|
+
}), stylex.props(styles.dialog, overlayPaddingReset.reset, sideStyle, dynamicStyles.inlineSize(widthValue, mobileWidth), isOpen && styles.open, isOpen && sideOpenStyle, hasScrim ? styles.scrim : dynamicStyles.stackZ(stackZ), hasScrim && isOpen && styles.scrimOpen, xstyle), className, style),
|
|
442
384
|
...safeProps,
|
|
385
|
+
"aria-label": label,
|
|
386
|
+
"aria-modal": hasScrim ? 'true' : undefined,
|
|
387
|
+
onClick: composeEventHandlers(onClickProp, handleClick),
|
|
388
|
+
onKeyDown: composeEventHandlers(onKeyDownProp, handleKeyDown),
|
|
389
|
+
onCancel: handleCancel,
|
|
443
390
|
children: [/*#__PURE__*/_jsx("div", {
|
|
444
391
|
tabIndex: -1,
|
|
445
392
|
...{
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
},
|
|
449
|
-
1: {
|
|
450
|
-
className: "x1iyjqo2 x2lwn1j xh8yej3 x1odjw0f x6ikm8r xish69e xx69xxh x1a2a7pz x1s85apg"
|
|
451
|
-
}
|
|
452
|
-
}[!!collapsed << 0],
|
|
393
|
+
className: "x1iyjqo2 x2lwn1j xh8yej3 x1odjw0f x6ikm8r xish69e xx69xxh x1a148e8 x1a2a7pz"
|
|
394
|
+
},
|
|
453
395
|
children: children
|
|
454
|
-
}),
|
|
455
|
-
/*#__PURE__*/
|
|
456
|
-
// Collapsed rail: one full-size expand button with the label
|
|
457
|
-
// reading vertically.
|
|
458
|
-
_jsx("button", {
|
|
459
|
-
type: "button",
|
|
460
|
-
"aria-label": `Expand ${label}`,
|
|
461
|
-
onClick: () => onCollapsedChange?.(false),
|
|
462
|
-
...{
|
|
463
|
-
0: {
|
|
464
|
-
className: "xjyslct xng3xce x1ghz6dp x8o8v82 x7a5moj x1iyjqo2 xh8yej3 x2lwn1j x78zum5 x6s0dn4 xl56j7k x1ypdohk xjbqb8w xtao9ic xv1l7n4 xjb2p0i xcr08ib xmhvcl5 x1kq96og xuxw1ft xb3r6kr xlyipyv x98t3bc x1a2a7pz"
|
|
465
|
-
},
|
|
466
|
-
1: {
|
|
467
|
-
className: "xjyslct xng3xce x1ghz6dp x8o8v82 x7a5moj x1iyjqo2 xh8yej3 x2lwn1j x78zum5 x6s0dn4 xl56j7k x1ypdohk xjbqb8w xtao9ic xv1l7n4 xjb2p0i xcr08ib xmhvcl5 x1kq96og xuxw1ft xb3r6kr xlyipyv x98t3bc x1a2a7pz x19jd1h0"
|
|
468
|
-
}
|
|
469
|
-
}[!!(side === 'start') << 0],
|
|
470
|
-
children: label
|
|
471
|
-
}) : (showCloseButton || canCollapse && onCollapsedChange != null) && /*#__PURE__*/_jsxs("div", {
|
|
396
|
+
}), hasCloseButton && /*#__PURE__*/_jsx("div", {
|
|
472
397
|
...{
|
|
473
398
|
className: "x10l6tqk xctzyg x72tfeb x78zum5 xzye2dw x1vjfegm"
|
|
474
399
|
},
|
|
475
|
-
children:
|
|
476
|
-
icon: /*#__PURE__*/_jsx(Icon, {
|
|
477
|
-
icon: side === 'start' ? 'chevronLeft' : 'chevronRight',
|
|
478
|
-
size: "sm",
|
|
479
|
-
color: "inherit"
|
|
480
|
-
}),
|
|
481
|
-
label: `Collapse ${label}`,
|
|
482
|
-
variant: "ghost",
|
|
483
|
-
onClick: () => onCollapsedChange(true)
|
|
484
|
-
}), showCloseButton && /*#__PURE__*/_jsx(IconButton, {
|
|
400
|
+
children: /*#__PURE__*/_jsx(IconButton, {
|
|
485
401
|
icon: /*#__PURE__*/_jsx(Icon, {
|
|
486
402
|
icon: "close",
|
|
487
403
|
size: "sm",
|
|
@@ -489,8 +405,8 @@ export function Drawer({
|
|
|
489
405
|
}),
|
|
490
406
|
label: "Close",
|
|
491
407
|
variant: "ghost",
|
|
492
|
-
onClick:
|
|
493
|
-
})
|
|
408
|
+
onClick: () => onOpenChange(false)
|
|
409
|
+
})
|
|
494
410
|
})]
|
|
495
411
|
});
|
|
496
412
|
}
|
|
@@ -35,8 +35,8 @@ export interface InfoTipProps {
|
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* An inline info-icon help affordance: a small "i" button that reveals a
|
|
38
|
-
* tooltip on hover
|
|
39
|
-
* metrics for permission notes, metric definitions, and field help.
|
|
38
|
+
* tooltip on hover, keyboard focus, and tap. Use it next to labels, values,
|
|
39
|
+
* and metrics for permission notes, metric definitions, and field help.
|
|
40
40
|
*
|
|
41
41
|
* The value over hand-composing Icon inside Tooltip is the pre-wired
|
|
42
42
|
* accessible trigger: a real button with an aria-label, Tab-reachable,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InfoTip.d.ts","sourceRoot":"","sources":["../../src/InfoTip/InfoTip.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,EAAgC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAGpE,OAAO,EAAO,KAAK,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAW5D;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;AAEnC,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,OAAO,EAAE,SAAS,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AA2BD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,KAA0B,EAC1B,IAAW,GACZ,EAAE,YAAY,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"InfoTip.d.ts","sourceRoot":"","sources":["../../src/InfoTip/InfoTip.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,EAAgC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAGpE,OAAO,EAAO,KAAK,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAW5D;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;AAEnC,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,OAAO,EAAE,SAAS,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AA2BD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,KAA0B,EAC1B,IAAW,GACZ,EAAE,YAAY,GAAG,SAAS,CAiD1B;yBArDe,OAAO"}
|