@giddaa-housing/ui 3.6.0 → 3.7.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/theme.css CHANGED
@@ -283,20 +283,23 @@
283
283
  }
284
284
  }
285
285
 
286
- /* Drives `Sonar`. Spread rather than `transform: scale()` on purpose: spread
287
- grows the ring by the same number of pixels on every side and traces the
288
- element's own border-radius, so one keyframe fits a 8px dot and a wide
289
- button alike. Scaling would expand a wide element far more horizontally
290
- than vertically which is why sonar-glow above needs its per-axis
291
- --sonar-glow-scale-x/y knobs. */
286
+ /* Drives `Sonar`. Transform and opacity only, because they are the two
287
+ properties a browser can animate on the compositor: this grew the ring's
288
+ box-shadow spread instead until it turned out to repaint the ring and resize
289
+ its layer on every frame, which iOS Safari visibly stutters and flashes
290
+ through. The ring is now painted once at its full spread — still tracing the
291
+ element's own border-radius, still growing by the same number of pixels on
292
+ every side — and scaled back to the child's edge to start from. Per-axis,
293
+ like sonar-glow above, so a wide element's ring doesn't travel further
294
+ sideways than vertically; `sonar.tsx` measures the child and sets the two. */
292
295
  @keyframes sonar-wave {
293
296
  from {
294
- box-shadow: 0 0 0 0 currentColor;
297
+ transform: scale(var(--sonar-scale-x, 0.5), var(--sonar-scale-y, 0.5));
295
298
  opacity: 0.55;
296
299
  }
297
300
 
298
301
  to {
299
- box-shadow: 0 0 0 var(--sonar-spread, 0.625rem) currentColor;
302
+ transform: scale(1, 1);
300
303
  opacity: 0;
301
304
  }
302
305
  }
package/dist/calendar.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { ChevronLeft, ChevronRight } from "./icons.js";
3
3
  import { cn } from "./utils/cn.js";
4
4
  import { Button } from "./button.js";
5
- import { _ as ComboboxValue, d as ComboboxInput, f as ComboboxItem, g as ComboboxTrigger, m as ComboboxList, o as ComboboxContent, s as ComboboxEmpty, t as Combobox } from "./combobox-CACVdp1R.js";
5
+ import { _ as ComboboxValue, d as ComboboxInput, f as ComboboxItem, g as ComboboxTrigger, m as ComboboxList, o as ComboboxContent, s as ComboboxEmpty, t as Combobox } from "./combobox-D70DFHoM.js";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  import * as React from "react";
8
8
  import { DayPicker, getDefaultClassNames } from "react-day-picker";
@@ -121,6 +121,16 @@ const comboboxContentBodyVariants = cva("flex min-h-0 flex-1 flex-col overflow-h
121
121
  } },
122
122
  defaultVariants: { size: "md" }
123
123
  });
124
+ const comboboxEdgeSizes = {
125
+ sm: "px-4",
126
+ md: "px-5.5",
127
+ lg: "px-6"
128
+ };
129
+ const comboboxLabelSizes = {
130
+ sm: "px-3",
131
+ md: "px-4",
132
+ lg: "px-4"
133
+ };
124
134
  const comboboxItemVariants = cva("group/combobox-item relative flex w-full cursor-pointer items-center font-normal text-fg-primary outline-none select-none data-highlighted:bg-surface data-disabled:pointer-events-none data-disabled:text-fg-caption-placeholder [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
125
135
  variants: { size: {
126
136
  sm: "gap-1.5 rounded-md px-3 py-1.5 text-gdt-xs",
@@ -239,18 +249,20 @@ function ComboboxContent({ className, side = "bottom", sideOffset = 6, align = "
239
249
  }) });
240
250
  }
241
251
  function ComboboxHeader({ className, type = "button", ...props }) {
252
+ const resolvedSize = useComponentSize();
242
253
  return /* @__PURE__ */ jsx("button", {
243
254
  type,
244
255
  "data-slot": "combobox-header",
245
- className: cn("relative z-20 flex min-h-9 w-full shrink-0 cursor-pointer items-center gap-2 rounded-none rounded-t-[inherit] border-line-subtle border-b bg-canvas px-3 py-2 text-left text-gdt-sm font-bold text-fg-brand outline-none transition-colors hover:bg-surface-brand-subtle focus-visible:bg-surface-brand-subtle focus-visible:inset-ring-2 focus-visible:inset-ring-line-focus active:bg-surface-brand-subtle disabled:pointer-events-none disabled:text-fg-caption-placeholder", "[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", className),
256
+ className: cn("relative z-20 flex min-h-9 w-full shrink-0 cursor-pointer items-center gap-2 rounded-none rounded-t-[inherit] border-line-subtle border-b bg-canvas py-2 text-left text-gdt-sm font-bold text-fg-brand outline-none transition-colors hover:bg-surface-brand-subtle focus-visible:bg-surface-brand-subtle focus-visible:inset-ring-2 focus-visible:inset-ring-line-focus active:bg-surface-brand-subtle disabled:pointer-events-none disabled:text-fg-caption-placeholder", "[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", comboboxEdgeSizes[resolvedSize], className),
246
257
  ...props
247
258
  });
248
259
  }
