@giddaa-housing/ui 3.1.0 → 3.3.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.
Files changed (69) hide show
  1. package/css/generated/shared.css +1 -1
  2. package/css/giddaa.css +12 -3
  3. package/css/theme.css +4 -1
  4. package/dist/accordion.js +3 -2
  5. package/dist/activity-timeline.js +2 -2
  6. package/dist/alert.js +4 -4
  7. package/dist/breadcrumb.js +3 -3
  8. package/dist/button.js +8 -4
  9. package/dist/calendar.js +3 -3
  10. package/dist/call-card.js +1 -1
  11. package/dist/carousel.js +3 -3
  12. package/dist/chart.js +1 -1
  13. package/dist/chat.js +1 -1
  14. package/dist/checkbox.js +2 -2
  15. package/dist/combobox.js +6 -6
  16. package/dist/cta.js +3 -3
  17. package/dist/currency-selector.d.ts +10 -8
  18. package/dist/currency-selector.js +247 -28
  19. package/dist/data-table.js +2 -2
  20. package/dist/date-picker.js +6 -6
  21. package/dist/dialog.js +2 -2
  22. package/dist/dropdown-menu.js +20 -20
  23. package/dist/dropzone.js +1 -1
  24. package/dist/editorial-card.d.ts +20 -11
  25. package/dist/editorial-card.js +67 -2
  26. package/dist/file-upload.js +1 -1
  27. package/dist/filter.js +1 -1
  28. package/dist/footer.d.ts +8 -3
  29. package/dist/footer.js +16 -5
  30. package/dist/icons.d.ts +93 -0
  31. package/dist/icons.js +905 -0
  32. package/dist/infinite-scroll.js +1 -1
  33. package/dist/input-otp.js +2 -2
  34. package/dist/kpi-card.js +1 -1
  35. package/dist/match.js +1 -1
  36. package/dist/media-gallery-hero.js +4 -4
  37. package/dist/media-player.js +59 -48
  38. package/dist/message.js +1 -1
  39. package/dist/mobile-sidebar.js +4 -4
  40. package/dist/multi-step-form.js +2 -2
  41. package/dist/number-input.js +3 -3
  42. package/dist/pagination.js +4 -4
  43. package/dist/password-input.js +1 -1
  44. package/dist/phone-input.js +4 -4
  45. package/dist/photo-gallery.js +3 -3
  46. package/dist/price-tag.js +1 -1
  47. package/dist/property-listing-card.js +1 -1
  48. package/dist/rich-text-editor.js +4 -4
  49. package/dist/scroll-spy.d.ts +61 -0
  50. package/dist/scroll-spy.js +295 -0
  51. package/dist/search-input.js +1 -1
  52. package/dist/select.js +6 -6
  53. package/dist/sheet.js +2 -2
  54. package/dist/sidebar.js +1 -1
  55. package/dist/stepper.js +2 -2
  56. package/dist/styles.css +239 -26
  57. package/dist/tabs.d.ts +13 -1
  58. package/dist/tabs.js +9 -2
  59. package/dist/tag.js +1 -1
  60. package/dist/testimonial-block.js +1 -1
  61. package/dist/theme-switcher.d.ts +31 -0
  62. package/dist/theme-switcher.js +78 -0
  63. package/dist/time-picker.js +2 -2
  64. package/dist/toast.d.ts +38 -10
  65. package/dist/toast.js +56 -52
  66. package/dist/top-navbar.js +3 -3
  67. package/dist/video-player-dialog.d.ts +57 -0
  68. package/dist/video-player-dialog.js +188 -0
  69. package/package.json +17 -2
