@passui/react 0.1.45 → 0.1.46
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/README.md +57 -46
- package/dist/types/src/components/accordion/accordion.d.ts +1 -1
- package/dist/types/src/components/breadcrumb/breadcrumb.d.ts +1 -1
- package/dist/types/src/components/inline-disclosure/inline-disclosure.d.ts +1 -1
- package/dist/types/src/components/popover/anchored-surface.d.ts +5 -1
- package/dist/types/src/components/popover/index.d.ts +41 -0
- package/dist/types/src/components/popover/popover-content.d.ts +32 -0
- package/dist/types/src/components/popover/popover-root.d.ts +22 -0
- package/dist/types/src/components/popover/popover-trigger.d.ts +23 -0
- package/dist/types/src/components/stepper/rolling-digit.d.ts +1 -1
- package/dist/types/src/components/table/table.d.ts +1 -1
- package/dist/types/src/components/view-controller/view-controller.d.ts +2 -2
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/machines/popover.machine.d.ts +30 -0
- package/package.json +307 -307
- package/src/appearance/index.ts +2 -2
- package/src/appearance/platform.tsx +76 -60
- package/src/appearance/theme.tsx +409 -377
- package/src/components/accordion/accordion.tsx +58 -49
- package/src/components/ambient/ambient.tsx +25 -25
- package/src/components/ambient/index.ts +1 -1
- package/src/components/aspect-ratio/aspect-ratio.tsx +21 -16
- package/src/components/breadcrumb/breadcrumb.tsx +63 -57
- package/src/components/button/button-styles.ts +39 -32
- package/src/components/button/button.tsx +91 -84
- package/src/components/button/icon-button.tsx +27 -25
- package/src/components/button/pending-spinner.tsx +8 -8
- package/src/components/button/use-pending-indicator.ts +11 -11
- package/src/components/chip/chip.tsx +35 -30
- package/src/components/code-block/code-block.tsx +40 -39
- package/src/components/combo-box/combo-box.tsx +5 -5
- package/src/components/command/command.tsx +124 -94
- package/src/components/compact-date-picker/calendar-month.ts +75 -53
- package/src/components/compact-date-picker/compact-date-picker.tsx +308 -289
- package/src/components/compact-time-picker/compact-time-picker.tsx +288 -281
- package/src/components/compact-time-picker/time-value.ts +32 -29
- package/src/components/content-unavailable-view/content-unavailable-view.tsx +64 -48
- package/src/components/content-view/content-view.tsx +168 -159
- package/src/components/content-view/index.ts +1 -1
- package/src/components/context-menu/conceal-menu-source.ts +25 -25
- package/src/components/context-menu/context-menu-host.tsx +439 -402
- package/src/components/context-menu/context-menu-store.ts +125 -123
- package/src/components/context-menu/menu-navigation.ts +25 -18
- package/src/components/context-menu/menu-position.ts +33 -29
- package/src/components/context-menu/menu-reveal.ts +32 -32
- package/src/components/context-menu/use-context-menu.ts +63 -56
- package/src/components/conversation/conversation.tsx +265 -263
- package/src/components/conversation/index.ts +1 -1
- package/src/components/date-picker/date-picker.tsx +95 -94
- package/src/components/date-picker/date-value.ts +20 -10
- package/src/components/dialog/dialog-host.tsx +105 -103
- package/src/components/dialog/dialog-store.ts +37 -36
- package/src/components/dialog/dialog.tsx +192 -179
- package/src/components/dialog/index.ts +1 -1
- package/src/components/disclosure-group/disclosure-group.tsx +93 -86
- package/src/components/divider/divider.tsx +24 -22
- package/src/components/inline-disclosure/inline-disclosure.tsx +40 -36
- package/src/components/keyboard-shortcut/keyboard-shortcut.tsx +23 -19
- package/src/components/labeled-content/labeled-content.tsx +68 -68
- package/src/components/locale-switcher/index.ts +1 -1
- package/src/components/locale-switcher/locale-switcher.tsx +279 -251
- package/src/components/menu/menu.tsx +75 -58
- package/src/components/morph/index.ts +2 -2
- package/src/components/morph/morph.tsx +227 -201
- package/src/components/morph/use-morph-disclosure.ts +19 -19
- package/src/components/one-time-code/one-time-code.tsx +216 -200
- package/src/components/picker/picker-trigger.ts +16 -13
- package/src/components/picker/picker.tsx +371 -345
- package/src/components/popover/anchored-surface.tsx +253 -229
- package/src/components/popover/index.ts +50 -0
- package/src/components/popover/popover-content.tsx +334 -0
- package/src/components/popover/popover-fit.ts +58 -53
- package/src/components/popover/popover-root.tsx +97 -0
- package/src/components/popover/popover-trigger.tsx +71 -0
- package/src/components/profile-image/profile-image.tsx +80 -64
- package/src/components/progress-view/progress-view.tsx +61 -59
- package/src/components/progress-view/use-liquid-progress.ts +38 -38
- package/src/components/radio-group/radio-group.tsx +71 -68
- package/src/components/search-field/expanding-search-field.tsx +191 -177
- package/src/components/search-field/search-field.tsx +59 -50
- package/src/components/search-list/search-list.tsx +246 -236
- package/src/components/section/section.tsx +58 -58
- package/src/components/secure-field/secure-field.tsx +3 -3
- package/src/components/segmented-control/segmented-control.tsx +136 -136
- package/src/components/sheet/modal-environment.ts +71 -64
- package/src/components/sheet/sheet-portal.tsx +58 -53
- package/src/components/sheet/sheet.tsx +146 -141
- package/src/components/sheet/use-sheet-focus.ts +97 -82
- package/src/components/sidebar/sidebar.tsx +78 -78
- package/src/components/skeleton/skeleton.tsx +30 -21
- package/src/components/slider/slider.tsx +113 -104
- package/src/components/slosh-slider/liquid-step.ts +32 -31
- package/src/components/slosh-slider/slosh-slider.tsx +265 -228
- package/src/components/stat-tile/index.ts +1 -1
- package/src/components/stat-tile/stat-tile.tsx +79 -68
- package/src/components/status-indicator/status-indicator.tsx +40 -37
- package/src/components/stepper/rolling-digit.tsx +82 -68
- package/src/components/stepper/stepper.tsx +122 -113
- package/src/components/swatch-picker/swatch-picker.tsx +120 -120
- package/src/components/tab-bar/tab-bar.tsx +149 -148
- package/src/components/tab-view/tab-view.tsx +140 -137
- package/src/components/table/table.tsx +117 -98
- package/src/components/text-editor/text-editor.tsx +34 -29
- package/src/components/text-field/text-field.tsx +182 -180
- package/src/components/toast/toast-store.ts +127 -115
- package/src/components/toast/toaster.tsx +361 -347
- package/src/components/toggle/toggle.tsx +297 -282
- package/src/components/tooltip/tooltip-host.tsx +157 -150
- package/src/components/view-controller/index.ts +1 -1
- package/src/components/view-controller/view-controller.tsx +64 -53
- package/src/components/wake-slider/wake-slider.tsx +220 -205
- package/src/hooks/scroll/minimize-decision.ts +11 -7
- package/src/hooks/use-anchored-disclosure.ts +19 -19
- package/src/hooks/use-anchored-placement.ts +29 -25
- package/src/hooks/use-dismiss.ts +33 -29
- package/src/hooks/use-floating-dismiss.ts +24 -22
- package/src/hooks/use-media-query.ts +67 -60
- package/src/hooks/use-minimize-on-scroll.ts +69 -60
- package/src/hooks/use-visual-viewport.ts +63 -63
- package/src/hooks/viewport/types.ts +16 -16
- package/src/hooks/viewport/viewport-metrics.ts +16 -10
- package/src/icons/icons.tsx +440 -328
- package/src/index.ts +91 -91
- package/src/lib/anchored-placement.ts +70 -65
- package/src/lib/class-names.ts +14 -13
- package/src/lib/clipboard.ts +8 -7
- package/src/lib/date.ts +61 -60
- package/src/lib/floating-layers.ts +39 -24
- package/src/lib/haptics.ts +10 -10
- package/src/lib/language.ts +9 -9
- package/src/lib/range-value.ts +27 -21
- package/src/lib/screen-edges.ts +33 -30
- package/src/lib/shapes.ts +38 -34
- package/src/machines/popover.machine.ts +51 -0
- package/src/motion/transitions.ts +46 -43
- package/src/styles/code-block.css +69 -43
- package/src/styles/motion-controls.css +393 -191
- package/src/tokens.ts +1 -1
- package/dist/types/src/components/popover/popover.d.ts +0 -21
- package/src/components/popover/popover.tsx +0 -334
|
@@ -1,198 +1,211 @@
|
|
|
1
|
-
import { Sheet } from "../sheet/sheet"
|
|
2
|
-
import { AnimatePresence, motion, useReducedMotion } from "motion/react"
|
|
3
|
-
import { Button } from "../button/button"
|
|
4
|
-
import { cn } from "../../lib/class-names"
|
|
5
|
-
import { contentCrossfade, spring
|
|
6
|
-
import {
|
|
1
|
+
import { Sheet } from "../sheet/sheet";
|
|
2
|
+
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
|
|
3
|
+
import { Button } from "../button/button";
|
|
4
|
+
import { cn } from "../../lib/class-names";
|
|
5
|
+
import { contentCrossfade, spring } from "../../motion/transitions";
|
|
6
|
+
import {
|
|
7
|
+
createContext,
|
|
8
|
+
useContext,
|
|
9
|
+
useId,
|
|
10
|
+
type FormEvent,
|
|
11
|
+
type ReactNode,
|
|
12
|
+
} from "react";
|
|
7
13
|
|
|
8
|
-
const CloseContext = createContext<() => void>(() => {})
|
|
9
|
-
export type DialogPresentation = "drawer" | "center" | "inline"
|
|
10
|
-
export type DialogTone = "default" | "destructive"
|
|
11
|
-
export type DialogSize = "sm" | "md" | "lg"
|
|
14
|
+
const CloseContext = createContext<() => void>(() => {});
|
|
15
|
+
export type DialogPresentation = "drawer" | "center" | "inline";
|
|
16
|
+
export type DialogTone = "default" | "destructive";
|
|
17
|
+
export type DialogSize = "sm" | "md" | "lg";
|
|
12
18
|
|
|
13
19
|
const titleText: Record<DialogSize, string> = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
20
|
+
sm: "text-subheadline",
|
|
21
|
+
md: "text-title3",
|
|
22
|
+
lg: "text-title2",
|
|
23
|
+
};
|
|
18
24
|
const descriptionText: Record<DialogSize, string> = {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
25
|
+
sm: "text-caption",
|
|
26
|
+
md: "text-footnote",
|
|
27
|
+
lg: "text-subheadline",
|
|
28
|
+
};
|
|
23
29
|
const bodySpacing: Record<DialogSize, string> = {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
30
|
+
sm: "gap-3 p-4",
|
|
31
|
+
md: "gap-4 p-5",
|
|
32
|
+
lg: "gap-5 p-6",
|
|
33
|
+
};
|
|
28
34
|
const footerSpacing: Record<DialogSize, string> = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
35
|
+
sm: "pt-2",
|
|
36
|
+
md: "pt-3",
|
|
37
|
+
lg: "pt-4",
|
|
38
|
+
};
|
|
33
39
|
|
|
34
40
|
export type DialogProps = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
41
|
+
open: boolean;
|
|
42
|
+
onOpenChange: (open: boolean) => void;
|
|
43
|
+
title: ReactNode;
|
|
44
|
+
description?: ReactNode;
|
|
45
|
+
children?: ReactNode;
|
|
46
|
+
footer?: ReactNode;
|
|
47
|
+
/** `drawer` (responsive sheet), `center` (floating panel), or `inline`. @default "drawer" */
|
|
48
|
+
presentation?: DialogPresentation;
|
|
49
|
+
/** Title, description, body and footer density. @default "md" */
|
|
50
|
+
size?: DialogSize;
|
|
51
|
+
className?: string;
|
|
52
|
+
onSubmit?: (event: FormEvent<HTMLFormElement>) => void;
|
|
53
|
+
};
|
|
48
54
|
type ActionsProps = {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
55
|
+
submitLabel: ReactNode;
|
|
56
|
+
cancelLabel: ReactNode;
|
|
57
|
+
pending?: boolean;
|
|
58
|
+
disabled?: boolean;
|
|
59
|
+
tone?: DialogTone;
|
|
60
|
+
onConfirm?: () => void;
|
|
61
|
+
};
|
|
56
62
|
|
|
57
63
|
export function Dialog({
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
open,
|
|
65
|
+
onOpenChange,
|
|
66
|
+
title,
|
|
67
|
+
description,
|
|
68
|
+
children,
|
|
69
|
+
footer,
|
|
70
|
+
presentation = "drawer",
|
|
71
|
+
size = "md",
|
|
72
|
+
className,
|
|
73
|
+
onSubmit,
|
|
68
74
|
}: DialogProps) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
75
|
+
const titleId = useId();
|
|
76
|
+
const reducedMotion = useReducedMotion();
|
|
77
|
+
const close = () => onOpenChange(false);
|
|
78
|
+
const content = (
|
|
79
|
+
<>
|
|
80
|
+
{presentation !== "inline" && (
|
|
81
|
+
<h2 id={titleId} className={cn(titleText[size], "font-semibold")}>
|
|
82
|
+
{title}
|
|
83
|
+
</h2>
|
|
84
|
+
)}
|
|
85
|
+
{description && (
|
|
86
|
+
<div className={cn(descriptionText[size], "text-label-secondary")}>
|
|
87
|
+
{description}
|
|
88
|
+
</div>
|
|
89
|
+
)}
|
|
90
|
+
{children && <div className="flex flex-col gap-4">{children}</div>}
|
|
91
|
+
{footer && (
|
|
92
|
+
<div
|
|
93
|
+
className={cn(
|
|
94
|
+
"flex flex-wrap justify-end gap-2",
|
|
95
|
+
footerSpacing[size],
|
|
96
|
+
)}
|
|
97
|
+
>
|
|
98
|
+
{footer}
|
|
99
|
+
</div>
|
|
100
|
+
)}
|
|
101
|
+
</>
|
|
102
|
+
);
|
|
103
|
+
const body = (
|
|
104
|
+
<CloseContext value={close}>
|
|
105
|
+
{onSubmit ? (
|
|
106
|
+
<form
|
|
107
|
+
onSubmit={onSubmit}
|
|
108
|
+
className={cn(
|
|
109
|
+
"flex min-h-0 flex-col overflow-y-auto",
|
|
110
|
+
bodySpacing[size],
|
|
111
|
+
className,
|
|
112
|
+
)}
|
|
113
|
+
>
|
|
114
|
+
{content}
|
|
115
|
+
</form>
|
|
116
|
+
) : (
|
|
117
|
+
<div
|
|
118
|
+
className={cn(
|
|
119
|
+
"flex min-h-0 flex-col overflow-y-auto",
|
|
120
|
+
bodySpacing[size],
|
|
121
|
+
className,
|
|
122
|
+
)}
|
|
123
|
+
>
|
|
124
|
+
{content}
|
|
125
|
+
</div>
|
|
126
|
+
)}
|
|
127
|
+
</CloseContext>
|
|
128
|
+
);
|
|
129
|
+
if (presentation === "inline")
|
|
130
|
+
return (
|
|
131
|
+
<AnimatePresence initial={false}>
|
|
132
|
+
{open && (
|
|
133
|
+
<motion.div
|
|
134
|
+
key={titleId}
|
|
135
|
+
initial={{
|
|
136
|
+
height: reducedMotion ? "auto" : 0,
|
|
137
|
+
opacity: 0,
|
|
138
|
+
scale: reducedMotion ? 1 : 0.97,
|
|
139
|
+
}}
|
|
140
|
+
animate={{
|
|
141
|
+
height: "auto",
|
|
142
|
+
opacity: 1,
|
|
143
|
+
scale: 1,
|
|
144
|
+
}}
|
|
145
|
+
exit={{
|
|
146
|
+
height: reducedMotion ? "auto" : 0,
|
|
147
|
+
opacity: 0,
|
|
148
|
+
scale: reducedMotion ? 1 : 0.98,
|
|
149
|
+
}}
|
|
150
|
+
transition={reducedMotion ? { duration: 0 } : spring.bouncy}
|
|
151
|
+
className="overflow-hidden"
|
|
152
|
+
style={{ transformOrigin: "top center" }}
|
|
153
|
+
>
|
|
154
|
+
<motion.div
|
|
155
|
+
initial={reducedMotion ? false : contentCrossfade.initial}
|
|
156
|
+
animate={reducedMotion ? undefined : contentCrossfade.animate}
|
|
157
|
+
transition={
|
|
158
|
+
reducedMotion ? { duration: 0 } : contentCrossfade.transition
|
|
159
|
+
}
|
|
160
|
+
>
|
|
161
|
+
{body}
|
|
162
|
+
</motion.div>
|
|
163
|
+
</motion.div>
|
|
164
|
+
)}
|
|
165
|
+
</AnimatePresence>
|
|
166
|
+
);
|
|
167
|
+
return (
|
|
168
|
+
<Sheet
|
|
169
|
+
open={open}
|
|
170
|
+
onClose={close}
|
|
171
|
+
label=""
|
|
172
|
+
labelledBy={titleId}
|
|
173
|
+
placement={presentation === "center" ? "center" : "adaptive"}
|
|
174
|
+
>
|
|
175
|
+
{body}
|
|
176
|
+
</Sheet>
|
|
177
|
+
);
|
|
167
178
|
}
|
|
168
179
|
|
|
169
180
|
/** The standard footer: a primary action and a cancel that closes the dialog. */
|
|
170
181
|
function Actions({
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
182
|
+
submitLabel,
|
|
183
|
+
cancelLabel,
|
|
184
|
+
pending = false,
|
|
185
|
+
disabled = false,
|
|
186
|
+
tone = "default",
|
|
187
|
+
onConfirm,
|
|
177
188
|
}: ActionsProps) {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
189
|
+
const close = useContext(CloseContext);
|
|
190
|
+
return (
|
|
191
|
+
<>
|
|
192
|
+
<Button
|
|
193
|
+
type={onConfirm ? "button" : "submit"}
|
|
194
|
+
variant={tone === "destructive" ? "ghost" : "default"}
|
|
195
|
+
className={
|
|
196
|
+
tone === "destructive" ? "bg-danger/10 text-danger" : undefined
|
|
197
|
+
}
|
|
198
|
+
isPending={pending}
|
|
199
|
+
disabled={disabled}
|
|
200
|
+
onClick={onConfirm}
|
|
201
|
+
>
|
|
202
|
+
{submitLabel}
|
|
203
|
+
</Button>
|
|
204
|
+
<Button type="button" variant="secondary" onClick={close}>
|
|
205
|
+
{cancelLabel}
|
|
206
|
+
</Button>
|
|
207
|
+
</>
|
|
208
|
+
);
|
|
196
209
|
}
|
|
197
210
|
|
|
198
|
-
Dialog.Actions = Actions
|
|
211
|
+
Dialog.Actions = Actions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "./dialog"
|
|
1
|
+
export * from "./dialog";
|
|
@@ -1,101 +1,108 @@
|
|
|
1
|
-
import { Button } from "../button/button"
|
|
2
|
-
import { type ReactNode, useId } from "react"
|
|
3
|
-
import { ChevronDownIcon } from "../../icons/icons"
|
|
4
|
-
import { cn } from "../../lib/class-names"
|
|
5
|
-
import { InlineDisclosure } from "../inline-disclosure/inline-disclosure"
|
|
1
|
+
import { Button } from "../button/button";
|
|
2
|
+
import { type ReactNode, useId } from "react";
|
|
3
|
+
import { ChevronDownIcon } from "../../icons/icons";
|
|
4
|
+
import { cn } from "../../lib/class-names";
|
|
5
|
+
import { InlineDisclosure } from "../inline-disclosure/inline-disclosure";
|
|
6
6
|
|
|
7
|
-
export type DisclosureGroupSize = "sm" | "md" | "lg"
|
|
7
|
+
export type DisclosureGroupSize = "sm" | "md" | "lg";
|
|
8
8
|
|
|
9
9
|
const triggerSizes: Record<DisclosureGroupSize, string> = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
10
|
+
sm: "h-auto min-h-9 w-full rounded-lg px-3 py-2 text-start text-footnote active:scale-100",
|
|
11
|
+
md: "h-auto min-h-11 w-full rounded-xl px-4 py-3 text-start text-subheadline active:scale-100",
|
|
12
|
+
lg: "h-auto min-h-13 w-full rounded-2xl px-5 py-4 text-start text-body active:scale-100",
|
|
13
|
+
};
|
|
14
14
|
const descriptionSizes: Record<DisclosureGroupSize, string> = {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
15
|
+
sm: "text-caption2 leading-caption2 font-normal break-words whitespace-normal text-label-secondary",
|
|
16
|
+
md: "text-footnote leading-footnote font-normal break-words whitespace-normal text-label-secondary",
|
|
17
|
+
lg: "text-subheadline leading-subheadline font-normal break-words whitespace-normal text-label-secondary",
|
|
18
|
+
};
|
|
19
19
|
const contentSizes: Record<DisclosureGroupSize, string> = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
20
|
+
sm: "min-w-0 px-3 pb-3 text-footnote leading-footnote text-label-secondary [overflow-wrap:anywhere]",
|
|
21
|
+
md: "min-w-0 px-4 pb-4 text-subheadline leading-subheadline text-label-secondary [overflow-wrap:anywhere]",
|
|
22
|
+
lg: "min-w-0 px-5 pb-5 text-body leading-body text-label-secondary [overflow-wrap:anywhere]",
|
|
23
|
+
};
|
|
24
24
|
const chevronSizes: Record<DisclosureGroupSize, number> = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
25
|
+
sm: 15,
|
|
26
|
+
md: 17,
|
|
27
|
+
lg: 19,
|
|
28
|
+
};
|
|
29
29
|
|
|
30
30
|
export interface DisclosureGroupProps {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
label: string;
|
|
32
|
+
open: boolean;
|
|
33
|
+
onOpenChange: (open: boolean) => void;
|
|
34
|
+
children: ReactNode;
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
className?: string;
|
|
37
|
+
/** Trigger layout when composed inside a shared surface such as Accordion. */
|
|
38
|
+
triggerClassName?: string;
|
|
39
|
+
/** Supporting text beneath the title. */
|
|
40
|
+
description?: string;
|
|
41
|
+
/** Trigger, description and content density. @default "md" */
|
|
42
|
+
size?: DisclosureGroupSize;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/** A controlled, accessible disclosure row with the shared inline reveal. */
|
|
46
46
|
export function DisclosureGroup({
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
47
|
+
label,
|
|
48
|
+
open,
|
|
49
|
+
onOpenChange,
|
|
50
|
+
children,
|
|
51
|
+
disabled = false,
|
|
52
|
+
className,
|
|
53
|
+
triggerClassName,
|
|
54
|
+
description,
|
|
55
|
+
size = "md",
|
|
56
56
|
}: DisclosureGroupProps) {
|
|
57
|
-
|
|
57
|
+
const id = useId();
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
59
|
+
return (
|
|
60
|
+
<div className={cn("w-full min-w-0", className)}>
|
|
61
|
+
<h3 className="m-0">
|
|
62
|
+
<Button
|
|
63
|
+
variant="ghost"
|
|
64
|
+
contentClassName="w-full min-w-0 justify-between gap-3"
|
|
65
|
+
type="button"
|
|
66
|
+
id={`${id}-trigger`}
|
|
67
|
+
aria-expanded={open}
|
|
68
|
+
aria-controls={id}
|
|
69
|
+
disabled={disabled}
|
|
70
|
+
onClick={() => onOpenChange(!open)}
|
|
71
|
+
className={cn(
|
|
72
|
+
triggerSizes[size],
|
|
73
|
+
"text-label hover:bg-fill/60 font-normal focus-visible:ring-offset-0 focus-visible:ring-inset",
|
|
74
|
+
"focus-visible:outline-accent-text disabled:cursor-not-allowed disabled:opacity-40",
|
|
75
|
+
triggerClassName,
|
|
76
|
+
)}
|
|
77
|
+
>
|
|
78
|
+
<span className="flex min-w-0 flex-col gap-0.5">
|
|
79
|
+
<span className="font-medium break-words whitespace-normal">
|
|
80
|
+
{label}
|
|
81
|
+
</span>
|
|
82
|
+
{description && (
|
|
83
|
+
<span className={descriptionSizes[size]}>{description}</span>
|
|
84
|
+
)}
|
|
85
|
+
</span>
|
|
86
|
+
<ChevronDownIcon
|
|
87
|
+
size={chevronSizes[size]}
|
|
88
|
+
aria-hidden="true"
|
|
89
|
+
className={cn(
|
|
90
|
+
"text-label-tertiary duration-normal shrink-0 transition-transform motion-reduce:transition-none",
|
|
91
|
+
open && "rotate-180",
|
|
92
|
+
)}
|
|
93
|
+
/>
|
|
94
|
+
</Button>
|
|
95
|
+
</h3>
|
|
96
|
+
<section
|
|
97
|
+
id={id}
|
|
98
|
+
aria-labelledby={`${id}-trigger`}
|
|
99
|
+
aria-hidden={!open}
|
|
100
|
+
inert={!open}
|
|
101
|
+
>
|
|
102
|
+
<InlineDisclosure open={open}>
|
|
103
|
+
<div className={contentSizes[size]}>{children}</div>
|
|
104
|
+
</InlineDisclosure>
|
|
105
|
+
</section>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
101
108
|
}
|
|
@@ -1,31 +1,33 @@
|
|
|
1
|
-
import type { HTMLAttributes } from "react"
|
|
2
|
-
import { cn } from "../../lib/class-names"
|
|
1
|
+
import type { HTMLAttributes } from "react";
|
|
2
|
+
import { cn } from "../../lib/class-names";
|
|
3
3
|
|
|
4
|
-
export type DividerOrientation = "horizontal" | "vertical"
|
|
4
|
+
export type DividerOrientation = "horizontal" | "vertical";
|
|
5
5
|
|
|
6
6
|
export interface DividerProps extends HTMLAttributes<HTMLHRElement> {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
orientation?: DividerOrientation;
|
|
8
|
+
/** Decorative separators are omitted from the accessibility tree. @default true */
|
|
9
|
+
decorative?: boolean;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
/** A semantic separator using the shared surface color. */
|
|
13
13
|
export function Divider({
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
orientation = "horizontal",
|
|
15
|
+
decorative = true,
|
|
16
|
+
className,
|
|
17
|
+
...props
|
|
18
18
|
}: DividerProps) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
return (
|
|
20
|
+
<hr
|
|
21
|
+
{...props}
|
|
22
|
+
role={decorative ? "none" : "separator"}
|
|
23
|
+
aria-orientation={decorative ? undefined : orientation}
|
|
24
|
+
className={cn(
|
|
25
|
+
"bg-separator shrink-0 border-0",
|
|
26
|
+
orientation === "horizontal"
|
|
27
|
+
? "h-px w-full"
|
|
28
|
+
: "h-full w-px self-stretch",
|
|
29
|
+
className,
|
|
30
|
+
)}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
31
33
|
}
|