249
260
  function ComboboxFooter({ className, type = "button", ...props }) {
261
+ const resolvedSize = useComponentSize();
250
262
  return /* @__PURE__ */ jsx("button", {
251
263
  type,
252
264
  "data-slot": "combobox-footer",
253
- className: cn("relative z-20 flex min-h-9 w-full shrink-0 cursor-pointer items-center gap-2 rounded-none rounded-b-[inherit] border-line-subtle border-t bg-canvas px-3 py-2 text-left text-gdt-sm font-semibold text-fg-secondary outline-none transition-colors hover:bg-surface focus-visible:bg-surface focus-visible:inset-ring-2 focus-visible:inset-ring-line-focus active:bg-surface-raised disabled:pointer-events-none disabled:text-fg-caption-placeholder", "[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", className),
265
+ className: cn("relative z-20 flex min-h-9 w-full shrink-0 cursor-pointer items-center gap-2 rounded-none rounded-b-[inherit] border-line-subtle border-t bg-canvas py-2 text-left text-gdt-sm font-semibold text-fg-secondary outline-none transition-colors hover:bg-surface focus-visible:bg-surface focus-visible:inset-ring-2 focus-visible:inset-ring-line-focus active:bg-surface-raised disabled:pointer-events-none disabled:text-fg-caption-placeholder", "[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", comboboxEdgeSizes[resolvedSize], className),
254
266
  ...props
255
267
  });
256
268
  }
@@ -286,9 +298,10 @@ function ComboboxGroup({ className, ...props }) {
286
298
  });
287
299
  }
288
300
  function ComboboxLabel({ className, ...props }) {
301
+ const resolvedSize = useComponentSize();
289
302
  return /* @__PURE__ */ jsx(Combobox.GroupLabel, {
290
303
  "data-slot": "combobox-label",
291
- className: cn("px-3 py-1 text-gdt-xs text-fg-secondary", className),
304
+ className: cn("py-1 text-gdt-xs text-fg-secondary", comboboxLabelSizes[resolvedSize], className),
292
305
  ...props
293
306
  });
294
307
  }
package/dist/combobox.js CHANGED
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import { _ as ComboboxValue, a as ComboboxCollection, b as useComboboxVirtualizer, c as ComboboxFooter, d as ComboboxInput, f as ComboboxItem, g as ComboboxTrigger, h as ComboboxSeparator, i as ComboboxChipsInput, l as ComboboxGroup, m as ComboboxList, n as ComboboxChip, o as ComboboxContent, p as ComboboxLabel, r as ComboboxChips, s as ComboboxEmpty, t as Combobox, u as ComboboxHeader, v as ComboboxVirtualizedList, y as useComboboxAnchor } from "./combobox-CACVdp1R.js";
2
+ import { _ as ComboboxValue, a as ComboboxCollection, b as useComboboxVirtualizer, c as ComboboxFooter, d as ComboboxInput, f as ComboboxItem, g as ComboboxTrigger, h as ComboboxSeparator, i as ComboboxChipsInput, l as ComboboxGroup, m as ComboboxList, n as ComboboxChip, o as ComboboxContent, p as ComboboxLabel, r as ComboboxChips, s as ComboboxEmpty, t as Combobox, u as ComboboxHeader, v as ComboboxVirtualizedList, y as useComboboxAnchor } from "./combobox-D70DFHoM.js";
3
3
  export { Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxFooter, ComboboxGroup, ComboboxHeader, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxSeparator, ComboboxTrigger, ComboboxValue, ComboboxVirtualizedList, useComboboxAnchor, useComboboxVirtualizer };
package/dist/dialog.d.ts CHANGED
@@ -4,7 +4,7 @@ import { Dialog as Dialog$1 } from "@base-ui/react/dialog";
4
4
  //#region src/dialog.d.ts
5
5
  declare function Dialog({ ...props }: Dialog$1.Root.Props): React.JSX.Element;
6
6
  declare function DialogTrigger({ ...props }: Dialog$1.Trigger.Props): React.JSX.Element;