@@ -0,0 +1,78 @@
1
+ "use client";
2
+ import { ChevronDown, Monitor, Moon, Sun } from "./icons.js";
3
+ import { t as cn } from "./cn-BI_4DMBf.js";
4
+ import { useComponentSize } from "./size-context.js";
5
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger } from "./dropdown-menu.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { cva } from "class-variance-authority";
8
+ import * as React from "react";
9
+ //#region src/theme-switcher.tsx
10
+ const themeSwitcherVariants = cva("group/theme-switcher inline-flex shrink-0 items-center justify-center rounded-full bg-action-tertiary font-bold text-fg-primary outline-none transition-[background-color,box-shadow,scale] duration-(--duration-motion-press) ease-gdt-out hover:bg-action-tertiary-hover active:scale-[0.97] active:bg-action-tertiary-pressed focus-visible:shadow-[0_0_0_2px_var(--color-line-focus)] data-popup-open:bg-action-tertiary-pressed motion-reduce:active:scale-100 [&_svg]:shrink-0", {
11
+ variants: { size: {
12
+ sm: "h-8 gap-1.5 px-3 text-gdt-xs [&_svg]:size-3.5",
13
+ md: "h-10 gap-2 px-3.5 text-gdt-sm [&_svg]:size-4",
14
+ lg: "h-12 gap-2.5 px-4.5 text-gdt-md [&_svg]:size-4.5"
15
+ } },
16
+ defaultVariants: { size: "md" }
17
+ });
18
+ const defaultThemeSwitcherOptions = [
19
+ {
20
+ value: "light",
21
+ label: "Light",
22
+ icon: /* @__PURE__ */ jsx(Sun, { "aria-hidden": "true" })
23
+ },
24
+ {
25
+ value: "dark",
26
+ label: "Dark",
27
+ icon: /* @__PURE__ */ jsx(Moon, { "aria-hidden": "true" })
28
+ },
29
+ {
30
+ value: "system",
31
+ label: "System",
32
+ icon: /* @__PURE__ */ jsx(Monitor, { "aria-hidden": "true" })
33
+ }
34
+ ];
35
+ function ThemeSwitcher({ className, size, value, defaultValue = "system", onValueChange, options = defaultThemeSwitcherOptions, showIcon = true, showLabel = true, "aria-label": ariaLabel, ...props }) {
36
+ const resolvedSize = useComponentSize(size);
37
+ const resolvedOptions = options.length ? options : defaultThemeSwitcherOptions;
38
+ const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue);
39
+ const requestedValue = value ?? uncontrolledValue;
40
+ const selectedTheme = resolvedOptions.find((option) => option.value === requestedValue) ?? resolvedOptions[0];
41
+ const selectedValue = selectedTheme.value;
42
+ function handleValueChange(nextValue) {
43
+ const nextTheme = nextValue;
44
+ if (value === void 0) setUncontrolledValue(nextTheme);
45
+ onValueChange?.(nextTheme);
46
+ }
47
+ return /* @__PURE__ */ jsxs(DropdownMenu, {
48
+ size: resolvedSize,
49
+ children: [/* @__PURE__ */ jsxs(DropdownMenuTrigger, {
50
+ "data-slot": "theme-switcher",
51
+ className: cn(themeSwitcherVariants({ size: resolvedSize }), className),
52
+ "aria-label": ariaLabel ?? (!showLabel ? `Theme: ${selectedTheme.label}` : void 0),
53
+ ...props,
54
+ children: [
55
+ showIcon && selectedTheme.icon,
56
+ showLabel && /* @__PURE__ */ jsx("span", { children: selectedTheme.label }),
57
+ /* @__PURE__ */ jsx(ChevronDown, {
58
+ "aria-hidden": "true",
59
+ className: "text-fg-secondary transition-transform duration-(--duration-motion-popup) group-data-[popup-open]/theme-switcher:rotate-180 motion-reduce:transition-none"
60
+ })
61
+ ]
62
+ }), /* @__PURE__ */ jsx(DropdownMenuContent, {
63
+ align: "end",
64
+ className: "w-auto min-w-36",
65
+ children: /* @__PURE__ */ jsx(DropdownMenuRadioGroup, {
66
+ value: selectedValue,
67
+ onValueChange: handleValueChange,
68
+ children: resolvedOptions.map(({ value: optionValue, label, icon }) => /* @__PURE__ */ jsxs(DropdownMenuRadioItem, {
69
+ value: optionValue,
70
+ closeOnClick: true,
71
+ children: [icon, label]
72
+ }, optionValue))
73
+ })
74
+ })]
75
+ });
76
+ }
77
+ //#endregion
78
+ export { ThemeSwitcher, defaultThemeSwitcherOptions, themeSwitcherVariants };
@@ -1,9 +1,9 @@
1
1
  "use client";
2
+ import { Clock } from "./icons.js";
2
3
  import { t as cn } from "./cn-BI_4DMBf.js";
3
4
  import { t as useReducedMotion } from "./use-reduced-motion-BDvOK14x.js";
4
5
  import { Popover, PopoverContent } from "./popover.js";
5
6
  import { n as PickerFooter, r as PickerTrigger, t as PICKER_COLLISION_AVOIDANCE } from "./picker-xSTzeYhc.js";
6
- import { ClockIcon } from "lucide-react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  import * as React from "react";
9
9
  //#region src/lib/time-picker-paint.ts
