@avenue-ticketing/ui 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/utils.ts","../../src/react/avatar.tsx"],"names":[],"mappings":"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","file":"avatar.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { useEffect, useState } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst avatarSizeClass = {\n sm: \"h-8 w-8 min-h-8 min-w-8\",\n md: \"h-10 w-10 min-h-10 min-w-10\",\n lg: \"h-12 w-12 min-h-12 min-w-12\",\n} as const;\n\nconst avatarFallbackTextClass = {\n sm: \"text-xs\",\n md: \"text-sm\",\n lg: \"text-base\",\n} as const;\n\nexport type AvatarSize = keyof typeof avatarSizeClass;\n\nconst AvatarSizeContext = React.createContext<AvatarSize>(\"md\");\n\nconst avatarHideFallbackWhenImage =\n \"[&:has([data-slot=avatar-image])_[data-slot=avatar-fallback]]:pointer-events-none [&:has([data-slot=avatar-image])_[data-slot=avatar-fallback]]:opacity-0\";\n\nexport type AvatarProps = React.HTMLAttributes<HTMLDivElement> & {\n /** @default md */\n size?: AvatarSize;\n};\n\nconst Avatar = React.forwardRef<HTMLDivElement, AvatarProps>(\n ({ className, size = \"md\", children, ...props }, ref) => {\n return (\n <AvatarSizeContext.Provider value={size}>\n <div\n ref={ref}\n data-slot=\"avatar\"\n data-size={size}\n className={cn(\n \"relative flex shrink-0 overflow-hidden rounded-full\",\n avatarHideFallbackWhenImage,\n avatarSizeClass[size],\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </AvatarSizeContext.Provider>\n );\n },\n);\nAvatar.displayName = \"Avatar\";\n\nexport type AvatarImageProps = React.ImgHTMLAttributes<HTMLImageElement>;\n\nconst AvatarImage = React.forwardRef<HTMLImageElement, AvatarImageProps>(\n (props, ref) => {\n /* eslint-disable react/prop-types -- props typed as AvatarImageProps */\n const {\n className,\n onLoad,\n onError,\n alt = \"\",\n ...imgProps\n } = props;\n /* eslint-enable react/prop-types */\n const [failed, setFailed] = useState(false);\n const src = imgProps.src;\n\n useEffect(() => {\n setFailed(false);\n }, [src]);\n\n if (!src || failed) {\n return null;\n }\n\n return (\n <img\n ref={ref}\n alt={alt}\n data-slot=\"avatar-image\"\n className={cn(\n \"absolute inset-0 z-10 h-full w-full object-cover\",\n className,\n )}\n onLoad={onLoad}\n onError={(e) => {\n setFailed(true);\n onError?.(e);\n }}\n {...imgProps}\n />\n );\n },\n);\nAvatarImage.displayName = \"AvatarImage\";\n\nexport type AvatarFallbackProps = React.HTMLAttributes<HTMLDivElement>;\n\nconst AvatarFallback = React.forwardRef<HTMLDivElement, AvatarFallbackProps>(\n ({ className, ...props }, ref) => {\n const size = React.useContext(AvatarSizeContext);\n\n return (\n <div\n ref={ref}\n data-slot=\"avatar-fallback\"\n className={cn(\n \"absolute inset-0 z-0 flex items-center justify-center rounded-full bg-primary/10 font-semibold text-primary select-none\",\n avatarFallbackTextClass[size],\n className,\n )}\n {...props}\n />\n );\n },\n);\nAvatarFallback.displayName = \"AvatarFallback\";\n\nconst avatarGroupOverflowTextClass: Record<AvatarSize, string> = {\n sm: \"text-[10px]\",\n md: \"text-xs\",\n lg: \"text-sm\",\n};\n\nexport type AvatarGroupProps = Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"children\"\n> & {\n children: React.ReactNode;\n /**\n * show only the first `max` avatars; extra members become a +N chip (direct\n * `Avatar` children only).\n */\n max?: number;\n /** chip size; use the same `size` on each `Avatar` so the stack lines up */\n size?: AvatarSize;\n};\n\nconst AvatarGroup = React.forwardRef<HTMLDivElement, AvatarGroupProps>(\n (\n { className, children, max, size = \"md\", ...rest },\n ref,\n ) => {\n const items = React.Children.toArray(children).filter(\n (node): node is React.ReactElement =>\n React.isValidElement(node) && node.type === Avatar,\n );\n\n const overflow =\n max != null && max > 0 && items.length > max ? items.length - max : 0;\n const shown = max != null && max > 0 ? items.slice(0, max) : items;\n\n return (\n <div\n ref={ref}\n data-slot=\"avatar-group\"\n data-size={size}\n className={cn(\"flex items-center -space-x-2\", className)}\n {...rest}\n >\n {shown.map((child, index) =>\n React.cloneElement(child, {\n key: child.key ?? `avatar-group-${index}`,\n className: cn(\n (child.props as { className?: string }).className,\n \"ring-background relative z-0 ring-2\",\n ),\n style: {\n ...((child.props as { style?: React.CSSProperties }).style ??\n {}),\n zIndex: index + 1,\n },\n } as Partial<typeof child.props>),\n )}\n {overflow > 0 ? (\n <span\n aria-label={`${overflow} more`}\n className={cn(\n \"border-background text-primary bg-primary/15 ring-background relative flex shrink-0 items-center justify-center rounded-full border-2 font-semibold tabular-nums ring-2\",\n avatarSizeClass[size],\n avatarGroupOverflowTextClass[size],\n )}\n style={{ zIndex: shown.length + 1 }}\n >\n +{overflow > 99 ? 99 : overflow}\n </span>\n ) : null}\n </div>\n );\n },\n);\nAvatarGroup.displayName = \"AvatarGroup\";\n\nexport { Avatar, AvatarImage, AvatarFallback, AvatarGroup };\n"]}
1
+ {"version":3,"sources":["../../src/lib/utils.ts","../../src/react/avatar.tsx"],"names":[],"mappings":"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","file":"avatar.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { useEffect, useState } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\nconst avatarSizeClass = {\n sm: \"h-8 w-8 min-h-8 min-w-8\",\n md: \"h-10 w-10 min-h-10 min-w-10\",\n lg: \"h-12 w-12 min-h-12 min-w-12\",\n} as const;\n\nconst avatarFallbackTextClass = {\n sm: \"text-xs\",\n md: \"text-sm\",\n lg: \"text-base\",\n} as const;\n\nexport type AvatarSize = keyof typeof avatarSizeClass;\n\nconst AvatarSizeContext = React.createContext<AvatarSize>(\"md\");\n\nconst avatarHideFallbackWhenImage =\n \"[&:has([data-slot=avatar-image])_[data-slot=avatar-fallback]]:pointer-events-none [&:has([data-slot=avatar-image])_[data-slot=avatar-fallback]]:opacity-0\";\n\nexport type AvatarProps = React.HTMLAttributes<HTMLDivElement> & {\n /** @default md */\n size?: AvatarSize;\n};\n\nconst Avatar = React.forwardRef<HTMLDivElement, AvatarProps>(\n ({ className, size = \"md\", children, ...props }, ref) => {\n return (\n <AvatarSizeContext.Provider value={size}>\n <div\n ref={ref}\n data-slot=\"avatar\"\n data-size={size}\n className={cn(\n \"relative flex shrink-0 overflow-hidden rounded-full\",\n avatarHideFallbackWhenImage,\n avatarSizeClass[size],\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </AvatarSizeContext.Provider>\n );\n },\n);\nAvatar.displayName = \"Avatar\";\n\nexport type AvatarImageProps = React.ImgHTMLAttributes<HTMLImageElement>;\n\nconst AvatarImage = React.forwardRef<HTMLImageElement, AvatarImageProps>(\n (props, ref) => {\n /* eslint-disable react/prop-types -- props typed as AvatarImageProps */\n const {\n className,\n onLoad,\n onError,\n alt = \"\",\n ...imgProps\n } = props;\n /* eslint-enable react/prop-types */\n const [failed, setFailed] = useState(false);\n const src = imgProps.src;\n\n useEffect(() => {\n setFailed(false);\n }, [src]);\n\n if (!src || failed) {\n return null;\n }\n\n return (\n <img\n ref={ref}\n alt={alt}\n data-slot=\"avatar-image\"\n className={cn(\n \"absolute inset-0 z-10 h-full w-full object-cover\",\n className,\n )}\n onLoad={onLoad}\n onError={(e) => {\n setFailed(true);\n onError?.(e);\n }}\n {...imgProps}\n />\n );\n },\n);\nAvatarImage.displayName = \"AvatarImage\";\n\nexport type AvatarFallbackProps = React.HTMLAttributes<HTMLDivElement>;\n\nconst AvatarFallback = React.forwardRef<HTMLDivElement, AvatarFallbackProps>(\n ({ className, ...props }, ref) => {\n const size = React.useContext(AvatarSizeContext);\n\n return (\n <div\n ref={ref}\n data-slot=\"avatar-fallback\"\n className={cn(\n \"absolute inset-0 z-0 flex items-center justify-center rounded-full bg-primary/10 font-semibold text-primary select-none\",\n avatarFallbackTextClass[size],\n className,\n )}\n {...props}\n />\n );\n },\n);\nAvatarFallback.displayName = \"AvatarFallback\";\n\nconst avatarGroupOverflowTextClass: Record<AvatarSize, string> = {\n sm: \"text-[10px]\",\n md: \"text-xs\",\n lg: \"text-sm\",\n};\n\nexport type AvatarGroupProps = Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"children\"\n> & {\n children: React.ReactNode;\n /**\n * show only the first `max` avatars; extra members become a +N chip (direct\n * `Avatar` children only).\n */\n max?: number;\n /** chip size; use the same `size` on each `Avatar` so the stack lines up */\n size?: AvatarSize;\n};\n\nconst AvatarGroup = React.forwardRef<HTMLDivElement, AvatarGroupProps>(\n (\n { className, children, max, size = \"md\", ...rest },\n ref,\n ) => {\n const items = React.Children.toArray(children).filter(\n (node): node is React.ReactElement =>\n React.isValidElement(node) && node.type === Avatar,\n );\n\n const overflow =\n max != null && max > 0 && items.length > max ? items.length - max : 0;\n const shown = max != null && max > 0 ? items.slice(0, max) : items;\n\n return (\n <div\n ref={ref}\n data-slot=\"avatar-group\"\n data-size={size}\n className={cn(\"flex items-center -space-x-2\", className)}\n {...rest}\n >\n {shown.map((child, index) =>\n React.cloneElement(child, {\n key: child.key ?? `avatar-group-${index}`,\n className: cn(\n (child.props as { className?: string }).className,\n \"ring-background relative z-0 ring-2\",\n ),\n style: {\n ...((child.props as { style?: React.CSSProperties }).style ??\n {}),\n zIndex: index + 1,\n },\n } as Partial<typeof child.props>),\n )}\n {overflow > 0 ? (\n <span\n aria-label={`${overflow} more`}\n className={cn(\n \"border-background text-primary bg-primary/15 ring-background relative flex shrink-0 items-center justify-center rounded-full border-2 font-semibold tabular-nums ring-2\",\n avatarSizeClass[size],\n avatarGroupOverflowTextClass[size],\n )}\n style={{ zIndex: shown.length + 1 }}\n >\n +{overflow > 99 ? 99 : overflow}\n </span>\n ) : null}\n </div>\n );\n },\n);\nAvatarGroup.displayName = \"AvatarGroup\";\n\nexport { Avatar, AvatarImage, AvatarFallback, AvatarGroup };\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/utils.ts","../../src/react/badge.tsx"],"names":[],"mappings":"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","file":"badge.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\n/** Matches `button.tsx` primary / secondary — no separate outline variants. */\nconst variantClass = {\n primary:\n \"border border-transparent bg-primary text-background\",\n secondary:\n \"border border-primary/10 bg-transparent text-primary\",\n} as const;\n\n/** Same keys as `button.tsx` `roundedClass`. */\nconst roundedClass = {\n full: \"rounded-full\",\n lg: \"rounded-lg\",\n md: \"rounded-md\",\n} as const;\n\nconst sizeClass = {\n md: \"min-h-6 min-w-6 px-2 text-xs\",\n lg: \"min-h-7 min-w-7 px-2.5 text-sm\",\n} as const;\n\nconst OVERRIDE_BG_ALPHA = 0.18;\nconst OVERRIDE_BORDER_ALPHA = 0.38;\n\nfunction parseHexToRgb(\n value: string,\n): { r: number; g: number; b: number } | null {\n const v = value.trim();\n if (!v.startsWith(\"#\") || v.length < 2) return null;\n let h = v.slice(1);\n if (h.length === 3) {\n h = h\n .split(\"\")\n .map((c) => c + c)\n .join(\"\");\n } else if (h.length === 8) {\n h = h.slice(0, 6);\n }\n if (h.length !== 6 || !/^[0-9A-Fa-f]{6}$/i.test(h)) return null;\n const r = parseInt(h.slice(0, 2), 16);\n const g = parseInt(h.slice(2, 4), 16);\n const b = parseInt(h.slice(4, 6), 16);\n if ([r, g, b].some((n) => Number.isNaN(n))) return null;\n return { r, g, b };\n}\n\nfunction overrideColorStyles(rgb: { r: number; g: number; b: number }): {\n backgroundColor: string;\n color: string;\n boxShadow: string;\n} {\n const { r, g, b } = rgb;\n return {\n backgroundColor: `rgba(${r},${g},${b},${OVERRIDE_BG_ALPHA})`,\n color: `rgb(${r},${g},${b})`,\n boxShadow: `inset 0 0 0 1px rgba(${r},${g},${b},${OVERRIDE_BORDER_ALPHA})`,\n };\n}\n\nexport type BadgeProps = React.HTMLAttributes<HTMLSpanElement> & {\n /** @default secondary — same as Button default. */\n variant?: keyof typeof variantClass;\n /** @default md */\n size?: keyof typeof sizeClass;\n /**\n * Corner radius — same options as `Button` (`full` | `lg` | `md`).\n * @default full (pill)\n */\n rounded?: keyof typeof roundedClass;\n /**\n * When set, the label is the number capped at `max` with a \"+\" suffix\n * (e.g. `max={99}` → `99+`). Ignores `children` for the visible text.\n */\n count?: number;\n /** Upper bound before showing `{max}+`. Default `99`. */\n max?: number;\n /**\n * Hex color (`#RGB`, `#RRGGBB`, or `#RRGGBBAA`) — tints the badge to that\n * hue. When set, `variant` is ignored for colors. Invalid values are ignored\n * and the badge falls back to `variant`.\n */\n overrideColor?: string;\n};\n\nfunction formatCount(count: number, max: number): string {\n if (count > max) return `${max}+`;\n return String(count);\n}\n\nconst Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(\n (\n {\n className,\n variant = \"secondary\",\n size = \"md\",\n rounded = \"full\",\n count,\n max = 99,\n children,\n \"aria-label\": ariaLabelProp,\n overrideColor,\n style,\n ...props\n },\n ref,\n ) => {\n const content = count !== undefined ? formatCount(count, max) : children;\n const rgb =\n overrideColor && overrideColor.trim() !== \"\"\n ? parseHexToRgb(overrideColor)\n : null;\n const useOverride = rgb != null;\n const overrideStyle = useOverride\n ? overrideColorStyles(rgb)\n : undefined;\n\n return (\n <span\n ref={ref}\n data-slot=\"badge\"\n data-size={size}\n data-rounded={rounded}\n data-override={useOverride ? \"true\" : undefined}\n aria-label={ariaLabelProp}\n className={cn(\n \"inline-flex shrink-0 items-center justify-center font-semibold leading-none tabular-nums\",\n roundedClass[rounded],\n sizeClass[size],\n !useOverride && variantClass[variant],\n useOverride && \"border-0\",\n className,\n )}\n style={{ ...overrideStyle, ...style }}\n {...props}\n >\n {content}\n </span>\n );\n },\n);\n\nBadge.displayName = \"Badge\";\n\nexport { Badge };\n"]}
1
+ {"version":3,"sources":["../../src/lib/utils.ts","../../src/react/badge.tsx"],"names":[],"mappings":"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","file":"badge.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\n/** Matches `button.tsx` primary / secondary — no separate outline variants. */\nconst variantClass = {\n primary:\n \"border border-transparent bg-primary text-background\",\n secondary:\n \"border border-primary/10 bg-transparent text-primary\",\n} as const;\n\n/** Same keys as `button.tsx` `roundedClass`. */\nconst roundedClass = {\n full: \"rounded-full\",\n lg: \"rounded-lg\",\n md: \"rounded-md\",\n} as const;\n\nconst sizeClass = {\n md: \"min-h-6 min-w-6 px-2 text-xs\",\n lg: \"min-h-7 min-w-7 px-2.5 text-sm\",\n} as const;\n\nconst OVERRIDE_BG_ALPHA = 0.18;\nconst OVERRIDE_BORDER_ALPHA = 0.38;\n\nfunction parseHexToRgb(\n value: string,\n): { r: number; g: number; b: number } | null {\n const v = value.trim();\n if (!v.startsWith(\"#\") || v.length < 2) return null;\n let h = v.slice(1);\n if (h.length === 3) {\n h = h\n .split(\"\")\n .map((c) => c + c)\n .join(\"\");\n } else if (h.length === 8) {\n h = h.slice(0, 6);\n }\n if (h.length !== 6 || !/^[0-9A-Fa-f]{6}$/i.test(h)) return null;\n const r = parseInt(h.slice(0, 2), 16);\n const g = parseInt(h.slice(2, 4), 16);\n const b = parseInt(h.slice(4, 6), 16);\n if ([r, g, b].some((n) => Number.isNaN(n))) return null;\n return { r, g, b };\n}\n\nfunction overrideColorStyles(rgb: { r: number; g: number; b: number }): {\n backgroundColor: string;\n color: string;\n boxShadow: string;\n} {\n const { r, g, b } = rgb;\n return {\n backgroundColor: `rgba(${r},${g},${b},${OVERRIDE_BG_ALPHA})`,\n color: `rgb(${r},${g},${b})`,\n boxShadow: `inset 0 0 0 1px rgba(${r},${g},${b},${OVERRIDE_BORDER_ALPHA})`,\n };\n}\n\nexport type BadgeProps = React.HTMLAttributes<HTMLSpanElement> & {\n /** @default secondary — same as Button default. */\n variant?: keyof typeof variantClass;\n /** @default md */\n size?: keyof typeof sizeClass;\n /**\n * Corner radius — same options as `Button` (`full` | `lg` | `md`).\n * @default full (pill)\n */\n rounded?: keyof typeof roundedClass;\n /**\n * When set, the label is the number capped at `max` with a \"+\" suffix\n * (e.g. `max={99}` → `99+`). Ignores `children` for the visible text.\n */\n count?: number;\n /** Upper bound before showing `{max}+`. Default `99`. */\n max?: number;\n /**\n * Hex color (`#RGB`, `#RRGGBB`, or `#RRGGBBAA`) — tints the badge to that\n * hue. When set, `variant` is ignored for colors. Invalid values are ignored\n * and the badge falls back to `variant`.\n */\n overrideColor?: string;\n};\n\nfunction formatCount(count: number, max: number): string {\n if (count > max) return `${max}+`;\n return String(count);\n}\n\nconst Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(\n (\n {\n className,\n variant = \"secondary\",\n size = \"md\",\n rounded = \"full\",\n count,\n max = 99,\n children,\n \"aria-label\": ariaLabelProp,\n overrideColor,\n style,\n ...props\n },\n ref,\n ) => {\n const content = count !== undefined ? formatCount(count, max) : children;\n const rgb =\n overrideColor && overrideColor.trim() !== \"\"\n ? parseHexToRgb(overrideColor)\n : null;\n const useOverride = rgb != null;\n const overrideStyle = useOverride\n ? overrideColorStyles(rgb)\n : undefined;\n\n return (\n <span\n ref={ref}\n data-slot=\"badge\"\n data-size={size}\n data-rounded={rounded}\n data-override={useOverride ? \"true\" : undefined}\n aria-label={ariaLabelProp}\n className={cn(\n \"inline-flex shrink-0 items-center justify-center font-semibold leading-none tabular-nums\",\n roundedClass[rounded],\n sizeClass[size],\n !useOverride && variantClass[variant],\n useOverride && \"border-0\",\n className,\n )}\n style={{ ...overrideStyle, ...style }}\n {...props}\n >\n {content}\n </span>\n );\n },\n);\n\nBadge.displayName = \"Badge\";\n\nexport { Badge };\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/utils.ts","../../src/react/button.tsx"],"names":[],"mappings":";;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACDA,IAAM,SAAA,GAAY;AAAA,EAChB,EAAA,EAAI,qFAAA;AAAA,EACJ,OAAA,EACE,uFAAA;AAAA,EACF,EAAA,EAAI;AACN,CAAA;AAGA,IAAM,iBAAA,GAAoB;AAAA,EACxB,EAAA,EAAI,uEAAA;AAAA,EACJ,OAAA,EACE,0EAAA;AAAA,EACF,EAAA,EAAI;AACN,CAAA;AAEA,IAAM,YAAA,GAAe;AAAA,EACnB,IAAA,EAAM,cAAA;AAAA,EACN,EAAA,EAAI,YAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAEA,IAAM,YAAA,GAAe;AAAA,EACnB,OAAA,EACE,+FAAA;AAAA,EACF,SAAA,EACE,wEAAA;AAAA,EACF,WAAA,EACE,wEAAA;AAAA,EACF,OAAA,EACE;AACJ,CAAA;AAuBA,IAAM,MAAA,GAAe,KAAA,CAAA,UAAA;AAAA,EACnB,CACE;AAAA,IACE,SAAA;AAAA,IACA,IAAA,GAAO,QAAA;AAAA,IACP,OAAA,GAAU,WAAA;AAAA,IACV,OAAA,EAAS,WAAA;AAAA,IACT,IAAA,GAAO,SAAA;AAAA,IACP,QAAA,GAAW,KAAA;AAAA,IACX,QAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,OAAA,GAAU,WAAA,KAAgB,QAAA,GAAW,IAAA,GAAO,MAAA,CAAA;AAElD,IAAA,uBACE,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA,EAAU,QAAA;AAAA,QACV,gBAAA,EAAgB,WAAW,EAAA,GAAK,MAAA;AAAA,QAChC,SAAA,EAAW,EAAA;AAAA,UACT,iSAAA;AAAA,UACA,8EAAA;AAAA,UACA,4GAAA;AAAA,UACA,QAAA,GAAW,iBAAA,CAAkB,IAAI,CAAA,GAAI,UAAU,IAAI,CAAA;AAAA,UACnD,aAAa,OAAO,CAAA;AAAA,UACpB,aAAa,OAAO,CAAA;AAAA,UACpB;AAAA,SACF;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"button.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst sizeClass = {\n xs: \"h-8 min-h-8 gap-2 px-4 text-sm has-[>svg]:px-3 [&_svg:not([class*='size-'])]:size-3\",\n default:\n \"h-10 min-h-10 gap-2 px-5 text-sm has-[>svg]:px-4 [&_svg:not([class*='size-'])]:size-4\",\n lg: \"h-11 min-h-11 gap-2 px-6 text-base has-[>svg]:px-5 [&_svg:not([class*='size-'])]:size-5\",\n} as const;\n\n/** Square hit targets for `iconOnly` — same keys as `sizeClass` (`default` | `lg`). */\nconst iconOnlySizeClass = {\n xs: \"size-8 min-h-8 min-w-8 gap-0 p-0 [&_svg:not([class*='size-'])]:size-3\",\n default:\n \"size-10 min-h-10 min-w-10 gap-0 p-0 [&_svg:not([class*='size-'])]:size-4\",\n lg: \"size-11 min-h-11 min-w-11 gap-0 p-0 [&_svg:not([class*='size-'])]:size-5\",\n} as const;\n\nconst roundedClass = {\n full: \"rounded-full\",\n lg: \"rounded-lg\",\n md: \"rounded-md\",\n} as const;\n\nconst variantClass = {\n primary:\n \"bg-primary text-background border border-transparent hover:bg-primary/90 active:bg-primary/85\",\n secondary:\n \"bg-background text-primary border border-primary/10 hover:bg-primary/5\",\n destructive:\n \"bg-background text-red-500 border border-red-500/25 hover:bg-red-500/5\",\n success:\n \"bg-background text-green-500 border border-green-500/25 hover:bg-green-500/5\",\n} as const;\n\nexport type ButtonProps = React.ComponentProps<\"button\"> & {\n /**\n * Visual style: neutral (`secondary`, `primary`), or outline (`destructive`,\n * `success`) using Tailwind `red-500` / `green-500` text and matching borders on\n * `bg-background` (no solid fill).\n */\n variant?: keyof typeof variantClass;\n /**\n * Corner radius. Labeled buttons default to `full` (pill). `iconOnly` buttons\n * default to `md` (square corners) unless you pass `rounded` explicitly.\n */\n rounded?: keyof typeof roundedClass;\n /** Height and horizontal padding: `default` or `lg` only. */\n size?: keyof typeof sizeClass;\n /**\n * Square icon-only control; same `size` presets (`default` | `lg`). Pair with\n * `aria-label` (or `title`) when there is no visible text.\n */\n iconOnly?: boolean;\n};\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n type = \"button\",\n variant = \"secondary\",\n rounded: roundedProp,\n size = \"default\",\n iconOnly = false,\n disabled,\n ...props\n },\n ref,\n ) => {\n const rounded = roundedProp ?? (iconOnly ? \"md\" : \"full\");\n\n return (\n <button\n type={type}\n disabled={disabled}\n data-slot=\"button\"\n data-icon-only={iconOnly ? \"\" : undefined}\n className={cn(\n \"inline-flex shrink-0 cursor-pointer items-center justify-center whitespace-nowrap outline-none scale-100 transition-[color,background-color,box-shadow,transform] duration-150 ease-out active:scale-[0.98] active:duration-100 active:ease-linear [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n \"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\",\n \"focus-visible:border-ring font-medium lg:tracking-wide focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n iconOnly ? iconOnlySizeClass[size] : sizeClass[size],\n roundedClass[rounded],\n variantClass[variant],\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = \"Button\";\n\nexport { Button };\n"]}
1
+ {"version":3,"sources":["../../src/lib/utils.ts","../../src/react/button.tsx"],"names":[],"mappings":";;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACDA,IAAM,SAAA,GAAY;AAAA,EAChB,EAAA,EAAI,qFAAA;AAAA,EACJ,OAAA,EACE,uFAAA;AAAA,EACF,EAAA,EAAI;AACN,CAAA;AAGA,IAAM,iBAAA,GAAoB;AAAA,EACxB,EAAA,EAAI,uEAAA;AAAA,EACJ,OAAA,EACE,0EAAA;AAAA,EACF,EAAA,EAAI;AACN,CAAA;AAEA,IAAM,YAAA,GAAe;AAAA,EACnB,IAAA,EAAM,cAAA;AAAA,EACN,EAAA,EAAI,YAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAEA,IAAM,YAAA,GAAe;AAAA,EACnB,OAAA,EACE,+FAAA;AAAA,EACF,SAAA,EACE,wEAAA;AAAA,EACF,WAAA,EACE,wEAAA;AAAA,EACF,OAAA,EACE;AACJ,CAAA;AAuBA,IAAM,MAAA,GAAe,KAAA,CAAA,UAAA;AAAA,EACnB,CACE;AAAA,IACE,SAAA;AAAA,IACA,IAAA,GAAO,QAAA;AAAA,IACP,OAAA,GAAU,WAAA;AAAA,IACV,OAAA,EAAS,WAAA;AAAA,IACT,IAAA,GAAO,SAAA;AAAA,IACP,QAAA,GAAW,KAAA;AAAA,IACX,QAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,OAAA,GAAU,WAAA,KAAgB,QAAA,GAAW,IAAA,GAAO,MAAA,CAAA;AAElD,IAAA,uBACE,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA,EAAU,QAAA;AAAA,QACV,gBAAA,EAAgB,WAAW,EAAA,GAAK,MAAA;AAAA,QAChC,SAAA,EAAW,EAAA;AAAA,UACT,iSAAA;AAAA,UACA,8EAAA;AAAA,UACA,4GAAA;AAAA,UACA,QAAA,GAAW,iBAAA,CAAkB,IAAI,CAAA,GAAI,UAAU,IAAI,CAAA;AAAA,UACnD,aAAa,OAAO,CAAA;AAAA,UACpB,aAAa,OAAO,CAAA;AAAA,UACpB;AAAA,SACF;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"button.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\nconst sizeClass = {\n xs: \"h-8 min-h-8 gap-2 px-4 text-sm has-[>svg]:px-3 [&_svg:not([class*='size-'])]:size-3\",\n default:\n \"h-10 min-h-10 gap-2 px-5 text-sm has-[>svg]:px-4 [&_svg:not([class*='size-'])]:size-4\",\n lg: \"h-11 min-h-11 gap-2 px-6 text-base has-[>svg]:px-5 [&_svg:not([class*='size-'])]:size-5\",\n} as const;\n\n/** Square hit targets for `iconOnly` — same keys as `sizeClass` (`default` | `lg`). */\nconst iconOnlySizeClass = {\n xs: \"size-8 min-h-8 min-w-8 gap-0 p-0 [&_svg:not([class*='size-'])]:size-3\",\n default:\n \"size-10 min-h-10 min-w-10 gap-0 p-0 [&_svg:not([class*='size-'])]:size-4\",\n lg: \"size-11 min-h-11 min-w-11 gap-0 p-0 [&_svg:not([class*='size-'])]:size-5\",\n} as const;\n\nconst roundedClass = {\n full: \"rounded-full\",\n lg: \"rounded-lg\",\n md: \"rounded-md\",\n} as const;\n\nconst variantClass = {\n primary:\n \"bg-primary text-background border border-transparent hover:bg-primary/90 active:bg-primary/85\",\n secondary:\n \"bg-background text-primary border border-primary/10 hover:bg-primary/5\",\n destructive:\n \"bg-background text-red-500 border border-red-500/25 hover:bg-red-500/5\",\n success:\n \"bg-background text-green-500 border border-green-500/25 hover:bg-green-500/5\",\n} as const;\n\nexport type ButtonProps = React.ComponentProps<\"button\"> & {\n /**\n * Visual style: neutral (`secondary`, `primary`), or outline (`destructive`,\n * `success`) using Tailwind `red-500` / `green-500` text and matching borders on\n * `bg-background` (no solid fill).\n */\n variant?: keyof typeof variantClass;\n /**\n * Corner radius. Labeled buttons default to `full` (pill). `iconOnly` buttons\n * default to `md` (square corners) unless you pass `rounded` explicitly.\n */\n rounded?: keyof typeof roundedClass;\n /** Height and horizontal padding: `default` or `lg` only. */\n size?: keyof typeof sizeClass;\n /**\n * Square icon-only control; same `size` presets (`default` | `lg`). Pair with\n * `aria-label` (or `title`) when there is no visible text.\n */\n iconOnly?: boolean;\n};\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n type = \"button\",\n variant = \"secondary\",\n rounded: roundedProp,\n size = \"default\",\n iconOnly = false,\n disabled,\n ...props\n },\n ref,\n ) => {\n const rounded = roundedProp ?? (iconOnly ? \"md\" : \"full\");\n\n return (\n <button\n type={type}\n disabled={disabled}\n data-slot=\"button\"\n data-icon-only={iconOnly ? \"\" : undefined}\n className={cn(\n \"inline-flex shrink-0 cursor-pointer items-center justify-center whitespace-nowrap outline-none scale-100 transition-[color,background-color,box-shadow,transform] duration-150 ease-out active:scale-[0.98] active:duration-100 active:ease-linear [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n \"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\",\n \"focus-visible:border-ring font-medium lg:tracking-wide focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n iconOnly ? iconOnlySizeClass[size] : sizeClass[size],\n roundedClass[rounded],\n variantClass[variant],\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = \"Button\";\n\nexport { Button };\n"]}