@waveso/ui 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -182,7 +182,7 @@ Browse every component, with live variants and source, in **Storybook** (`npm ru
182
182
  |---|---|
183
183
  | React | ^19.0.0 |
184
184
  | React DOM | ^19.0.0 |
185
- | Base UI | ^1.5.0 |
185
+ | Base UI | ^1.6.0 |
186
186
  | Tailwind CSS | v4 |
187
187
  | CVA | ^0.7.0 |
188
188
  | clsx | ^2.0.0 |
package/dist/badge.d.ts CHANGED
@@ -5,7 +5,7 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
5
5
 
6
6
  //#region src/badge.d.ts
7
7
  declare const badgeVariants: (props?: ({
8
- variant?: "default" | "destructive" | "link" | "outline" | "success" | "warning" | "secondary" | "ghost" | null | undefined;
8
+ variant?: "default" | "outline" | "secondary" | "ghost" | "success" | "destructive" | "link" | "warning" | null | undefined;
9
9
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
10
10
  type BadgeProps = useRender.ComponentProps<"span"> & VariantProps<typeof badgeVariants>;
11
11
  declare function Badge({
package/dist/button.d.ts CHANGED
@@ -6,8 +6,8 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
6
6
 
7
7
  //#region src/button.d.ts
8
8
  declare const buttonVariants: (props?: ({
9
- variant?: "default" | "destructive" | "link" | "outline" | "success" | "secondary" | "ghost" | null | undefined;
10
- size?: "default" | "sm" | "lg" | "icon" | "xs" | "xl" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
9
+ variant?: "default" | "outline" | "secondary" | "ghost" | "success" | "destructive" | "link" | null | undefined;
10
+ size?: "default" | "xs" | "sm" | "lg" | "xl" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
11
11
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
12
12
  type ButtonProps = React.ComponentProps<typeof Button$1> & VariantProps<typeof buttonVariants>;
13
13
  declare function Button({
@@ -1 +1 @@
1
- {"version":3,"file":"combobox.d.ts","names":[],"sources":["../src/combobox.tsx"],"mappings":"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"}
1
+ {"version":3,"file":"combobox.d.ts","names":[],"sources":["../src/combobox.tsx"],"mappings":"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"}
package/dist/combobox.js CHANGED
@@ -30,6 +30,7 @@ function ComboboxTrigger({ className, children, ...props }) {
30
30
  function ComboboxClear({ className, ...props }) {
31
31
  return /* @__PURE__ */ jsx(Combobox$1.Clear, {
32
32
  "data-slot": "combobox-clear",
33
+ "aria-label": "Clear",
33
34
  render: /* @__PURE__ */ jsx(InputGroupButton, {
34
35
  variant: "ghost",
35
36
  size: "icon-xs"
@@ -39,7 +40,7 @@ function ComboboxClear({ className, ...props }) {
39
40
  children: /* @__PURE__ */ jsx(CloseIcon, { className: "pointer-events-none" })
40
41
  });
41
42
  }
42
- function ComboboxInput({ className, children, disabled = false, showTrigger = true, showClear = false, ...props }) {
43
+ function ComboboxInput({ className, children, disabled, showTrigger = true, showClear = false, ...props }) {
43
44
  return /* @__PURE__ */ jsxs(Combobox$1.InputGroup, {
44
45
  render: /* @__PURE__ */ jsx(InputGroup, { className: cn(className) }),
45
46
  children: [
@@ -168,6 +169,7 @@ function ComboboxChip({ className, children, showRemove = true, ...props }) {
168
169
  }),
169
170
  className: "-ml-1 opacity-50 hover:opacity-100",
170
171
  "data-slot": "combobox-chip-remove",
172
+ "aria-label": "Remove",
171
173
  children: /* @__PURE__ */ jsx(CloseIcon, { className: "pointer-events-none" })
172
174
  }) : null]
173
175
  });
@@ -1 +1 @@
1
- {"version":3,"file":"combobox.js","names":["ComboboxPrimitive"],"sources":["../src/combobox.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Combobox as ComboboxPrimitive } from \"@base-ui/react/combobox\"\n\nimport { cn } from \"./lib/utils\"\nimport { Button } from \"./button\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n} from \"./input-group\"\nimport { ChevronDownIcon, CloseIcon, CheckIcon } from \"./lib/internal-icons\"\n\ntype ComboboxProps = React.ComponentProps<typeof ComboboxPrimitive.Root>\n\ntype ComboboxValueProps = React.ComponentProps<typeof ComboboxPrimitive.Value>\ntype ComboboxTriggerProps = React.ComponentProps<typeof ComboboxPrimitive.Trigger>\ntype ComboboxClearProps = React.ComponentProps<typeof ComboboxPrimitive.Clear>\ntype ComboboxInputProps = React.ComponentProps<typeof ComboboxPrimitive.Input>\n\ntype ComboboxPortalProps = React.ComponentProps<typeof ComboboxPrimitive.Portal>\ntype ComboboxPositionerProps = React.ComponentProps<typeof ComboboxPrimitive.Positioner>\ntype ComboboxPopupProps = React.ComponentProps<typeof ComboboxPrimitive.Popup>\n\ntype ComboboxListProps = React.ComponentProps<typeof ComboboxPrimitive.List>\ntype ComboboxItemProps = React.ComponentProps<typeof ComboboxPrimitive.Item>\ntype ComboboxGroupProps = React.ComponentProps<typeof ComboboxPrimitive.Group>\ntype ComboboxLabelProps = React.ComponentProps<typeof ComboboxPrimitive.GroupLabel>\ntype ComboboxCollectionProps = React.ComponentProps<typeof ComboboxPrimitive.Collection>\ntype ComboboxEmptyProps = React.ComponentProps<typeof ComboboxPrimitive.Empty>\ntype ComboboxSeparatorProps = React.ComponentProps<typeof ComboboxPrimitive.Separator>\ntype ComboboxChipsProps = React.ComponentProps<typeof ComboboxPrimitive.Chips>\ntype ComboboxChipProps = React.ComponentProps<typeof ComboboxPrimitive.Chip>\ntype ComboboxChipsInputProps = React.ComponentProps<typeof ComboboxPrimitive.Input>\n\ntype ComboboxInputWrapperProps = ComboboxInputProps & {\n showTrigger?: boolean\n showClear?: boolean\n}\n\ntype ComboboxChipWrapperProps = ComboboxChipProps & {\n showRemove?: boolean\n}\n\ntype ComboboxContentProps = ComboboxPopupProps &\n Pick<\n ComboboxPositionerProps,\n \"side\" | \"align\" | \"sideOffset\" | \"alignOffset\" | \"anchor\"\n >\n\nfunction Combobox({ ...props }: ComboboxProps) {\n return <ComboboxPrimitive.Root data-slot=\"combobox\" {...props} />\n}\n\nfunction ComboboxValue({ ...props }: ComboboxValueProps) {\n return <ComboboxPrimitive.Value data-slot=\"combobox-value\" {...props} />\n}\n\nfunction ComboboxTrigger({ className, children, ...props }: ComboboxTriggerProps) {\n return (\n <ComboboxPrimitive.Trigger\n data-slot=\"combobox-trigger\"\n className={cn(\n \"[&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronDownIcon\n className=\"text-muted pointer-events-none size-4\"\n />\n </ComboboxPrimitive.Trigger>\n )\n}\n\nfunction ComboboxClear({ className, ...props }: ComboboxClearProps) {\n return (\n <ComboboxPrimitive.Clear\n data-slot=\"combobox-clear\"\n render={<InputGroupButton variant=\"ghost\" size=\"icon-xs\" />}\n className={cn(\"motion-scale-sm\", className)}\n {...props}\n >\n <CloseIcon\n className=\"pointer-events-none\"\n />\n </ComboboxPrimitive.Clear>\n )\n}\n\nfunction ComboboxInput({\n className,\n children,\n disabled = false,\n showTrigger = true,\n showClear = false,\n ...props\n}: ComboboxInputWrapperProps) {\n return (\n <ComboboxPrimitive.InputGroup render={<InputGroup className={cn(className)} />}>\n <ComboboxPrimitive.Input render={<InputGroupInput disabled={disabled} />} {...props} />\n <InputGroupAddon align=\"inline-end\">\n {/* Stack the trigger chevron and clear button in one cell so they\n * cross-fade. In single-select mode Base UI mounts the Clear only\n * when a value is *selected* (not while typing), and marks it with\n * a persistent `data-visible` attribute. The chevron keys its\n * fade-out (opacity/blur/scale via `motion-scale-sm`) off that exact\n * attribute, so chevron→clear cross-fades in place. */}\n <div className=\"relative grid size-6 *:[grid-area:1/1]\">\n {showTrigger ? (\n <InputGroupButton\n size=\"icon-xs\"\n variant=\"ghost\"\n nativeButton\n render={<ComboboxTrigger />}\n data-slot=\"input-group-button\"\n className={cn(\n \"motion-scale-sm data-pressed:bg-transparent\",\n \"group-has-[[data-slot=combobox-clear][data-visible]]/input-group:pointer-events-none\",\n \"group-has-[[data-slot=combobox-clear][data-visible]]/input-group:opacity-0\",\n \"group-has-[[data-slot=combobox-clear][data-visible]]/input-group:[filter:blur(var(--blur-sm))]\",\n \"group-has-[[data-slot=combobox-clear][data-visible]]/input-group:scale-[var(--scale-sm)]\",\n )}\n disabled={disabled}\n />\n ) : null}\n {showClear ? <ComboboxClear disabled={disabled} /> : null}\n </div>\n </InputGroupAddon>\n {children}\n </ComboboxPrimitive.InputGroup>\n )\n}\n\nfunction ComboboxPortal({ ...props }: ComboboxPortalProps) {\n return <ComboboxPrimitive.Portal data-slot=\"combobox-portal\" {...props} />\n}\n\nfunction ComboboxPositioner({ className, ...props }: ComboboxPositionerProps) {\n return (\n <ComboboxPrimitive.Positioner\n data-slot=\"combobox-positioner\"\n className={className}\n {...props}\n />\n )\n}\n\nfunction ComboboxContent({\n className,\n side = \"bottom\",\n sideOffset = 6,\n align = \"start\",\n alignOffset = 0,\n anchor,\n ...props\n}: ComboboxContentProps) {\n return (\n <ComboboxPortal>\n <ComboboxPositioner\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n anchor={anchor}\n className=\"isolate z-50\"\n >\n <ComboboxPrimitive.Popup\n data-slot=\"combobox-content\"\n className={cn(\n \"motion-pop-md bg-elevated text-contrast ring-contrast/10 *:data-[slot=input-group]:bg-edge/30 *:data-[slot=input-group]:border-edge/30 group/combobox-content relative max-h-(--available-height) max-w-(--available-width) min-w-(--anchor-width) origin-(--transform-origin) overflow-hidden rounded-md shadow-md ring-1 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:shadow-none\",\n className,\n )}\n {...props}\n />\n </ComboboxPositioner>\n </ComboboxPortal>\n )\n}\n\nfunction ComboboxList({ className, ...props }: ComboboxListProps) {\n return (\n <ComboboxPrimitive.List\n data-slot=\"combobox-list\"\n className={cn(\n \"[scrollbar-width:none] [&::-webkit-scrollbar]:hidden max-h-[min(calc(--spacing(72)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto overscroll-contain p-1 data-empty:p-0\",\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction ComboboxItem({ className, children, ...props }: ComboboxItemProps) {\n return (\n <ComboboxPrimitive.Item\n data-slot=\"combobox-item\"\n className={cn(\n \"data-highlighted:bg-primary data-highlighted:text-white not-data-[variant=destructive]:data-highlighted:**:text-white relative flex w-full cursor-clickable items-center gap-2 rounded-sm py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n {children}\n <ComboboxPrimitive.ItemIndicator\n render={\n <span data-slot=\"combobox-item-indicator\" className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\" />\n }\n >\n <CheckIcon\n className=\"pointer-events-none\"\n />\n </ComboboxPrimitive.ItemIndicator>\n </ComboboxPrimitive.Item>\n )\n}\n\nfunction ComboboxGroup({ className, ...props }: ComboboxGroupProps) {\n return (\n <ComboboxPrimitive.Group\n data-slot=\"combobox-group\"\n className={cn(className)}\n {...props}\n />\n )\n}\n\nfunction ComboboxLabel({ className, ...props }: ComboboxLabelProps) {\n return (\n <ComboboxPrimitive.GroupLabel\n data-slot=\"combobox-label\"\n className={cn(\"text-muted px-2 py-1.5 text-xs\", className)}\n {...props}\n />\n )\n}\n\nfunction ComboboxCollection({ ...props }: ComboboxCollectionProps) {\n return <ComboboxPrimitive.Collection data-slot=\"combobox-collection\" {...props} />\n}\n\nfunction ComboboxEmpty({ className, ...props }: ComboboxEmptyProps) {\n return (\n <ComboboxPrimitive.Empty\n data-slot=\"combobox-empty\"\n className={cn(\n \"text-muted hidden w-full justify-center py-2 text-center text-sm group-data-empty/combobox-content:flex\",\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction ComboboxSeparator({ className, ...props }: ComboboxSeparatorProps) {\n return (\n <ComboboxPrimitive.Separator\n data-slot=\"combobox-separator\"\n className={cn(\"bg-line -mx-1 my-1 h-px\", className)}\n {...props}\n />\n )\n}\n\nfunction ComboboxChips({ className, ...props }: ComboboxChipsProps) {\n return (\n <ComboboxPrimitive.Chips\n data-slot=\"combobox-chips\"\n className={cn(\n \"dark:bg-edge/30 border-edge focus-within:border-focus focus-within:ring-focus/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive dark:has-aria-invalid:border-destructive/50 flex min-h-8 flex-wrap items-center gap-1 rounded-md border bg-transparent bg-clip-padding px-2.5 py-1 text-sm transition-colors focus-within:ring-3 has-aria-invalid:ring-3 has-data-[slot=combobox-chip]:px-1\",\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction ComboboxChip({\n className,\n children,\n showRemove = true,\n ...props\n}: ComboboxChipWrapperProps) {\n return (\n <ComboboxPrimitive.Chip\n data-slot=\"combobox-chip\"\n className={cn(\n \"bg-secondary text-contrast flex h-[calc(--spacing(5.25))] w-fit items-center justify-center gap-1 rounded-sm px-1.5 text-xs font-medium whitespace-nowrap has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pr-0\",\n className,\n )}\n {...props}\n >\n {children}\n {showRemove ? (\n <ComboboxPrimitive.ChipRemove\n render={<Button variant=\"ghost\" size=\"icon-xs\" />}\n className=\"-ml-1 opacity-50 hover:opacity-100\"\n data-slot=\"combobox-chip-remove\"\n >\n <CloseIcon\n className=\"pointer-events-none\"\n />\n </ComboboxPrimitive.ChipRemove>\n ) : null}\n </ComboboxPrimitive.Chip>\n )\n}\n\nfunction ComboboxChipsInput({ className, ...props }: ComboboxChipsInputProps) {\n return (\n <ComboboxPrimitive.Input\n data-slot=\"combobox-chip-input\"\n className={cn(\"min-w-16 flex-1 outline-none\", className)}\n {...props}\n />\n )\n}\n\nfunction useComboboxAnchor() {\n return React.useRef<HTMLDivElement | null>(null)\n}\n\nexport {\n Combobox,\n ComboboxInput,\n ComboboxContent,\n ComboboxList,\n ComboboxItem,\n ComboboxGroup,\n ComboboxLabel,\n ComboboxCollection,\n ComboboxEmpty,\n ComboboxSeparator,\n ComboboxChips,\n ComboboxChip,\n ComboboxChipsInput,\n ComboboxTrigger,\n ComboboxValue,\n ComboboxClear,\n useComboboxAnchor,\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"combobox.js","names":["ComboboxPrimitive"],"sources":["../src/combobox.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Combobox as ComboboxPrimitive } from \"@base-ui/react/combobox\"\n\nimport { cn } from \"./lib/utils\"\nimport { Button } from \"./button\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n} from \"./input-group\"\nimport { ChevronDownIcon, CloseIcon, CheckIcon } from \"./lib/internal-icons\"\n\ntype ComboboxProps = React.ComponentProps<typeof ComboboxPrimitive.Root>\n\ntype ComboboxValueProps = React.ComponentProps<typeof ComboboxPrimitive.Value>\ntype ComboboxTriggerProps = React.ComponentProps<typeof ComboboxPrimitive.Trigger>\ntype ComboboxClearProps = React.ComponentProps<typeof ComboboxPrimitive.Clear>\ntype ComboboxInputProps = React.ComponentProps<typeof ComboboxPrimitive.Input>\n\ntype ComboboxPortalProps = React.ComponentProps<typeof ComboboxPrimitive.Portal>\ntype ComboboxPositionerProps = React.ComponentProps<typeof ComboboxPrimitive.Positioner>\ntype ComboboxPopupProps = React.ComponentProps<typeof ComboboxPrimitive.Popup>\n\ntype ComboboxListProps = React.ComponentProps<typeof ComboboxPrimitive.List>\ntype ComboboxItemProps = React.ComponentProps<typeof ComboboxPrimitive.Item>\ntype ComboboxGroupProps = React.ComponentProps<typeof ComboboxPrimitive.Group>\ntype ComboboxLabelProps = React.ComponentProps<typeof ComboboxPrimitive.GroupLabel>\ntype ComboboxCollectionProps = React.ComponentProps<typeof ComboboxPrimitive.Collection>\ntype ComboboxEmptyProps = React.ComponentProps<typeof ComboboxPrimitive.Empty>\ntype ComboboxSeparatorProps = React.ComponentProps<typeof ComboboxPrimitive.Separator>\ntype ComboboxChipsProps = React.ComponentProps<typeof ComboboxPrimitive.Chips>\ntype ComboboxChipProps = React.ComponentProps<typeof ComboboxPrimitive.Chip>\ntype ComboboxChipsInputProps = React.ComponentProps<typeof ComboboxPrimitive.Input>\n\ntype ComboboxInputWrapperProps = ComboboxInputProps & {\n showTrigger?: boolean\n showClear?: boolean\n}\n\ntype ComboboxChipWrapperProps = ComboboxChipProps & {\n showRemove?: boolean\n}\n\ntype ComboboxContentProps = ComboboxPopupProps &\n Pick<\n ComboboxPositionerProps,\n \"side\" | \"align\" | \"sideOffset\" | \"alignOffset\" | \"anchor\"\n >\n\nfunction Combobox({ ...props }: ComboboxProps) {\n return <ComboboxPrimitive.Root data-slot=\"combobox\" {...props} />\n}\n\nfunction ComboboxValue({ ...props }: ComboboxValueProps) {\n return <ComboboxPrimitive.Value data-slot=\"combobox-value\" {...props} />\n}\n\nfunction ComboboxTrigger({ className, children, ...props }: ComboboxTriggerProps) {\n return (\n <ComboboxPrimitive.Trigger\n data-slot=\"combobox-trigger\"\n className={cn(\n \"[&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronDownIcon\n className=\"text-muted pointer-events-none size-4\"\n />\n </ComboboxPrimitive.Trigger>\n )\n}\n\nfunction ComboboxClear({ className, ...props }: ComboboxClearProps) {\n return (\n <ComboboxPrimitive.Clear\n data-slot=\"combobox-clear\"\n aria-label=\"Clear\"\n render={<InputGroupButton variant=\"ghost\" size=\"icon-xs\" />}\n className={cn(\"motion-scale-sm\", className)}\n {...props}\n >\n <CloseIcon\n className=\"pointer-events-none\"\n />\n </ComboboxPrimitive.Clear>\n )\n}\n\nfunction ComboboxInput({\n className,\n children,\n // No `= false` default: forcing `disabled={false}` onto the rendered input\n // would override the disabled state Base UI computes from a disabled\n // `<Combobox>` root. Leaving it `undefined` lets the root's state win, while\n // an explicit `disabled` prop is still respected.\n disabled,\n showTrigger = true,\n showClear = false,\n ...props\n}: ComboboxInputWrapperProps) {\n return (\n <ComboboxPrimitive.InputGroup render={<InputGroup className={cn(className)} />}>\n <ComboboxPrimitive.Input render={<InputGroupInput disabled={disabled} />} {...props} />\n <InputGroupAddon align=\"inline-end\">\n {/* Stack the trigger chevron and clear button in one cell so they\n * cross-fade. In single-select mode Base UI mounts the Clear only\n * when a value is *selected* (not while typing), and marks it with\n * a persistent `data-visible` attribute. The chevron keys its\n * fade-out (opacity/blur/scale via `motion-scale-sm`) off that exact\n * attribute, so chevron→clear cross-fades in place. */}\n <div className=\"relative grid size-6 *:[grid-area:1/1]\">\n {showTrigger ? (\n <InputGroupButton\n size=\"icon-xs\"\n variant=\"ghost\"\n nativeButton\n render={<ComboboxTrigger />}\n data-slot=\"input-group-button\"\n className={cn(\n \"motion-scale-sm data-pressed:bg-transparent\",\n \"group-has-[[data-slot=combobox-clear][data-visible]]/input-group:pointer-events-none\",\n \"group-has-[[data-slot=combobox-clear][data-visible]]/input-group:opacity-0\",\n \"group-has-[[data-slot=combobox-clear][data-visible]]/input-group:[filter:blur(var(--blur-sm))]\",\n \"group-has-[[data-slot=combobox-clear][data-visible]]/input-group:scale-[var(--scale-sm)]\",\n )}\n disabled={disabled}\n />\n ) : null}\n {showClear ? <ComboboxClear disabled={disabled} /> : null}\n </div>\n </InputGroupAddon>\n {children}\n </ComboboxPrimitive.InputGroup>\n )\n}\n\nfunction ComboboxPortal({ ...props }: ComboboxPortalProps) {\n return <ComboboxPrimitive.Portal data-slot=\"combobox-portal\" {...props} />\n}\n\nfunction ComboboxPositioner({ className, ...props }: ComboboxPositionerProps) {\n return (\n <ComboboxPrimitive.Positioner\n data-slot=\"combobox-positioner\"\n className={className}\n {...props}\n />\n )\n}\n\nfunction ComboboxContent({\n className,\n side = \"bottom\",\n sideOffset = 6,\n align = \"start\",\n alignOffset = 0,\n anchor,\n ...props\n}: ComboboxContentProps) {\n return (\n <ComboboxPortal>\n <ComboboxPositioner\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n anchor={anchor}\n className=\"isolate z-50\"\n >\n <ComboboxPrimitive.Popup\n data-slot=\"combobox-content\"\n className={cn(\n \"motion-pop-md bg-elevated text-contrast ring-contrast/10 *:data-[slot=input-group]:bg-edge/30 *:data-[slot=input-group]:border-edge/30 group/combobox-content relative max-h-(--available-height) max-w-(--available-width) min-w-(--anchor-width) origin-(--transform-origin) overflow-hidden rounded-md shadow-md ring-1 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:shadow-none\",\n className,\n )}\n {...props}\n />\n </ComboboxPositioner>\n </ComboboxPortal>\n )\n}\n\nfunction ComboboxList({ className, ...props }: ComboboxListProps) {\n return (\n <ComboboxPrimitive.List\n data-slot=\"combobox-list\"\n className={cn(\n \"[scrollbar-width:none] [&::-webkit-scrollbar]:hidden max-h-[min(calc(--spacing(72)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto overscroll-contain p-1 data-empty:p-0\",\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction ComboboxItem({ className, children, ...props }: ComboboxItemProps) {\n return (\n <ComboboxPrimitive.Item\n data-slot=\"combobox-item\"\n className={cn(\n \"data-highlighted:bg-primary data-highlighted:text-white not-data-[variant=destructive]:data-highlighted:**:text-white relative flex w-full cursor-clickable items-center gap-2 rounded-sm py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n {children}\n <ComboboxPrimitive.ItemIndicator\n render={\n <span data-slot=\"combobox-item-indicator\" className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\" />\n }\n >\n <CheckIcon\n className=\"pointer-events-none\"\n />\n </ComboboxPrimitive.ItemIndicator>\n </ComboboxPrimitive.Item>\n )\n}\n\nfunction ComboboxGroup({ className, ...props }: ComboboxGroupProps) {\n return (\n <ComboboxPrimitive.Group\n data-slot=\"combobox-group\"\n className={cn(className)}\n {...props}\n />\n )\n}\n\nfunction ComboboxLabel({ className, ...props }: ComboboxLabelProps) {\n return (\n <ComboboxPrimitive.GroupLabel\n data-slot=\"combobox-label\"\n className={cn(\"text-muted px-2 py-1.5 text-xs\", className)}\n {...props}\n />\n )\n}\n\nfunction ComboboxCollection({ ...props }: ComboboxCollectionProps) {\n return <ComboboxPrimitive.Collection data-slot=\"combobox-collection\" {...props} />\n}\n\nfunction ComboboxEmpty({ className, ...props }: ComboboxEmptyProps) {\n return (\n <ComboboxPrimitive.Empty\n data-slot=\"combobox-empty\"\n className={cn(\n \"text-muted hidden w-full justify-center py-2 text-center text-sm group-data-empty/combobox-content:flex\",\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction ComboboxSeparator({ className, ...props }: ComboboxSeparatorProps) {\n return (\n <ComboboxPrimitive.Separator\n data-slot=\"combobox-separator\"\n className={cn(\"bg-line -mx-1 my-1 h-px\", className)}\n {...props}\n />\n )\n}\n\nfunction ComboboxChips({ className, ...props }: ComboboxChipsProps) {\n return (\n <ComboboxPrimitive.Chips\n data-slot=\"combobox-chips\"\n className={cn(\n \"dark:bg-edge/30 border-edge focus-within:border-focus focus-within:ring-focus/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive dark:has-aria-invalid:border-destructive/50 flex min-h-8 flex-wrap items-center gap-1 rounded-md border bg-transparent bg-clip-padding px-2.5 py-1 text-sm transition-colors focus-within:ring-3 has-aria-invalid:ring-3 has-data-[slot=combobox-chip]:px-1\",\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction ComboboxChip({\n className,\n children,\n showRemove = true,\n ...props\n}: ComboboxChipWrapperProps) {\n return (\n <ComboboxPrimitive.Chip\n data-slot=\"combobox-chip\"\n className={cn(\n \"bg-secondary text-contrast flex h-[calc(--spacing(5.25))] w-fit items-center justify-center gap-1 rounded-sm px-1.5 text-xs font-medium whitespace-nowrap has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pr-0\",\n className,\n )}\n {...props}\n >\n {children}\n {showRemove ? (\n <ComboboxPrimitive.ChipRemove\n render={<Button variant=\"ghost\" size=\"icon-xs\" />}\n className=\"-ml-1 opacity-50 hover:opacity-100\"\n data-slot=\"combobox-chip-remove\"\n aria-label=\"Remove\"\n >\n <CloseIcon\n className=\"pointer-events-none\"\n />\n </ComboboxPrimitive.ChipRemove>\n ) : null}\n </ComboboxPrimitive.Chip>\n )\n}\n\nfunction ComboboxChipsInput({ className, ...props }: ComboboxChipsInputProps) {\n return (\n <ComboboxPrimitive.Input\n data-slot=\"combobox-chip-input\"\n className={cn(\"min-w-16 flex-1 outline-none\", className)}\n {...props}\n />\n )\n}\n\nfunction useComboboxAnchor() {\n return React.useRef<HTMLDivElement | null>(null)\n}\n\nexport {\n Combobox,\n ComboboxInput,\n ComboboxContent,\n ComboboxList,\n ComboboxItem,\n ComboboxGroup,\n ComboboxLabel,\n ComboboxCollection,\n ComboboxEmpty,\n ComboboxSeparator,\n ComboboxChips,\n ComboboxChip,\n ComboboxChipsInput,\n ComboboxTrigger,\n ComboboxValue,\n ComboboxClear,\n useComboboxAnchor,\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"count.d.ts","names":[],"sources":["../src/count.tsx"],"mappings":";;;;UAeU,UAAA;;EAER,EAAA,WAAa,IAAA;EAFL;EAIR,IAAA;;EAEA,QAAA;EAJA;EAMA,KAAA;EAJA;;;;;;EAWA,MAAA,IAAU,KAAA;EAMV;EAJA,MAAA;EAMA;EAJA,MAAA;EAMU;EAJV,QAAA,EAAU,YAAA;EAMA;EAJV,IAAA;EAQG;EANH,MAAA,IAAU,CAAA;;EAEV,UAAA;AAAA;AAI4B;AAAA,KAAzB,YAAA,GAAe,UAAA;;iBAKX,OAAA,CAAQ,CAAA;;AAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwEjB,KAAA,CAAA;EACP,EAAA;EACA,IAAA,EAAM,KAAA;EACN,QAAA;EACA,KAAA;EACA,MAAA;EACA,MAAA;EACA,MAAA;EACA,QAAA;EACA,IAAA;EACA,MAAA;EACA;AAAA,GACC,UAAA,GAAU,oBAAA,CAAA,GAAA,CAAA,OAAA;;cAyLP,OAAA,SAAO,KAAA"}
1
+ {"version":3,"file":"count.d.ts","names":[],"sources":["../src/count.tsx"],"mappings":";;;;UAeU,UAAA;;EAER,EAAA,WAAa,IAAA;EAFL;EAIR,IAAA;;EAEA,QAAA;EAJA;EAMA,KAAA;EAJA;;;;;;EAWA,MAAA,IAAU,KAAA;EAMV;EAJA,MAAA;EAMA;EAJA,MAAA;EAMU;EAJV,QAAA,EAAU,YAAA;EAMA;EAJV,IAAA;EAQG;EANH,MAAA,IAAU,CAAA;;EAEV,UAAA;AAAA;AAI4B;AAAA,KAAzB,YAAA,GAAe,UAAA;;iBAKX,OAAA,CAAQ,CAAA;;AAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwEjB,KAAA,CAAA;EACP,EAAA;EACA,IAAA,EAAM,KAAA;EACN,QAAA;EACA,KAAA;EACA,MAAA;EACA,MAAA;EACA,MAAA;EACA,QAAA;EACA,IAAA;EACA,MAAA;EACA;AAAA,GACC,UAAA,GAAU,oBAAA,CAAA,GAAA,CAAA,OAAA;;cAkMP,OAAA,SAAO,KAAA"}
package/dist/count.js CHANGED
@@ -89,11 +89,15 @@ function NumberCount({ to, from: start, duration, delay, format, prefix, suffix,
89
89
  margin: "-50px"
90
90
  });
91
91
  const [display, setDisplay] = useState(start);
92
- const hasAnimated = useRef(false);
92
+ const easingRef = useRef(easing);
93
+ const onCompleteRef = useRef(onComplete);
94
+ useEffect(() => {
95
+ easingRef.current = easing;
96
+ onCompleteRef.current = onComplete;
97
+ });
93
98
  const formatFn = format ?? ((n) => Number.isInteger(to) ? Math.round(n).toLocaleString() : n.toLocaleString());
94
99
  useEffect(() => {
95
- if (!isInView || hasAnimated.current) return;
96
- hasAnimated.current = true;
100
+ if (!isInView) return;
97
101
  const delayMs = delay * 1e3;
98
102
  let raf;
99
103
  let startTime;
@@ -102,10 +106,9 @@ function NumberCount({ to, from: start, duration, delay, format, prefix, suffix,
102
106
  if (!startTime) startTime = timestamp;
103
107
  const elapsed = timestamp - startTime;
104
108
  const progress = Math.min(elapsed / duration, 1);
105
- const easedProgress = easing(progress);
106
- setDisplay(start + (to - start) * easedProgress);
109
+ setDisplay(start + (to - start) * easingRef.current(progress));
107
110
  if (progress < 1) raf = requestAnimationFrame(animate);
108
- else onComplete?.();
111
+ else onCompleteRef.current?.();
109
112
  };
110
113
  raf = requestAnimationFrame(animate);
111
114
  }, delayMs);
@@ -118,9 +121,7 @@ function NumberCount({ to, from: start, duration, delay, format, prefix, suffix,
118
121
  to,
119
122
  start,
120
123
  duration,
121
- delay,
122
- easing,
123
- onComplete
124
+ delay
124
125
  ]);
125
126
  if (!isValidElement(children)) return children;
126
127
  const existingRef = children.props.ref;
package/dist/count.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"count.js","names":[],"sources":["../src/count.tsx"],"sourcesContent":["\"use client\"\n\nimport {\n type ReactElement,\n type Ref,\n cloneElement,\n isValidElement,\n useEffect,\n useRef,\n useState,\n} from \"react\"\nimport { useInView } from \"motion/react\"\n\n// ── Types ────────────────────────────────────────────────────────────\n\ninterface CountProps {\n /** Target number or Date to count to */\n to: number | Date\n /** Starting number. Default: 0. Ignored when `to` is a Date. */\n from?: number\n /** Animation duration in milliseconds. Default: 900. Ignored when `to` is a Date. */\n duration?: number\n /** Delay before starting in seconds. Default: 0 */\n delay?: number\n /**\n * Format the value for display.\n * - For numbers: receives the current interpolated number.\n * - For dates: receives remaining milliseconds.\n * Default: toLocaleString() for numbers, dd:hh:mm:ss for dates.\n */\n format?: (value: number) => string\n /** Prefix string (e.g., \"$\"). Default: '' */\n prefix?: string\n /** Suffix string (e.g., \"%\", \"+\"). Default: '' */\n suffix?: string\n /** Element to render into. Receives the formatted value as children. */\n children: ReactElement\n /** Trigger once. Default: true */\n once?: boolean\n /** Easing function. Default: easeOut. Ignored when `to` is a Date. */\n easing?: (t: number) => number\n /** Called when the count finishes (reaches target or date passes). */\n onComplete?: () => void\n}\n\n/** @deprecated Use `Count` instead. `CountUp` is an alias kept for backwards compatibility. */\ntype CountUpProps = CountProps\n\n// ── Easing ───────────────────────────────────────────────────────────\n\n/** Cubic ease-out: fast start, smooth deceleration */\nfunction easeOut(t: number): number {\n return 1 - Math.pow(1 - t, 3)\n}\n\n// ── Date Formatting ──────────────────────────────────────────────────\n\nfunction formatCountdown(ms: number): string {\n if (ms <= 0) return \"00:00:00\"\n\n const totalSeconds = Math.floor(ms / 1000)\n const days = Math.floor(totalSeconds / 86400)\n const hours = Math.floor((totalSeconds % 86400) / 3600)\n const minutes = Math.floor((totalSeconds % 3600) / 60)\n const seconds = totalSeconds % 60\n\n const pad = (n: number) => String(n).padStart(2, \"0\")\n\n if (days > 0) {\n return `${days}d ${pad(hours)}:${pad(minutes)}:${pad(seconds)}`\n }\n return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`\n}\n\n// ── Ref Merge ────────────────────────────────────────────────────────\n\nfunction mergeRef(\n internalRef: React.RefObject<HTMLElement | null>,\n externalRef?: Ref<HTMLElement>,\n) {\n return (el: HTMLElement | null) => {\n ;(internalRef as { current: HTMLElement | null }).current = el\n if (typeof externalRef === \"function\") externalRef(el)\n else if (externalRef && typeof externalRef === \"object\") {\n ;(externalRef as { current: HTMLElement | null }).current = el\n }\n }\n}\n\n// ── Count ────────────────────────────────────────────────────────────\n\n/**\n * Animated number counter. Counts up, counts down, or live-counts to a date.\n *\n * Direction is automatic — if `from < to` it counts up, if `from > to` it\n * counts down. When `to` is a Date, it becomes a live countdown that ticks\n * every second.\n *\n * Zero wrapper — injects the formatted value as children via cloneElement.\n *\n * @example\n * ```tsx\n * // Count up\n * <Count to={1234}>\n * <span className=\"text-4xl font-bold tabular-nums\" />\n * </Count>\n *\n * // Count down\n * <Count from={100} to={0} onComplete={() => alert(\"Done!\")}>\n * <span className=\"text-4xl font-bold tabular-nums\" />\n * </Count>\n *\n * // Live countdown to a date\n * <Count to={new Date(\"2026-04-01T00:00:00\")}>\n * <span className=\"text-2xl font-mono tabular-nums\" />\n * </Count>\n *\n * // Custom date format\n * <Count to={launchDate} format={(ms) => `${Math.ceil(ms / 86400000)} days left`}>\n * <span className=\"text-xl\" />\n * </Count>\n * ```\n */\nfunction Count({\n to,\n from: start = 0,\n duration = 900,\n delay = 0,\n format,\n prefix = \"\",\n suffix = \"\",\n children,\n once = true,\n easing = easeOut,\n onComplete,\n}: CountProps) {\n const isDate = to instanceof Date\n\n if (isDate) {\n return (\n <DateCount\n to={to}\n delay={delay}\n format={format}\n prefix={prefix}\n suffix={suffix}\n once={once}\n onComplete={onComplete}\n >\n {children}\n </DateCount>\n )\n }\n\n return (\n <NumberCount\n to={to}\n from={start}\n duration={duration}\n delay={delay}\n format={format}\n prefix={prefix}\n suffix={suffix}\n once={once}\n easing={easing}\n onComplete={onComplete}\n >\n {children}\n </NumberCount>\n )\n}\n\n// ── Number Count (up or down) ────────────────────────────────────────\n\nfunction NumberCount({\n to,\n from: start,\n duration,\n delay,\n format,\n prefix,\n suffix,\n children,\n once,\n easing,\n onComplete,\n}: {\n to: number\n from: number\n duration: number\n delay: number\n format?: (value: number) => string\n prefix: string\n suffix: string\n children: ReactElement\n once: boolean\n easing: (t: number) => number\n onComplete?: () => void\n}) {\n const ref = useRef<HTMLElement>(null)\n const isInView = useInView(ref, { once, margin: \"-50px\" })\n const [display, setDisplay] = useState(start)\n const hasAnimated = useRef(false)\n\n const formatFn = format ?? ((n: number) =>\n Number.isInteger(to) ? Math.round(n).toLocaleString() : n.toLocaleString()\n )\n\n useEffect(() => {\n if (!isInView || hasAnimated.current) return\n hasAnimated.current = true\n\n const delayMs = delay * 1000\n let raf: number\n let startTime: number\n\n const timer = setTimeout(() => {\n const animate = (timestamp: number) => {\n if (!startTime) startTime = timestamp\n const elapsed = timestamp - startTime\n const progress = Math.min(elapsed / duration, 1)\n const easedProgress = easing(progress)\n const current = start + (to - start) * easedProgress\n\n setDisplay(current)\n\n if (progress < 1) {\n raf = requestAnimationFrame(animate)\n } else {\n onComplete?.()\n }\n }\n\n raf = requestAnimationFrame(animate)\n }, delayMs)\n\n return () => {\n clearTimeout(timer)\n cancelAnimationFrame(raf)\n }\n }, [isInView, to, start, duration, delay, easing, onComplete])\n\n if (!isValidElement(children)) return children\n\n const childProps = children.props as Record<string, unknown>\n const existingRef = (childProps as { ref?: Ref<HTMLElement> }).ref\n\n return cloneElement(children, {\n ref: mergeRef(ref, existingRef),\n children: `${prefix}${formatFn(display)}${suffix}`,\n } as Record<string, unknown>)\n}\n\n// ── Date Count (live countdown) ──────────────────────────────────────\n\nfunction DateCount({\n to,\n delay,\n format,\n prefix,\n suffix,\n children,\n once,\n onComplete,\n}: {\n to: Date\n delay: number\n format?: (value: number) => string\n prefix: string\n suffix: string\n children: ReactElement\n once: boolean\n onComplete?: () => void\n}) {\n const ref = useRef<HTMLElement>(null)\n const isInView = useInView(ref, { once, margin: \"-50px\" })\n const [remaining, setRemaining] = useState(() => Math.max(0, to.getTime() - Date.now()))\n const [started, setStarted] = useState(false)\n const completedRef = useRef(false)\n\n const formatFn = format ?? formatCountdown\n\n useEffect(() => {\n if (!isInView || started) return\n const timer = setTimeout(() => setStarted(true), delay * 1000)\n return () => clearTimeout(timer)\n }, [isInView, delay, started])\n\n useEffect(() => {\n if (!started) return\n\n const tick = () => {\n const ms = Math.max(0, to.getTime() - Date.now())\n setRemaining(ms)\n\n if (ms <= 0 && !completedRef.current) {\n completedRef.current = true\n onComplete?.()\n }\n }\n\n tick()\n const interval = setInterval(tick, 1000)\n return () => clearInterval(interval)\n }, [started, to, onComplete])\n\n if (!isValidElement(children)) return children\n\n const childProps = children.props as Record<string, unknown>\n const existingRef = (childProps as { ref?: Ref<HTMLElement> }).ref\n\n return cloneElement(children, {\n ref: mergeRef(ref, existingRef),\n children: `${prefix}${formatFn(remaining)}${suffix}`,\n } as Record<string, unknown>)\n}\n\n// ── Exports ──────────────────────────────────────────────────────────\n\n/** @deprecated Use `Count` instead */\nconst CountUp = Count\n\nexport { Count, CountUp, easeOut }\nexport type { CountProps, CountUpProps }\n"],"mappings":"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"}
1
+ {"version":3,"file":"count.js","names":[],"sources":["../src/count.tsx"],"sourcesContent":["\"use client\"\n\nimport {\n type ReactElement,\n type Ref,\n cloneElement,\n isValidElement,\n useEffect,\n useRef,\n useState,\n} from \"react\"\nimport { useInView } from \"motion/react\"\n\n// ── Types ────────────────────────────────────────────────────────────\n\ninterface CountProps {\n /** Target number or Date to count to */\n to: number | Date\n /** Starting number. Default: 0. Ignored when `to` is a Date. */\n from?: number\n /** Animation duration in milliseconds. Default: 900. Ignored when `to` is a Date. */\n duration?: number\n /** Delay before starting in seconds. Default: 0 */\n delay?: number\n /**\n * Format the value for display.\n * - For numbers: receives the current interpolated number.\n * - For dates: receives remaining milliseconds.\n * Default: toLocaleString() for numbers, dd:hh:mm:ss for dates.\n */\n format?: (value: number) => string\n /** Prefix string (e.g., \"$\"). Default: '' */\n prefix?: string\n /** Suffix string (e.g., \"%\", \"+\"). Default: '' */\n suffix?: string\n /** Element to render into. Receives the formatted value as children. */\n children: ReactElement\n /** Trigger once. Default: true */\n once?: boolean\n /** Easing function. Default: easeOut. Ignored when `to` is a Date. */\n easing?: (t: number) => number\n /** Called when the count finishes (reaches target or date passes). */\n onComplete?: () => void\n}\n\n/** @deprecated Use `Count` instead. `CountUp` is an alias kept for backwards compatibility. */\ntype CountUpProps = CountProps\n\n// ── Easing ───────────────────────────────────────────────────────────\n\n/** Cubic ease-out: fast start, smooth deceleration */\nfunction easeOut(t: number): number {\n return 1 - Math.pow(1 - t, 3)\n}\n\n// ── Date Formatting ──────────────────────────────────────────────────\n\nfunction formatCountdown(ms: number): string {\n if (ms <= 0) return \"00:00:00\"\n\n const totalSeconds = Math.floor(ms / 1000)\n const days = Math.floor(totalSeconds / 86400)\n const hours = Math.floor((totalSeconds % 86400) / 3600)\n const minutes = Math.floor((totalSeconds % 3600) / 60)\n const seconds = totalSeconds % 60\n\n const pad = (n: number) => String(n).padStart(2, \"0\")\n\n if (days > 0) {\n return `${days}d ${pad(hours)}:${pad(minutes)}:${pad(seconds)}`\n }\n return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`\n}\n\n// ── Ref Merge ────────────────────────────────────────────────────────\n\nfunction mergeRef(\n internalRef: React.RefObject<HTMLElement | null>,\n externalRef?: Ref<HTMLElement>,\n) {\n return (el: HTMLElement | null) => {\n ;(internalRef as { current: HTMLElement | null }).current = el\n if (typeof externalRef === \"function\") externalRef(el)\n else if (externalRef && typeof externalRef === \"object\") {\n ;(externalRef as { current: HTMLElement | null }).current = el\n }\n }\n}\n\n// ── Count ────────────────────────────────────────────────────────────\n\n/**\n * Animated number counter. Counts up, counts down, or live-counts to a date.\n *\n * Direction is automatic — if `from < to` it counts up, if `from > to` it\n * counts down. When `to` is a Date, it becomes a live countdown that ticks\n * every second.\n *\n * Zero wrapper — injects the formatted value as children via cloneElement.\n *\n * @example\n * ```tsx\n * // Count up\n * <Count to={1234}>\n * <span className=\"text-4xl font-bold tabular-nums\" />\n * </Count>\n *\n * // Count down\n * <Count from={100} to={0} onComplete={() => alert(\"Done!\")}>\n * <span className=\"text-4xl font-bold tabular-nums\" />\n * </Count>\n *\n * // Live countdown to a date\n * <Count to={new Date(\"2026-04-01T00:00:00\")}>\n * <span className=\"text-2xl font-mono tabular-nums\" />\n * </Count>\n *\n * // Custom date format\n * <Count to={launchDate} format={(ms) => `${Math.ceil(ms / 86400000)} days left`}>\n * <span className=\"text-xl\" />\n * </Count>\n * ```\n */\nfunction Count({\n to,\n from: start = 0,\n duration = 900,\n delay = 0,\n format,\n prefix = \"\",\n suffix = \"\",\n children,\n once = true,\n easing = easeOut,\n onComplete,\n}: CountProps) {\n const isDate = to instanceof Date\n\n if (isDate) {\n return (\n <DateCount\n to={to}\n delay={delay}\n format={format}\n prefix={prefix}\n suffix={suffix}\n once={once}\n onComplete={onComplete}\n >\n {children}\n </DateCount>\n )\n }\n\n return (\n <NumberCount\n to={to}\n from={start}\n duration={duration}\n delay={delay}\n format={format}\n prefix={prefix}\n suffix={suffix}\n once={once}\n easing={easing}\n onComplete={onComplete}\n >\n {children}\n </NumberCount>\n )\n}\n\n// ── Number Count (up or down) ────────────────────────────────────────\n\nfunction NumberCount({\n to,\n from: start,\n duration,\n delay,\n format,\n prefix,\n suffix,\n children,\n once,\n easing,\n onComplete,\n}: {\n to: number\n from: number\n duration: number\n delay: number\n format?: (value: number) => string\n prefix: string\n suffix: string\n children: ReactElement\n once: boolean\n easing: (t: number) => number\n onComplete?: () => void\n}) {\n const ref = useRef<HTMLElement>(null)\n const isInView = useInView(ref, { once, margin: \"-50px\" })\n const [display, setDisplay] = useState(start)\n\n // Keep the callbacks in refs so a parent re-render with inline `easing` /\n // `onComplete` props doesn't re-run the animation effect — which would cancel\n // the in-flight rAF and freeze the counter mid-count. The effect below keys\n // only on the values that should actually (re)start the animation, so a live\n // `to` change or a re-entry (with `once={false}`) restarts cleanly.\n const easingRef = useRef(easing)\n const onCompleteRef = useRef(onComplete)\n useEffect(() => {\n easingRef.current = easing\n onCompleteRef.current = onComplete\n })\n\n const formatFn = format ?? ((n: number) =>\n Number.isInteger(to) ? Math.round(n).toLocaleString() : n.toLocaleString()\n )\n\n useEffect(() => {\n if (!isInView) return\n\n const delayMs = delay * 1000\n let raf: number\n let startTime: number\n\n const timer = setTimeout(() => {\n const animate = (timestamp: number) => {\n if (!startTime) startTime = timestamp\n const elapsed = timestamp - startTime\n const progress = Math.min(elapsed / duration, 1)\n const current = start + (to - start) * easingRef.current(progress)\n\n setDisplay(current)\n\n if (progress < 1) {\n raf = requestAnimationFrame(animate)\n } else {\n onCompleteRef.current?.()\n }\n }\n\n raf = requestAnimationFrame(animate)\n }, delayMs)\n\n return () => {\n clearTimeout(timer)\n cancelAnimationFrame(raf)\n }\n }, [isInView, to, start, duration, delay])\n\n if (!isValidElement(children)) return children\n\n const childProps = children.props as Record<string, unknown>\n const existingRef = (childProps as { ref?: Ref<HTMLElement> }).ref\n\n return cloneElement(children, {\n ref: mergeRef(ref, existingRef),\n children: `${prefix}${formatFn(display)}${suffix}`,\n } as Record<string, unknown>)\n}\n\n// ── Date Count (live countdown) ──────────────────────────────────────\n\nfunction DateCount({\n to,\n delay,\n format,\n prefix,\n suffix,\n children,\n once,\n onComplete,\n}: {\n to: Date\n delay: number\n format?: (value: number) => string\n prefix: string\n suffix: string\n children: ReactElement\n once: boolean\n onComplete?: () => void\n}) {\n const ref = useRef<HTMLElement>(null)\n const isInView = useInView(ref, { once, margin: \"-50px\" })\n const [remaining, setRemaining] = useState(() => Math.max(0, to.getTime() - Date.now()))\n const [started, setStarted] = useState(false)\n const completedRef = useRef(false)\n\n const formatFn = format ?? formatCountdown\n\n useEffect(() => {\n if (!isInView || started) return\n const timer = setTimeout(() => setStarted(true), delay * 1000)\n return () => clearTimeout(timer)\n }, [isInView, delay, started])\n\n useEffect(() => {\n if (!started) return\n\n const tick = () => {\n const ms = Math.max(0, to.getTime() - Date.now())\n setRemaining(ms)\n\n if (ms <= 0 && !completedRef.current) {\n completedRef.current = true\n onComplete?.()\n }\n }\n\n tick()\n const interval = setInterval(tick, 1000)\n return () => clearInterval(interval)\n }, [started, to, onComplete])\n\n if (!isValidElement(children)) return children\n\n const childProps = children.props as Record<string, unknown>\n const existingRef = (childProps as { ref?: Ref<HTMLElement> }).ref\n\n return cloneElement(children, {\n ref: mergeRef(ref, existingRef),\n children: `${prefix}${formatFn(remaining)}${suffix}`,\n } as Record<string, unknown>)\n}\n\n// ── Exports ──────────────────────────────────────────────────────────\n\n/** @deprecated Use `Count` instead */\nconst CountUp = Count\n\nexport { Count, CountUp, easeOut }\nexport type { CountProps, CountUpProps }\n"],"mappings":";;;;;;AAmDA,SAAS,QAAQ,GAAmB;AAClC,QAAO,IAAI,KAAK,IAAI,IAAI,GAAG,EAAE;;AAK/B,SAAS,gBAAgB,IAAoB;AAC3C,KAAI,MAAM,EAAG,QAAO;CAEpB,MAAM,eAAe,KAAK,MAAM,KAAK,IAAK;CAC1C,MAAM,OAAO,KAAK,MAAM,eAAe,MAAM;CAC7C,MAAM,QAAQ,KAAK,MAAO,eAAe,QAAS,KAAK;CACvD,MAAM,UAAU,KAAK,MAAO,eAAe,OAAQ,GAAG;CACtD,MAAM,UAAU,eAAe;CAE/B,MAAM,OAAO,MAAc,OAAO,EAAE,CAAC,SAAS,GAAG,IAAI;AAErD,KAAI,OAAO,EACT,QAAO,GAAG,KAAK,IAAI,IAAI,MAAM,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,IAAI,QAAQ;AAE/D,QAAO,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,IAAI,QAAQ;;AAKtD,SAAS,SACP,aACA,aACA;AACA,SAAQ,OAA2B;AAC/B,cAAgD,UAAU;AAC5D,MAAI,OAAO,gBAAgB,WAAY,aAAY,GAAG;WAC7C,eAAe,OAAO,gBAAgB,SAC3C,aAAgD,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuClE,SAAS,MAAM,EACb,IACA,MAAM,QAAQ,GACd,WAAW,KACX,QAAQ,GACR,QACA,SAAS,IACT,SAAS,IACT,UACA,OAAO,MACP,SAAS,SACT,cACa;AAGb,KAFe,cAAc,KAG3B,QACE,oBAAC,WAAD;EACM;EACG;EACC;EACA;EACA;EACF;EACM;EAEX;EACS,CAAA;AAIhB,QACE,oBAAC,aAAD;EACM;EACJ,MAAM;EACI;EACH;EACC;EACA;EACA;EACF;EACE;EACI;EAEX;EACW,CAAA;;AAMlB,SAAS,YAAY,EACnB,IACA,MAAM,OACN,UACA,OACA,QACA,QACA,QACA,UACA,MACA,QACA,cAaC;CACD,MAAM,MAAM,OAAoB,KAAK;CACrC,MAAM,WAAW,UAAU,KAAK;EAAE;EAAM,QAAQ;EAAS,CAAC;CAC1D,MAAM,CAAC,SAAS,cAAc,SAAS,MAAM;CAO7C,MAAM,YAAY,OAAO,OAAO;CAChC,MAAM,gBAAgB,OAAO,WAAW;AACxC,iBAAgB;AACd,YAAU,UAAU;AACpB,gBAAc,UAAU;GACxB;CAEF,MAAM,WAAW,YAAY,MAC3B,OAAO,UAAU,GAAG,GAAG,KAAK,MAAM,EAAE,CAAC,gBAAgB,GAAG,EAAE,gBAAgB;AAG5E,iBAAgB;AACd,MAAI,CAAC,SAAU;EAEf,MAAM,UAAU,QAAQ;EACxB,IAAI;EACJ,IAAI;EAEJ,MAAM,QAAQ,iBAAiB;GAC7B,MAAM,WAAW,cAAsB;AACrC,QAAI,CAAC,UAAW,aAAY;IAC5B,MAAM,UAAU,YAAY;IAC5B,MAAM,WAAW,KAAK,IAAI,UAAU,UAAU,EAAE;AAGhD,eAFgB,SAAS,KAAK,SAAS,UAAU,QAAQ,SAAS,CAE/C;AAEnB,QAAI,WAAW,EACb,OAAM,sBAAsB,QAAQ;QAEpC,eAAc,WAAW;;AAI7B,SAAM,sBAAsB,QAAQ;KACnC,QAAQ;AAEX,eAAa;AACX,gBAAa,MAAM;AACnB,wBAAqB,IAAI;;IAE1B;EAAC;EAAU;EAAI;EAAO;EAAU;EAAM,CAAC;AAE1C,KAAI,CAAC,eAAe,SAAS,CAAE,QAAO;CAGtC,MAAM,cADa,SAAS,MACmC;AAE/D,QAAO,aAAa,UAAU;EAC5B,KAAK,SAAS,KAAK,YAAY;EAC/B,UAAU,GAAG,SAAS,SAAS,QAAQ,GAAG;EAC3C,CAA4B;;AAK/B,SAAS,UAAU,EACjB,IACA,OACA,QACA,QACA,QACA,UACA,MACA,cAUC;CACD,MAAM,MAAM,OAAoB,KAAK;CACrC,MAAM,WAAW,UAAU,KAAK;EAAE;EAAM,QAAQ;EAAS,CAAC;CAC1D,MAAM,CAAC,WAAW,gBAAgB,eAAe,KAAK,IAAI,GAAG,GAAG,SAAS,GAAG,KAAK,KAAK,CAAC,CAAC;CACxF,MAAM,CAAC,SAAS,cAAc,SAAS,MAAM;CAC7C,MAAM,eAAe,OAAO,MAAM;CAElC,MAAM,WAAW,UAAU;AAE3B,iBAAgB;AACd,MAAI,CAAC,YAAY,QAAS;EAC1B,MAAM,QAAQ,iBAAiB,WAAW,KAAK,EAAE,QAAQ,IAAK;AAC9D,eAAa,aAAa,MAAM;IAC/B;EAAC;EAAU;EAAO;EAAQ,CAAC;AAE9B,iBAAgB;AACd,MAAI,CAAC,QAAS;EAEd,MAAM,aAAa;GACjB,MAAM,KAAK,KAAK,IAAI,GAAG,GAAG,SAAS,GAAG,KAAK,KAAK,CAAC;AACjD,gBAAa,GAAG;AAEhB,OAAI,MAAM,KAAK,CAAC,aAAa,SAAS;AACpC,iBAAa,UAAU;AACvB,kBAAc;;;AAIlB,QAAM;EACN,MAAM,WAAW,YAAY,MAAM,IAAK;AACxC,eAAa,cAAc,SAAS;IACnC;EAAC;EAAS;EAAI;EAAW,CAAC;AAE7B,KAAI,CAAC,eAAe,SAAS,CAAE,QAAO;CAGtC,MAAM,cADa,SAAS,MACmC;AAE/D,QAAO,aAAa,UAAU;EAC5B,KAAK,SAAS,KAAK,YAAY;EAC/B,UAAU,GAAG,SAAS,SAAS,UAAU,GAAG;EAC7C,CAA4B;;;AAM/B,MAAM,UAAU"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "./lib/utils.js";
3
3
  import * as React from "react";
4
- import { jsx } from "react/jsx-runtime";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/encrypted-text.tsx
6
6
  const DEFAULT_CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-={}[];:,.<>/?";
7
7
  function randomChar(charset) {
@@ -85,22 +85,25 @@ function EncryptedText({ text, className, revealDelayMs = 50, charset = DEFAULT_
85
85
  scrambleOneChar
86
86
  ]);
87
87
  if (!text) return null;
88
- return /* @__PURE__ */ jsx("span", {
88
+ return /* @__PURE__ */ jsxs("span", {
89
89
  ref,
90
90
  "data-slot": "encrypted-text",
91
91
  className,
92
- "aria-label": text,
93
92
  ...props,
94
- children: text.split("").map((char, index) => {
93
+ children: [/* @__PURE__ */ jsx("span", {
94
+ className: "sr-only",
95
+ children: text
96
+ }), text.split("").map((char, index) => {
95
97
  const isRevealed = !scrambleOnly && index < revealCount;
96
98
  const displayChar = isRevealed ? char : char === " " ? " " : scrambleCharsRef.current[index] ?? randomChar(charset);
97
99
  return /* @__PURE__ */ jsx("span", {
100
+ "aria-hidden": "true",
98
101
  "data-slot": "encrypted-text-char",
99
102
  "data-revealed": isRevealed || void 0,
100
103
  className: cn(isRevealed ? revealedClassName : encryptedClassName),
101
104
  children: displayChar
102
105
  }, index);
103
- })
106
+ })]
104
107
  });
105
108
  }
106
109
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"encrypted-text.js","names":[],"sources":["../src/encrypted-text.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\n\ntype EncryptedTextProps = React.ComponentProps<\"span\"> & {\n text: string\n revealDelayMs?: number\n charset?: string\n flipDelayMs?: number\n encryptedClassName?: string\n revealedClassName?: string\n scrambleOnly?: boolean\n scrambleOneChar?: boolean\n}\n\nconst DEFAULT_CHARSET =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-={}[];:,.<>/?\"\n\nfunction randomChar(charset: string): string {\n return charset.charAt(Math.floor(Math.random() * charset.length))\n}\n\nfunction scramblePreservingSpaces(original: string, charset: string): string {\n if (!original) return \"\"\n let result = \"\"\n for (let i = 0; i < original.length; i += 1) {\n result += original[i] === \" \" ? \" \" : randomChar(charset)\n }\n return result\n}\n\nfunction EncryptedText({\n text,\n className,\n revealDelayMs = 50,\n charset = DEFAULT_CHARSET,\n flipDelayMs = 50,\n encryptedClassName,\n revealedClassName,\n scrambleOnly = false,\n scrambleOneChar = false,\n ...props\n}: EncryptedTextProps) {\n const ref = React.useRef<HTMLSpanElement>(null)\n const [isInView, setIsInView] = React.useState(false)\n const [revealCount, setRevealCount] = React.useState(0)\n const [, setFlipTick] = React.useState(0)\n\n const animationFrameRef = React.useRef<number | null>(null)\n const startTimeRef = React.useRef(0)\n const lastFlipTimeRef = React.useRef(0)\n const scrambleCharsRef = React.useRef<string[]>(\n text ? scramblePreservingSpaces(text, charset).split(\"\") : []\n )\n\n React.useEffect(() => {\n const el = ref.current\n if (!el) return\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (entry?.isIntersecting) {\n setIsInView(true)\n observer.disconnect()\n }\n },\n { threshold: 0 }\n )\n\n observer.observe(el)\n return () => observer.disconnect()\n }, [])\n\n React.useEffect(() => {\n if (!isInView) return\n\n const initial = text\n ? scramblePreservingSpaces(text, charset)\n : \"\"\n scrambleCharsRef.current = initial.split(\"\")\n startTimeRef.current = performance.now()\n lastFlipTimeRef.current = startTimeRef.current\n setRevealCount(0)\n\n let isCancelled = false\n\n const update = (now: number) => {\n if (isCancelled) return\n\n const totalLength = text.length\n\n if (scrambleOnly) {\n const timeSinceLastFlip = now - lastFlipTimeRef.current\n if (timeSinceLastFlip >= Math.max(0, flipDelayMs)) {\n if (scrambleOneChar) {\n const indices: number[] = []\n for (let i = 0; i < totalLength; i++) {\n if (text[i] !== \" \") indices.push(i)\n }\n if (indices.length > 0) {\n const idx = indices[Math.floor(Math.random() * indices.length)]!\n scrambleCharsRef.current[idx] = randomChar(charset)\n }\n } else {\n for (let index = 0; index < totalLength; index += 1) {\n scrambleCharsRef.current[index] =\n text[index] === \" \" ? \" \" : randomChar(charset)\n }\n }\n lastFlipTimeRef.current = now\n setFlipTick((t) => (t + 1) & 0xffff)\n }\n animationFrameRef.current = requestAnimationFrame(update)\n return\n }\n\n const elapsedMs = now - startTimeRef.current\n const currentRevealCount = Math.min(\n totalLength,\n Math.floor(elapsedMs / Math.max(1, revealDelayMs))\n )\n\n setRevealCount(currentRevealCount)\n\n if (currentRevealCount >= totalLength) return\n\n const timeSinceLastFlip = now - lastFlipTimeRef.current\n if (timeSinceLastFlip >= Math.max(0, flipDelayMs)) {\n for (let index = currentRevealCount; index < totalLength; index += 1) {\n scrambleCharsRef.current[index] =\n text[index] === \" \" ? \" \" : randomChar(charset)\n }\n lastFlipTimeRef.current = now\n }\n\n animationFrameRef.current = requestAnimationFrame(update)\n }\n\n animationFrameRef.current = requestAnimationFrame(update)\n\n return () => {\n isCancelled = true\n if (animationFrameRef.current !== null) {\n cancelAnimationFrame(animationFrameRef.current)\n }\n }\n }, [isInView, text, revealDelayMs, charset, flipDelayMs, scrambleOnly, scrambleOneChar])\n\n if (!text) return null\n\n return (\n <span\n ref={ref}\n data-slot=\"encrypted-text\"\n className={className}\n aria-label={text}\n {...props}\n >\n {text.split(\"\").map((char, index) => {\n const isRevealed = !scrambleOnly && index < revealCount\n const displayChar = isRevealed\n ? char\n : char === \" \"\n ? \" \"\n : (scrambleCharsRef.current[index] ?? randomChar(charset))\n\n return (\n <span\n key={index}\n data-slot=\"encrypted-text-char\"\n data-revealed={isRevealed || undefined}\n className={cn(isRevealed ? revealedClassName : encryptedClassName)}\n >\n {displayChar}\n </span>\n )\n })}\n </span>\n )\n}\n\nexport { EncryptedText }\n"],"mappings":"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"}
1
+ {"version":3,"file":"encrypted-text.js","names":[],"sources":["../src/encrypted-text.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\n\ntype EncryptedTextProps = React.ComponentProps<\"span\"> & {\n text: string\n revealDelayMs?: number\n charset?: string\n flipDelayMs?: number\n encryptedClassName?: string\n revealedClassName?: string\n scrambleOnly?: boolean\n scrambleOneChar?: boolean\n}\n\nconst DEFAULT_CHARSET =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-={}[];:,.<>/?\"\n\nfunction randomChar(charset: string): string {\n return charset.charAt(Math.floor(Math.random() * charset.length))\n}\n\nfunction scramblePreservingSpaces(original: string, charset: string): string {\n if (!original) return \"\"\n let result = \"\"\n for (let i = 0; i < original.length; i += 1) {\n result += original[i] === \" \" ? \" \" : randomChar(charset)\n }\n return result\n}\n\nfunction EncryptedText({\n text,\n className,\n revealDelayMs = 50,\n charset = DEFAULT_CHARSET,\n flipDelayMs = 50,\n encryptedClassName,\n revealedClassName,\n scrambleOnly = false,\n scrambleOneChar = false,\n ...props\n}: EncryptedTextProps) {\n const ref = React.useRef<HTMLSpanElement>(null)\n const [isInView, setIsInView] = React.useState(false)\n const [revealCount, setRevealCount] = React.useState(0)\n const [, setFlipTick] = React.useState(0)\n\n const animationFrameRef = React.useRef<number | null>(null)\n const startTimeRef = React.useRef(0)\n const lastFlipTimeRef = React.useRef(0)\n const scrambleCharsRef = React.useRef<string[]>(\n text ? scramblePreservingSpaces(text, charset).split(\"\") : []\n )\n\n React.useEffect(() => {\n const el = ref.current\n if (!el) return\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (entry?.isIntersecting) {\n setIsInView(true)\n observer.disconnect()\n }\n },\n { threshold: 0 }\n )\n\n observer.observe(el)\n return () => observer.disconnect()\n }, [])\n\n React.useEffect(() => {\n if (!isInView) return\n\n const initial = text\n ? scramblePreservingSpaces(text, charset)\n : \"\"\n scrambleCharsRef.current = initial.split(\"\")\n startTimeRef.current = performance.now()\n lastFlipTimeRef.current = startTimeRef.current\n setRevealCount(0)\n\n let isCancelled = false\n\n const update = (now: number) => {\n if (isCancelled) return\n\n const totalLength = text.length\n\n if (scrambleOnly) {\n const timeSinceLastFlip = now - lastFlipTimeRef.current\n if (timeSinceLastFlip >= Math.max(0, flipDelayMs)) {\n if (scrambleOneChar) {\n const indices: number[] = []\n for (let i = 0; i < totalLength; i++) {\n if (text[i] !== \" \") indices.push(i)\n }\n if (indices.length > 0) {\n const idx = indices[Math.floor(Math.random() * indices.length)]!\n scrambleCharsRef.current[idx] = randomChar(charset)\n }\n } else {\n for (let index = 0; index < totalLength; index += 1) {\n scrambleCharsRef.current[index] =\n text[index] === \" \" ? \" \" : randomChar(charset)\n }\n }\n lastFlipTimeRef.current = now\n setFlipTick((t) => (t + 1) & 0xffff)\n }\n animationFrameRef.current = requestAnimationFrame(update)\n return\n }\n\n const elapsedMs = now - startTimeRef.current\n const currentRevealCount = Math.min(\n totalLength,\n Math.floor(elapsedMs / Math.max(1, revealDelayMs))\n )\n\n setRevealCount(currentRevealCount)\n\n if (currentRevealCount >= totalLength) return\n\n const timeSinceLastFlip = now - lastFlipTimeRef.current\n if (timeSinceLastFlip >= Math.max(0, flipDelayMs)) {\n for (let index = currentRevealCount; index < totalLength; index += 1) {\n scrambleCharsRef.current[index] =\n text[index] === \" \" ? \" \" : randomChar(charset)\n }\n lastFlipTimeRef.current = now\n }\n\n animationFrameRef.current = requestAnimationFrame(update)\n }\n\n animationFrameRef.current = requestAnimationFrame(update)\n\n return () => {\n isCancelled = true\n if (animationFrameRef.current !== null) {\n cancelAnimationFrame(animationFrameRef.current)\n }\n }\n }, [isInView, text, revealDelayMs, charset, flipDelayMs, scrambleOnly, scrambleOneChar])\n\n if (!text) return null\n\n return (\n <span\n ref={ref}\n data-slot=\"encrypted-text\"\n className={className}\n {...props}\n >\n {/* Real text for assistive tech; the animated glyphs below are decorative\n * (aria-label on a role-less span is unreliable, and the scrambled\n * characters must not be read out). */}\n <span className=\"sr-only\">{text}</span>\n {text.split(\"\").map((char, index) => {\n const isRevealed = !scrambleOnly && index < revealCount\n const displayChar = isRevealed\n ? char\n : char === \" \"\n ? \" \"\n : (scrambleCharsRef.current[index] ?? randomChar(charset))\n\n return (\n <span\n key={index}\n aria-hidden=\"true\"\n data-slot=\"encrypted-text-char\"\n data-revealed={isRevealed || undefined}\n className={cn(isRevealed ? revealedClassName : encryptedClassName)}\n >\n {displayChar}\n </span>\n )\n })}\n </span>\n )\n}\n\nexport { EncryptedText }\n"],"mappings":"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"}
@@ -152,7 +152,8 @@ function GradientRevealText({ text, duration = 0, colors = DEFAULT_COLORS, baseO
152
152
  onMouseMove: updatePos,
153
153
  className: cn("select-none", className),
154
154
  style: { opacity: measured ? 1 : 0 },
155
- "aria-hidden": true,
155
+ role: "img",
156
+ "aria-label": text,
156
157
  children: [
157
158
  /* @__PURE__ */ jsxs("defs", { children: [
158
159
  /* @__PURE__ */ jsx("linearGradient", {
@@ -1 +1 @@
1
- {"version":3,"file":"gradient-reveal-text.js","names":[],"sources":["../src/gradient-reveal-text.tsx"],"sourcesContent":["\"use client\"\n\nimport { useRef, useEffect, useState, useId, useCallback } from \"react\"\nimport { cn } from \"./lib/utils\"\n\ninterface GradientRevealTextProps {\n /** The text to display */\n text: string\n /** Spotlight follow speed in seconds. Default: 0 (instant) */\n duration?: number\n /** Gradient colors for the reveal effect. Default: rainbow */\n colors?: string[]\n /** Base stroke opacity when not hovered. Default: 0.3 */\n baseOpacity?: number\n /** Hovered stroke opacity. Default: 0.7 */\n hoverOpacity?: number\n /** Font family for SVG text. Default: Helvetica Neue */\n fontFamily?: string\n /** Spotlight radius multiplier relative to text height. Default: 0.6 */\n spotlightSize?: number\n /** Stroke width in px. Default: auto (1.5% of text height) */\n strokeWidth?: number\n /** Base stroke color. Default: neutral-200 (light) / neutral-800 (dark) via Tailwind */\n baseColor?: string\n className?: string\n}\n\nconst DEFAULT_COLORS = [\n \"#eab308\",\n \"#ef4444\",\n \"#3b82f6\",\n \"#06b6d4\",\n \"#8b5cf6\",\n]\n\n/**\n * Large decorative text with a gradient spotlight that follows the cursor.\n *\n * Renders as an SVG that auto-sizes to fit the text with zero padding.\n * The gradient reveal effect activates on hover — a circular spotlight\n * follows the mouse, revealing rainbow-colored strokes beneath.\n *\n * @example\n * ```tsx\n * <GradientRevealText text=\"HELLO\" />\n * <GradientRevealText text=\"BRAND\" colors={[\"#ff0000\", \"#00ff00\"]} />\n * ```\n */\nfunction GradientRevealText({\n text,\n duration = 0,\n colors = DEFAULT_COLORS,\n baseOpacity = 0.3,\n hoverOpacity = 0.7,\n fontFamily = \"Helvetica Neue, Helvetica, Arial, sans-serif\",\n spotlightSize = 0.6,\n strokeWidth: strokeWidthPx,\n baseColor,\n className,\n}: GradientRevealTextProps) {\n const uid = useId()\n const svgRef = useRef<SVGSVGElement>(null)\n const textRef = useRef<SVGTextElement>(null)\n const gradientRef = useRef<SVGRadialGradientElement>(null)\n\n const [vb, setVb] = useState({ x: 0, y: 0, w: 100, h: 20 })\n const [measured, setMeasured] = useState(false)\n const [hovered, setHovered] = useState(false)\n\n // Target position (where cursor is) and current animated position\n const targetPos = useRef({ cx: 0.5, cy: 0.5 })\n const currentPos = useRef({ cx: 0.5, cy: 0.5 })\n const rafId = useRef<number>(0)\n\n // Measure text bbox → set viewBox to fit exactly\n const measure = useCallback(() => {\n const el = textRef.current\n if (!el) return\n const bbox = el.getBBox()\n if (bbox.width === 0) return\n\n setVb({ x: bbox.x, y: bbox.y, w: bbox.width, h: bbox.height })\n setMeasured(true)\n }, [])\n\n useEffect(() => {\n measure()\n document.fonts?.ready?.then(measure)\n }, [text, measure])\n\n // Update the SVG gradient attributes directly (no React re-render)\n const applyGradientPos = useCallback((cx: number, cy: number) => {\n const el = gradientRef.current\n if (!el) return\n const svgCx = vb.x + cx * vb.w\n const svgCy = vb.y + cy * vb.h\n el.setAttribute(\"cx\", String(svgCx))\n el.setAttribute(\"cy\", String(svgCy))\n }, [vb])\n\n // RAF loop for smooth follow\n useEffect(() => {\n if (duration <= 0) return\n\n // Lerp factor: higher = faster catch-up. Derived from duration.\n const speed = 1 - Math.pow(0.001, 1 / (duration * 60))\n\n const tick = () => {\n const cur = currentPos.current\n const tgt = targetPos.current\n cur.cx += (tgt.cx - cur.cx) * speed\n cur.cy += (tgt.cy - cur.cy) * speed\n applyGradientPos(cur.cx, cur.cy)\n rafId.current = requestAnimationFrame(tick)\n }\n\n rafId.current = requestAnimationFrame(tick)\n return () => cancelAnimationFrame(rafId.current)\n }, [duration, applyGradientPos])\n\n const updatePos = (e: React.MouseEvent<SVGSVGElement>) => {\n const svg = svgRef.current\n if (!svg) return\n const rect = svg.getBoundingClientRect()\n const cx = (e.clientX - rect.left) / rect.width\n const cy = (e.clientY - rect.top) / rect.height\n targetPos.current = { cx, cy }\n\n // If no smooth follow, apply instantly\n if (duration <= 0) {\n currentPos.current = { cx, cy }\n applyGradientPos(cx, cy)\n }\n }\n\n const handleMouseEnter = (e: React.MouseEvent<SVGSVGElement>) => {\n // Snap to entry point — no lerp on first frame\n const svg = svgRef.current\n if (svg) {\n const rect = svg.getBoundingClientRect()\n const cx = (e.clientX - rect.left) / rect.width\n const cy = (e.clientY - rect.top) / rect.height\n targetPos.current = { cx, cy }\n currentPos.current = { cx, cy }\n applyGradientPos(cx, cy)\n }\n setHovered(true)\n }\n\n // Derived values\n const spotlightR = vb.h * spotlightSize\n const strokeW = strokeWidthPx ?? vb.h * 0.015\n const initCx = vb.x + 0.5 * vb.w\n const initCy = vb.y + 0.5 * vb.h\n\n // Unique SVG IDs\n const gradientId = `grad-${uid}`\n const maskId = `mask-${uid}`\n const revealId = `reveal-${uid}`\n\n // Evenly distribute color stops\n const stops = colors.map((color, i) => ({\n offset: `${(i / Math.max(colors.length - 1, 1)) * 100}%`,\n color,\n }))\n\n const textStyle = {\n fontSize: \"1em\",\n fontFamily,\n fill: \"none\",\n strokeWidth: strokeW,\n strokeLinejoin: \"round\" as const,\n strokeLinecap: \"round\" as const,\n paintOrder: \"stroke fill\" as const,\n }\n\n return (\n <svg\n ref={svgRef}\n data-slot=\"gradient-reveal-text\"\n width=\"100%\"\n viewBox={`${vb.x} ${vb.y} ${vb.w} ${vb.h}`}\n preserveAspectRatio=\"xMidYMid meet\"\n xmlns=\"http://www.w3.org/2000/svg\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={() => setHovered(false)}\n onMouseMove={updatePos}\n className={cn(\"select-none\", className)}\n style={{ opacity: measured ? 1 : 0 }}\n aria-hidden\n >\n <defs>\n <linearGradient id={gradientId} x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n {hovered &&\n stops.map((s) => (\n <stop key={s.offset} offset={s.offset} stopColor={s.color} />\n ))}\n </linearGradient>\n\n <radialGradient\n ref={gradientRef}\n id={revealId}\n gradientUnits=\"userSpaceOnUse\"\n r={spotlightR}\n cx={initCx}\n cy={initCy}\n >\n <stop offset=\"0%\" stopColor=\"white\" />\n <stop offset=\"100%\" stopColor=\"black\" />\n </radialGradient>\n\n <mask id={maskId}>\n <rect\n x={vb.x - vb.w}\n y={vb.y - vb.h}\n width={vb.w * 3}\n height={vb.h * 3}\n fill={`url(#${revealId})`}\n />\n </mask>\n </defs>\n\n {/* Hidden text for measurement */}\n <text\n ref={textRef}\n x=\"50%\"\n y=\"50%\"\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className=\"font-bold\"\n style={{ fontSize: \"1em\", fontFamily, visibility: \"hidden\" }}\n >\n {text}\n </text>\n\n {/* Base stroke — subtle outline */}\n <text\n x=\"50%\"\n y=\"50%\"\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className={baseColor ? \"font-bold\" : \"font-bold stroke-neutral-200 dark:stroke-neutral-800\"}\n style={{\n ...textStyle,\n ...(baseColor ? { stroke: baseColor } : {}),\n opacity: hovered ? hoverOpacity : baseOpacity,\n transition: \"opacity 0.3s ease\",\n }}\n >\n {text}\n </text>\n\n {/* Gradient reveal on hover */}\n <text\n x=\"50%\"\n y=\"50%\"\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n mask={`url(#${maskId})`}\n className=\"font-bold\"\n style={{\n ...textStyle,\n stroke: `url(#${gradientId})`,\n }}\n >\n {text}\n </text>\n </svg>\n )\n}\n\nexport { GradientRevealText }\nexport type { GradientRevealTextProps }\n"],"mappings":"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"}
1
+ {"version":3,"file":"gradient-reveal-text.js","names":[],"sources":["../src/gradient-reveal-text.tsx"],"sourcesContent":["\"use client\"\n\nimport { useRef, useEffect, useState, useId, useCallback } from \"react\"\nimport { cn } from \"./lib/utils\"\n\ninterface GradientRevealTextProps {\n /** The text to display */\n text: string\n /** Spotlight follow speed in seconds. Default: 0 (instant) */\n duration?: number\n /** Gradient colors for the reveal effect. Default: rainbow */\n colors?: string[]\n /** Base stroke opacity when not hovered. Default: 0.3 */\n baseOpacity?: number\n /** Hovered stroke opacity. Default: 0.7 */\n hoverOpacity?: number\n /** Font family for SVG text. Default: Helvetica Neue */\n fontFamily?: string\n /** Spotlight radius multiplier relative to text height. Default: 0.6 */\n spotlightSize?: number\n /** Stroke width in px. Default: auto (1.5% of text height) */\n strokeWidth?: number\n /** Base stroke color. Default: neutral-200 (light) / neutral-800 (dark) via Tailwind */\n baseColor?: string\n className?: string\n}\n\nconst DEFAULT_COLORS = [\n \"#eab308\",\n \"#ef4444\",\n \"#3b82f6\",\n \"#06b6d4\",\n \"#8b5cf6\",\n]\n\n/**\n * Large decorative text with a gradient spotlight that follows the cursor.\n *\n * Renders as an SVG that auto-sizes to fit the text with zero padding.\n * The gradient reveal effect activates on hover — a circular spotlight\n * follows the mouse, revealing rainbow-colored strokes beneath.\n *\n * @example\n * ```tsx\n * <GradientRevealText text=\"HELLO\" />\n * <GradientRevealText text=\"BRAND\" colors={[\"#ff0000\", \"#00ff00\"]} />\n * ```\n */\nfunction GradientRevealText({\n text,\n duration = 0,\n colors = DEFAULT_COLORS,\n baseOpacity = 0.3,\n hoverOpacity = 0.7,\n fontFamily = \"Helvetica Neue, Helvetica, Arial, sans-serif\",\n spotlightSize = 0.6,\n strokeWidth: strokeWidthPx,\n baseColor,\n className,\n}: GradientRevealTextProps) {\n const uid = useId()\n const svgRef = useRef<SVGSVGElement>(null)\n const textRef = useRef<SVGTextElement>(null)\n const gradientRef = useRef<SVGRadialGradientElement>(null)\n\n const [vb, setVb] = useState({ x: 0, y: 0, w: 100, h: 20 })\n const [measured, setMeasured] = useState(false)\n const [hovered, setHovered] = useState(false)\n\n // Target position (where cursor is) and current animated position\n const targetPos = useRef({ cx: 0.5, cy: 0.5 })\n const currentPos = useRef({ cx: 0.5, cy: 0.5 })\n const rafId = useRef<number>(0)\n\n // Measure text bbox → set viewBox to fit exactly\n const measure = useCallback(() => {\n const el = textRef.current\n if (!el) return\n const bbox = el.getBBox()\n if (bbox.width === 0) return\n\n setVb({ x: bbox.x, y: bbox.y, w: bbox.width, h: bbox.height })\n setMeasured(true)\n }, [])\n\n useEffect(() => {\n measure()\n document.fonts?.ready?.then(measure)\n }, [text, measure])\n\n // Update the SVG gradient attributes directly (no React re-render)\n const applyGradientPos = useCallback((cx: number, cy: number) => {\n const el = gradientRef.current\n if (!el) return\n const svgCx = vb.x + cx * vb.w\n const svgCy = vb.y + cy * vb.h\n el.setAttribute(\"cx\", String(svgCx))\n el.setAttribute(\"cy\", String(svgCy))\n }, [vb])\n\n // RAF loop for smooth follow\n useEffect(() => {\n if (duration <= 0) return\n\n // Lerp factor: higher = faster catch-up. Derived from duration.\n const speed = 1 - Math.pow(0.001, 1 / (duration * 60))\n\n const tick = () => {\n const cur = currentPos.current\n const tgt = targetPos.current\n cur.cx += (tgt.cx - cur.cx) * speed\n cur.cy += (tgt.cy - cur.cy) * speed\n applyGradientPos(cur.cx, cur.cy)\n rafId.current = requestAnimationFrame(tick)\n }\n\n rafId.current = requestAnimationFrame(tick)\n return () => cancelAnimationFrame(rafId.current)\n }, [duration, applyGradientPos])\n\n const updatePos = (e: React.MouseEvent<SVGSVGElement>) => {\n const svg = svgRef.current\n if (!svg) return\n const rect = svg.getBoundingClientRect()\n const cx = (e.clientX - rect.left) / rect.width\n const cy = (e.clientY - rect.top) / rect.height\n targetPos.current = { cx, cy }\n\n // If no smooth follow, apply instantly\n if (duration <= 0) {\n currentPos.current = { cx, cy }\n applyGradientPos(cx, cy)\n }\n }\n\n const handleMouseEnter = (e: React.MouseEvent<SVGSVGElement>) => {\n // Snap to entry point — no lerp on first frame\n const svg = svgRef.current\n if (svg) {\n const rect = svg.getBoundingClientRect()\n const cx = (e.clientX - rect.left) / rect.width\n const cy = (e.clientY - rect.top) / rect.height\n targetPos.current = { cx, cy }\n currentPos.current = { cx, cy }\n applyGradientPos(cx, cy)\n }\n setHovered(true)\n }\n\n // Derived values\n const spotlightR = vb.h * spotlightSize\n const strokeW = strokeWidthPx ?? vb.h * 0.015\n const initCx = vb.x + 0.5 * vb.w\n const initCy = vb.y + 0.5 * vb.h\n\n // Unique SVG IDs\n const gradientId = `grad-${uid}`\n const maskId = `mask-${uid}`\n const revealId = `reveal-${uid}`\n\n // Evenly distribute color stops\n const stops = colors.map((color, i) => ({\n offset: `${(i / Math.max(colors.length - 1, 1)) * 100}%`,\n color,\n }))\n\n const textStyle = {\n fontSize: \"1em\",\n fontFamily,\n fill: \"none\",\n strokeWidth: strokeW,\n strokeLinejoin: \"round\" as const,\n strokeLinecap: \"round\" as const,\n paintOrder: \"stroke fill\" as const,\n }\n\n return (\n <svg\n ref={svgRef}\n data-slot=\"gradient-reveal-text\"\n width=\"100%\"\n viewBox={`${vb.x} ${vb.y} ${vb.w} ${vb.h}`}\n preserveAspectRatio=\"xMidYMid meet\"\n xmlns=\"http://www.w3.org/2000/svg\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={() => setHovered(false)}\n onMouseMove={updatePos}\n className={cn(\"select-none\", className)}\n style={{ opacity: measured ? 1 : 0 }}\n role=\"img\"\n aria-label={text}\n >\n <defs>\n <linearGradient id={gradientId} x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n {hovered &&\n stops.map((s) => (\n <stop key={s.offset} offset={s.offset} stopColor={s.color} />\n ))}\n </linearGradient>\n\n <radialGradient\n ref={gradientRef}\n id={revealId}\n gradientUnits=\"userSpaceOnUse\"\n r={spotlightR}\n cx={initCx}\n cy={initCy}\n >\n <stop offset=\"0%\" stopColor=\"white\" />\n <stop offset=\"100%\" stopColor=\"black\" />\n </radialGradient>\n\n <mask id={maskId}>\n <rect\n x={vb.x - vb.w}\n y={vb.y - vb.h}\n width={vb.w * 3}\n height={vb.h * 3}\n fill={`url(#${revealId})`}\n />\n </mask>\n </defs>\n\n {/* Hidden text for measurement */}\n <text\n ref={textRef}\n x=\"50%\"\n y=\"50%\"\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className=\"font-bold\"\n style={{ fontSize: \"1em\", fontFamily, visibility: \"hidden\" }}\n >\n {text}\n </text>\n\n {/* Base stroke — subtle outline */}\n <text\n x=\"50%\"\n y=\"50%\"\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className={baseColor ? \"font-bold\" : \"font-bold stroke-neutral-200 dark:stroke-neutral-800\"}\n style={{\n ...textStyle,\n ...(baseColor ? { stroke: baseColor } : {}),\n opacity: hovered ? hoverOpacity : baseOpacity,\n transition: \"opacity 0.3s ease\",\n }}\n >\n {text}\n </text>\n\n {/* Gradient reveal on hover */}\n <text\n x=\"50%\"\n y=\"50%\"\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n mask={`url(#${maskId})`}\n className=\"font-bold\"\n style={{\n ...textStyle,\n stroke: `url(#${gradientId})`,\n }}\n >\n {text}\n </text>\n </svg>\n )\n}\n\nexport { GradientRevealText }\nexport type { GradientRevealTextProps }\n"],"mappings":"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"}
@@ -6,23 +6,16 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  //#region src/infinite-scroll.tsx
7
7
  function InfiniteScroll({ onLoadMore, hasMore, isLoading = false, direction = "down", root, rootMargin = "200px", threshold = 0, loader, endMessage, className, children }) {
8
8
  const sentinelRef = React.useRef(null);
9
- const loadingRef = React.useRef(false);
10
9
  const onLoadMoreRef = React.useRef(onLoadMore);
11
10
  React.useEffect(() => {
12
11
  onLoadMoreRef.current = onLoadMore;
13
12
  }, [onLoadMore]);
14
- React.useEffect(() => {
15
- if (!isLoading) loadingRef.current = false;
16
- }, [isLoading]);
17
13
  React.useEffect(() => {
18
14
  const sentinel = sentinelRef.current;
19
- if (!sentinel || !hasMore) return;
15
+ if (!sentinel || !hasMore || isLoading) return;
20
16
  const observer = new IntersectionObserver((entries) => {
21
17
  const [entry] = entries;
22
- if (entry?.isIntersecting && !loadingRef.current) {
23
- loadingRef.current = true;
24
- onLoadMoreRef.current();
25
- }
18
+ if (entry?.isIntersecting) onLoadMoreRef.current();
26
19
  }, {
27
20
  root: root?.current ?? null,
28
21
  rootMargin,
@@ -34,6 +27,7 @@ function InfiniteScroll({ onLoadMore, hasMore, isLoading = false, direction = "d
34
27
  };
35
28
  }, [
36
29
  hasMore,
30
+ isLoading,
37
31
  root,
38
32
  rootMargin,
39
33
  threshold
@@ -1 +1 @@
1
- {"version":3,"file":"infinite-scroll.js","names":[],"sources":["../src/infinite-scroll.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\nimport { Spinner } from \"./spinner\"\n\ntype InfiniteScrollProps = {\n onLoadMore: () => void\n hasMore: boolean\n isLoading?: boolean\n direction?: \"down\" | \"up\"\n root?: React.RefObject<Element | null>\n rootMargin?: string\n threshold?: number\n loader?: React.ReactNode\n endMessage?: React.ReactNode\n className?: string\n children?: React.ReactNode\n}\n\nfunction InfiniteScroll({\n onLoadMore,\n hasMore,\n isLoading = false,\n direction = \"down\",\n root,\n rootMargin = \"200px\",\n threshold = 0,\n loader,\n endMessage,\n className,\n children,\n}: InfiniteScrollProps) {\n const sentinelRef = React.useRef<HTMLDivElement>(null)\n const loadingRef = React.useRef(false)\n\n const onLoadMoreRef = React.useRef(onLoadMore)\n React.useEffect(() => {\n onLoadMoreRef.current = onLoadMore\n }, [onLoadMore])\n\n React.useEffect(() => {\n if (!isLoading) {\n loadingRef.current = false\n }\n }, [isLoading])\n\n React.useEffect(() => {\n const sentinel = sentinelRef.current\n if (!sentinel || !hasMore) return\n\n const observer = new IntersectionObserver(\n (entries) => {\n const [entry] = entries\n if (entry?.isIntersecting && !loadingRef.current) {\n loadingRef.current = true\n onLoadMoreRef.current()\n }\n },\n {\n root: root?.current ?? null,\n rootMargin,\n threshold,\n }\n )\n\n observer.observe(sentinel)\n\n return () => {\n observer.disconnect()\n }\n }, [hasMore, root, rootMargin, threshold])\n\n const loaderContent = isLoading && (\n <div\n data-slot=\"infinite-scroll-loader\"\n className=\"flex items-center justify-center py-6\"\n >\n {loader ?? <Spinner className=\"size-6 text-muted\" />}\n </div>\n )\n\n const endContent = !hasMore && !isLoading && endMessage && (\n <div\n data-slot=\"infinite-scroll-end\"\n className=\"flex items-center justify-center py-6 text-sm text-muted\"\n >\n {endMessage}\n </div>\n )\n\n const sentinel = (\n <div\n ref={sentinelRef}\n data-slot=\"infinite-scroll-sentinel\"\n aria-hidden=\"true\"\n className=\"h-px\"\n />\n )\n\n return (\n <div\n data-slot=\"infinite-scroll\"\n aria-busy={isLoading}\n className={cn(\"flex flex-col\", className)}\n >\n {direction === \"up\" && (\n <>\n {sentinel}\n {loaderContent}\n </>\n )}\n\n {children}\n\n {direction === \"down\" && (\n <>\n {sentinel}\n {loaderContent}\n </>\n )}\n\n {endContent}\n </div>\n )\n}\n\nexport { InfiniteScroll, type InfiniteScrollProps }\n"],"mappings":";;;;;;AAqBA,SAAS,eAAe,EACtB,YACA,SACA,YAAY,OACZ,YAAY,QACZ,MACA,aAAa,SACb,YAAY,GACZ,QACA,YACA,WACA,YACsB;CACtB,MAAM,cAAc,MAAM,OAAuB,KAAK;CACtD,MAAM,aAAa,MAAM,OAAO,MAAM;CAEtC,MAAM,gBAAgB,MAAM,OAAO,WAAW;AAC9C,OAAM,gBAAgB;AACpB,gBAAc,UAAU;IACvB,CAAC,WAAW,CAAC;AAEhB,OAAM,gBAAgB;AACpB,MAAI,CAAC,UACH,YAAW,UAAU;IAEtB,CAAC,UAAU,CAAC;AAEf,OAAM,gBAAgB;EACpB,MAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,YAAY,CAAC,QAAS;EAE3B,MAAM,WAAW,IAAI,sBAClB,YAAY;GACX,MAAM,CAAC,SAAS;AAChB,OAAI,OAAO,kBAAkB,CAAC,WAAW,SAAS;AAChD,eAAW,UAAU;AACrB,kBAAc,SAAS;;KAG3B;GACE,MAAM,MAAM,WAAW;GACvB;GACA;GACD,CACF;AAED,WAAS,QAAQ,SAAS;AAE1B,eAAa;AACX,YAAS,YAAY;;IAEtB;EAAC;EAAS;EAAM;EAAY;EAAU,CAAC;CAE1C,MAAM,gBAAgB,aACpB,oBAAC,OAAD;EACE,aAAU;EACV,WAAU;YAET,UAAU,oBAAC,SAAD,EAAS,WAAU,qBAAsB,CAAA;EAChD,CAAA;CAGR,MAAM,aAAa,CAAC,WAAW,CAAC,aAAa,cAC3C,oBAAC,OAAD;EACE,aAAU;EACV,WAAU;YAET;EACG,CAAA;CAGR,MAAM,WACJ,oBAAC,OAAD;EACE,KAAK;EACL,aAAU;EACV,eAAY;EACZ,WAAU;EACV,CAAA;AAGJ,QACE,qBAAC,OAAD;EACE,aAAU;EACV,aAAW;EACX,WAAW,GAAG,iBAAiB,UAAU;YAH3C;GAKG,cAAc,QACb,qBAAA,UAAA,EAAA,UAAA,CACG,UACA,cACA,EAAA,CAAA;GAGJ;GAEA,cAAc,UACb,qBAAA,UAAA,EAAA,UAAA,CACG,UACA,cACA,EAAA,CAAA;GAGJ;GACG"}
1
+ {"version":3,"file":"infinite-scroll.js","names":[],"sources":["../src/infinite-scroll.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\nimport { Spinner } from \"./spinner\"\n\ntype InfiniteScrollProps = {\n onLoadMore: () => void\n hasMore: boolean\n isLoading?: boolean\n direction?: \"down\" | \"up\"\n root?: React.RefObject<Element | null>\n rootMargin?: string\n threshold?: number\n loader?: React.ReactNode\n endMessage?: React.ReactNode\n className?: string\n children?: React.ReactNode\n}\n\nfunction InfiniteScroll({\n onLoadMore,\n hasMore,\n isLoading = false,\n direction = \"down\",\n root,\n rootMargin = \"200px\",\n threshold = 0,\n loader,\n endMessage,\n className,\n children,\n}: InfiniteScrollProps) {\n const sentinelRef = React.useRef<HTMLDivElement>(null)\n\n const onLoadMoreRef = React.useRef(onLoadMore)\n React.useEffect(() => {\n onLoadMoreRef.current = onLoadMore\n }, [onLoadMore])\n\n React.useEffect(() => {\n const sentinel = sentinelRef.current\n // Don't observe while a load is in flight. Re-observing when `isLoading`\n // flips back to false re-checks the sentinel's CURRENT visibility (an\n // IntersectionObserver fires an initial callback on `observe`), so a\n // sentinel that stayed in view across the load triggers the next page.\n // Without this the observer only fires on intersection *transitions* and\n // stalls once the sentinel stops moving.\n if (!sentinel || !hasMore || isLoading) return\n\n const observer = new IntersectionObserver(\n (entries) => {\n const [entry] = entries\n if (entry?.isIntersecting) {\n onLoadMoreRef.current()\n }\n },\n {\n root: root?.current ?? null,\n rootMargin,\n threshold,\n }\n )\n\n observer.observe(sentinel)\n\n return () => {\n observer.disconnect()\n }\n }, [hasMore, isLoading, root, rootMargin, threshold])\n\n const loaderContent = isLoading && (\n <div\n data-slot=\"infinite-scroll-loader\"\n className=\"flex items-center justify-center py-6\"\n >\n {loader ?? <Spinner className=\"size-6 text-muted\" />}\n </div>\n )\n\n const endContent = !hasMore && !isLoading && endMessage && (\n <div\n data-slot=\"infinite-scroll-end\"\n className=\"flex items-center justify-center py-6 text-sm text-muted\"\n >\n {endMessage}\n </div>\n )\n\n const sentinel = (\n <div\n ref={sentinelRef}\n data-slot=\"infinite-scroll-sentinel\"\n aria-hidden=\"true\"\n className=\"h-px\"\n />\n )\n\n return (\n <div\n data-slot=\"infinite-scroll\"\n aria-busy={isLoading}\n className={cn(\"flex flex-col\", className)}\n >\n {direction === \"up\" && (\n <>\n {sentinel}\n {loaderContent}\n </>\n )}\n\n {children}\n\n {direction === \"down\" && (\n <>\n {sentinel}\n {loaderContent}\n </>\n )}\n\n {endContent}\n </div>\n )\n}\n\nexport { InfiniteScroll, type InfiniteScrollProps }\n"],"mappings":";;;;;;AAqBA,SAAS,eAAe,EACtB,YACA,SACA,YAAY,OACZ,YAAY,QACZ,MACA,aAAa,SACb,YAAY,GACZ,QACA,YACA,WACA,YACsB;CACtB,MAAM,cAAc,MAAM,OAAuB,KAAK;CAEtD,MAAM,gBAAgB,MAAM,OAAO,WAAW;AAC9C,OAAM,gBAAgB;AACpB,gBAAc,UAAU;IACvB,CAAC,WAAW,CAAC;AAEhB,OAAM,gBAAgB;EACpB,MAAM,WAAW,YAAY;AAO7B,MAAI,CAAC,YAAY,CAAC,WAAW,UAAW;EAExC,MAAM,WAAW,IAAI,sBAClB,YAAY;GACX,MAAM,CAAC,SAAS;AAChB,OAAI,OAAO,eACT,eAAc,SAAS;KAG3B;GACE,MAAM,MAAM,WAAW;GACvB;GACA;GACD,CACF;AAED,WAAS,QAAQ,SAAS;AAE1B,eAAa;AACX,YAAS,YAAY;;IAEtB;EAAC;EAAS;EAAW;EAAM;EAAY;EAAU,CAAC;CAErD,MAAM,gBAAgB,aACpB,oBAAC,OAAD;EACE,aAAU;EACV,WAAU;YAET,UAAU,oBAAC,SAAD,EAAS,WAAU,qBAAsB,CAAA;EAChD,CAAA;CAGR,MAAM,aAAa,CAAC,WAAW,CAAC,aAAa,cAC3C,oBAAC,OAAD;EACE,aAAU;EACV,WAAU;YAET;EACG,CAAA;CAGR,MAAM,WACJ,oBAAC,OAAD;EACE,KAAK;EACL,aAAU;EACV,eAAY;EACZ,WAAU;EACV,CAAA;AAGJ,QACE,qBAAC,OAAD;EACE,aAAU;EACV,aAAW;EACX,WAAW,GAAG,iBAAiB,UAAU;YAH3C;GAKG,cAAc,QACb,qBAAA,UAAA,EAAA,UAAA,CACG,UACA,cACA,EAAA,CAAA;GAGJ;GAEA,cAAc,UACb,qBAAA,UAAA,EAAA,UAAA,CACG,UACA,cACA,EAAA,CAAA;GAGJ;GACG"}
@@ -18,7 +18,7 @@ declare function InputGroup({
18
18
  ...props
19
19
  }: InputGroupProps): _$react_jsx_runtime0.JSX.Element;
20
20
  declare const inputGroupAddonVariants: (props?: ({
21
- align?: "inline-end" | "inline-start" | "block-end" | "block-start" | null | undefined;
21
+ align?: "inline-start" | "inline-end" | "block-start" | "block-end" | null | undefined;
22
22
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
23
23
  declare function InputGroupAddon({
24
24
  className,
@@ -26,7 +26,7 @@ declare function InputGroupAddon({
26
26
  ...props
27
27
  }: InputGroupAddonProps): _$react_jsx_runtime0.JSX.Element;
28
28
  declare const inputGroupButtonVariants: (props?: ({
29
- size?: "sm" | "xs" | "icon-xs" | "icon-sm" | null | undefined;
29
+ size?: "xs" | "sm" | "icon-xs" | "icon-sm" | null | undefined;
30
30
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
31
31
  declare function InputGroupButton({
32
32
  className,
package/dist/item.d.ts CHANGED
@@ -8,10 +8,10 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
8
8
  //#region src/item.d.ts
9
9
  declare const itemVariants: (props?: ({
10
10
  variant?: "default" | "outline" | "muted" | null | undefined;
11
- size?: "default" | "sm" | "xs" | null | undefined;
11
+ size?: "default" | "xs" | "sm" | null | undefined;
12
12
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
13
13
  declare const itemMediaVariants: (props?: ({
14
- variant?: "default" | "image" | "icon" | null | undefined;
14
+ variant?: "default" | "icon" | "image" | null | undefined;
15
15
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
16
16
  type ItemGroupProps = React.ComponentProps<"div">;
17
17
  type ItemSeparatorProps = React.ComponentProps<typeof Separator>;
package/dist/label.js CHANGED
@@ -6,7 +6,7 @@ import { jsx } from "react/jsx-runtime";
6
6
  function Label({ className, ...props }) {
7
7
  return /* @__PURE__ */ jsx("label", {
8
8
  "data-slot": "label",
9
- className: cn("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className),
9
+ className: cn("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled]:pointer-events-none group-data-[disabled]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className),
10
10
  ...props
11
11
  });
12
12
  }
package/dist/label.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"label.js","names":[],"sources":["../src/label.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\n\ntype LabelProps = React.ComponentProps<\"label\">\n\nfunction Label({ className, ...props }: LabelProps) {\n return (\n <label\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n"],"mappings":";;;;;AAQA,SAAS,MAAM,EAAE,WAAW,GAAG,SAAqB;AAClD,QACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GACT,uNACA,UACD;EACD,GAAI;EACJ,CAAA"}
1
+ {"version":3,"file":"label.js","names":[],"sources":["../src/label.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\n\ntype LabelProps = React.ComponentProps<\"label\">\n\nfunction Label({ className, ...props }: LabelProps) {\n return (\n <label\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled]:pointer-events-none group-data-[disabled]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n"],"mappings":";;;;;AAQA,SAAS,MAAM,EAAE,WAAW,GAAG,SAAqB;AAClD,QACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GACT,6MACA,UACD;EACD,GAAI;EACJ,CAAA"}
@@ -5,7 +5,7 @@ import * as _$react_jsx_runtime0 from "react/jsx-runtime";
5
5
  /**
6
6
  * Internal-only SVG icons used by wave-ui components.
7
7
  *
8
- * NOT a public entry point — bundled into shared chunks via tsup splitting.
8
+ * NOT a public entry point — imported by components via relative paths.
9
9
  */
10
10
  type IconProps = React.SVGProps<SVGSVGElement>;
11
11
  declare function ChevronDownIcon(props: IconProps): _$react_jsx_runtime0.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"internal-icons.d.ts","names":[],"sources":["../../src/lib/internal-icons.tsx"],"mappings":";;;;;;;;AAmIuB;KA3HlB,SAAA,GAAY,KAAA,CAAM,QAAA,CAAS,aAAA;AAAA,iBAkBhB,eAAA,CAAgB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAQhC,aAAA,CAAc,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAQ9B,eAAA,CAAgB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAShC,gBAAA,CAAiB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAYjC,SAAA,CAAU,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAQ1B,SAAA,CAAU,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAS1B,SAAA,CAAU,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAQ1B,YAAA,CAAa,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAU7B,oBAAA,CAAqB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAUrC,kBAAA,CAAmB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAanC,gBAAA,CAAiB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;;cAUpC,UAAA,EAAU,OAAA,CAAA,yBAAA,CAAA,IAAA,CAAA,SAAA,WAAA,OAAA,CAAA,aAAA,CAAA,aAAA;AAAA,iBAqBP,iBAAA,CAAkB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAUlC,iBAAA,CAAkB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBASlC,cAAA,CAAe,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAU/B,eAAA,CAAgB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAchC,SAAA,CAAU,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAU1B,QAAA,CAAS,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"internal-icons.d.ts","names":[],"sources":["../../src/lib/internal-icons.tsx"],"mappings":";;;;;;;;AAwIuB;KAhIlB,SAAA,GAAY,KAAA,CAAM,QAAA,CAAS,aAAA;AAAA,iBAuBhB,eAAA,CAAgB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAQhC,aAAA,CAAc,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAQ9B,eAAA,CAAgB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAShC,gBAAA,CAAiB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAYjC,SAAA,CAAU,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAQ1B,SAAA,CAAU,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAS1B,SAAA,CAAU,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAQ1B,YAAA,CAAa,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAU7B,oBAAA,CAAqB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAUrC,kBAAA,CAAmB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAanC,gBAAA,CAAiB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;;cAUpC,UAAA,EAAU,OAAA,CAAA,yBAAA,CAAA,IAAA,CAAA,SAAA,WAAA,OAAA,CAAA,aAAA,CAAA,aAAA;AAAA,iBAqBP,iBAAA,CAAkB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAUlC,iBAAA,CAAkB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBASlC,cAAA,CAAe,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAU/B,eAAA,CAAgB,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAchC,SAAA,CAAU,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAU1B,QAAA,CAAS,KAAA,EAAO,SAAA,GAAS,oBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -4,7 +4,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
4
4
  /**
5
5
  * Internal-only SVG icons used by wave-ui components.
6
6
  *
7
- * NOT a public entry point — bundled into shared chunks via tsup splitting.
7
+ * NOT a public entry point — imported by components via relative paths.
8
8
  */
9
9
  const SVG_BASE = {
10
10
  xmlns: "http://www.w3.org/2000/svg",
@@ -15,7 +15,9 @@ const SVG_BASE = {
15
15
  stroke: "currentColor",
16
16
  strokeWidth: 2,
17
17
  strokeLinecap: "round",
18
- strokeLinejoin: "round"
18
+ strokeLinejoin: "round",
19
+ "aria-hidden": true,
20
+ focusable: false
19
21
  };
20
22
  function ChevronDownIcon(props) {
21
23
  return /* @__PURE__ */ jsx("svg", {
@@ -1 +1 @@
1
- {"version":3,"file":"internal-icons.js","names":[],"sources":["../../src/lib/internal-icons.tsx"],"sourcesContent":["/**\n * Internal-only SVG icons used by wave-ui components.\n *\n * NOT a public entry point — bundled into shared chunks via tsup splitting.\n */\n\nimport { forwardRef } from 'react';\n\ntype IconProps = React.SVGProps<SVGSVGElement>;\n\nconst SVG_BASE = {\n xmlns: 'http://www.w3.org/2000/svg',\n width: 24,\n height: 24,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n} as const;\n\n// ---------------------------------------------------------------------------\n// Navigation chevrons\n// ---------------------------------------------------------------------------\n\nexport function ChevronDownIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\nexport function ChevronUpIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n );\n}\n\nexport function ChevronLeftIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n );\n}\n\n\nexport function ChevronRightIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Actions\n// ---------------------------------------------------------------------------\n\nexport function CheckIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\nexport function CloseIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\nexport function MinusIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"M5 12h14\" />\n </svg>\n );\n}\n\nexport function EllipsisIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\n </svg>\n );\n}\n\nexport function EllipsisVerticalIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\n </svg>\n );\n}\n\nexport function ChevronsUpDownIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"m7 15 5 5 5-5\" />\n <path d=\"m7 9 5-5 5 5\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// UI chrome\n// ---------------------------------------------------------------------------\n\nexport function SidebarPanelIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n </svg>\n );\n}\n\n/** `forwardRef` because `Spinner` exposes this as `React.ComponentProps<\"svg\">`. */\nexport const LoaderIcon = forwardRef<SVGSVGElement, IconProps>(\n function LoaderIcon(props, ref) {\n return (\n <svg {...SVG_BASE} ref={ref} {...props}>\n <path d=\"M12 2v4\" />\n <path d=\"m16.2 7.8 2.9-2.9\" />\n <path d=\"M18 12h4\" />\n <path d=\"m16.2 16.2 2.9 2.9\" />\n <path d=\"M12 18v4\" />\n <path d=\"m4.9 19.1 2.9-2.9\" />\n <path d=\"M2 12h4\" />\n <path d=\"m4.9 4.9 2.9 2.9\" />\n </svg>\n );\n },\n);\n\n// ---------------------------------------------------------------------------\n// Toast status icons\n// ---------------------------------------------------------------------------\n\nexport function AlertTriangleIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n );\n}\n\nexport function SuccessCircleIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n </svg>\n );\n}\n\nexport function InfoCircleIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n </svg>\n );\n}\n\nexport function ErrorCircleIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m15 9-6 6\" />\n <path d=\"m9 9 6 6\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Social icons\n// ---------------------------------------------------------------------------\n\nexport function TrashIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\" />\n <path d=\"M3 6h18\" />\n <path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </svg>\n );\n}\n\nexport function StarIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\" />\n </svg>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"internal-icons.js","names":[],"sources":["../../src/lib/internal-icons.tsx"],"sourcesContent":["/**\n * Internal-only SVG icons used by wave-ui components.\n *\n * NOT a public entry point — imported by components via relative paths.\n */\n\nimport { forwardRef } from 'react';\n\ntype IconProps = React.SVGProps<SVGSVGElement>;\n\nconst SVG_BASE = {\n xmlns: 'http://www.w3.org/2000/svg',\n width: 24,\n height: 24,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n // Decorative by default — the control rendering an icon provides the\n // accessible name (aria-label / sr-only text). A component using an icon\n // *meaningfully* overrides this via props (e.g. Spinner sets aria-hidden={false}).\n \"aria-hidden\": true,\n focusable: false,\n} as const;\n\n// ---------------------------------------------------------------------------\n// Navigation chevrons\n// ---------------------------------------------------------------------------\n\nexport function ChevronDownIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\nexport function ChevronUpIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n );\n}\n\nexport function ChevronLeftIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n );\n}\n\n\nexport function ChevronRightIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Actions\n// ---------------------------------------------------------------------------\n\nexport function CheckIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\nexport function CloseIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\nexport function MinusIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"M5 12h14\" />\n </svg>\n );\n}\n\nexport function EllipsisIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\n </svg>\n );\n}\n\nexport function EllipsisVerticalIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\n </svg>\n );\n}\n\nexport function ChevronsUpDownIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"m7 15 5 5 5-5\" />\n <path d=\"m7 9 5-5 5 5\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// UI chrome\n// ---------------------------------------------------------------------------\n\nexport function SidebarPanelIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n </svg>\n );\n}\n\n/** `forwardRef` because `Spinner` exposes this as `React.ComponentProps<\"svg\">`. */\nexport const LoaderIcon = forwardRef<SVGSVGElement, IconProps>(\n function LoaderIcon(props, ref) {\n return (\n <svg {...SVG_BASE} ref={ref} {...props}>\n <path d=\"M12 2v4\" />\n <path d=\"m16.2 7.8 2.9-2.9\" />\n <path d=\"M18 12h4\" />\n <path d=\"m16.2 16.2 2.9 2.9\" />\n <path d=\"M12 18v4\" />\n <path d=\"m4.9 19.1 2.9-2.9\" />\n <path d=\"M2 12h4\" />\n <path d=\"m4.9 4.9 2.9 2.9\" />\n </svg>\n );\n },\n);\n\n// ---------------------------------------------------------------------------\n// Toast status icons\n// ---------------------------------------------------------------------------\n\nexport function AlertTriangleIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n );\n}\n\nexport function SuccessCircleIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n </svg>\n );\n}\n\nexport function InfoCircleIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n </svg>\n );\n}\n\nexport function ErrorCircleIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m15 9-6 6\" />\n <path d=\"m9 9 6 6\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Social icons\n// ---------------------------------------------------------------------------\n\nexport function TrashIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\" />\n <path d=\"M3 6h18\" />\n <path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </svg>\n );\n}\n\nexport function StarIcon(props: IconProps) {\n return (\n <svg {...SVG_BASE} {...props}>\n <path d=\"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\" />\n </svg>\n );\n}\n"],"mappings":"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"}
package/dist/spinner.js CHANGED
@@ -4,8 +4,10 @@ import { jsx } from "react/jsx-runtime";
4
4
  //#region src/spinner.tsx
5
5
  function Spinner({ className, ...props }) {
6
6
  return /* @__PURE__ */ jsx(LoaderIcon, {
7
+ "data-slot": "spinner",
7
8
  role: "status",
8
9
  "aria-label": "Loading",
10
+ "aria-hidden": false,
9
11
  className: cn("size-4 animate-spin", className),
10
12
  ...props
11
13
  });
@@ -1 +1 @@
1
- {"version":3,"file":"spinner.js","names":[],"sources":["../src/spinner.tsx"],"sourcesContent":["import { cn } from \"./lib/utils\"\nimport { LoaderIcon } from \"./lib/internal-icons\"\n\ntype SpinnerProps = React.ComponentProps<\"svg\">\n\nfunction Spinner({ className, ...props }: SpinnerProps) {\n return (\n <LoaderIcon role=\"status\" aria-label=\"Loading\" className={cn(\"size-4 animate-spin\", className)} {...props} />\n )\n}\n\nexport { Spinner }\n"],"mappings":";;;;AAKA,SAAS,QAAQ,EAAE,WAAW,GAAG,SAAuB;AACtD,QACE,oBAAC,YAAD;EAAY,MAAK;EAAS,cAAW;EAAU,WAAW,GAAG,uBAAuB,UAAU;EAAE,GAAI;EAAS,CAAA"}
1
+ {"version":3,"file":"spinner.js","names":[],"sources":["../src/spinner.tsx"],"sourcesContent":["import { cn } from \"./lib/utils\"\nimport { LoaderIcon } from \"./lib/internal-icons\"\n\ntype SpinnerProps = React.ComponentProps<\"svg\">\n\nfunction Spinner({ className, ...props }: SpinnerProps) {\n return (\n <LoaderIcon\n data-slot=\"spinner\"\n role=\"status\"\n aria-label=\"Loading\"\n // The spinner IS the accessible status, so it opts out of the\n // decorative-by-default aria-hidden that internal icons carry.\n aria-hidden={false}\n className={cn(\"size-4 animate-spin\", className)}\n {...props}\n />\n )\n}\n\nexport { Spinner }\n"],"mappings":";;;;AAKA,SAAS,QAAQ,EAAE,WAAW,GAAG,SAAuB;AACtD,QACE,oBAAC,YAAD;EACE,aAAU;EACV,MAAK;EACL,cAAW;EAGX,eAAa;EACb,WAAW,GAAG,uBAAuB,UAAU;EAC/C,GAAI;EACJ,CAAA"}
package/dist/styles.css CHANGED
@@ -33,17 +33,17 @@
33
33
 
34
34
  /* Wave — brand ramp. 500 = Wave Blue #0074DE.
35
35
  * A true cobalt signal: calm, trustable, solid, constant. */
36
- --wave-50: #EEF8FF;
37
- --wave-100: #D6EEFF;
38
- --wave-200: #AEDDFF;
39
- --wave-300: #7BC3FF;
40
- --wave-400: #3EA3FF;
41
- --wave-500: #0074DE;
42
- --wave-600: #0061C6;
43
- --wave-700: #004C9F;
44
- --wave-800: #003976;
45
- --wave-900: #042954;
46
- --wave-950: #061C37;
36
+ --wave-50: oklch(0.974 0.014 238); /* #EEF8FF */
37
+ --wave-100: oklch(0.937 0.034 239); /* #D6EEFF */
38
+ --wave-200: oklch(0.876 0.068 240); /* #AEDDFF */
39
+ --wave-300: oklch(0.793 0.112 245); /* #7BC3FF */
40
+ --wave-400: oklch(0.700 0.164 250); /* #3EA3FF */
41
+ --wave-500: oklch(0.566 0.184 255); /* #0074DE */
42
+ --wave-600: oklch(0.506 0.175 256); /* #0061C6 */
43
+ --wave-700: oklch(0.429 0.150 257); /* #004C9F */
44
+ --wave-800: oklch(0.351 0.118 255); /* #003976 */
45
+ --wave-900: oklch(0.284 0.088 255); /* #042954 */
46
+ --wave-950: oklch(0.226 0.060 255); /* #061C37 */
47
47
 
48
48
  /* ── Neutral theme palettes (primitives) ─────────────────────────────────
49
49
  * Three complete neutral ramps, one per theme. The theme class on <html>
@@ -53,45 +53,45 @@
53
53
  * ──────────────────────────────────────────────────────────────────────── */
54
54
 
55
55
  /* Graphite — neutral grey (default) */
56
- --graphite-50: #FAFAFB;
57
- --graphite-100: #F3F3F4;
58
- --graphite-200: #E5E5E8;
59
- --graphite-300: #D1D2D7;
60
- --graphite-400: #ABACB2;
61
- --graphite-500: #8B8C94;
62
- --graphite-600: #6C6D76;
63
- --graphite-700: #4C4D55;
64
- --graphite-800: #3B3C44;
65
- --graphite-900: #323339;
66
- --graphite-950: #2C2D32;
56
+ --graphite-50: oklch(0.985 0.001 286); /* #FAFAFB */
57
+ --graphite-100: oklch(0.964 0.001 286); /* #F3F3F4 */
58
+ --graphite-200: oklch(0.923 0.004 286); /* #E5E5E8 */
59
+ --graphite-300: oklch(0.864 0.007 277); /* #D1D2D7 */
60
+ --graphite-400: oklch(0.745 0.009 279); /* #ABACB2 */
61
+ --graphite-500: oklch(0.642 0.012 280); /* #8B8C94 */
62
+ --graphite-600: oklch(0.537 0.014 281); /* #6C6D76 */
63
+ --graphite-700: oklch(0.422 0.013 280); /* #4C4D55 */
64
+ --graphite-800: oklch(0.358 0.014 280); /* #3B3C44 */
65
+ --graphite-900: oklch(0.322 0.011 278); /* #323339 */
66
+ --graphite-950: oklch(0.298 0.009 277); /* #2C2D32 */
67
67
 
68
68
  /* Ink — deep navy surfaces, neutral-cool structure (page #020812, surface #050F1E).
69
69
  * Chroma fades from full navy at the dark surfaces to near-neutral at the light
70
70
  * end, so text/borders read as a distinct layer rather than melting into navy. */
71
- --ink-50: #F2F4F6;
72
- --ink-100: #DFE1E5;
73
- --ink-200: #C5C9CE;
74
- --ink-300: #AAAFB6;
75
- --ink-400: #8C929A;
76
- --ink-500: #6E747D;
77
- --ink-600: #4F5763;
78
- --ink-700: #323D4C;
79
- --ink-800: #162336;
80
- --ink-900: #050F1E;
81
- --ink-950: #020812;
71
+ --ink-50: oklch(0.966 0.003 248); /* #F2F4F6 */
72
+ --ink-100: oklch(0.909 0.006 265); /* #DFE1E5 */
73
+ --ink-200: oklch(0.834 0.008 254); /* #C5C9CE */
74
+ --ink-300: oklch(0.752 0.011 257); /* #AAAFB6 */
75
+ --ink-400: oklch(0.658 0.014 256); /* #8C929A */
76
+ --ink-500: oklch(0.557 0.016 258); /* #6E747D */
77
+ --ink-600: oklch(0.454 0.022 258); /* #4F5763 */
78
+ --ink-700: oklch(0.356 0.030 256); /* #323D4C */
79
+ --ink-800: oklch(0.254 0.041 258); /* #162336 */
80
+ --ink-900: oklch(0.168 0.036 257); /* #050F1E */
81
+ --ink-950: oklch(0.132 0.027 252); /* #020812 */
82
82
 
83
83
  /* Paper — cool near-neutral (anchor #EFF0EB @ 200 = foundation) */
84
- --paper-50: #FCFDFA;
85
- --paper-100: #F6F7F3;
86
- --paper-200: #EFF0EB;
87
- --paper-300: #D7D8D2;
88
- --paper-400: #AAACA5;
89
- --paper-500: #83847D;
90
- --paper-600: #63645E;
91
- --paper-700: #494A44;
92
- --paper-800: #30312C;
93
- --paper-900: #1B1C18;
94
- --paper-950: #0C0D09;
84
+ --paper-50: oklch(0.992 0.004 122); /* #FCFDFA */
85
+ --paper-100: oklch(0.974 0.005 118); /* #F6F7F3 */
86
+ --paper-200: oklch(0.953 0.007 116); /* #EFF0EB */
87
+ --paper-300: oklch(0.880 0.008 114); /* #D7D8D2 */
88
+ --paper-400: oklch(0.741 0.010 120); /* #AAACA5 */
89
+ --paper-500: oklch(0.610 0.010 113); /* #83847D */
90
+ --paper-600: oklch(0.500 0.009 114); /* #63645E */
91
+ --paper-700: oklch(0.406 0.010 115); /* #494A44 */
92
+ --paper-800: oklch(0.310 0.009 116); /* #30312C */
93
+ --paper-900: oklch(0.224 0.008 118); /* #1B1C18 */
94
+ --paper-950: oklch(0.156 0.008 119); /* #0C0D09 */
95
95
 
96
96
  /* Active neutral alias — the theme class on <html> repoints these to one of
97
97
  * the ramps above (step 3). Default (no theme class) = Graphite. The semantic
@@ -146,12 +146,12 @@
146
146
  /* Rings = brand themed */
147
147
  --focus: var(--primary);
148
148
 
149
- /* Shadow — two dials for the layered `shadow-*` scale: `--shadow-color` (HSL
150
- * components — a deep cool-tinted near-black, never pure #000 which reads
151
- * heavy) and `--shadow-strength` (per-layer alpha / intensity). Both resolve
152
- * per :root/.dark, so retinting OR dimming every shadow is one token. For a
153
- * colored surface set a named tint, e.g. `--shadow-color-primary`. */
154
- --shadow-color: 220deg 45% 6%;
149
+ /* Shadow — two dials for the layered `shadow-*` scale: `--shadow-color` (oklch
150
+ * components `L C H` — a deep cool-tinted near-black, never pure black which
151
+ * reads heavy) and `--shadow-strength` (per-layer alpha / intensity). Both
152
+ * resolve per :root/.dark, so retinting OR dimming every shadow is one token.
153
+ * For a colored surface set a named tint, e.g. `--shadow-color-primary`. */
154
+ --shadow-color: 0.159 0.021 263; /* was hsl(220 45% 6%) */
155
155
  --shadow-strength: 0.22;
156
156
 
157
157
  /* Status */
@@ -238,7 +238,7 @@
238
238
 
239
239
  /* Shadow — darker tint, lower strength: a near-black shadow on a dark
240
240
  * surface reads heavier than on white, so dim it. */
241
- --shadow-color: 220deg 40% 3%;
241
+ --shadow-color: 0.125 0.011 259; /* was hsl(220 40% 3%) */
242
242
  --shadow-strength: 0.18;
243
243
 
244
244
  /* Status */
@@ -347,23 +347,23 @@
347
347
  * Overrides Tailwind's shadow-sm/md/lg. */
348
348
  @theme {
349
349
  --shadow-sm:
350
- 0px 0.5px 0.7px hsl(var(--shadow-color) / var(--shadow-strength)),
351
- 0px 0.8px 1px -1.2px hsl(var(--shadow-color) / var(--shadow-strength)),
352
- 0px 2px 2.5px -2.5px hsl(var(--shadow-color) / var(--shadow-strength));
350
+ 0px 0.5px 0.7px oklch(var(--shadow-color) / var(--shadow-strength)),
351
+ 0px 0.8px 1px -1.2px oklch(var(--shadow-color) / var(--shadow-strength)),
352
+ 0px 2px 2.5px -2.5px oklch(var(--shadow-color) / var(--shadow-strength));
353
353
  --shadow-md:
354
- 0px 0.5px 0.7px hsl(var(--shadow-color) / var(--shadow-strength)),
355
- 0px 1.6px 2px -0.8px hsl(var(--shadow-color) / var(--shadow-strength)),
356
- 0px 4.1px 5.2px -1.7px hsl(var(--shadow-color) / var(--shadow-strength)),
357
- 0px 10px 12.6px -2.5px hsl(var(--shadow-color) / var(--shadow-strength));
354
+ 0px 0.5px 0.7px oklch(var(--shadow-color) / var(--shadow-strength)),
355
+ 0px 1.6px 2px -0.8px oklch(var(--shadow-color) / var(--shadow-strength)),
356
+ 0px 4.1px 5.2px -1.7px oklch(var(--shadow-color) / var(--shadow-strength)),
357
+ 0px 10px 12.6px -2.5px oklch(var(--shadow-color) / var(--shadow-strength));
358
358
  --shadow-lg:
359
- 0px 0.5px 0.7px hsl(var(--shadow-color) / var(--shadow-strength)),
360
- 0px 2.9px 3.7px -0.4px hsl(var(--shadow-color) / var(--shadow-strength)),
361
- 0px 5.4px 6.8px -0.7px hsl(var(--shadow-color) / var(--shadow-strength)),
362
- 0px 8.9px 11.2px -1.1px hsl(var(--shadow-color) / var(--shadow-strength)),
363
- 0px 14.3px 18px -1.4px hsl(var(--shadow-color) / var(--shadow-strength)),
364
- 0px 22.3px 28.1px -1.8px hsl(var(--shadow-color) / var(--shadow-strength)),
365
- 0px 33.9px 42.7px -2.1px hsl(var(--shadow-color) / var(--shadow-strength)),
366
- 0px 50px 62.9px -2.5px hsl(var(--shadow-color) / var(--shadow-strength));
359
+ 0px 0.5px 0.7px oklch(var(--shadow-color) / var(--shadow-strength)),
360
+ 0px 2.9px 3.7px -0.4px oklch(var(--shadow-color) / var(--shadow-strength)),
361
+ 0px 5.4px 6.8px -0.7px oklch(var(--shadow-color) / var(--shadow-strength)),
362
+ 0px 8.9px 11.2px -1.1px oklch(var(--shadow-color) / var(--shadow-strength)),
363
+ 0px 14.3px 18px -1.4px oklch(var(--shadow-color) / var(--shadow-strength)),
364
+ 0px 22.3px 28.1px -1.8px oklch(var(--shadow-color) / var(--shadow-strength)),
365
+ 0px 33.9px 42.7px -2.1px oklch(var(--shadow-color) / var(--shadow-strength)),
366
+ 0px 50px 62.9px -2.5px oklch(var(--shadow-color) / var(--shadow-strength));
367
367
  }
368
368
 
369
369
  /* ---------------------------------------------------------------------------
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.d.ts","names":[],"sources":["../src/textarea.tsx"],"mappings":";;;;KAIK,aAAA,GAAgB,IAAA,CAAK,KAAA,CAAM,cAAA;EAC9B,QAAA,GAAW,KAAA,CAAM,kBAAA,CAAmB,mBAAA;EACpC,aAAA,IAAiB,KAAA;AAAA;AAAA,iBAGV,QAAA,CAAA;EAAW,SAAA;EAAW,QAAA;EAAU,aAAA;EAAA,GAAkB;AAAA,GAAS,aAAA,GAAa,oBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"textarea.d.ts","names":[],"sources":["../src/textarea.tsx"],"mappings":";;;;KAMK,aAAA,GAAgB,IAAA,CAAK,KAAA,CAAM,cAAA;EAC9B,QAAA,GAAW,KAAA,CAAM,kBAAA,CAAmB,mBAAA;EACpC,aAAA,IAAiB,KAAA;AAAA;AAAA,iBAGV,QAAA,CAAA;EAAW,SAAA;EAAW,QAAA;EAAU,aAAA;EAAA,GAAkB;AAAA,GAAS,aAAA,GAAa,oBAAA,CAAA,GAAA,CAAA,OAAA"}
package/dist/textarea.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "./lib/utils.js";
2
3
  import "react";
3
4
  import { jsx } from "react/jsx-runtime";
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.js","names":[],"sources":["../src/textarea.tsx"],"sourcesContent":["import * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\n\ntype TextareaProps = Omit<React.ComponentProps<\"textarea\">, \"onChange\"> & {\n onChange?: React.ChangeEventHandler<HTMLTextAreaElement>\n onValueChange?: (value: string) => void\n}\n\nfunction Textarea({ className, onChange, onValueChange, ...props }: TextareaProps) {\n function handleChange(e: React.ChangeEvent<HTMLTextAreaElement>) {\n onChange?.(e)\n onValueChange?.(e.target.value)\n }\n\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n \"border-edge dark:bg-edge/30 focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 resize-none disabled:bg-edge/50 disabled:cursor-not-allowed dark:disabled:bg-edge/80 placeholder:text-soft flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-2.5 py-2 text-base transition-colors outline-none focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 md:text-sm\",\n className,\n )}\n onChange={handleChange}\n {...props}\n />\n )\n}\n\nexport { Textarea }\n"],"mappings":";;;;AASA,SAAS,SAAS,EAAE,WAAW,UAAU,eAAe,GAAG,SAAwB;CACjF,SAAS,aAAa,GAA2C;AAC/D,aAAW,EAAE;AACb,kBAAgB,EAAE,OAAO,MAAM;;AAGjC,QACE,oBAAC,YAAD;EACE,aAAU;EACV,WAAW,GACT,ojBACA,UACD;EACD,UAAU;EACV,GAAI;EACJ,CAAA"}
1
+ {"version":3,"file":"textarea.js","names":[],"sources":["../src/textarea.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\n\ntype TextareaProps = Omit<React.ComponentProps<\"textarea\">, \"onChange\"> & {\n onChange?: React.ChangeEventHandler<HTMLTextAreaElement>\n onValueChange?: (value: string) => void\n}\n\nfunction Textarea({ className, onChange, onValueChange, ...props }: TextareaProps) {\n function handleChange(e: React.ChangeEvent<HTMLTextAreaElement>) {\n onChange?.(e)\n onValueChange?.(e.target.value)\n }\n\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n \"border-edge dark:bg-edge/30 focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 resize-none disabled:bg-edge/50 disabled:cursor-not-allowed dark:disabled:bg-edge/80 placeholder:text-soft flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-2.5 py-2 text-base transition-colors outline-none focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 md:text-sm\",\n className,\n )}\n onChange={handleChange}\n {...props}\n />\n )\n}\n\nexport { Textarea }\n"],"mappings":";;;;;AAWA,SAAS,SAAS,EAAE,WAAW,UAAU,eAAe,GAAG,SAAwB;CACjF,SAAS,aAAa,GAA2C;AAC/D,aAAW,EAAE;AACb,kBAAgB,EAAE,OAAO,MAAM;;AAGjC,QACE,oBAAC,YAAD;EACE,aAAU;EACV,WAAW,GACT,ojBACA,UACD;EACD,UAAU;EACV,GAAI;EACJ,CAAA"}
package/dist/toast.d.ts CHANGED
@@ -7,7 +7,7 @@ import * as _$_base_ui_react0 from "@base-ui/react";
7
7
  //#region src/toast.d.ts
8
8
  declare const toastRootClass = "bg-elevated text-contrast ring-contrast/10 rounded-md p-4 text-sm shadow-md ring-1 outline-none select-none";
9
9
  declare const toastIconVariants: (props?: ({
10
- type?: "loading" | "success" | "info" | "warning" | "error" | null | undefined;
10
+ type?: "success" | "loading" | "info" | "warning" | "error" | null | undefined;
11
11
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
12
12
  declare const toastViewportVariants: (props?: ({
13
13
  position?: "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right" | null | undefined;
@@ -7,7 +7,6 @@ import { ToggleGroup as ToggleGroup$1 } from "@base-ui/react/toggle-group";
7
7
  //#region src/toggle-group.d.ts
8
8
  type ToggleGroupProps = ToggleGroup$1.Props & VariantProps<typeof toggleVariants> & {
9
9
  spacing?: number;
10
- orientation?: "horizontal" | "vertical";
11
10
  };
12
11
  type ToggleGroupItemProps = Toggle.Props & VariantProps<typeof toggleVariants>;
13
12
  declare function ToggleGroup({
@@ -1 +1 @@
1
- {"version":3,"file":"toggle-group.d.ts","names":[],"sources":["../src/toggle-group.tsx"],"mappings":";;;;;;;KAeK,gBAAA,GAAmB,aAAA,CAAqB,KAAA,GAC3C,YAAA,QAAoB,cAAA;EAClB,OAAA;EACA,WAAA;AAAA;AAAA,KAGC,oBAAA,GAAuB,MAAA,CAAgB,KAAA,GAC1C,YAAA,QAAoB,cAAA;AAAA,iBASb,WAAA,CAAA;EACP,SAAA;EACA,OAAA;EACA,IAAA;EACA,OAAA;EACA,WAAA;EACA,QAAA;EAAA,GACG;AAAA,GACF,gBAAA,GAAgB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAwBV,eAAA,CAAA;EACP,SAAA;EACA,QAAA;EACA,OAAA;EACA,IAAA;EAAA,GACG;AAAA,GACF,oBAAA,GAAoB,oBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"toggle-group.d.ts","names":[],"sources":["../src/toggle-group.tsx"],"mappings":";;;;;;;KAeK,gBAAA,GAAmB,aAAA,CAAqB,KAAA,GAC3C,YAAA,QAAoB,cAAA;EAClB,OAAA;AAAA;AAAA,KAGC,oBAAA,GAAuB,MAAA,CAAgB,KAAA,GAC1C,YAAA,QAAoB,cAAA;AAAA,iBASb,WAAA,CAAA;EACP,SAAA;EACA,OAAA;EACA,IAAA;EACA,OAAA;EACA,WAAA;EACA,QAAA;EAAA,GACG;AAAA,GACF,gBAAA,GAAgB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAwBV,eAAA,CAAA;EACP,SAAA;EACA,QAAA;EACA,OAAA;EACA,IAAA;EAAA,GACG;AAAA,GACF,oBAAA,GAAoB,oBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -14,11 +14,11 @@ const ToggleGroupContext = React.createContext({
14
14
  });
15
15
  function ToggleGroup({ className, variant, size, spacing = 0, orientation = "horizontal", children, ...props }) {
16
16
  return /* @__PURE__ */ jsx(ToggleGroup$1, {
17
+ orientation,
17
18
  "data-slot": "toggle-group",
18
19
  "data-variant": variant,
19
20
  "data-size": size,
20
21
  "data-spacing": spacing,
21
- "data-orientation": orientation,
22
22
  style: { "--gap": spacing },
23
23
  className: cn("group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-md data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch data-[size=sm]:rounded-sm", className),
24
24
  ...props,
@@ -1 +1 @@
1
- {"version":3,"file":"toggle-group.js","names":["ToggleGroupPrimitive","TogglePrimitive"],"sources":["../src/toggle-group.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Toggle as TogglePrimitive } from \"@base-ui/react/toggle\"\nimport { ToggleGroup as ToggleGroupPrimitive } from \"@base-ui/react/toggle-group\"\nimport { type VariantProps } from \"class-variance-authority\"\n\nimport { toggleVariants } from \"./toggle\"\nimport { cn } from \"./lib/utils\"\n\ntype ToggleGroupContextValue = VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n}\n\ntype ToggleGroupProps = ToggleGroupPrimitive.Props &\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }\n\ntype ToggleGroupItemProps = TogglePrimitive.Props &\n VariantProps<typeof toggleVariants>\n\nconst ToggleGroupContext = React.createContext<ToggleGroupContextValue>({\n size: \"default\",\n variant: \"default\",\n spacing: 0,\n orientation: \"horizontal\",\n})\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n spacing = 0,\n orientation = \"horizontal\",\n children,\n ...props\n}: ToggleGroupProps) {\n return (\n <ToggleGroupPrimitive\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n data-spacing={spacing}\n data-orientation={orientation}\n style={{ \"--gap\": spacing } as React.CSSProperties}\n className={cn(\n \"group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-md data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch data-[size=sm]:rounded-sm\",\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider\n value={{ variant, size, spacing, orientation }}\n >\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ToggleGroupItemProps) {\n const context = React.useContext(ToggleGroupContext)\n\n return (\n <TogglePrimitive\n data-slot=\"toggle-group-item\"\n data-variant={context.variant || variant}\n data-size={context.size || size}\n data-spacing={context.spacing}\n className={cn(\n \"shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-[orientation=horizontal]/toggle-group:data-[spacing=0]:first:rounded-l-md group-data-[orientation=vertical]/toggle-group:data-[spacing=0]:first:rounded-t-md group-data-[orientation=horizontal]/toggle-group:data-[spacing=0]:last:rounded-r-md group-data-[orientation=vertical]/toggle-group:data-[spacing=0]:last:rounded-b-md group-data-[orientation=horizontal]/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-[orientation=vertical]/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-[orientation=horizontal]/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-[orientation=vertical]/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t\",\n toggleVariants({\n variant: context.variant || variant,\n size: context.size || size,\n }),\n className\n )}\n {...props}\n >\n {children}\n </TogglePrimitive>\n )\n}\n\nexport { ToggleGroup, ToggleGroupItem }\n"],"mappings":";;;;;;;;AAwBA,MAAM,qBAAqB,MAAM,cAAuC;CACtE,MAAM;CACN,SAAS;CACT,SAAS;CACT,aAAa;CACd,CAAC;AAEF,SAAS,YAAY,EACnB,WACA,SACA,MACA,UAAU,GACV,cAAc,cACd,UACA,GAAG,SACgB;AACnB,QACE,oBAACA,eAAD;EACE,aAAU;EACV,gBAAc;EACd,aAAW;EACX,gBAAc;EACd,oBAAkB;EAClB,OAAO,EAAE,SAAS,SAAS;EAC3B,WAAW,GACT,uMACA,UACD;EACD,GAAI;YAEJ,oBAAC,mBAAmB,UAApB;GACE,OAAO;IAAE;IAAS;IAAM;IAAS;IAAa;GAE7C;GAC2B,CAAA;EACT,CAAA;;AAI3B,SAAS,gBAAgB,EACvB,WACA,UACA,UAAU,WACV,OAAO,WACP,GAAG,SACoB;CACvB,MAAM,UAAU,MAAM,WAAW,mBAAmB;AAEpD,QACE,oBAACC,QAAD;EACE,aAAU;EACV,gBAAc,QAAQ,WAAW;EACjC,aAAW,QAAQ,QAAQ;EAC3B,gBAAc,QAAQ;EACtB,WAAW,GACT,s2BACA,eAAe;GACb,SAAS,QAAQ,WAAW;GAC5B,MAAM,QAAQ,QAAQ;GACvB,CAAC,EACF,UACD;EACD,GAAI;EAEH;EACe,CAAA"}
1
+ {"version":3,"file":"toggle-group.js","names":["ToggleGroupPrimitive","TogglePrimitive"],"sources":["../src/toggle-group.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Toggle as TogglePrimitive } from \"@base-ui/react/toggle\"\nimport { ToggleGroup as ToggleGroupPrimitive } from \"@base-ui/react/toggle-group\"\nimport { type VariantProps } from \"class-variance-authority\"\n\nimport { toggleVariants } from \"./toggle\"\nimport { cn } from \"./lib/utils\"\n\ntype ToggleGroupContextValue = VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n}\n\ntype ToggleGroupProps = ToggleGroupPrimitive.Props &\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n }\n\ntype ToggleGroupItemProps = TogglePrimitive.Props &\n VariantProps<typeof toggleVariants>\n\nconst ToggleGroupContext = React.createContext<ToggleGroupContextValue>({\n size: \"default\",\n variant: \"default\",\n spacing: 0,\n orientation: \"horizontal\",\n})\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n spacing = 0,\n orientation = \"horizontal\",\n children,\n ...props\n}: ToggleGroupProps) {\n return (\n <ToggleGroupPrimitive\n orientation={orientation}\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n data-spacing={spacing}\n style={{ \"--gap\": spacing } as React.CSSProperties}\n className={cn(\n \"group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-md data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch data-[size=sm]:rounded-sm\",\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider\n value={{ variant, size, spacing, orientation }}\n >\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ToggleGroupItemProps) {\n const context = React.useContext(ToggleGroupContext)\n\n return (\n <TogglePrimitive\n data-slot=\"toggle-group-item\"\n data-variant={context.variant || variant}\n data-size={context.size || size}\n data-spacing={context.spacing}\n className={cn(\n \"shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-[orientation=horizontal]/toggle-group:data-[spacing=0]:first:rounded-l-md group-data-[orientation=vertical]/toggle-group:data-[spacing=0]:first:rounded-t-md group-data-[orientation=horizontal]/toggle-group:data-[spacing=0]:last:rounded-r-md group-data-[orientation=vertical]/toggle-group:data-[spacing=0]:last:rounded-b-md group-data-[orientation=horizontal]/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-[orientation=vertical]/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-[orientation=horizontal]/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-[orientation=vertical]/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t\",\n toggleVariants({\n variant: context.variant || variant,\n size: context.size || size,\n }),\n className\n )}\n {...props}\n >\n {children}\n </TogglePrimitive>\n )\n}\n\nexport { ToggleGroup, ToggleGroupItem }\n"],"mappings":";;;;;;;;AAuBA,MAAM,qBAAqB,MAAM,cAAuC;CACtE,MAAM;CACN,SAAS;CACT,SAAS;CACT,aAAa;CACd,CAAC;AAEF,SAAS,YAAY,EACnB,WACA,SACA,MACA,UAAU,GACV,cAAc,cACd,UACA,GAAG,SACgB;AACnB,QACE,oBAACA,eAAD;EACe;EACb,aAAU;EACV,gBAAc;EACd,aAAW;EACX,gBAAc;EACd,OAAO,EAAE,SAAS,SAAS;EAC3B,WAAW,GACT,uMACA,UACD;EACD,GAAI;YAEJ,oBAAC,mBAAmB,UAApB;GACE,OAAO;IAAE;IAAS;IAAM;IAAS;IAAa;GAE7C;GAC2B,CAAA;EACT,CAAA;;AAI3B,SAAS,gBAAgB,EACvB,WACA,UACA,UAAU,WACV,OAAO,WACP,GAAG,SACoB;CACvB,MAAM,UAAU,MAAM,WAAW,mBAAmB;AAEpD,QACE,oBAACC,QAAD;EACE,aAAU;EACV,gBAAc,QAAQ,WAAW;EACjC,aAAW,QAAQ,QAAQ;EAC3B,gBAAc,QAAQ;EACtB,WAAW,GACT,s2BACA,eAAe;GACb,SAAS,QAAQ,WAAW;GAC5B,MAAM,QAAQ,QAAQ;GACvB,CAAC,EACF,UACD;EACD,GAAI;EAEH;EACe,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waveso/ui",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Wave UI component library built on Base UI and Tailwind CSS",
5
5
  "type": "module",
6
6
  "sideEffects": [