@passui/react 0.1.41 → 0.1.43
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/types/src/components/locale-switcher/locale-switcher.d.ts +4 -1
- package/dist/types/src/components/morph/morph.d.ts +3 -0
- package/dist/types/src/components/wake-slider/wake-slider.d.ts +4 -1
- package/dist/types/src/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/components/locale-switcher/locale-switcher.tsx +47 -7
- package/src/components/morph/morph.tsx +24 -2
- package/src/components/wake-slider/wake-slider.tsx +12 -4
- package/src/index.ts +1 -0
- package/src/styles/motion-controls.css +4 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type LocaleSwitcherSize = "sm" | "md" | "lg";
|
|
1
2
|
export type LocaleSwitcherProps<L extends string> = {
|
|
2
3
|
locales: readonly L[];
|
|
3
4
|
locale: L;
|
|
@@ -5,6 +6,8 @@ export type LocaleSwitcherProps<L extends string> = {
|
|
|
5
6
|
/** localStorage key for where the person dragged it. */
|
|
6
7
|
storageKey: string;
|
|
7
8
|
label: string;
|
|
9
|
+
/** Trigger, header, list item and icon scale. @default "md" */
|
|
10
|
+
size?: LocaleSwitcherSize;
|
|
8
11
|
};
|
|
9
12
|
/** A draggable floating language picker that snaps to the nearest corner. */
|
|
10
|
-
export declare function LocaleSwitcher<L extends string>({ locales, locale, onSelect, storageKey, label, }: LocaleSwitcherProps<L>): import("react").JSX.Element;
|
|
13
|
+
export declare function LocaleSwitcher<L extends string>({ locales, locale, onSelect, storageKey, label, size, }: LocaleSwitcherProps<L>): import("react").JSX.Element;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type HTMLMotionProps } from "motion/react";
|
|
2
2
|
import { type ReactNode, type RefObject } from "react";
|
|
3
|
+
export type MorphSize = "sm" | "md" | "lg";
|
|
3
4
|
export interface MorphProps extends Omit<HTMLMotionProps<"div">, "children"> {
|
|
4
5
|
/** Controls whether the overlay is presented. */
|
|
5
6
|
open: boolean;
|
|
@@ -13,6 +14,8 @@ export interface MorphProps extends Omit<HTMLMotionProps<"div">, "children"> {
|
|
|
13
14
|
labelledBy?: string;
|
|
14
15
|
/** Allow tapping the backdrop to close. Escape still calls onClose. @default true */
|
|
15
16
|
dismissOnOutsidePress?: boolean;
|
|
17
|
+
/** Outer padding and panel max-width. @default "md" */
|
|
18
|
+
size?: MorphSize;
|
|
16
19
|
className?: string;
|
|
17
20
|
children?: ReactNode;
|
|
18
21
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type WakeSliderSize = "sm" | "md" | "lg";
|
|
1
2
|
export interface WakeSliderProps {
|
|
2
3
|
label: string;
|
|
3
4
|
value?: number;
|
|
@@ -8,5 +9,7 @@ export interface WakeSliderProps {
|
|
|
8
9
|
disabled?: boolean;
|
|
9
10
|
className?: string;
|
|
10
11
|
formatValue?: (value: number) => string;
|
|
12
|
+
/** Bar height at rest and value text scale. @default "md" */
|
|
13
|
+
size?: WakeSliderSize;
|
|
11
14
|
}
|
|
12
|
-
export declare function WakeSlider({ label, value: controlledValue, defaultValue, onChange, disabled, className, formatValue, bars, wake, }: WakeSliderProps): import("react").JSX.Element;
|
|
15
|
+
export declare function WakeSlider({ label, value: controlledValue, defaultValue, onChange, disabled, className, formatValue, size, bars, wake, }: WakeSliderProps): import("react").JSX.Element;
|
|
@@ -46,6 +46,7 @@ export * from "./lib/haptics";
|
|
|
46
46
|
export * from "./lib/clipboard";
|
|
47
47
|
export * from "./lib/screen-edges";
|
|
48
48
|
export * from "./motion/transitions";
|
|
49
|
+
export { AnimatePresence, motion } from "motion/react";
|
|
49
50
|
export * from "./appearance";
|
|
50
51
|
export * from "./components/date-picker/date-picker";
|
|
51
52
|
export * from "./components/compact-date-picker/compact-date-picker";
|
package/package.json
CHANGED
|
@@ -6,6 +6,39 @@ import { useDismiss } from "../../hooks/use-dismiss"
|
|
|
6
6
|
import { CheckIcon, GlobeIcon } from "../../icons/icons"
|
|
7
7
|
import { Popover } from "../popover/popover"
|
|
8
8
|
|
|
9
|
+
export type LocaleSwitcherSize = "sm" | "md" | "lg"
|
|
10
|
+
|
|
11
|
+
const triggerSizes: Record<LocaleSwitcherSize, string> = {
|
|
12
|
+
sm: "glass-menu flex h-9 min-w-16 touch-none cursor-grab items-center justify-center gap-1.5 rounded-full px-3 text-caption2 font-semibold text-label active:cursor-grabbing",
|
|
13
|
+
md: "glass-menu flex h-12 min-w-20 touch-none cursor-grab items-center justify-center gap-2 rounded-full px-4 text-caption font-semibold text-label active:cursor-grabbing",
|
|
14
|
+
lg: "glass-menu flex h-14 min-w-24 touch-none cursor-grab items-center justify-center gap-2.5 rounded-full px-5 text-subheadline font-semibold text-label active:cursor-grabbing",
|
|
15
|
+
}
|
|
16
|
+
const iconSizes: Record<LocaleSwitcherSize, string> = {
|
|
17
|
+
sm: "size-4",
|
|
18
|
+
md: "size-5",
|
|
19
|
+
lg: "size-6",
|
|
20
|
+
}
|
|
21
|
+
const popoverWidths: Record<LocaleSwitcherSize, string> = {
|
|
22
|
+
sm: "w-44",
|
|
23
|
+
md: "w-52",
|
|
24
|
+
lg: "w-60",
|
|
25
|
+
}
|
|
26
|
+
const headerSizes: Record<LocaleSwitcherSize, string> = {
|
|
27
|
+
sm: "flex min-h-9 w-full items-center justify-center gap-1.5 rounded-4xl bg-fill/50 text-caption2 font-semibold text-label",
|
|
28
|
+
md: "flex min-h-12 w-full items-center justify-center gap-2 rounded-4xl bg-fill/50 text-caption font-semibold text-label",
|
|
29
|
+
lg: "flex min-h-14 w-full items-center justify-center gap-2.5 rounded-4xl bg-fill/50 text-subheadline font-semibold text-label",
|
|
30
|
+
}
|
|
31
|
+
const itemSizes: Record<LocaleSwitcherSize, string> = {
|
|
32
|
+
sm: "flex min-h-9 items-center justify-between gap-2 rounded-4xl px-3 py-2 text-left text-caption text-label outline-none",
|
|
33
|
+
md: "flex min-h-11 items-center justify-between gap-3 rounded-4xl px-3.5 py-2.5 text-left text-footnote text-label outline-none",
|
|
34
|
+
lg: "flex min-h-13 items-center justify-between gap-3 rounded-4xl px-4 py-3 text-left text-subheadline text-label outline-none",
|
|
35
|
+
}
|
|
36
|
+
const checkIconSizes: Record<LocaleSwitcherSize, string> = {
|
|
37
|
+
sm: "size-3.5 shrink-0",
|
|
38
|
+
md: "size-4 shrink-0",
|
|
39
|
+
lg: "size-5 shrink-0",
|
|
40
|
+
}
|
|
41
|
+
|
|
9
42
|
type Side = "left" | "right"
|
|
10
43
|
type Edge = "top" | "bottom"
|
|
11
44
|
|
|
@@ -58,6 +91,8 @@ export type LocaleSwitcherProps<L extends string> = {
|
|
|
58
91
|
/** localStorage key for where the person dragged it. */
|
|
59
92
|
storageKey: string
|
|
60
93
|
label: string
|
|
94
|
+
/** Trigger, header, list item and icon scale. @default "md" */
|
|
95
|
+
size?: LocaleSwitcherSize
|
|
61
96
|
}
|
|
62
97
|
|
|
63
98
|
/** A draggable floating language picker that snaps to the nearest corner. */
|
|
@@ -67,6 +102,7 @@ export function LocaleSwitcher<L extends string>({
|
|
|
67
102
|
onSelect,
|
|
68
103
|
storageKey,
|
|
69
104
|
label,
|
|
105
|
+
size = "md",
|
|
70
106
|
}: LocaleSwitcherProps<L>) {
|
|
71
107
|
const containerRef = useRef<HTMLDivElement>(null)
|
|
72
108
|
const triggerRef = useRef<HTMLButtonElement>(null)
|
|
@@ -177,9 +213,9 @@ export function LocaleSwitcher<L extends string>({
|
|
|
177
213
|
setOpen(true)
|
|
178
214
|
}
|
|
179
215
|
}}
|
|
180
|
-
className=
|
|
216
|
+
className={triggerSizes[size]}
|
|
181
217
|
>
|
|
182
|
-
<GlobeIcon aria-hidden="true" className=
|
|
218
|
+
<GlobeIcon aria-hidden="true" className={iconSizes[size]} />
|
|
183
219
|
{locale.toUpperCase()}
|
|
184
220
|
</button>
|
|
185
221
|
<Popover
|
|
@@ -189,7 +225,8 @@ export function LocaleSwitcher<L extends string>({
|
|
|
189
225
|
role="menu"
|
|
190
226
|
aria-label={label}
|
|
191
227
|
className={cn(
|
|
192
|
-
"top-0 flex
|
|
228
|
+
"top-0 flex max-w-[calc(100vw-2.5rem)] gap-2 p-2",
|
|
229
|
+
popoverWidths[size],
|
|
193
230
|
anchor.side === "right" ? "right-0" : "left-0",
|
|
194
231
|
growsUp ? "flex-col-reverse" : "flex-col"
|
|
195
232
|
)}
|
|
@@ -201,9 +238,9 @@ export function LocaleSwitcher<L extends string>({
|
|
|
201
238
|
setOpen(false)
|
|
202
239
|
triggerRef.current?.focus()
|
|
203
240
|
}}
|
|
204
|
-
className=
|
|
241
|
+
className={headerSizes[size]}
|
|
205
242
|
>
|
|
206
|
-
<GlobeIcon aria-hidden="true" className=
|
|
243
|
+
<GlobeIcon aria-hidden="true" className={iconSizes[size]} />
|
|
207
244
|
{locale.toUpperCase()}
|
|
208
245
|
</button>
|
|
209
246
|
<div className="flex flex-col gap-1">
|
|
@@ -224,14 +261,17 @@ export function LocaleSwitcher<L extends string>({
|
|
|
224
261
|
}
|
|
225
262
|
}}
|
|
226
263
|
className={cn(
|
|
227
|
-
|
|
264
|
+
itemSizes[size],
|
|
228
265
|
"hover:bg-fill/65 focus-visible:bg-fill/65 transition-colors",
|
|
229
266
|
active && "bg-accent/12 font-medium"
|
|
230
267
|
)}
|
|
231
268
|
>
|
|
232
269
|
{item.label}
|
|
233
270
|
{active && (
|
|
234
|
-
<CheckIcon
|
|
271
|
+
<CheckIcon
|
|
272
|
+
aria-hidden="true"
|
|
273
|
+
className={checkIconSizes[size]}
|
|
274
|
+
/>
|
|
235
275
|
)}
|
|
236
276
|
</button>
|
|
237
277
|
)
|
|
@@ -7,6 +7,19 @@ import { SheetPortal } from "../sheet/sheet-portal"
|
|
|
7
7
|
import { cn } from "../../lib/class-names"
|
|
8
8
|
import { contentCrossfade, fluidCollapse, fluidOvershoot } from "../../motion/transitions"
|
|
9
9
|
|
|
10
|
+
export type MorphSize = "sm" | "md" | "lg"
|
|
11
|
+
|
|
12
|
+
const outerPaddings: Record<MorphSize, string> = {
|
|
13
|
+
sm: "p-4",
|
|
14
|
+
md: "p-6",
|
|
15
|
+
lg: "p-8",
|
|
16
|
+
}
|
|
17
|
+
const panelMaxWidths: Record<MorphSize, string> = {
|
|
18
|
+
sm: "max-w-sm",
|
|
19
|
+
md: "max-w-[720px]",
|
|
20
|
+
lg: "max-w-3xl",
|
|
21
|
+
}
|
|
22
|
+
|
|
10
23
|
export interface MorphProps extends Omit<HTMLMotionProps<"div">, "children"> {
|
|
11
24
|
/** Controls whether the overlay is presented. */
|
|
12
25
|
open: boolean
|
|
@@ -20,6 +33,8 @@ export interface MorphProps extends Omit<HTMLMotionProps<"div">, "children"> {
|
|
|
20
33
|
labelledBy?: string
|
|
21
34
|
/** Allow tapping the backdrop to close. Escape still calls onClose. @default true */
|
|
22
35
|
dismissOnOutsidePress?: boolean
|
|
36
|
+
/** Outer padding and panel max-width. @default "md" */
|
|
37
|
+
size?: MorphSize
|
|
23
38
|
className?: string
|
|
24
39
|
children?: ReactNode
|
|
25
40
|
}
|
|
@@ -44,6 +59,7 @@ function OpenMorph({
|
|
|
44
59
|
label,
|
|
45
60
|
labelledBy,
|
|
46
61
|
dismissOnOutsidePress = true,
|
|
62
|
+
size = "md",
|
|
47
63
|
className,
|
|
48
64
|
children,
|
|
49
65
|
...props
|
|
@@ -131,7 +147,12 @@ function OpenMorph({
|
|
|
131
147
|
|
|
132
148
|
return (
|
|
133
149
|
<SheetPortal>
|
|
134
|
-
<div
|
|
150
|
+
<div
|
|
151
|
+
className={cn(
|
|
152
|
+
"fixed inset-0 z-[75] flex items-center justify-center",
|
|
153
|
+
outerPaddings[size]
|
|
154
|
+
)}
|
|
155
|
+
>
|
|
135
156
|
<motion.div
|
|
136
157
|
aria-hidden="true"
|
|
137
158
|
className="absolute inset-0 bg-black/30 backdrop-blur-md"
|
|
@@ -150,7 +171,8 @@ function OpenMorph({
|
|
|
150
171
|
tabIndex={-1}
|
|
151
172
|
className={cn(
|
|
152
173
|
"relative isolate flex w-full flex-col rounded-5xl outline-none",
|
|
153
|
-
"max-h-[92%]
|
|
174
|
+
"max-h-[92%]",
|
|
175
|
+
panelMaxWidths[size],
|
|
154
176
|
settled && "overflow-hidden",
|
|
155
177
|
className
|
|
156
178
|
)}
|
|
@@ -24,7 +24,9 @@ import { cn } from "../../lib/class-names"
|
|
|
24
24
|
changes, which is what the reading and the colours need, and
|
|
25
25
|
the loop runs only while some bar still has energy. */
|
|
26
26
|
|
|
27
|
-
const H = 20 // a bar at rest, px
|
|
27
|
+
const H: Record<WakeSliderSize, number> = { sm: 16, md: 20, lg: 26 } // a bar at rest, px
|
|
28
|
+
|
|
29
|
+
export type WakeSliderSize = "sm" | "md" | "lg"
|
|
28
30
|
|
|
29
31
|
export interface WakeSliderProps {
|
|
30
32
|
label: string
|
|
@@ -36,6 +38,8 @@ export interface WakeSliderProps {
|
|
|
36
38
|
disabled?: boolean
|
|
37
39
|
className?: string
|
|
38
40
|
formatValue?: (value: number) => string
|
|
41
|
+
/** Bar height at rest and value text scale. @default "md" */
|
|
42
|
+
size?: WakeSliderSize
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
export function WakeSlider({
|
|
@@ -46,6 +50,7 @@ export function WakeSlider({
|
|
|
46
50
|
disabled = false,
|
|
47
51
|
className,
|
|
48
52
|
formatValue,
|
|
53
|
+
size = "md",
|
|
49
54
|
/* how many bars make the track */
|
|
50
55
|
bars = 36,
|
|
51
56
|
/* how high the wake rises, 0..100 */
|
|
@@ -144,7 +149,10 @@ export function WakeSlider({
|
|
|
144
149
|
const lit = Math.round((value / 100) * (n - 1))
|
|
145
150
|
|
|
146
151
|
return (
|
|
147
|
-
<div
|
|
152
|
+
<div
|
|
153
|
+
className={cn("passui-wake-slider not-typeset", disabled && "opacity-40", className)}
|
|
154
|
+
data-size={size}
|
|
155
|
+
>
|
|
148
156
|
<div
|
|
149
157
|
ref={track}
|
|
150
158
|
className="passui-wake-track"
|
|
@@ -156,7 +164,7 @@ export function WakeSlider({
|
|
|
156
164
|
aria-valuemin={0}
|
|
157
165
|
aria-valuemax={100}
|
|
158
166
|
aria-valuenow={value}
|
|
159
|
-
style={{ height: H * 2.6, "--wake-bars": n } as CSSProperties}
|
|
167
|
+
style={{ height: H[size] * 2.6, "--wake-bars": n } as CSSProperties}
|
|
160
168
|
onPointerDown={(e) => {
|
|
161
169
|
if (disabled || e.button !== 0) return
|
|
162
170
|
e.currentTarget.focus()
|
|
@@ -225,7 +233,7 @@ export function WakeSlider({
|
|
|
225
233
|
aria-hidden="true"
|
|
226
234
|
className="passui-wake-bar"
|
|
227
235
|
data-on={(value > 0 && i <= lit) || undefined}
|
|
228
|
-
style={{ height: H }}
|
|
236
|
+
style={{ height: H[size] }}
|
|
229
237
|
/>
|
|
230
238
|
))}
|
|
231
239
|
</div>
|
package/src/index.ts
CHANGED
|
@@ -62,6 +62,7 @@ export * from "./lib/haptics"
|
|
|
62
62
|
export * from "./lib/clipboard"
|
|
63
63
|
export * from "./lib/screen-edges"
|
|
64
64
|
export * from "./motion/transitions"
|
|
65
|
+
export { AnimatePresence, motion } from "motion/react"
|
|
65
66
|
export * from "./appearance"
|
|
66
67
|
|
|
67
68
|
export * from "./components/date-picker/date-picker"
|
|
@@ -189,6 +189,10 @@
|
|
|
189
189
|
font-variant-numeric: tabular-nums;
|
|
190
190
|
color: var(--color-label-secondary);
|
|
191
191
|
}
|
|
192
|
+
.passui-wake-slider[data-size="sm"] { gap: 0.75rem; }
|
|
193
|
+
.passui-wake-slider[data-size="sm"] .passui-wake-value { font-size: var(--text-caption); }
|
|
194
|
+
.passui-wake-slider[data-size="lg"] { gap: 1.25rem; }
|
|
195
|
+
.passui-wake-slider[data-size="lg"] .passui-wake-value { font-size: var(--text-subheadline); }
|
|
192
196
|
@media (prefers-reduced-motion: reduce) {
|
|
193
197
|
.passui-wake-bar, .passui-search-pill { transition: none; }
|
|
194
198
|
.passui-search-pill:active { scale: 1; }
|