7
- declare function DialogPortal({ ...props }: Dialog$1.Portal.Props): React.JSX.Element;
7
+ declare function DialogPortal({ className, ...props }: Dialog$1.Portal.Props): React.JSX.Element;
8
8
  declare function DialogClose({ ...props }: Dialog$1.Close.Props): React.JSX.Element;
9
9
  declare function DialogOverlay({ className, ...props }: Dialog$1.Backdrop.Props): React.JSX.Element;
10
10
  declare const dialogContentVariants: (props?: ({
@@ -16,10 +16,12 @@ declare const dialogIconVariants: (props?: ({
16
16
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
17
17
  type DialogContentProps = Dialog$1.Popup.Props & VariantProps<typeof dialogContentVariants> & {
18
18
  showCloseButton?: boolean;
19
+ /** Controls the visual response when this surface participates in a nested dialog stack. */
20
+ nestingEffect?: "stack" | "none";
19
21
  /** @internal Positions specialized popup shells without changing the surface. */
20
22
  popupClassName?: string;
21
23
  };
22
- declare function DialogContent({ className, children, size, showCloseButton, popupClassName, ...props }: DialogContentProps): React.JSX.Element;
24
+ declare function DialogContent({ className, children, size, showCloseButton, nestingEffect, popupClassName, ...props }: DialogContentProps): React.JSX.Element;
23
25
  declare function DialogIcon({ className, size, tone, ...props }: React.ComponentProps<"div"> & VariantProps<typeof dialogIconVariants>): React.JSX.Element;
24
26
  declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
25
27
  declare function DialogFooter({ className, showCloseButton, children, ...props }: React.ComponentProps<"div"> & {
package/dist/dialog.js CHANGED
@@ -3,16 +3,15 @@ import { X } from "./icons.js";
3
3
  import { cn } from "./utils/cn.js";
4
4
  import { SizeProvider, useComponentSize } from "./size-context.js";
5
5
  import { Button } from "./button.js";
6
- import { DialogNestingProvider, useDialogNestingDepth } from "./dialog-nesting.js";
7
6
  import { jsx, jsxs } from "react/jsx-runtime";
8
7
  import { cva } from "class-variance-authority";
9
8
  import { Dialog as Dialog$1 } from "@base-ui/react/dialog";
10
9
  //#region src/dialog.tsx
11
10
  function Dialog({ ...props }) {
12
- return /* @__PURE__ */ jsx(DialogNestingProvider, { children: /* @__PURE__ */ jsx(Dialog$1.Root, {
11
+ return /* @__PURE__ */ jsx(Dialog$1.Root, {
13
12
  "data-slot": "dialog",
14
13
  ...props
15
- }) });
14
+ });
16
15
  }
17
16
  function DialogTrigger({ ...props }) {
18
17
  return /* @__PURE__ */ jsx(Dialog$1.Trigger, {
@@ -20,9 +19,10 @@ function DialogTrigger({ ...props }) {
20
19
  ...props
21
20
  });
22
21
  }
23
- function DialogPortal({ ...props }) {
22
+ function DialogPortal({ className, ...props }) {
24
23
  return /* @__PURE__ */ jsx(Dialog$1.Portal, {
25
24
  "data-slot": "dialog-portal",
25
+ className: (state) => cn("group/dialog-portal", typeof className === "function" ? className(state) : className),
26
26
  ...props
27
27
  });
28
28
  }
@@ -33,16 +33,14 @@ function DialogClose({ ...props }) {
33
33
  });
34
34
  }
35
35
  function DialogOverlay({ className, ...props }) {
36
- const nested = useDialogNestingDepth() > 1;
37
36
  return /* @__PURE__ */ jsx(Dialog$1.Backdrop, {
38
37
  forceRender: true,
39
38
  "data-slot": "dialog-overlay",
40
- "data-nested": nested || void 0,
41
- className: cn("fixed inset-0 z-50 transition-opacity duration-150 ease-gdt-out data-closed:opacity-0 data-open:opacity-100", nested ? "bg-black/25" : "bg-black/55 supports-backdrop-filter:backdrop-blur-xl", className),
39
+ className: cn("fixed inset-0 z-50 bg-black/55 transition-opacity duration-150 ease-gdt-out data-closed:opacity-0 data-open:opacity-100 supports-backdrop-filter:backdrop-blur-xl group-has-[>.is-nested-dialog]/dialog-portal:bg-black/25 supports-backdrop-filter:group-has-[>.is-nested-dialog]/dialog-portal:backdrop-blur-none", className),
42
40
  ...props
43
41
  });
44
42
  }
45
- const dialogContentVariants = cva("group/dialog-content pointer-events-none fixed top-1/2 left-1/2 z-50 w-full max-w-[calc(100vw-2rem)] -translate-x-1/2 -translate-y-1/2 overflow-visible outline-none [--dialog-padding:1.25rem] origin-center transition-[opacity,scale] duration-[var(--duration-motion-popup)] ease-gdt-out data-starting-style:opacity-0 data-starting-style:scale-95 data-ending-style:opacity-0 data-ending-style:scale-95 motion-reduce:data-starting-style:scale-100 motion-reduce:data-ending-style:scale-100 data-[nested-dialog-open]:scale-[0.96]", {
43
+ const dialogContentVariants = cva("group/dialog-content pointer-events-none fixed top-1/2 left-1/2 z-50 w-full max-w-[calc(100vw-2rem)] -translate-x-1/2 -translate-y-1/2 overflow-visible outline-none [--dialog-padding:1.25rem] origin-center transition-[opacity,scale] duration-[var(--duration-motion-popup)] ease-gdt-out data-starting-style:opacity-0 data-starting-style:scale-95 data-ending-style:opacity-0 data-ending-style:scale-95 motion-reduce:data-starting-style:scale-100 motion-reduce:data-ending-style:scale-100", {
46
44
  variants: { size: {
47
45
  sm: "sm:w-90 sm:[--dialog-padding:1.5rem]",
48
46
  md: "sm:w-105 sm:[--dialog-padding:1.5rem]",
@@ -69,14 +67,15 @@ const dialogIconVariants = cva("flex shrink-0 items-center justify-center [&_svg
69
67
  tone: "brand"
70
68
  }
71
69
  });
72
- function DialogContent({ className, children, size, showCloseButton = true, popupClassName, ...props }) {
70
+ function DialogContent({ className, children, size, showCloseButton = true, nestingEffect = "stack", popupClassName, ...props }) {
73
71
  const resolvedSize = useComponentSize(size);
74
72
  return /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsx(SizeProvider, {
75
73
  size: resolvedSize,
76
74
  children: /* @__PURE__ */ jsxs(Dialog$1.Popup, {
77
75
  "data-slot": "dialog-content",
78
76
  "data-size": resolvedSize,
79
- className: cn(dialogContentVariants({ size: resolvedSize }), popupClassName),
77
+ "data-nesting-effect": nestingEffect,
78
+ className: (state) => cn(dialogContentVariants({ size: resolvedSize }), nestingEffect === "stack" && state.nested && "is-nested-dialog", nestingEffect === "stack" && "data-[nested-dialog-open]:scale-[0.96]", popupClassName),
80
79
  ...props,
81
80
  children: [/* @__PURE__ */ jsx("div", {
82
81
  "data-slot": "dialog-surface",
@@ -86,7 +85,7 @@ function DialogContent({ className, children, size, showCloseButton = true, popu
86
85
  "data-slot": "dialog-close",
87
86
  render: /* @__PURE__ */ jsxs(Button, {
88
87
  variant: "tertiary",
89
- className: "pointer-events-auto absolute -top-10 right-0 z-10 group-data-[nested-dialog-open]/dialog-content:hidden",
88
+ className: cn("pointer-events-auto absolute -top-10 right-0 z-10", nestingEffect === "stack" && "group-data-[nested-dialog-open]/dialog-content:hidden"),
90
89
  size: "icon-sm",
91
90
  children: [/* @__PURE__ */ jsx(X, {}), /* @__PURE__ */ jsx("span", {
92
91
  className: "sr-only",
package/dist/infotip.js CHANGED
@@ -11,7 +11,6 @@ function Infotip({ ...props }) {
11
11
  }
12
12
  function InfotipTrigger({ ...props }) {
13
13
  return /* @__PURE__ */ jsx(Popover.Trigger, {
14
- nativeButton: false,
15
14
  "data-slot": "infotip-trigger",
16
15
  openOnHover: true,
17
16
  delay: 100,
@@ -80,12 +80,12 @@ function InputGroupAddon({ className, align = "inline-start", ...props }) {
80
80
  ...props
81
81
  });
82
82
  }
83
- const inputGroupButtonVariants = cva("flex items-center gap-2 text-sm shadow-none rounded-full", {
83
+ const inputGroupButtonVariants = cva("flex items-center gap-2 shadow-none rounded-full", {
84
84
  variants: { size: {
85
- xs: "h-6 gap-1 px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
86
- sm: "",
87
- "icon-xs": "size-6 p-0 has-[>svg]:p-0",
88
- "icon-sm": "size-8 p-0 has-[>svg]:p-0"
85
+ xs: "h-6 gap-1 px-1.5 text-gdt-xs [&_svg:not([class*='size-'])]:size-3.5",
86
+ sm: "text-gdt-sm",
87
+ "icon-xs": "size-6 min-w-0 gap-0 p-0 text-gdt-xs has-[>svg]:p-0 [&_svg:not([class*='size-'])]:size-3.5",
88
+ "icon-sm": "size-8 min-w-0 gap-0 p-0 text-gdt-sm has-[>svg]:p-0 [&_svg:not([class*='size-'])]:size-4"
89
89
  } },
90
90
  defaultVariants: { size: "xs" }
91
91
  });
package/dist/match.d.ts CHANGED
@@ -7,12 +7,21 @@ declare const matchVariants: (props?: ({
7
7
  size?: "lg" | "md" | "sm" | null | undefined;
8
8
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
9
9
  type MatchVariant = NonNullable<VariantProps<typeof matchVariants>["variant"]>;
10
- type MatchProps = Omit<React.ComponentProps<"button">, "children" | "value"> & Omit<VariantProps<typeof matchVariants>, "size"> & {
10
+ type MatchProps = Omit<React.HTMLAttributes<HTMLElement>, "children"> & Omit<VariantProps<typeof matchVariants>, "size"> & {
11
11
  value: number;
12
12
  size?: ComponentSizeValue;
13
13
  label?: string;
14
14
  showChevron?: boolean;
15
+ /**
16
+ * Forces the read-only presentation on (`true`) or off (`false`). Left
17
+ * unset, a `Match` is read-only unless it is given an `onClick` — a score
18
+ * with nothing behind it should not read as a control.
19
+ */
20
+ readOnly?: boolean;
21
+ disabled?: boolean;
22
+ type?: "button" | "submit" | "reset";
23
+ ref?: React.Ref<HTMLElement>;
15
24
  };
16
- declare function Match({ className, value, variant, size, label, showChevron, type, "aria-label": ariaLabel, ...props }: MatchProps): React.JSX.Element;
25
+ declare function Match({ className, value, variant, size, label, showChevron, readOnly, type, disabled, onClick, ref, "aria-label": ariaLabel, ...props }: MatchProps): React.JSX.Element;
17
26
  //#endregion
18
27
  export { Match, type MatchProps, type MatchVariant, matchVariants };
package/dist/match.js CHANGED
@@ -3,7 +3,7 @@ import { ChevronDown } from "./icons.js";
3
3
  import { cn } from "./utils/cn.js";
4
4
  import { resolveResponsiveComponentSize, useComponentSizeValue } from "./size-context.js";
5
5
  import { CircularProgress } from "./progress.js";
6
- import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
7
  import { cva } from "class-variance-authority";
8
8
  //#region src/match.tsx
9
9
  const matchVariants = cva("inline-flex w-fit shrink-0 items-center rounded-full border border-line-subtle bg-surface text-fg-primary shadow-none transition-[background-color,border-color,box-shadow] outline-none focus-visible:border-line-focus focus-visible:shadow-[0px_0px_0px_2px_var(--color-line-focus)] disabled:pointer-events-none disabled:opacity-60", {
@@ -83,54 +83,71 @@ function normalizeMatchValue(value) {
83
83
  if (!Number.isFinite(value)) return 0;
84
84
  return Math.min(100, Math.max(0, Math.round(value)));
85
85
  }
86
- function Match({ className, value, variant = "bar", size, label = "Match", showChevron = true, type = "button", "aria-label": ariaLabel, ...props }) {
86
+ function Match({ className, value, variant = "bar", size, label = "Match", showChevron, readOnly, type = "button", disabled, onClick, ref, "aria-label": ariaLabel, ...props }) {
87
87
  const sizeValue = useComponentSizeValue(size);
88
88
  const resolvedSizes = resolveResponsiveComponentSize(sizeValue);
89
89
  const responsive = typeof sizeValue !== "string";
90
90
  const resolvedVariant = variant ?? "bar";
91
91
  const progress = normalizeMatchValue(value);
92
92
  const text = `${progress}% ${label}`;
93
+ const interactive = readOnly === void 0 ? onClick !== void 0 : !readOnly;
94
+ const chevron = showChevron ?? interactive;
93
95
  const rootSizeClasses = cn(matchVariants({
94
96
  variant: resolvedVariant,
95
97
  size: resolvedSizes.base
96
98
  }), responsive && matchBreakpointClasses(resolvedVariant, "md", resolvedSizes.md), responsive && matchBreakpointClasses(resolvedVariant, "lg", resolvedSizes.lg));
97
- return /* @__PURE__ */ jsxs("button", {
98
- type,
99
+ const rootProps = {
99
100
  "aria-label": ariaLabel ?? text,
100
101
  "data-slot": "match",
101
102
  "data-variant": resolvedVariant,
102
103
  "data-size": resolvedSizes.base,
103
104
  "data-size-md": responsive ? resolvedSizes.md : void 0,
104
105
  "data-size-lg": responsive ? resolvedSizes.lg : void 0,
105
- className: cn(rootSizeClasses, className),
106
+ className: cn(rootSizeClasses, className)
107
+ };
108
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
109
+ resolvedVariant === "donut" ? /* @__PURE__ */ jsx(MatchDonut, {
110
+ progress,
111
+ sizes: resolvedSizes,
112
+ responsive
113
+ }) : null,
114
+ /* @__PURE__ */ jsx("span", {
115
+ "data-slot": "match-label",
116
+ className: "shrink-0 font-bold",
117
+ children: text
118
+ }),
119
+ resolvedVariant === "bar" ? /* @__PURE__ */ jsx("span", {
120
+ "aria-hidden": "true",
121
+ "data-slot": "match-bar-track",
122
+ className: cn("relative shrink-0 overflow-hidden rounded-full bg-surface-raised", matchBarSizes[resolvedSizes.base], responsive && responsiveClass("md", matchBarSizes[resolvedSizes.md]), responsive && responsiveClass("lg", matchBarSizes[resolvedSizes.lg])),
123
+ children: /* @__PURE__ */ jsx("span", {
124
+ "data-slot": "match-bar-fill",
125
+ className: "absolute inset-y-0 left-0 rounded-full bg-action-primary",
126
+ style: { width: `${progress}%` }
127
+ })
128
+ }) : null,
129
+ chevron ? /* @__PURE__ */ jsx(ChevronDown, {
130
+ "aria-hidden": "true",
131
+ "data-slot": "match-chevron",
132
+ className: cn("shrink-0 text-fg-secondary", matchChevronSizes[resolvedSizes.base], responsive && responsiveClass("md", matchChevronSizes[resolvedSizes.md]), responsive && responsiveClass("lg", matchChevronSizes[resolvedSizes.lg]))
133
+ }) : null
134
+ ] });
135
+ if (!interactive) return /* @__PURE__ */ jsx("span", {
136
+ ...rootProps,
137
+ "data-readonly": "true",
138
+ role: "img",
139
+ ref,
140
+ ...props,
141
+ children: content
142
+ });
143
+ return /* @__PURE__ */ jsx("button", {
144
+ ...rootProps,
145
+ type,
146
+ disabled,
147
+ onClick,
148
+ ref,
106
149
  ...props,
107
- children: [
108
- resolvedVariant === "donut" ? /* @__PURE__ */ jsx(MatchDonut, {
109
- progress,
110
- sizes: resolvedSizes,
111
- responsive
112
- }) : null,
113
- /* @__PURE__ */ jsx("span", {
114
- "data-slot": "match-label",
115
- className: "shrink-0 font-bold",
116
- children: text
117
- }),
118
- resolvedVariant === "bar" ? /* @__PURE__ */ jsx("span", {
119
- "aria-hidden": "true",
120
- "data-slot": "match-bar-track",
121
- className: cn("relative shrink-0 overflow-hidden rounded-full bg-surface-raised", matchBarSizes[resolvedSizes.base], responsive && responsiveClass("md", matchBarSizes[resolvedSizes.md]), responsive && responsiveClass("lg", matchBarSizes[resolvedSizes.lg])),
122
- children: /* @__PURE__ */ jsx("span", {
123
- "data-slot": "match-bar-fill",
124
- className: "absolute inset-y-0 left-0 rounded-full bg-action-primary",
125
- style: { width: `${progress}%` }
126
- })
127
- }) : null,
128
- showChevron ? /* @__PURE__ */ jsx(ChevronDown, {
129
- "aria-hidden": "true",
130
- "data-slot": "match-chevron",
131
- className: cn("shrink-0 text-fg-secondary", matchChevronSizes[resolvedSizes.base], responsive && responsiveClass("md", matchChevronSizes[resolvedSizes.md]), responsive && responsiveClass("lg", matchChevronSizes[resolvedSizes.lg]))
132
- }) : null
133
- ]
150
+ children: content
134
151
  });
135
152
  }
136
153
  const responsiveSizeClasses = {
@@ -171,7 +171,7 @@ function MediaPlayerRoot({ audio, children, className, onBlurCapture, onFocusCap
171
171
  "data-slot": "media-player",
172
172
  role: "region",
173
173
  tabIndex: 0,
174
- className: cn("group/media-player relative isolate block w-full overflow-hidden rounded-2xl bg-fg-primary text-fg-on-brand shadow-2 outline-none", "data-[controls=hidden]:cursor-none", "data-[audio]:bg-[image:var(--gradient-accent-forest-to-brass)]", "data-[fullscreen]:rounded-none data-[fullscreen]:shadow-none", className),
174
+ className: cn("group/media-player relative isolate block w-full overflow-hidden rounded-2xl bg-fg-primary text-fg-on-brand shadow-2 outline-none [transform:translateZ(0)]", "data-[controls=hidden]:cursor-none", "data-[audio]:bg-[image:var(--gradient-accent-forest-to-brass)]", "data-[fullscreen]:rounded-none data-[fullscreen]:shadow-none", className),
175
175
  ...props,
176
176
  onBlurCapture: (event) => {
177
177
  onBlurCapture?.(event);
@@ -264,7 +264,7 @@ function MediaPlayerVideo({ className, ref, ...props }) {
264
264
  setRef(ref, node);
265
265
  }, [ref]),
266
266
  "data-slot": "media-player-video",
267
- className: cn("block aspect-video size-full rounded-[inherit] object-cover", "group-data-[fullscreen]/media-player:aspect-auto group-data-[fullscreen]/media-player:object-contain", className),
267
+ className: cn("block aspect-video size-full object-cover", "group-data-[fullscreen]/media-player:aspect-auto group-data-[fullscreen]/media-player:object-contain", className),
268
268
  playsInline: true,
269
269
  ...props
270
270
  });
@@ -891,7 +891,7 @@ function MediaPlayerError({ children, className, ...props }) {
891
891
  return /* @__PURE__ */ jsx("div", {
892
892
  "data-slot": "media-player-error",
893
893
  role: "alert",
894
- className: cn("absolute inset-0 z-20 flex flex-col items-center justify-center gap-1 rounded-[inherit] bg-canvas/85 px-6 text-center text-fg-primary backdrop-blur-sm", className),
894
+ className: cn("absolute inset-0 z-20 flex flex-col items-center justify-center gap-1 bg-canvas px-6 text-center text-fg-primary", className),
895
895
  ...props,
896
896
  children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
897
897
  /* @__PURE__ */ jsx(TriangleAlert, {
@@ -27,8 +27,8 @@ function MobileSidebarContent({ className, showCloseButton = false, ...props })
27
27
  side: "right",
28
28
  size: "sm",
29
29
  showCloseButton,
30
- popupClassName: "h-dvh w-[min(100vw,24.375rem)]",
31
- className: cn("h-dvh w-[min(100vw,24.375rem)] rounded-none border-y-0 border-r-0 bg-canvas [--sheet-padding-x:1.25rem] [--sheet-padding-top:0.8125rem]", className),
30
+ popupClassName: "h-dvh w-full max-w-[24.375rem]",
31
+ className: cn("h-dvh w-full rounded-none border-y-0 border-r-0 bg-canvas [--sheet-padding-x:1.25rem] [--sheet-padding-top:0.8125rem]", className),
32
32
  ...props
33
33
  });
34
34
  }
@@ -81,7 +81,7 @@ function MobileSidebarNav({ className, ...props }) {
81
81
  function MobileSidebarList({ className, ...props }) {
82
82
  return /* @__PURE__ */ jsx("ul", {
83
83
  "data-slot": "mobile-sidebar-list",
84
- className: cn("flex flex-col", className),
84
+ className: cn("-mx-4 flex flex-col gap-1", className),
85
85
  ...props
86
86
  });
87
87
  }
@@ -97,7 +97,7 @@ function MobileSidebarLink({ active = false, icon, className, children, render,
97
97
  defaultTagName: "a",
98
98
  props: mergeProps({
99
99
  "aria-current": active ? "page" : void 0,
100
- className: cn("group/mobile-sidebar-link grid min-h-11 w-full grid-cols-1 items-center rounded-xl px-2 py-2.5 text-left text-gdt-md font-semibold text-fg-primary outline-none transition-colors hover:bg-surface focus-visible:shadow-[0_0_0_2px_var(--color-line-focus)]", active && "bg-surface-brand-subtle text-fg-brand", className),
100
+ className: cn("group/mobile-sidebar-link grid min-h-11 w-full grid-cols-1 items-center rounded-xl px-4 py-2.5 text-left text-gdt-md font-semibold text-fg-primary outline-none transition-colors hover:bg-surface focus-visible:shadow-[0_0_0_2px_var(--color-line-focus)]", active && "bg-surface-brand-subtle text-fg-brand hover:bg-surface-brand-subtle", className),
101
101
  children: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("span", {
102
102
  className: cn("grid min-w-0 items-center", icon ? "grid-cols-[1.25rem_minmax(0,1fr)] gap-3" : "grid-cols-1"),
103
103
  children: [icon ? /* @__PURE__ */ jsx("span", {
@@ -127,7 +127,7 @@ function MobileSidebarGroupTrigger({ active = false, icon, className, children,
127
127
  return /* @__PURE__ */ jsxs(CollapsibleTrigger, {
128
128
  "data-slot": "mobile-sidebar-group-trigger",
129
129
  "data-active": active || void 0,
130
- className: cn("grid min-h-11 w-full grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-xl px-2 py-2.5 text-left text-gdt-md font-semibold text-fg-primary outline-none transition-colors hover:bg-surface focus-visible:shadow-[0_0_0_2px_var(--color-line-focus)]", active && "bg-surface-brand-subtle text-fg-brand", className),
130
+ className: cn("grid min-h-11 w-full grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-xl px-4 py-2.5 text-left text-gdt-md font-semibold text-fg-primary outline-none transition-colors hover:bg-surface focus-visible:shadow-[0_0_0_2px_var(--color-line-focus)]", active && "bg-surface-brand-subtle text-fg-brand hover:bg-surface-brand-subtle", className),
131
131
  ...props,
132
132
  children: [/* @__PURE__ */ jsxs("span", {
133
133
  className: cn("grid min-w-0 items-center", icon ? "grid-cols-[1.25rem_minmax(0,1fr)] gap-3" : "grid-cols-1"),
@@ -154,7 +154,7 @@ function MobileSidebarGroupPanel({ className, ...props }) {
154
154
  function MobileSidebarSubList({ className, ...props }) {
155
155
  return /* @__PURE__ */ jsx("ul", {
156
156
  "data-slot": "mobile-sidebar-sub-list",
157
- className: cn("ml-8 flex flex-col pb-1", className),
157
+ className: cn("ml-8 flex flex-col gap-0.5 pb-2 pt-1", className),
158
158
  ...props
159
159
  });
160
160
  }
@@ -168,7 +168,7 @@ function MobileSidebarSubheading({ className, ...props }) {
168
168
  function MobileSidebarSubLink({ className, render, ...props }) {
169
169
  return useRender({
170
170
  defaultTagName: "a",
171
- props: mergeProps({ className: cn("block rounded-lg px-2 py-1.5 text-gdt-sm font-medium text-fg-secondary outline-none transition-colors hover:bg-surface hover:text-fg-primary focus-visible:shadow-[0_0_0_2px_var(--color-line-focus)]", className) }, props),
171
+ props: mergeProps({ className: cn("block rounded-lg px-4 py-1.5 text-gdt-sm font-medium text-fg-secondary outline-none transition-colors hover:bg-surface hover:text-fg-primary focus-visible:shadow-[0_0_0_2px_var(--color-line-focus)]", className) }, props),
172
172
  render,
173
173
  state: { slot: "mobile-sidebar-sub-link" }
174
174
  });
@@ -3,19 +3,36 @@ import * as React from "react";
3
3
  import { CountryCode } from "libphonenumber-js";
4
4
  //#region src/phone-input.d.ts
5
5
  interface PhoneInputProps {
6
+ /** Controlled E.164 value, e.g. `"+2348012345678"`. */
6
7
  value?: string;
7
8
  onChange?: (value: string | undefined) => void;
9
+ /** Country the field starts on, before anything is typed. */
8
10
  defaultCountry?: CountryCode;
9
11
  size?: ComponentSizeValue;
10
12
  disabled?: boolean;
11
13
  readOnly?: boolean;
12
14
  placeholder?: string;
15
+ /**
16
+ * Content pinned to the trailing edge of the field — a validity tick, a
17
+ * "Verify" button, an extension. It sits outside the number, so it never
18
+ * shifts as the number is formatted.
19
+ */
20
+ rightAddon?: React.ReactNode;
13
21
  className?: string;
14
22
  id?: string;
15
23
  name?: string;
16
24
  ref?: React.Ref<HTMLInputElement>;
17
25
  "aria-invalid"?: boolean;
18
26
  }
19
- declare function PhoneInput({ value, onChange, defaultCountry, size, disabled, readOnly, placeholder, className, id, name, ref, "aria-invalid": ariaInvalid }: PhoneInputProps): React.JSX.Element;
27
+ /**
28
+ * A phone field that takes a number written either way round.
29
+ *
30
+ * `0801 234 5678` and `+234 801 234 5678` are the same number, and both are
31
+ * accepted here: typing or pasting a leading `+` switches the field to
32
+ * international entry and moves the country selector to match, while a plain
33
+ * national number is read against the selected country, trunk prefix and all.
34
+ * `onChange` receives E.164 in both cases.
35
+ */
36
+ declare function PhoneInput({ value, onChange, defaultCountry, size, disabled, readOnly, placeholder, rightAddon, className, id, name, ref, "aria-invalid": ariaInvalid }: PhoneInputProps): React.JSX.Element;
20
37
  //#endregion
21
38
  export { type CountryCode, PhoneInput, type PhoneInputProps };