@giddaa-housing/ui 2.0.0 → 3.0.0
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/css/generated/shared.css +1 -1
- package/css/theme.css +24 -0
- package/dist/accordion.js +1 -1
- package/dist/{button-BZIeyUw6.d.ts → button-DW5OijoR.d.ts} +1 -1
- package/dist/button-group.d.ts +1 -1
- package/dist/button-group.js +2 -2
- package/dist/button.d.ts +1 -1
- package/dist/button.js +4 -3
- package/dist/call-card.d.ts +131 -0
- package/dist/call-card.js +300 -0
- package/dist/card.d.ts +4 -2
- package/dist/card.js +7 -7
- package/dist/carousel.js +12 -9
- package/dist/chat.d.ts +208 -0
- package/dist/chat.js +528 -0
- package/dist/checkbox.js +1 -1
- package/dist/combobox.d.ts +48 -1
- package/dist/combobox.js +78 -5
- package/dist/cta.d.ts +1 -1
- package/dist/data-table.d.ts +1 -1
- package/dist/data-table.js +1 -1
- package/dist/date-picker.d.ts +5 -2
- package/dist/date-picker.js +11 -6
- package/dist/dialog.js +2 -2
- package/dist/dropdown-menu.js +1 -1
- package/dist/file-upload.js +3 -3
- package/dist/infinite-scroll.d.ts +40 -0
- package/dist/infinite-scroll.js +125 -0
- package/dist/infotip.js +1 -1
- package/dist/input-group.d.ts +1 -1
- package/dist/media-player.js +15 -8
- package/dist/message.d.ts +263 -0
- package/dist/message.js +524 -0
- package/dist/multi-step-form.js +10 -6
- package/dist/page-header.d.ts +6 -6
- package/dist/page-header.js +21 -7
- package/dist/pagination.d.ts +1 -1
- package/dist/picker-xSTzeYhc.js +50 -0
- package/dist/popover.d.ts +2 -2
- package/dist/popover.js +3 -2
- package/dist/price-tag.js +1 -1
- package/dist/property-listing-card.d.ts +1 -1
- package/dist/radio-group.js +1 -1
- package/dist/rich-text-editor.js +3 -3
- package/dist/select.js +1 -1
- package/dist/sheet.js +1 -1
- package/dist/sidebar.d.ts +1 -1
- package/dist/sidebar.js +5 -5
- package/dist/skeleton.js +1 -1
- package/dist/slider.js +3 -2
- package/dist/styles.css +1893 -160
- package/dist/switch.js +3 -3
- package/dist/table.js +2 -2
- package/dist/tabs.js +4 -4
- package/dist/time-picker.d.ts +4 -1
- package/dist/time-picker.js +93 -12
- package/dist/toast.js +1 -1
- package/dist/tooltip.d.ts +2 -1
- package/dist/tooltip.js +9 -2
- package/dist/use-reduced-motion-BDvOK14x.js +17 -0
- package/package.json +18 -1
- package/dist/picker-lzgmsNfG.js +0 -32
package/dist/button.js
CHANGED
|
@@ -7,9 +7,10 @@ import { useRender } from "@base-ui/react/use-render";
|
|
|
7
7
|
import { cva } from "class-variance-authority";
|
|
8
8
|
import { Button as Button$1 } from "@base-ui/react/button";
|
|
9
9
|
//#region src/button.tsx
|
|
10
|
-
const buttonVariants = cva("group/button inline-flex shrink-0 items-center justify-center rounded-full bg-clip-padding whitespace-nowrap font-bold transition-[background-color,color,border-color,box-shadow,
|
|
10
|
+
const buttonVariants = cva("group/button inline-flex shrink-0 items-center justify-center rounded-full bg-clip-padding whitespace-nowrap font-bold transition-[background-color,color,border-color,box-shadow,scale,translate] duration-(--duration-motion-press) ease-gdt-out outline-none select-none focus-visible:border-line-focus focus-visible:shadow-[0px_0px_0px_2px_var(--color-line-focus)] active:not-aria-[haspopup]:translate-y-px motion-reduce:active:not-aria-[haspopup]:translate-y-0 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-invalid:border-line-danger aria-invalid:ring-3 aria-invalid:ring-line-danger/20 aria-invalid:focus-visible:border-line-danger aria-invalid:focus-visible:shadow-[0px_0px_0px_2px_var(--color-line-danger)] [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
11
11
|
variants: {
|
|
12
12
|
variant: {
|
|
13
|
+
back: "border border-line bg-canvas text-fg-primary hover:border-line-strong hover:bg-surface active:border-line-strong active:bg-surface-raised data-focused:border-line-strong data-focused:bg-surface data-pressed:border-line-strong data-pressed:bg-surface-raised disabled:border-line-subtle disabled:text-fg-caption-placeholder disabled:opacity-100 aria-disabled:border-line-subtle aria-disabled:text-fg-caption-placeholder aria-disabled:opacity-100",
|
|
13
14
|
primary: "bg-action-primary text-fg-on-brand hover:bg-action-primary-hover active:bg-action-primary-pressed",
|
|
14
15
|
"primary-outline": "border-2 border-action-primary bg-transparent text-fg-brand hover:bg-surface-brand-subtle active:bg-surface-brand-subtle data-focused:bg-surface-brand-subtle data-pressed:bg-surface-brand-subtle",
|
|
15
16
|
secondary: "bg-surface-brand-subtle text-fg-brand hover:bg-action-primary-hover hover:text-fg-on-brand active:bg-action-primary-pressed active:text-fg-on-brand data-focused:bg-action-primary-hover data-pressed:bg-action-primary-pressed data-focused:text-fg-on-brand data-pressed:text-fg-on-brand",
|
|
@@ -19,7 +20,7 @@ const buttonVariants = cva("group/button inline-flex shrink-0 items-center justi
|
|
|
19
20
|
ghost: "bg-transparent text-fg-primary hover:bg-surface active:bg-surface-raised data-focused:bg-surface data-pressed:bg-surface-raised",
|
|
20
21
|
danger: "bg-action-danger text-fg-on-brand hover:bg-action-danger-hover active:bg-action-danger-pressed data-focused:bg-action-danger-hover data-pressed:bg-action-danger-pressed",
|
|
21
22
|
whatsapp: "bg-whatsapp-button text-black [&_svg]:text-white hover:brightness-95 active:brightness-90 data-focused:brightness-95 data-pressed:brightness-90",
|
|
22
|
-
"glass-overlay": "bg-surface-glass-overlay-button text-fg-on-brand shadow-2 backdrop-blur-sm
|
|
23
|
+
"glass-overlay": "bg-surface-glass-overlay-button text-fg-on-brand shadow-2 backdrop-blur-sm active:scale-[0.97] motion-reduce:active:scale-100",
|
|
23
24
|
"link-brand": "border-transparent bg-transparent px-0 text-fg-brand hover:underline active:underline active:opacity-70",
|
|
24
25
|
"link-neutral": "border-transparent bg-transparent px-0 text-fg-secondary hover:underline active:underline active:opacity-70"
|
|
25
26
|
},
|
|
@@ -54,7 +55,7 @@ function Button({ className, variant = "primary", size, isLoading = false, child
|
|
|
54
55
|
disabled: _disabled,
|
|
55
56
|
...props,
|
|
56
57
|
children: [
|
|
57
|
-
isLoading && /* @__PURE__ */ jsx(Loader, { className: "size-4 animate-spin" }),
|
|
58
|
+
isLoading && /* @__PURE__ */ jsx(Loader, { className: "size-4 animate-spin motion-reduce:animate-none" }),
|
|
58
59
|
" ",
|
|
59
60
|
children
|
|
60
61
|
]
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Avatar } from "./avatar.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
//#region src/call-card.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Docked vs full-window presentation. Purely structural: `full` is the centered
|
|
6
|
+
* call window that floats over an overlay; `minimized` is the horizontal docked
|
|
7
|
+
* bar. Everything below the card shell — direction, spacing, type ramp — keys
|
|
8
|
+
* off this one axis.
|
|
9
|
+
*/
|
|
10
|
+
type CallCardSize = "full" | "minimized";
|
|
11
|
+
/**
|
|
12
|
+
* The five visual states from the design's two branches.
|
|
13
|
+
* OUTBOUND (a call we place): `calling` → `ringing` → `in-call` → `call-ended`,
|
|
14
|
+
* whose actions are Mute + End Call. INBOUND: `incoming`, whose actions are
|
|
15
|
+
* Ignore + Accept. `state` is the sole driver of the status-dot colour and of
|
|
16
|
+
* whether the End Call button retires to a neutral tone.
|
|
17
|
+
*/
|
|
18
|
+
type CallCardState = "ringing" | "calling" | "in-call" | "call-ended" | "incoming";
|
|
19
|
+
type CallCardOverlayProps = React.ComponentProps<"div">;
|
|
20
|
+
/**
|
|
21
|
+
* The scrim behind a `size="full"` card. An overlay must not share a surface
|
|
22
|
+
* with the thread behind it, so the card floats on `bg-surface-overlay` above
|
|
23
|
+
* this dimmed, blurred layer. Centres its child; give it the card as children.
|
|
24
|
+
*
|
|
25
|
+
* Only for the full state — a minimized bar docks inline and needs no scrim.
|
|
26
|
+
*/
|
|
27
|
+
declare function CallCardOverlay({ className, ...props }: CallCardOverlayProps): React.JSX.Element;
|
|
28
|
+
/** The card shell — surface, border, elevation, and the per-size layout. */
|
|
29
|
+
declare const callCardVariants: (props?: ({
|
|
30
|
+
size?: "full" | "minimized" | null | undefined;
|
|
31
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
32
|
+
interface CallCardProps extends React.ComponentProps<"section"> {
|
|
33
|
+
/** Docked bar vs full window — see {@link CallCardSize}. @default "full" */
|
|
34
|
+
size?: CallCardSize;
|
|
35
|
+
/**
|
|
36
|
+
* Which point of the call this is — see {@link CallCardState}. Required: it
|
|
37
|
+
* drives the status-dot colour and the End Call button's tone, so there is no
|
|
38
|
+
* safe default.
|
|
39
|
+
*/
|
|
40
|
+
state: CallCardState;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The reusable call overlay — the in-product surface shown while a voice call is
|
|
44
|
+
* ringing, connecting, connected, or just ended. A presentational primitive:
|
|
45
|
+
* it owns shape, elevation and per-size layout, and exposes state through
|
|
46
|
+
* context so its parts size and colour themselves. Wiring (mute, hang up,
|
|
47
|
+
* accept) is the consumer's — pass handlers to the action parts.
|
|
48
|
+
*
|
|
49
|
+
* Compose it like a Dialog: a shell with slotted parts. For the full state,
|
|
50
|
+
* wrap it in {@link CallCardOverlay}; the minimized bar docks on its own.
|
|
51
|
+
*/
|
|
52
|
+
declare function CallCard({ size, state, className, children, ...props }: CallCardProps): React.JSX.Element;
|
|
53
|
+
interface CallCardAvatarProps extends Omit<React.ComponentProps<typeof Avatar>, "size"> {
|
|
54
|
+
/** Contact photo. When absent, the fallback glyph shows. */
|
|
55
|
+
src?: string;
|
|
56
|
+
/** Alt text for the photo. */
|
|
57
|
+
alt?: string;
|
|
58
|
+
/** Fallback shown with no photo — initials or a glyph. @default person glyph */
|
|
59
|
+
fallback?: React.ReactNode;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The contact avatar. Wraps the giddaa `Avatar` so it inherits the brand-subtle
|
|
63
|
+
* wash and brand glyph tokens — 112px in the full window (the design's largest
|
|
64
|
+
* element), 40px on the docked bar. Pass `src` for a photo; the glyph is only a
|
|
65
|
+
* fallback.
|
|
66
|
+
*/
|
|
67
|
+
declare function CallCardAvatar({ src, alt, fallback, className, ...props }: CallCardAvatarProps): React.JSX.Element;
|
|
68
|
+
type CallCardIdentityProps = React.ComponentProps<"div">;
|
|
69
|
+
/** Stacks the name over the status line; centred in full, start-aligned when docked. */
|
|
70
|
+
declare function CallCardIdentity({ className, ...props }: CallCardIdentityProps): React.JSX.Element;
|
|
71
|
+
type CallCardNameProps = React.ComponentProps<"p">;
|
|
72
|
+
/** The contact name. Full uses the heading ramp; the docked bar truncates. */
|
|
73
|
+
declare function CallCardName({ className, ...props }: CallCardNameProps): React.JSX.Element;
|
|
74
|
+
type CallCardStatusProps = React.ComponentProps<"div">;
|
|
75
|
+
/**
|
|
76
|
+
* The status line: a state-coloured dot followed by its copy — the number, the
|
|
77
|
+
* running timer, or the end notice. The dot's colour comes from the card's
|
|
78
|
+
* `state`; the copy is the caller's (never bake the number or timer in).
|
|
79
|
+
*/
|
|
80
|
+
declare function CallCardStatus({ className, children, ...props }: CallCardStatusProps): React.JSX.Element;
|
|
81
|
+
type CallCardActionsProps = React.ComponentProps<"div">;
|
|
82
|
+
/**
|
|
83
|
+
* The action row. Holds the call actions, led by the window control. Turning an
|
|
84
|
+
* action off simply drops it — the row re-centres, no dead slot. Never leave it
|
|
85
|
+
* empty: an overlay with no controls traps the user in a live call.
|
|
86
|
+
*/
|
|
87
|
+
declare function CallCardActions({ className, ...props }: CallCardActionsProps): React.JSX.Element;
|
|
88
|
+
type CallCardActionTone = "tertiary" | "danger" | "primary";
|
|
89
|
+
interface CallCardActionProps extends React.ComponentProps<"button"> {
|
|
90
|
+
/**
|
|
91
|
+
* Surface emphasis. `tertiary` = reversible/neutral (Mute), `danger` =
|
|
92
|
+
* destructive (End Call, Ignore), `primary` = the call to answer (Accept).
|
|
93
|
+
* @default "tertiary"
|
|
94
|
+
*/
|
|
95
|
+
tone?: CallCardActionTone;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The circular icon-button primitive every call action is built from. Sizes
|
|
99
|
+
* itself off the card, colours itself off `tone`. Pass a single icon as its
|
|
100
|
+
* child; it's auto-sized. Use the presets below for the standard actions.
|
|
101
|
+
*/
|
|
102
|
+
declare function CallCardAction({ tone, type, className, ...props }: CallCardActionProps): React.JSX.Element;
|
|
103
|
+
interface CallCardMuteButtonProps extends Omit<CallCardActionProps, "tone" | "children"> {
|
|
104
|
+
/** Whether the mic is currently muted — swaps the glyph and the label. */
|
|
105
|
+
muted?: boolean;
|
|
106
|
+
}
|
|
107
|
+
/** Mute toggle. Reversible, so it stays neutral and never competes with End Call. */
|
|
108
|
+
declare function CallCardMuteButton({ muted, "aria-label": ariaLabel, ...props }: CallCardMuteButtonProps): React.JSX.Element;
|
|
109
|
+
type CallCardEndCallButtonProps = Omit<CallCardActionProps, "tone" | "children">;
|
|
110
|
+
/**
|
|
111
|
+
* End Call. Destructive, so it's `danger` — except in `call-ended`, where the
|
|
112
|
+
* call is already over and it retires to a neutral tone. The rotated handset is
|
|
113
|
+
* a placeholder for the exact SVG.
|
|
114
|
+
*/
|
|
115
|
+
declare function CallCardEndCallButton({ className, "aria-label": ariaLabel, ...props }: CallCardEndCallButtonProps): React.JSX.Element;
|
|
116
|
+
type CallCardAcceptButtonProps = Omit<CallCardActionProps, "tone" | "children">;
|
|
117
|
+
/** Accept an incoming call. The brand primary — the button the thumb finds first. */
|
|
118
|
+
declare function CallCardAcceptButton({ "aria-label": ariaLabel, ...props }: CallCardAcceptButtonProps): React.JSX.Element;
|
|
119
|
+
type CallCardIgnoreButtonProps = Omit<CallCardActionProps, "tone" | "children">;
|
|
120
|
+
/** Dismiss an incoming call. Same clay and rotated handset as End Call. */
|
|
121
|
+
declare function CallCardIgnoreButton({ "aria-label": ariaLabel, ...props }: CallCardIgnoreButtonProps): React.JSX.Element;
|
|
122
|
+
type CallCardWindowControlProps = React.ComponentProps<"button">;
|
|
123
|
+
/**
|
|
124
|
+
* The window chrome — Minimize in the full window (pinned top-right), Expand on
|
|
125
|
+
* the docked bar (leads the action row). Neutral and quiet by design: a window
|
|
126
|
+
* control is never destructive and must not pull the eye from End Call. Place it
|
|
127
|
+
* as the first child of {@link CallCardActions}; it self-positions per size.
|
|
128
|
+
*/
|
|
129
|
+
declare function CallCardWindowControl({ className, "aria-label": ariaLabel, type, ...props }: CallCardWindowControlProps): React.JSX.Element;
|
|
130
|
+
//#endregion
|
|
131
|
+
export { CallCard, CallCardAcceptButton, type CallCardAcceptButtonProps, CallCardAction, type CallCardActionProps, type CallCardActionTone, CallCardActions, CallCardAvatar, type CallCardAvatarProps, CallCardEndCallButton, type CallCardEndCallButtonProps, CallCardIdentity, type CallCardIdentityProps, CallCardIgnoreButton, type CallCardIgnoreButtonProps, CallCardMuteButton, type CallCardMuteButtonProps, CallCardName, type CallCardNameProps, CallCardOverlay, type CallCardOverlayProps, type CallCardProps, type CallCardSize, type CallCardState, CallCardStatus, type CallCardStatusProps, CallCardWindowControl, type CallCardWindowControlProps, callCardVariants };
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { t as cn } from "./cn-BI_4DMBf.js";
|
|
3
|
+
import { Avatar, AvatarFallback, AvatarImage } from "./avatar.js";
|
|
4
|
+
import { Maximize2, Mic, MicOff, Minimize2, Phone, User } from "lucide-react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { cva } from "class-variance-authority";
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
//#region src/call-card.tsx
|
|
9
|
+
const CallCardContext = React.createContext(null);
|
|
10
|
+
function useCallCardContext() {
|
|
11
|
+
const context = React.useContext(CallCardContext);
|
|
12
|
+
if (!context) throw new Error("CallCard parts must be rendered inside <CallCard>.");
|
|
13
|
+
return context;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Status-dot fill per state. The dot is the fastest read on the card, so it
|
|
17
|
+
* carries the state on its own — warning while the call is in flight, success
|
|
18
|
+
* once connected, danger once ended, info for an arriving call.
|
|
19
|
+
*/
|
|
20
|
+
const STATUS_DOT_TONE = {
|
|
21
|
+
ringing: "bg-status-warning",
|
|
22
|
+
calling: "bg-status-warning",
|
|
23
|
+
"in-call": "bg-status-success",
|
|
24
|
+
"call-ended": "bg-status-danger",
|
|
25
|
+
incoming: "bg-status-info"
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* The scrim behind a `size="full"` card. An overlay must not share a surface
|
|
29
|
+
* with the thread behind it, so the card floats on `bg-surface-overlay` above
|
|
30
|
+
* this dimmed, blurred layer. Centres its child; give it the card as children.
|
|
31
|
+
*
|
|
32
|
+
* Only for the full state — a minimized bar docks inline and needs no scrim.
|
|
33
|
+
*/
|
|
34
|
+
function CallCardOverlay({ className, ...props }) {
|
|
35
|
+
return /* @__PURE__ */ jsx("div", {
|
|
36
|
+
"data-slot": "call-card-overlay",
|
|
37
|
+
className: cn("fixed inset-0 isolate z-50 grid place-items-center p-4", "bg-black/10 supports-[backdrop-filter]:backdrop-blur-xl", "animate-in fade-in-0 duration-100", className),
|
|
38
|
+
...props
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/** The card shell — surface, border, elevation, and the per-size layout. */
|
|
42
|
+
const callCardVariants = cva("relative flex border border-line-subtle bg-surface-overlay shadow-2", {
|
|
43
|
+
variants: { size: {
|
|
44
|
+
full: "w-full max-w-[390px] flex-col items-center justify-center gap-7 rounded-2xl px-gdt-xl pt-14 pb-gdt-4xl md:max-w-[640px] md:gap-gdt-2xl md:px-gdt-4xl md:pt-gdt-4xl",
|
|
45
|
+
minimized: "h-14 w-full max-w-[358px] items-center gap-2.5 rounded-[14px] p-2.5 md:h-16 md:max-w-[360px] md:gap-gdt-md md:rounded-xl md:p-gdt-md"
|
|
46
|
+
} },
|
|
47
|
+
defaultVariants: { size: "full" }
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* The reusable call overlay — the in-product surface shown while a voice call is
|
|
51
|
+
* ringing, connecting, connected, or just ended. A presentational primitive:
|
|
52
|
+
* it owns shape, elevation and per-size layout, and exposes state through
|
|
53
|
+
* context so its parts size and colour themselves. Wiring (mute, hang up,
|
|
54
|
+
* accept) is the consumer's — pass handlers to the action parts.
|
|
55
|
+
*
|
|
56
|
+
* Compose it like a Dialog: a shell with slotted parts. For the full state,
|
|
57
|
+
* wrap it in {@link CallCardOverlay}; the minimized bar docks on its own.
|
|
58
|
+
*/
|
|
59
|
+
function CallCard({ size = "full", state, className, children, ...props }) {
|
|
60
|
+
const context = React.useMemo(() => ({
|
|
61
|
+
size,
|
|
62
|
+
state
|
|
63
|
+
}), [size, state]);
|
|
64
|
+
return /* @__PURE__ */ jsx(CallCardContext.Provider, {
|
|
65
|
+
value: context,
|
|
66
|
+
children: /* @__PURE__ */ jsx("section", {
|
|
67
|
+
"data-slot": "call-card",
|
|
68
|
+
"data-size": size,
|
|
69
|
+
"data-state": state,
|
|
70
|
+
role: state === "incoming" ? "alert" : "status",
|
|
71
|
+
"aria-live": state === "incoming" ? "assertive" : "polite",
|
|
72
|
+
className: cn("group/call-card", callCardVariants({ size }), className),
|
|
73
|
+
...props,
|
|
74
|
+
children
|
|
75
|
+
})
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The contact avatar. Wraps the giddaa `Avatar` so it inherits the brand-subtle
|
|
80
|
+
* wash and brand glyph tokens — 112px in the full window (the design's largest
|
|
81
|
+
* element), 40px on the docked bar. Pass `src` for a photo; the glyph is only a
|
|
82
|
+
* fallback.
|
|
83
|
+
*/
|
|
84
|
+
function CallCardAvatar({ src, alt, fallback, className, ...props }) {
|
|
85
|
+
const { size } = useCallCardContext();
|
|
86
|
+
const isFull = size === "full";
|
|
87
|
+
return /* @__PURE__ */ jsxs(Avatar, {
|
|
88
|
+
"data-slot": "call-card-avatar",
|
|
89
|
+
size: isFull ? "lg" : "md",
|
|
90
|
+
className: cn(isFull ? "size-24 md:size-28" : "size-9 md:size-10", className),
|
|
91
|
+
...props,
|
|
92
|
+
children: [src ? /* @__PURE__ */ jsx(AvatarImage, {
|
|
93
|
+
src,
|
|
94
|
+
alt
|
|
95
|
+
}) : null, /* @__PURE__ */ jsx(AvatarFallback, { children: fallback ?? /* @__PURE__ */ jsx(User, {
|
|
96
|
+
className: isFull ? "size-[38px] md:size-11" : "size-4 md:size-[18px]",
|
|
97
|
+
"aria-hidden": true
|
|
98
|
+
}) })]
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
const identityVariants = cva("flex min-w-0 flex-col justify-center", {
|
|
102
|
+
variants: { size: {
|
|
103
|
+
full: "items-center gap-1.5 text-center",
|
|
104
|
+
minimized: "flex-1 items-start gap-px md:gap-0.5"
|
|
105
|
+
} },
|
|
106
|
+
defaultVariants: { size: "full" }
|
|
107
|
+
});
|
|
108
|
+
/** Stacks the name over the status line; centred in full, start-aligned when docked. */
|
|
109
|
+
function CallCardIdentity({ className, ...props }) {
|
|
110
|
+
const { size } = useCallCardContext();
|
|
111
|
+
return /* @__PURE__ */ jsx("div", {
|
|
112
|
+
"data-slot": "call-card-identity",
|
|
113
|
+
className: cn(identityVariants({ size }), className),
|
|
114
|
+
...props
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const nameVariants = cva("min-w-0 text-fg-primary", {
|
|
118
|
+
variants: { size: {
|
|
119
|
+
full: "text-gdt-h4 md:text-gdt-h3",
|
|
120
|
+
minimized: "w-full truncate text-gdt-sm font-semibold"
|
|
121
|
+
} },
|
|
122
|
+
defaultVariants: { size: "full" }
|
|
123
|
+
});
|
|
124
|
+
/** The contact name. Full uses the heading ramp; the docked bar truncates. */
|
|
125
|
+
function CallCardName({ className, ...props }) {
|
|
126
|
+
const { size } = useCallCardContext();
|
|
127
|
+
return /* @__PURE__ */ jsx("p", {
|
|
128
|
+
"data-slot": "call-card-name",
|
|
129
|
+
className: cn(nameVariants({ size }), className),
|
|
130
|
+
...props
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
const statusVariants = cva("flex min-w-0 items-center text-fg-secondary", {
|
|
134
|
+
variants: { size: {
|
|
135
|
+
full: "justify-center gap-gdt-sm text-gdt-sm",
|
|
136
|
+
minimized: "gap-1.5 text-gdt-xs"
|
|
137
|
+
} },
|
|
138
|
+
defaultVariants: { size: "full" }
|
|
139
|
+
});
|
|
140
|
+
const statusDotVariants = cva("shrink-0 rounded-full", {
|
|
141
|
+
variants: { size: {
|
|
142
|
+
full: "size-2",
|
|
143
|
+
minimized: "size-1.5"
|
|
144
|
+
} },
|
|
145
|
+
defaultVariants: { size: "full" }
|
|
146
|
+
});
|
|
147
|
+
/**
|
|
148
|
+
* The status line: a state-coloured dot followed by its copy — the number, the
|
|
149
|
+
* running timer, or the end notice. The dot's colour comes from the card's
|
|
150
|
+
* `state`; the copy is the caller's (never bake the number or timer in).
|
|
151
|
+
*/
|
|
152
|
+
function CallCardStatus({ className, children, ...props }) {
|
|
153
|
+
const { size, state } = useCallCardContext();
|
|
154
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
155
|
+
"data-slot": "call-card-status",
|
|
156
|
+
className: cn(statusVariants({ size }), className),
|
|
157
|
+
...props,
|
|
158
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
159
|
+
"data-slot": "call-card-status-dot",
|
|
160
|
+
className: cn(statusDotVariants({ size }), STATUS_DOT_TONE[state]),
|
|
161
|
+
"aria-hidden": true
|
|
162
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
163
|
+
className: "min-w-0 truncate",
|
|
164
|
+
children
|
|
165
|
+
})]
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
const actionsVariants = cva("flex shrink-0 items-center justify-center", {
|
|
169
|
+
variants: { size: {
|
|
170
|
+
full: "gap-gdt-lg md:gap-5",
|
|
171
|
+
minimized: "gap-gdt-sm"
|
|
172
|
+
} },
|
|
173
|
+
defaultVariants: { size: "full" }
|
|
174
|
+
});
|
|
175
|
+
/**
|
|
176
|
+
* The action row. Holds the call actions, led by the window control. Turning an
|
|
177
|
+
* action off simply drops it — the row re-centres, no dead slot. Never leave it
|
|
178
|
+
* empty: an overlay with no controls traps the user in a live call.
|
|
179
|
+
*/
|
|
180
|
+
function CallCardActions({ className, ...props }) {
|
|
181
|
+
const { size } = useCallCardContext();
|
|
182
|
+
return /* @__PURE__ */ jsx("div", {
|
|
183
|
+
"data-slot": "call-card-actions",
|
|
184
|
+
className: cn(actionsVariants({ size }), className),
|
|
185
|
+
...props
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
const actionVariants = cva([
|
|
189
|
+
"grid shrink-0 place-items-center rounded-full outline-none transition-colors",
|
|
190
|
+
"focus-visible:ring-2 focus-visible:ring-line-focus focus-visible:ring-offset-2 focus-visible:ring-offset-surface-overlay",
|
|
191
|
+
"disabled:pointer-events-none disabled:opacity-50"
|
|
192
|
+
], {
|
|
193
|
+
variants: {
|
|
194
|
+
size: {
|
|
195
|
+
full: "size-14 [&_svg]:size-6 md:size-16 md:[&_svg]:size-[26px]",
|
|
196
|
+
minimized: "size-[34px] [&_svg]:size-[15px] md:size-9 md:[&_svg]:size-4"
|
|
197
|
+
},
|
|
198
|
+
tone: {
|
|
199
|
+
tertiary: "bg-action-tertiary text-fg-primary hover:bg-action-tertiary-hover",
|
|
200
|
+
danger: "bg-action-danger text-fg-on-brand hover:bg-action-danger-hover",
|
|
201
|
+
primary: "bg-action-primary text-fg-on-brand hover:bg-action-primary-hover"
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
defaultVariants: {
|
|
205
|
+
size: "full",
|
|
206
|
+
tone: "tertiary"
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
/**
|
|
210
|
+
* The circular icon-button primitive every call action is built from. Sizes
|
|
211
|
+
* itself off the card, colours itself off `tone`. Pass a single icon as its
|
|
212
|
+
* child; it's auto-sized. Use the presets below for the standard actions.
|
|
213
|
+
*/
|
|
214
|
+
function CallCardAction({ tone = "tertiary", type = "button", className, ...props }) {
|
|
215
|
+
const { size } = useCallCardContext();
|
|
216
|
+
return /* @__PURE__ */ jsx("button", {
|
|
217
|
+
"data-slot": "call-card-action",
|
|
218
|
+
type,
|
|
219
|
+
className: cn(actionVariants({
|
|
220
|
+
size,
|
|
221
|
+
tone
|
|
222
|
+
}), className),
|
|
223
|
+
...props
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/** Mute toggle. Reversible, so it stays neutral and never competes with End Call. */
|
|
227
|
+
function CallCardMuteButton({ muted = false, "aria-label": ariaLabel, ...props }) {
|
|
228
|
+
return /* @__PURE__ */ jsx(CallCardAction, {
|
|
229
|
+
tone: "tertiary",
|
|
230
|
+
"aria-pressed": muted,
|
|
231
|
+
"aria-label": ariaLabel ?? (muted ? "Unmute" : "Mute"),
|
|
232
|
+
...props,
|
|
233
|
+
children: muted ? /* @__PURE__ */ jsx(MicOff, {}) : /* @__PURE__ */ jsx(Mic, {})
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* End Call. Destructive, so it's `danger` — except in `call-ended`, where the
|
|
238
|
+
* call is already over and it retires to a neutral tone. The rotated handset is
|
|
239
|
+
* a placeholder for the exact SVG.
|
|
240
|
+
*/
|
|
241
|
+
function CallCardEndCallButton({ className, "aria-label": ariaLabel, ...props }) {
|
|
242
|
+
const { state } = useCallCardContext();
|
|
243
|
+
const ended = state === "call-ended";
|
|
244
|
+
return /* @__PURE__ */ jsx(CallCardAction, {
|
|
245
|
+
tone: ended ? "tertiary" : "danger",
|
|
246
|
+
"aria-label": ariaLabel ?? "End call",
|
|
247
|
+
className: cn(ended && "text-fg-primary", className),
|
|
248
|
+
...props,
|
|
249
|
+
children: /* @__PURE__ */ jsx(Phone, { className: "rotate-[135deg]" })
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
/** Accept an incoming call. The brand primary — the button the thumb finds first. */
|
|
253
|
+
function CallCardAcceptButton({ "aria-label": ariaLabel, ...props }) {
|
|
254
|
+
return /* @__PURE__ */ jsx(CallCardAction, {
|
|
255
|
+
tone: "primary",
|
|
256
|
+
"aria-label": ariaLabel ?? "Accept",
|
|
257
|
+
...props,
|
|
258
|
+
children: /* @__PURE__ */ jsx(Phone, {})
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
/** Dismiss an incoming call. Same clay and rotated handset as End Call. */
|
|
262
|
+
function CallCardIgnoreButton({ "aria-label": ariaLabel, ...props }) {
|
|
263
|
+
return /* @__PURE__ */ jsx(CallCardAction, {
|
|
264
|
+
tone: "danger",
|
|
265
|
+
"aria-label": ariaLabel ?? "Ignore",
|
|
266
|
+
...props,
|
|
267
|
+
children: /* @__PURE__ */ jsx(Phone, { className: "rotate-[135deg]" })
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
const windowControlVariants = cva([
|
|
271
|
+
"grid shrink-0 place-items-center rounded-full outline-none transition-colors",
|
|
272
|
+
"bg-action-tertiary text-fg-secondary hover:bg-action-tertiary-hover",
|
|
273
|
+
"focus-visible:ring-2 focus-visible:ring-line-focus focus-visible:ring-offset-2 focus-visible:ring-offset-surface-overlay"
|
|
274
|
+
], {
|
|
275
|
+
variants: { size: {
|
|
276
|
+
full: "absolute top-[15px] right-[15px] size-9 [&_svg]:size-4 md:top-[19px] md:right-[19px] md:size-10 md:[&_svg]:size-[18px]",
|
|
277
|
+
minimized: "size-[34px] [&_svg]:size-3.5 md:size-9 md:[&_svg]:size-[15px]"
|
|
278
|
+
} },
|
|
279
|
+
defaultVariants: { size: "full" }
|
|
280
|
+
});
|
|
281
|
+
/**
|
|
282
|
+
* The window chrome — Minimize in the full window (pinned top-right), Expand on
|
|
283
|
+
* the docked bar (leads the action row). Neutral and quiet by design: a window
|
|
284
|
+
* control is never destructive and must not pull the eye from End Call. Place it
|
|
285
|
+
* as the first child of {@link CallCardActions}; it self-positions per size.
|
|
286
|
+
*/
|
|
287
|
+
function CallCardWindowControl({ className, "aria-label": ariaLabel, type = "button", ...props }) {
|
|
288
|
+
const { size } = useCallCardContext();
|
|
289
|
+
const minimized = size === "minimized";
|
|
290
|
+
return /* @__PURE__ */ jsx("button", {
|
|
291
|
+
"data-slot": "call-card-window-control",
|
|
292
|
+
type,
|
|
293
|
+
"aria-label": ariaLabel ?? (minimized ? "Expand" : "Minimize"),
|
|
294
|
+
className: cn(windowControlVariants({ size }), className),
|
|
295
|
+
...props,
|
|
296
|
+
children: minimized ? /* @__PURE__ */ jsx(Maximize2, {}) : /* @__PURE__ */ jsx(Minimize2, {})
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
//#endregion
|
|
300
|
+
export { CallCard, CallCardAcceptButton, CallCardAction, CallCardActions, CallCardAvatar, CallCardEndCallButton, CallCardIdentity, CallCardIgnoreButton, CallCardMuteButton, CallCardName, CallCardOverlay, CallCardStatus, CallCardWindowControl, callCardVariants };
|
package/dist/card.d.ts
CHANGED
|
@@ -4,8 +4,10 @@ import { VariantProps } from "class-variance-authority";
|
|
|
4
4
|
declare const cardVariants: (props?: ({
|
|
5
5
|
selected?: boolean | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
-
type CardProps = useRender.ComponentProps<"article"> &
|
|
8
|
-
|
|
7
|
+
type CardProps = useRender.ComponentProps<"article"> & {
|
|
8
|
+
removePadding?: boolean;
|
|
9
|
+
} & VariantProps<typeof cardVariants>;
|
|
10
|
+
declare function Card({ className, render, selected, removePadding, ...props }: CardProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
9
11
|
declare function CardTitle({ className, render, ...props }: useRender.ComponentProps<"h3">): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
10
12
|
declare function CardHeader({ className, render, ...props }: useRender.ComponentProps<"div">): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
11
13
|
declare function CardDescription({ className, render, ...props }: useRender.ComponentProps<"p">): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
package/dist/card.js
CHANGED
|
@@ -3,17 +3,17 @@ import { mergeProps } from "@base-ui/react/merge-props";
|
|
|
3
3
|
import { useRender } from "@base-ui/react/use-render";
|
|
4
4
|
import { cva } from "class-variance-authority";
|
|
5
5
|
//#region src/card.tsx
|
|
6
|
-
const cardVariants = cva("group/card relative flex w-full min-w-0 flex-col gap-5 rounded-2xl border border-line-subtle bg-canvas py-
|
|
6
|
+
const cardVariants = cva("group/card relative flex w-full min-w-0 flex-col gap-5 rounded-2xl border border-line-subtle bg-canvas [--card-padding:1.5rem] py-(--card-padding) text-fg-primary shadow-1 transition-[background-color,border-color,box-shadow,transform] outline-none has-[[data-slot=card-action]:hover]:shadow-2 has-[[data-slot=card-action]:focus-visible]:border-line-focus has-[[data-slot=card-action]:focus-visible]:inset-ring-1 has-[[data-slot=card-action]:focus-visible]:inset-ring-line-focus has-[[data-slot=card-action]:active]:border-line-subtle has-[[data-slot=card-action]:active]:bg-surface has-[[data-slot=card-action]:active]:shadow-none!", {
|
|
7
7
|
variants: { selected: {
|
|
8
8
|
true: "border-line-focus bg-surface-brand-subtle inset-ring-1 inset-ring-line-focus has-[[data-slot=card-action]:hover]:border-line-focus has-[[data-slot=card-action]:hover]:bg-surface-brand-subtle has-[[data-slot=card-action]:hover]:inset-ring-1 has-[[data-slot=card-action]:active]:border-line-focus has-[[data-slot=card-action]:active]:bg-surface-brand-subtle has-[[data-slot=card-action]:active]:inset-ring-1 has-[[data-slot=card-action]:active]:inset-ring-line-focus",
|
|
9
9
|
false: ""
|
|
10
10
|
} },
|
|
11
11
|
defaultVariants: { selected: false }
|
|
12
12
|
});
|
|
13
|
-
function Card({ className, render, selected = false, ...props }) {
|
|
13
|
+
function Card({ className, render, selected = false, removePadding = false, ...props }) {
|
|
14
14
|
return useRender({
|
|
15
15
|
defaultTagName: "article",
|
|
16
|
-
props: mergeProps({ className: cn(cardVariants({ selected }), className) }, props),
|
|
16
|
+
props: mergeProps({ className: cn(cardVariants({ selected }), removePadding ? "py-0" : "", className) }, props),
|
|
17
17
|
render,
|
|
18
18
|
state: {
|
|
19
19
|
selected,
|
|
@@ -31,7 +31,7 @@ function CardTitle({ className, render, ...props }) {
|
|
|
31
31
|
function CardHeader({ className, render, ...props }) {
|
|
32
32
|
return useRender({
|
|
33
33
|
defaultTagName: "div",
|
|
34
|
-
props: mergeProps({ className: cn("flex min-w-0 flex-col gap-gdt-sm px-
|
|
34
|
+
props: mergeProps({ className: cn("flex min-w-0 flex-col gap-gdt-sm px-(--card-padding)", className) }, props),
|
|
35
35
|
render
|
|
36
36
|
});
|
|
37
37
|
}
|
|
@@ -45,14 +45,14 @@ function CardDescription({ className, render, ...props }) {
|
|
|
45
45
|
function CardContent({ className, render, ...props }) {
|
|
46
46
|
return useRender({
|
|
47
47
|
defaultTagName: "div",
|
|
48
|
-
props: mergeProps({ className: cn("min-w-0 px-
|
|
48
|
+
props: mergeProps({ className: cn("min-w-0 px-(--card-padding) text-gdt-sm text-fg-primary", className) }, props),
|
|
49
49
|
render
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
function CardFooter({ className, render, ...props }) {
|
|
53
53
|
return useRender({
|
|
54
54
|
defaultTagName: "div",
|
|
55
|
-
props: mergeProps({ className: cn("flex min-w-0
|
|
55
|
+
props: mergeProps({ className: cn("flex min-w-0 flex-wrap items-center justify-end gap-gdt-sm px-(--card-padding)", className) }, props),
|
|
56
56
|
render
|
|
57
57
|
});
|
|
58
58
|
}
|
|
@@ -61,7 +61,7 @@ function CardAction({ className, render, ...props }) {
|
|
|
61
61
|
defaultTagName: "button",
|
|
62
62
|
props: mergeProps({
|
|
63
63
|
"data-slot": "card-action",
|
|
64
|
-
className: cn("cursor-pointer focus-visible:outline-none
|
|
64
|
+
className: cn("absolute inset-0 z-10 cursor-pointer rounded-[inherit] focus-visible:outline-none", className)
|
|
65
65
|
}, props),
|
|
66
66
|
render
|
|
67
67
|
});
|
package/dist/carousel.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { t as cn } from "./cn-BI_4DMBf.js";
|
|
3
3
|
import { useComponentSize } from "./size-context.js";
|
|
4
|
+
import { t as useReducedMotion } from "./use-reduced-motion-BDvOK14x.js";
|
|
4
5
|
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
import { cva } from "class-variance-authority";
|
|
@@ -31,6 +32,7 @@ function useCarousel() {
|
|
|
31
32
|
}
|
|
32
33
|
function Carousel({ orientation = "horizontal", opts, setApi, plugins, size, imageSize, className, children, ...props }) {
|
|
33
34
|
const resolvedSize = useComponentSize(size);
|
|
35
|
+
const reducedMotion = useReducedMotion();
|
|
34
36
|
const [carouselRef, api] = useEmblaCarousel({
|
|
35
37
|
...opts,
|
|
36
38
|
axis: orientation === "horizontal" ? "x" : "y"
|
|
@@ -51,14 +53,14 @@ function Carousel({ orientation = "horizontal", opts, setApi, plugins, size, ima
|
|
|
51
53
|
onSelect(api);
|
|
52
54
|
}, [onSelect]);
|
|
53
55
|
const scrollPrev = React.useCallback(() => {
|
|
54
|
-
api?.scrollPrev();
|
|
55
|
-
}, [api]);
|
|
56
|
+
api?.scrollPrev(reducedMotion);
|
|
57
|
+
}, [api, reducedMotion]);
|
|
56
58
|
const scrollNext = React.useCallback(() => {
|
|
57
|
-
api?.scrollNext();
|
|
58
|
-
}, [api]);
|
|
59
|
+
api?.scrollNext(reducedMotion);
|
|
60
|
+
}, [api, reducedMotion]);
|
|
59
61
|
const scrollTo = React.useCallback((index) => {
|
|
60
|
-
api?.scrollTo(index);
|
|
61
|
-
}, [api]);
|
|
62
|
+
api?.scrollTo(index, reducedMotion);
|
|
63
|
+
}, [api, reducedMotion]);
|
|
62
64
|
const handleKeyDown = React.useCallback((event) => {
|
|
63
65
|
const prevKey = orientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
|
|
64
66
|
const nextKey = orientation === "horizontal" ? "ArrowRight" : "ArrowDown";
|
|
@@ -138,7 +140,7 @@ function CarouselItem({ className, ...props }) {
|
|
|
138
140
|
...props
|
|
139
141
|
});
|
|
140
142
|
}
|
|
141
|
-
const arrowVariants = cva(cn("absolute top-1/2 z-10 grid -translate-y-1/2 place-items-center rounded-full text-fg-on-brand/95 shadow-1 transition-[
|
|
143
|
+
const arrowVariants = cva(cn("absolute top-1/2 z-10 grid -translate-y-1/2 place-items-center rounded-full text-fg-on-brand/95 shadow-1 transition-[opacity,scale] duration-[var(--duration-motion-press)] ease-gdt-out outline-none", glassChrome, "focus-visible:shadow-[0px_0px_0px_2px_var(--color-line-focus)] active:scale-[0.97] motion-reduce:active:scale-100 disabled:pointer-events-none disabled:opacity-40"), {
|
|
142
144
|
variants: {
|
|
143
145
|
size: {
|
|
144
146
|
sm: "size-8 [&_svg]:size-4",
|
|
@@ -287,6 +289,7 @@ const INDICATOR_OFFSET = {
|
|
|
287
289
|
function CarouselIndicator({ className, count: countProp, selected: selectedProp, size: sizeProp, onSelect, ...props }) {
|
|
288
290
|
const ctx = React.useContext(CarouselContext);
|
|
289
291
|
const inheritedSize = useComponentSize(sizeProp);
|
|
292
|
+
const reducedMotion = useReducedMotion();
|
|
290
293
|
const size = sizeProp ?? ctx?.size ?? inheritedSize;
|
|
291
294
|
const count = countProp ?? ctx?.scrollSnaps.length ?? 0;
|
|
292
295
|
const selected = selectedProp ?? ctx?.selectedIndex ?? 0;
|
|
@@ -307,7 +310,7 @@ function CarouselIndicator({ className, count: countProp, selected: selectedProp
|
|
|
307
310
|
className: "overflow-hidden",
|
|
308
311
|
style: { width: viewportWidth },
|
|
309
312
|
children: /* @__PURE__ */ jsx("div", {
|
|
310
|
-
className: "flex items-center transition-transform duration-300 ease-out",
|
|
313
|
+
className: "flex items-center transition-transform duration-300 ease-out motion-reduce:transition-none",
|
|
311
314
|
style: {
|
|
312
315
|
gap,
|
|
313
316
|
transform: `translateX(${-start * step}px)`
|
|
@@ -325,7 +328,7 @@ function CarouselIndicator({ className, count: countProp, selected: selectedProp
|
|
|
325
328
|
width: dot,
|
|
326
329
|
height: dot,
|
|
327
330
|
opacity: faded ? .3 : isActive ? 1 : .55,
|
|
328
|
-
transform: faded ? "scale(0.6)" : "scale(1)"
|
|
331
|
+
transform: !reducedMotion && faded ? "scale(0.6)" : "scale(1)"
|
|
329
332
|
}
|
|
330
333
|
}, index);
|
|
331
334
|
})
|