@@ -264,7 +264,7 @@ function TimePicker({ value, onChange, format = "12h", disabled = false, size, p
264
264
  open,
265
265
  onOpenChange: handleOpenChange,
266
266
  children: [/* @__PURE__ */ jsx(PickerTrigger, {
267
- icon: ClockIcon,
267
+ icon: Clock,
268
268
  displayValue: value ?? "",
269
269
  placeholder,
270
270
  disabled,
package/dist/toast.d.ts CHANGED
@@ -1,21 +1,49 @@
1
- import { PropsWithChildren } from "react";
2
- import { ToastManagerAddOptions, ToastManagerUpdateOptions } from "@base-ui/react/toast";
1
+ import { PropsWithChildren, ReactNode } from "react";
2
+ import { ToastManagerAddOptions, ToastManagerUpdateOptions, ToastObject } from "@base-ui/react/toast";
3
3
  //#region src/toast.d.ts
4
4
  type ToastVariant = "success" | "info" | "warning" | "error" | "loading";
5
+ type ToastRenderProps = {
6
+ /** The live toast object, including `id`, `title`, and `description`. */
7
+ toast: ToastObject<ToastData>;
8
+ /** Dismisses this toast, playing the usual exit transition. */
9
+ close: () => void;
10
+ };
5
11
  type ToastData = {
6
- type: ToastVariant;
12
+ type?: ToastVariant;
13
+ render?: (props: ToastRenderProps) => ReactNode;
14
+ className?: string;
15
+ };
16
+ /**
17
+ * Options for `toast.add`. `render` and `className` are lifted to the top level
18
+ * for convenience and stored on the toast's `data` under the hood.
19
+ */
20
+ type ToastAddOptions = Omit<ToastManagerAddOptions<ToastData>, "data"> & {
21
+ /**
22
+ * Replaces the default icon/title/description layout with your own markup.
23
+ * The toast keeps its stacking, swipe, and timeout behavior.
24
+ */
25
+ render?: (props: ToastRenderProps) => ReactNode;
26
+ /** Merged into the toast surface classes — restyle padding, width, colors. */
27
+ className?: string;
28
+ data?: ToastData;
7
29
  };
8
30
  declare const toastManager: import("@base-ui/react").ToastManager<any>;
9
- declare const toast: ((options: ToastManagerAddOptions<ToastData>) => string) & {
10
- success: (options: ToastManagerAddOptions<ToastData>) => string;
11
- info: (options: ToastManagerAddOptions<ToastData>) => string;
12
- warning: (options: ToastManagerAddOptions<ToastData>) => string;
13
- error: (options: ToastManagerAddOptions<ToastData>) => string;
14
- loading: (options: ToastManagerAddOptions<ToastData>) => string;
31
+ declare function addToast({ render, className, data, ...options }: ToastAddOptions): string;
32
+ declare const toast: ((options: ToastAddOptions) => string) & {
33
+ /**
34
+ * Adds a toast without a preset variant. Pass `render` to take over the
35
+ * toast body entirely, or just `title`/`description` for the stock layout.
36
+ */
37
+ add: typeof addToast;
38
+ success: ({ data, ...options }: ToastAddOptions) => string;
39
+ info: ({ data, ...options }: ToastAddOptions) => string;
40
+ warning: ({ data, ...options }: ToastAddOptions) => string;
41
+ error: ({ data, ...options }: ToastAddOptions) => string;
42
+ loading: ({ data, ...options }: ToastAddOptions) => string;
15
43
  dismiss: (toastId?: string | number) => void;
16
44
  update: (toastId: string | number, options: ToastManagerUpdateOptions<ToastData>) => void;
17
45
  promise: <Value, T extends any = any>(promiseValue: Promise<Value>, options: import("@base-ui/react").ToastManagerPromiseOptions<Value, T>) => Promise<Value>;
18
46
  };
19
47
  declare function ToastProvider({ children }: PropsWithChildren): import("react").JSX.Element;
20
48
  //#endregion
21
- export { ToastProvider, toast, toastManager };
49
+ export { type ToastAddOptions, type ToastData, ToastProvider, type ToastRenderProps, type ToastVariant, toast, toastManager };
package/dist/toast.js CHANGED
@@ -1,48 +1,44 @@
1
+ "use client";
2
+ import { Check, Info, X } from "./icons.js";
1
3
  import { t as cn } from "./cn-BI_4DMBf.js";
2
4
  import { Button } from "./button.js";
3
- import { Check, Info, X } from "lucide-react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  import { Toast } from "@base-ui/react/toast";
6
7
  //#region src/toast.tsx
7
8
  const DEFAULT_TOAST_SIDE = "top";
8
9
  const DEFAULT_TOAST_ALIGN = "end";
9
10
  const toastManager = Toast.createToastManager();
10
- const toast = Object.assign((options) => toastManager.add(options), {
11
- success: (options) => toastManager.add({
11
+ function addToast({ render, className, data, ...options }) {
12
+ return toastManager.add({
12
13
  ...options,
13
14
  data: {
14
- type: "success",
15
- ...options.data
15
+ ...data,
16
+ render,
17
+ className
16
18
  }
17
- }),
18
- info: (options) => toastManager.add({
19
- ...options,
20
- data: {
21
- type: "info",
22
- ...options.data
23
- }
24
- }),
25
- warning: (options) => toastManager.add({
26
- ...options,
27
- data: {
28
- type: "warning",
29
- ...options.data
30
- }
31
- }),
32
- error: (options) => toastManager.add({
33
- ...options,
34
- data: {
35
- type: "error",
36
- ...options.data
37
- }
38
- }),
39
- loading: (options) => toastManager.add({
19
+ });
20
+ }
21
+ /** Presets the variant while leaving every `toast.add` option available. */
22
+ function addVariant(type) {
23
+ return ({ data, ...options }) => addToast({
40
24
  ...options,
41
25
  data: {
42
- type: "loading",
43
- ...options.data
26
+ type,
27
+ ...data
44
28
  }
45
- }),
29
+ });
30
+ }
31
+ const toast = Object.assign((options) => addToast(options), {
32
+ /**
33
+ * Adds a toast without a preset variant. Pass `render` to take over the
34
+ * toast body entirely, or just `title`/`description` for the stock layout.
35
+ */
36
+ add: addToast,
37
+ success: addVariant("success"),
38
+ info: addVariant("info"),
39
+ warning: addVariant("warning"),
40
+ error: addVariant("error"),
41
+ loading: addVariant("loading"),
46
42
  dismiss: (toastId) => toastManager.close(toastId?.toString()),
47
43
  update: (toastId, options) => toastManager.update(toastId.toString(), options),
48
44
  promise: toastManager.promise
@@ -78,32 +74,39 @@ function ToastList() {
78
74
  stack.domIndex += 1;
79
75
  if (item.transitionStatus !== "ending") stack.visibleIndex += 1;
80
76
  placementStacks.set(placement.key, stack);
77
+ const render = item.data?.render;
81
78
  return /* @__PURE__ */ jsx(Toast.Root, {
82
79
  toast: item,
83
- className: cn(toastRootBaseClassName, getToastPositionClassName(placement), getToastStackClassName(placement), getToastExitClassName(placement.side)),
80
+ className: cn(toastRootBaseClassName, getToastPositionClassName(placement), getToastStackClassName(placement), getToastExitClassName(placement.side), item.data?.className),
84
81
  swipeDirection: getSwipeDirections(item),
85
82
  style,
86
- children: /* @__PURE__ */ jsxs(Toast.Content, {
87
- className: "grid grid-cols-[16px_minmax(0,1fr)_24px] items-start gap-3 overflow-hidden px-2.5 py-3.5 pl-3 transition-opacity duration-250 data-behind:pointer-events-none data-behind:opacity-0 data-expanded:pointer-events-auto data-expanded:opacity-100",
88
- children: [
89
- /* @__PURE__ */ jsx(ToastIcon, { type: item.data?.type }),
90
- /* @__PURE__ */ jsxs("div", {
91
- className: "min-w-0 flex flex-col gap-1.5",
92
- children: [
93
- item.title ? /* @__PURE__ */ jsx(Toast.Title, { className: "text-gdt-sm font-semibold text-fg-primary" }) : null,
94
- item.description ? /* @__PURE__ */ jsx(Toast.Description, { className: "text-gdt-sm text-fg-secondary" }) : null,
95
- /* @__PURE__ */ jsx(Toast.Action, { className: cn("cursor-pointer border-0 bg-transparent p-0 font-inherit text-gdt-sm font-semibold inline-flex w-fit items-center hover:underline underline-offset-2", item.data?.type === "success" && "text-fg-brand", item.data?.type === "info" && "text-fg-primary", item.data?.type === "warning" && "text-fg-accent", item.data?.type === "error" && "text-fg-danger") })
96
- ]
97
- }),
98
- /* @__PURE__ */ jsx(Toast.Close, {
99
- render: /* @__PURE__ */ jsx(Button, {
100
- variant: "ghost",
101
- size: "icon-xs"
83
+ children: /* @__PURE__ */ jsx(Toast.Content, {
84
+ className: toastContentClassName,
85
+ children: render ? render({
86
+ toast: item,
87
+ close: () => toastManager.close(item.id)
88
+ }) : /* @__PURE__ */ jsxs("div", {
89
+ className: "grid grid-cols-[16px_minmax(0,1fr)_24px] items-start gap-3 overflow-hidden px-2.5 py-3.5 pl-3",
90
+ children: [
91
+ /* @__PURE__ */ jsx(ToastIcon, { type: item.data?.type }),
92
+ /* @__PURE__ */ jsxs("div", {
93
+ className: "min-w-0 flex flex-col gap-1.5",
94
+ children: [
95
+ item.title ? /* @__PURE__ */ jsx(Toast.Title, { className: "text-gdt-sm font-semibold text-fg-primary" }) : null,
96
+ item.description ? /* @__PURE__ */ jsx(Toast.Description, { className: "text-gdt-sm text-fg-secondary" }) : null,
97
+ /* @__PURE__ */ jsx(Toast.Action, { className: cn("cursor-pointer border-0 bg-transparent p-0 font-inherit text-gdt-sm font-semibold inline-flex w-fit items-center hover:underline underline-offset-2", item.data?.type === "success" && "text-fg-brand", item.data?.type === "info" && "text-fg-primary", item.data?.type === "warning" && "text-fg-accent", item.data?.type === "error" && "text-fg-danger") })
98
+ ]
102
99
  }),
103
- "aria-label": "Close toast",
104
- children: /* @__PURE__ */ jsx(X, { className: "size-4" })
105
- })
106
- ]
100
+ /* @__PURE__ */ jsx(Toast.Close, {
101
+ render: /* @__PURE__ */ jsx(Button, {
102
+ variant: "ghost",
103
+ size: "icon-xs"
104
+ }),
105
+ "aria-label": "Close toast",
106
+ children: /* @__PURE__ */ jsx(X, { className: "size-4" })
107
+ })
108
+ ]
109
+ })
107
110
  })
108
111
  }, item.id);
109
112
  });
@@ -133,6 +136,7 @@ function ToastIcon({ type }) {
133
136
  ]
134
137
  });
135
138
  }
139
+ const toastContentClassName = "transition-opacity duration-250 data-behind:pointer-events-none data-behind:opacity-0 data-expanded:pointer-events-auto data-expanded:opacity-100";
136
140
  const toastRootBaseClassName = "[--gap:12px] [--peek:12px] [--anchor-x:0px] [--anchor-y:0px] [--scale:calc(max(0,1-(var(--toast-placement-index)*0.04)))] [--shrink:calc(1-var(--scale))] [--height:var(--toast-placement-frontmost-height,var(--toast-height))] absolute z-[calc(1000-var(--toast-placement-index))] h-[var(--height)] min-h-[var(--height)] w-[min(335px,calc(100vw-32px))] overflow-visible rounded-lg border border-line bg-surface-overlay text-fg-primary shadow-[var(--elevation-e2-shadow)] pointer-events-auto select-none [transform:translateX(calc(var(--anchor-x)+var(--toast-swipe-movement-x,0px)))_translateY(var(--collapsed-y))_scale(var(--scale))] [transition:transform_var(--duration-motion-surface)_var(--ease-gdt-out),opacity_var(--duration-motion-surface)_var(--ease-gdt-out)] motion-reduce:[transition:opacity_var(--duration-motion-surface)_var(--ease-gdt-out)] data-swiping:transition-none after:absolute after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:pointer-events-auto after:content-[''] data-[expanded]:h-[var(--toast-height)] data-[expanded]:[transform:translateX(calc(var(--anchor-x)+var(--toast-swipe-movement-x,0px)))_translateY(var(--expanded-y))_scale(1)] data-[starting-style]:opacity-0 data-[starting-style]:[transform:translateX(var(--exit-x))_translateY(var(--exit-y))_scale(var(--scale))] data-[ending-style]:opacity-0 data-[limited]:opacity-0 [&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateX(var(--exit-x))_translateY(var(--exit-y))_scale(var(--scale))] data-[ending-style]:data-[swipe-direction=up]:[transform:translateX(calc(var(--anchor-x)+var(--toast-swipe-movement-x,0px)))_translateY(calc(var(--anchor-y)+var(--toast-swipe-movement-y)-150%))_scale(var(--scale))] data-[expanded]:data-[ending-style]:data-[swipe-direction=up]:[transform:translateX(calc(var(--anchor-x)+var(--toast-swipe-movement-x,0px)))_translateY(calc(var(--anchor-y)+var(--toast-swipe-movement-y)-150%))_scale(1)] data-[ending-style]:data-[swipe-direction=down]:[transform:translateX(calc(var(--anchor-x)+var(--toast-swipe-movement-x,0px)))_translateY(calc(var(--anchor-y)+var(--toast-swipe-movement-y)+150%))_scale(var(--scale))] data-[expanded]:data-[ending-style]:data-[swipe-direction=down]:[transform:translateX(calc(var(--anchor-x)+var(--toast-swipe-movement-x,0px)))_translateY(calc(var(--anchor-y)+var(--toast-swipe-movement-y)+150%))_scale(1)] data-[ending-style]:data-[swipe-direction=left]:[transform:translateX(calc(var(--anchor-x)+var(--toast-swipe-movement-x,0px)-150%))_translateY(var(--expanded-y))_scale(var(--scale))] data-[expanded]:data-[ending-style]:data-[swipe-direction=left]:[transform:translateX(calc(var(--anchor-x)+var(--toast-swipe-movement-x,0px)-150%))_translateY(var(--expanded-y))_scale(1)] data-[ending-style]:data-[swipe-direction=right]:[transform:translateX(calc(var(--anchor-x)+var(--toast-swipe-movement-x,0px)+150%))_translateY(var(--expanded-y))_scale(var(--scale))] data-[expanded]:data-[ending-style]:data-[swipe-direction=right]:[transform:translateX(calc(var(--anchor-x)+var(--toast-swipe-movement-x,0px)+150%))_translateY(var(--expanded-y))_scale(1)]";
137
141
  function getToastPlacement(item, isRtl = false) {
138
142
  const side = item.positionerProps?.side ?? DEFAULT_TOAST_SIDE;
@@ -1,7 +1,7 @@
1
1
  "use client";
2
+ import { ArrowUpRight, ChevronDown } from "./icons.js";
2
3
  import { t as cn } from "./cn-BI_4DMBf.js";
3
4
  import { MobileSidebar } from "./mobile-sidebar.js";
4
- import { ArrowUpRightIcon, ChevronDownIcon } from "lucide-react";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  import { mergeProps } from "@base-ui/react/merge-props";
7
7
  import { useRender } from "@base-ui/react/use-render";
@@ -68,7 +68,7 @@ function TopNavbarTrigger({ active = false, className, children, ...props }) {
68
68
  ...props,
69
69
  children: [children, /* @__PURE__ */ jsx(NavigationMenu.Icon, {
70
70
  className: "transition-transform duration-(--duration-motion-press) ease-gdt-out data-popup-open:rotate-180 motion-reduce:transition-none",
71
- children: /* @__PURE__ */ jsx(ChevronDownIcon, {
71
+ children: /* @__PURE__ */ jsx(ChevronDown, {
72
72
  "aria-hidden": "true",
73
73
  className: "size-3.5"
74
74
  })
@@ -103,7 +103,7 @@ function TopNavbarMenuLink({ featured = false, showArrow = true, className, chil
103
103
  "data-featured": featured || void 0,
104
104
  className: cn("group/top-navbar-card grid min-h-22 grid-cols-[auto_1fr_auto] items-start gap-3 rounded-xl p-3 text-left outline-none transition-[background-color,color,box-shadow,translate] duration-(--duration-motion-press) ease-gdt-out hover:bg-surface focus-visible:bg-surface focus-visible:shadow-[0_0_0_2px_var(--color-line-focus)] active:translate-y-px motion-reduce:active:translate-y-0", featured && "bg-surface-brand-subtle", className),
105
105
  ...props,
106
- children: [children, showArrow ? /* @__PURE__ */ jsx(ArrowUpRightIcon, {
106
+ children: [children, showArrow ? /* @__PURE__ */ jsx(ArrowUpRight, {
107
107
  "aria-hidden": "true",
108
108
  className: "mt-1 size-4 text-fg-caption-placeholder transition-[color,translate] duration-(--duration-motion-press) ease-gdt-out group-hover/top-navbar-card:translate-x-0.5 group-hover/top-navbar-card:-translate-y-0.5 group-hover/top-navbar-card:text-fg-brand motion-reduce:transition-colors"
109
109
  }) : null]
@@ -0,0 +1,57 @@
1
+ import { Dialog, DialogContent, DialogDescription, DialogTitle, DialogTrigger } from "./dialog.js";
2
+ import * as React from "react";
3
+ //#region src/video-player-dialog.d.ts
4
+ type VideoPlayerDialogTheme = "light" | "dark";
5
+ type VideoPlayerDialogSize = "sm" | "md" | "lg";
6
+ declare const videoPlayerDialogSurfaceVariants: (props?: ({
7
+ size?: "lg" | "md" | "sm" | null | undefined;
8
+ theme?: "dark" | "light" | null | undefined;
9
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
10
+ type VideoPlayerDialogProps = React.ComponentProps<typeof Dialog>;
11
+ /** Accessible modal root. Product state and media behavior remain consumer-owned. */
12
+ declare function VideoPlayerDialog(props: VideoPlayerDialogProps): React.JSX.Element;
13
+ type VideoPlayerDialogTriggerProps = React.ComponentProps<typeof DialogTrigger>;
14
+ declare function VideoPlayerDialogTrigger(props: VideoPlayerDialogTriggerProps): React.JSX.Element;
15
+ interface VideoPlayerDialogContentProps extends Omit<React.ComponentProps<typeof DialogContent>, "size"> {
16
+ size?: VideoPlayerDialogSize;
17
+ theme?: VideoPlayerDialogTheme;
18
+ surfaceClassName?: string;
19
+ }
20
+ /**
21
+ * Translation-free centered popup with one large, viewport-bounded scroll
22
+ * surface. The close button remains outside the scrolling surface.
23
+ */
24
+ declare function VideoPlayerDialogContent({ size, theme, showCloseButton, className, surfaceClassName, children, ...props }: VideoPlayerDialogContentProps): React.JSX.Element;
25
+ type VideoPlayerDialogMediaProps = React.ComponentProps<"div">;
26
+ /**
27
+ * Aspect-ratio media slot. Compose any `MediaPlayer*` primitives inside; this
28
+ * part only owns placement and clipping, never playback behavior or controls.
29
+ */
30
+ declare function VideoPlayerDialogMedia({ className, ...props }: VideoPlayerDialogMediaProps): React.JSX.Element;
31
+ type VideoPlayerDialogDetailsProps = React.ComponentProps<"div">;
32
+ declare function VideoPlayerDialogDetails({ className, ...props }: VideoPlayerDialogDetailsProps): React.JSX.Element;
33
+ type VideoPlayerDialogTitleProps = React.ComponentProps<typeof DialogTitle>;
34
+ declare function VideoPlayerDialogTitle({ className, ...props }: VideoPlayerDialogTitleProps): React.JSX.Element;
35
+ type VideoPlayerDialogDescriptionProps = React.ComponentProps<typeof DialogDescription>;
36
+ declare function VideoPlayerDialogDescription({ className, ...props }: VideoPlayerDialogDescriptionProps): React.JSX.Element;
37
+ interface VideoPlayerDialogPlaylistIndicatorProps extends React.ComponentProps<"span"> {
38
+ current: number;
39
+ total: number;
40
+ }
41
+ declare function VideoPlayerDialogPlaylistIndicator({ current, total, className, ...props }: VideoPlayerDialogPlaylistIndicatorProps): React.JSX.Element;
42
+ type VideoPlayerDialogPlaylistProps = React.ComponentProps<"section">;
43
+ declare function VideoPlayerDialogPlaylist({ className, ...props }: VideoPlayerDialogPlaylistProps): React.JSX.Element;
44
+ type VideoPlayerDialogPlaylistHeaderProps = React.ComponentProps<"h3">;
45
+ declare function VideoPlayerDialogPlaylistHeader({ className, ...props }: VideoPlayerDialogPlaylistHeaderProps): React.JSX.Element;
46
+ type VideoPlayerDialogPlaylistListProps = React.ComponentProps<"ul">;
47
+ declare function VideoPlayerDialogPlaylistList({ className, ...props }: VideoPlayerDialogPlaylistListProps): React.JSX.Element;
48
+ interface VideoPlayerDialogPlaylistItemProps extends Omit<React.ComponentProps<"button">, "title"> {
49
+ active?: boolean;
50
+ index?: number;
51
+ poster?: string;
52
+ title: React.ReactNode;
53
+ duration?: React.ReactNode;
54
+ }
55
+ declare function VideoPlayerDialogPlaylistItem({ active, index, poster, title, duration, className, ...props }: VideoPlayerDialogPlaylistItemProps): React.JSX.Element;
56
+ //#endregion
57
+ export { VideoPlayerDialog, VideoPlayerDialogContent, type VideoPlayerDialogContentProps, VideoPlayerDialogDescription, type VideoPlayerDialogDescriptionProps, VideoPlayerDialogDetails, type VideoPlayerDialogDetailsProps, VideoPlayerDialogMedia, type VideoPlayerDialogMediaProps, VideoPlayerDialogPlaylist, VideoPlayerDialogPlaylistHeader, type VideoPlayerDialogPlaylistHeaderProps, VideoPlayerDialogPlaylistIndicator, type VideoPlayerDialogPlaylistIndicatorProps, VideoPlayerDialogPlaylistItem, type VideoPlayerDialogPlaylistItemProps, VideoPlayerDialogPlaylistList, type VideoPlayerDialogPlaylistListProps, type VideoPlayerDialogPlaylistProps, type VideoPlayerDialogProps, type VideoPlayerDialogSize, type VideoPlayerDialogTheme, VideoPlayerDialogTitle, type VideoPlayerDialogTitleProps, VideoPlayerDialogTrigger, type VideoPlayerDialogTriggerProps, videoPlayerDialogSurfaceVariants };
@@ -0,0 +1,188 @@
1
+ "use client";
2
+ import { ListVideo } from "./icons.js";
3
+ import { t as cn } from "./cn-BI_4DMBf.js";
4
+ import { Dialog, DialogContent, DialogDescription, DialogTitle, DialogTrigger } from "./dialog.js";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { cva } from "class-variance-authority";
7
+ import * as React from "react";
8
+ //#region src/video-player-dialog.tsx
9
+ const WIDTHS = {
10
+ sm: "max-w-[584px]",
11
+ md: "max-w-[752px]",
12
+ lg: "max-w-[920px]"
13
+ };
14
+ const videoPlayerDialogSurfaceVariants = cva("group/video-dialog w-full border bg-surface-overlay shadow-[0_0_8px_2px_rgb(23_48_22/0.06)]", {
15
+ variants: {
16
+ size: {
17
+ sm: "rounded-[14px]",
18
+ md: "rounded-2xl",
19
+ lg: "rounded-[20px]"
20
+ },
21
+ theme: {
22
+ light: "border-line-subtle",
23
+ dark: "dark border-transparent bg-[#2c3329] text-[#ecf2ea]"
24
+ }
25
+ },
26
+ defaultVariants: {
27
+ size: "md",
28
+ theme: "light"
29
+ }
30
+ });
31
+ const VideoPlayerDialogContext = React.createContext(null);
32
+ function useVideoPlayerDialogContext() {
33
+ const context = React.useContext(VideoPlayerDialogContext);
34
+ if (!context) throw new Error("VideoPlayerDialog parts must be rendered inside <VideoPlayerDialogContent>.");
35
+ return context;
36
+ }
37
+ /** Accessible modal root. Product state and media behavior remain consumer-owned. */
38
+ function VideoPlayerDialog(props) {
39
+ return /* @__PURE__ */ jsx(Dialog, { ...props });
40
+ }
41
+ function VideoPlayerDialogTrigger(props) {
42
+ return /* @__PURE__ */ jsx(DialogTrigger, { ...props });
43
+ }
44
+ /**
45
+ * Translation-free centered popup with one large, viewport-bounded scroll
46
+ * surface. The close button remains outside the scrolling surface.
47
+ */
48
+ function VideoPlayerDialogContent({ size = "md", theme = "light", showCloseButton = true, className, surfaceClassName, children, ...props }) {
49
+ const context = React.useMemo(() => ({
50
+ size,
51
+ theme
52
+ }), [size, theme]);
53
+ return /* @__PURE__ */ jsx(DialogContent, {
54
+ showCloseButton,
55
+ "data-size": size,
56
+ "data-slot": "video-player-dialog-content",
57
+ "data-theme": theme,
58
+ className: cn("inset-0 m-auto h-fit max-h-none translate-x-0 translate-y-0 gap-0 overflow-visible border-0 bg-transparent p-0 shadow-none sm:w-full [--dialog-padding:0px]", WIDTHS[size], className),
59
+ ...props,
60
+ children: /* @__PURE__ */ jsx(VideoPlayerDialogContext.Provider, {
61
+ value: context,
62
+ children: /* @__PURE__ */ jsx("div", {
63
+ "data-slot": "video-player-dialog-surface",
64
+ className: cn("max-h-[calc(100dvh-4rem)] overflow-y-auto overscroll-contain", videoPlayerDialogSurfaceVariants({
65
+ size,
66
+ theme
67
+ }), surfaceClassName),
68
+ children
69
+ })
70
+ })
71
+ });
72
+ }
73
+ /**
74
+ * Aspect-ratio media slot. Compose any `MediaPlayer*` primitives inside; this
75
+ * part only owns placement and clipping, never playback behavior or controls.
76
+ */
77
+ function VideoPlayerDialogMedia({ className, ...props }) {
78
+ return /* @__PURE__ */ jsx("div", {
79
+ "data-slot": "video-player-dialog-media",
80
+ className: cn("relative isolate aspect-video w-full overflow-hidden rounded-t-[inherit] bg-[#11160f]", "[&>[data-slot=media-player]]:size-full [&>[data-slot=media-player]]:rounded-none [&>[data-slot=media-player]]:shadow-none", className),
81
+ ...props
82
+ });
83
+ }
84
+ function VideoPlayerDialogDetails({ className, ...props }) {
85
+ const { size } = useVideoPlayerDialogContext();
86
+ return /* @__PURE__ */ jsx("div", {
87
+ "data-slot": "video-player-dialog-details",
88
+ className: cn("flex flex-col", size === "sm" ? "gap-1 p-3" : size === "lg" ? "gap-1.5 px-5 pt-[18px] pb-5" : "gap-1 px-4 pt-3.5 pb-4", className),
89
+ ...props
90
+ });
91
+ }
92
+ function VideoPlayerDialogTitle({ className, ...props }) {
93
+ const { size } = useVideoPlayerDialogContext();
94
+ return /* @__PURE__ */ jsx(DialogTitle, {
95
+ "data-slot": "video-player-dialog-title",
96
+ className: cn("text-fg-primary", size === "sm" ? "text-gdt-lg font-bold" : size === "lg" ? "text-gdt-h4 font-extrabold" : "text-gdt-h5 font-extrabold", className),
97
+ ...props
98
+ });
99
+ }
100
+ function VideoPlayerDialogDescription({ className, ...props }) {
101
+ const { size } = useVideoPlayerDialogContext();
102
+ return /* @__PURE__ */ jsx(DialogDescription, {
103
+ "data-slot": "video-player-dialog-description",
104
+ className: cn("text-fg-secondary", size === "sm" ? "text-gdt-xs" : size === "lg" ? "text-gdt-md" : "text-gdt-sm", className),
105
+ ...props
106
+ });
107
+ }
108
+ function VideoPlayerDialogPlaylistIndicator({ current, total, className, ...props }) {
109
+ return /* @__PURE__ */ jsxs("span", {
110
+ "data-slot": "video-player-dialog-playlist-indicator",
111
+ className: cn("pointer-events-none absolute top-3 right-3 z-20 inline-flex h-9 items-center gap-2 rounded-full bg-black/40 px-3 text-gdt-xs font-bold whitespace-nowrap text-white shadow-[0_0_4px_rgb(0_0_0/0.1)] backdrop-blur-[15px]", className),
112
+ ...props,
113
+ children: [
114
+ /* @__PURE__ */ jsx(ListVideo, {
115
+ "aria-hidden": "true",
116
+ className: "size-4"
117
+ }),
118
+ /* @__PURE__ */ jsxs("span", {
119
+ "aria-hidden": "true",
120
+ children: [
121
+ current,
122
+ " / ",
123
+ total
124
+ ]
125
+ }),
126
+ /* @__PURE__ */ jsxs("span", {
127
+ className: "sr-only",
128
+ children: [
129
+ "Video ",
130
+ current,
131
+ " of ",
132
+ total
133
+ ]
134
+ })
135
+ ]
136
+ });
137
+ }
138
+ function VideoPlayerDialogPlaylist({ className, ...props }) {
139
+ return /* @__PURE__ */ jsx("section", {
140
+ "data-slot": "video-player-dialog-playlist",
141
+ className: cn("border-t border-line-subtle px-3 py-3 sm:px-4", className),
142
+ ...props
143
+ });
144
+ }
145
+ function VideoPlayerDialogPlaylistHeader({ className, ...props }) {
146
+ return /* @__PURE__ */ jsx("h3", {
147
+ "data-slot": "video-player-dialog-playlist-header",
148
+ className: cn("mb-2 px-2 text-gdt-xs font-semibold text-fg-secondary", className),
149
+ ...props
150
+ });
151
+ }
152
+ function VideoPlayerDialogPlaylistList({ className, ...props }) {
153
+ return /* @__PURE__ */ jsx("ul", {
154
+ "data-slot": "video-player-dialog-playlist-list",
155
+ className: cn("space-y-1", className),
156
+ ...props
157
+ });
158
+ }
159
+ function VideoPlayerDialogPlaylistItem({ active = false, index, poster, title, duration, className, ...props }) {
160
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("button", {
161
+ type: "button",
162
+ "aria-current": active ? "true" : void 0,
163
+ "data-slot": "video-player-dialog-playlist-item",
164
+ className: cn("flex w-full items-center gap-3 rounded-lg p-2 text-left outline-none transition-[background-color,transform] hover:bg-surface-raised focus-visible:ring-2 focus-visible:ring-line-focus active:scale-[0.99] aria-current:bg-surface-brand-subtle", className),
165
+ ...props,
166
+ children: [
167
+ index !== void 0 ? /* @__PURE__ */ jsx("span", {
168
+ className: "w-5 shrink-0 text-center text-gdt-xs font-semibold text-fg-caption-placeholder",
169
+ children: index
170
+ }) : null,
171
+ poster ? /* @__PURE__ */ jsx("img", {
172
+ src: poster,
173
+ alt: "",
174
+ className: "aspect-video w-20 shrink-0 rounded-md object-cover"
175
+ }) : null,
176
+ /* @__PURE__ */ jsx("span", {
177
+ className: "min-w-0 flex-1 truncate text-gdt-sm font-bold text-fg-primary",
178
+ children: title
179
+ }),
180
+ duration ? /* @__PURE__ */ jsx("span", {
181
+ className: "shrink-0 text-gdt-xs tabular-nums text-fg-secondary",
182
+ children: duration
183
+ }) : null
184
+ ]
185
+ }) });
186
+ }
187
+ //#endregion
188
+ export { VideoPlayerDialog, VideoPlayerDialogContent, VideoPlayerDialogDescription, VideoPlayerDialogDetails, VideoPlayerDialogMedia, VideoPlayerDialogPlaylist, VideoPlayerDialogPlaylistHeader, VideoPlayerDialogPlaylistIndicator, VideoPlayerDialogPlaylistItem, VideoPlayerDialogPlaylistList, VideoPlayerDialogTitle, VideoPlayerDialogTrigger, videoPlayerDialogSurfaceVariants };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@giddaa-housing/ui",
3
- "version": "3.1.0",
3
+ "version": "3.3.0",
4
4
  "description": "Giddaa reusable UI component library.",
5
5
  "type": "module",
6
6
  "private": false,
@@ -165,6 +165,10 @@
165
165
  "types": "./dist/heatmap-chart.d.ts",
166
166
  "import": "./dist/heatmap-chart.js"
167
167
  },
168
+ "./icons": {
169
+ "types": "./dist/icons.d.ts",
170
+ "import": "./dist/icons.js"
171
+ },
168
172
  "./infotip": {
169
173
  "types": "./dist/infotip.d.ts",
170
174
  "import": "./dist/infotip.js"
@@ -229,6 +233,10 @@
229
233
  "types": "./dist/media-player.d.ts",
230
234
  "import": "./dist/media-player.js"
231
235
  },
236
+ "./video-player-dialog": {
237
+ "types": "./dist/video-player-dialog.d.ts",
238
+ "import": "./dist/video-player-dialog.js"
239
+ },
232
240
  "./message": {
233
241
  "types": "./dist/message.d.ts",
234
242
  "import": "./dist/message.js"
@@ -309,6 +317,10 @@
309
317
  "types": "./dist/scatter-chart.d.ts",
310
318
  "import": "./dist/scatter-chart.js"
311
319
  },
320
+ "./scroll-spy": {
321
+ "types": "./dist/scroll-spy.d.ts",
322
+ "import": "./dist/scroll-spy.js"
323
+ },
312
324
  "./search-input": {
313
325
  "types": "./dist/search-input.d.ts",
314
326
  "import": "./dist/search-input.js"
@@ -377,6 +389,10 @@
377
389
  "types": "./dist/testimonial-block.d.ts",
378
390
  "import": "./dist/testimonial-block.js"
379
391
  },
392
+ "./theme-switcher": {
393
+ "types": "./dist/theme-switcher.d.ts",
394
+ "import": "./dist/theme-switcher.js"
395
+ },
380
396
  "./time-picker": {
381
397
  "types": "./dist/time-picker.d.ts",
382
398
  "import": "./dist/time-picker.js"
@@ -423,7 +439,6 @@
423
439
  "clsx": "^2.1.1",
424
440
  "embla-carousel-react": "^8.6.0",
425
441
  "libphonenumber-js": "^1.12.43",
426
- "lucide-react": "^0.545.0",
427
442
  "media-chrome": "^4.19.2",
428
443
  "react-day-picker": "^9.14.0",
429
444
  "react-phone-number-input": "^3.4.16",