@karakuri-ui/react 0.3.5 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/components/ui/checkbox.js +3 -1
  2. package/dist/components/ui/checkbox.js.map +1 -1
  3. package/dist/components/ui/checkbox.mjs +4 -2
  4. package/dist/components/ui/checkbox.mjs.map +1 -1
  5. package/dist/components/ui/field.d.mts +11 -1
  6. package/dist/components/ui/field.d.ts +11 -1
  7. package/dist/components/ui/field.js +37 -4
  8. package/dist/components/ui/field.js.map +1 -1
  9. package/dist/components/ui/field.mjs +35 -3
  10. package/dist/components/ui/field.mjs.map +1 -1
  11. package/dist/components/ui/index.d.mts +1 -1
  12. package/dist/components/ui/index.d.ts +1 -1
  13. package/dist/components/ui/input.js +1 -0
  14. package/dist/components/ui/input.js.map +1 -1
  15. package/dist/components/ui/input.mjs +2 -1
  16. package/dist/components/ui/input.mjs.map +1 -1
  17. package/dist/components/ui/navigation-menu.js +30 -9
  18. package/dist/components/ui/navigation-menu.js.map +1 -1
  19. package/dist/components/ui/navigation-menu.mjs +30 -9
  20. package/dist/components/ui/navigation-menu.mjs.map +1 -1
  21. package/dist/components/ui/pagination.js +2 -2
  22. package/dist/components/ui/pagination.js.map +1 -1
  23. package/dist/components/ui/pagination.mjs +3 -3
  24. package/dist/components/ui/pagination.mjs.map +1 -1
  25. package/dist/components/ui/radio-group.js +3 -0
  26. package/dist/components/ui/radio-group.js.map +1 -1
  27. package/dist/components/ui/radio-group.mjs +4 -1
  28. package/dist/components/ui/radio-group.mjs.map +1 -1
  29. package/dist/components/ui/select.d.mts +1 -1
  30. package/dist/components/ui/select.d.ts +1 -1
  31. package/dist/components/ui/select.js +10 -2
  32. package/dist/components/ui/select.js.map +1 -1
  33. package/dist/components/ui/select.mjs +10 -2
  34. package/dist/components/ui/select.mjs.map +1 -1
  35. package/dist/components/ui/slider.js +7 -1
  36. package/dist/components/ui/slider.js.map +1 -1
  37. package/dist/components/ui/slider.mjs +7 -1
  38. package/dist/components/ui/slider.mjs.map +1 -1
  39. package/dist/components/ui/switch.js +3 -1
  40. package/dist/components/ui/switch.js.map +1 -1
  41. package/dist/components/ui/switch.mjs +4 -2
  42. package/dist/components/ui/switch.mjs.map +1 -1
  43. package/dist/components/ui/textarea.js +1 -0
  44. package/dist/components/ui/textarea.js.map +1 -1
  45. package/dist/components/ui/textarea.mjs +2 -1
  46. package/dist/components/ui/textarea.mjs.map +1 -1
  47. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/pagination.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\n// ─── Built-in Icons ──────────────────────────────────────\n\nfunction ChevronLeftIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n )\n}\n\nfunction ChevronRightIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n )\n}\n\nfunction ChevronsLeftIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11 17l-5-5 5-5M18 17l-5-5 5-5\" />\n </svg>\n )\n}\n\nfunction ChevronsRightIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M13 7l5 5-5 5M6 7l5 5-5 5\" />\n </svg>\n )\n}\n\nfunction EllipsisIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" />\n </svg>\n )\n}\n\n// ─── usePagination Hook ──────────────────────────────────\n\nexport type PaginationRange = (number | 'dots')[]\n\nexport interface UsePaginationProps {\n /** Total number of pages */\n total: number\n /** Number of siblings on each side of current page */\n siblings?: number\n /** Number of boundary pages at start/end */\n boundaries?: number\n /** Current active page (1-based) */\n page: number\n}\n\nfunction range(start: number, end: number): number[] {\n const result: number[] = []\n for (let i = start; i <= end; i++) result.push(i)\n return result\n}\n\nexport function usePagination({\n total,\n siblings = 1,\n boundaries = 1,\n page,\n}: UsePaginationProps): PaginationRange {\n if (total <= 0) return []\n\n const totalPageNumbers = siblings * 2 + 3 + boundaries * 2\n if (totalPageNumbers >= total) {\n return range(1, total)\n }\n\n const leftSiblingIndex = Math.max(page - siblings, boundaries + 1)\n const rightSiblingIndex = Math.min(page + siblings, total - boundaries)\n\n const showLeftDots = leftSiblingIndex > boundaries + 2\n const showRightDots = rightSiblingIndex < total - boundaries - 1\n\n if (!showLeftDots && showRightDots) {\n const leftItemCount = 3 + 2 * siblings + boundaries\n const leftRange = range(1, leftItemCount)\n return [...leftRange, 'dots' as const, ...range(total - boundaries + 1, total)]\n }\n\n if (showLeftDots && !showRightDots) {\n const rightItemCount = 3 + 2 * siblings + boundaries\n const rightRange = range(total - rightItemCount + 1, total)\n return [...range(1, boundaries), 'dots' as const, ...rightRange]\n }\n\n return [\n ...range(1, boundaries),\n 'dots' as const,\n ...range(leftSiblingIndex, rightSiblingIndex),\n 'dots' as const,\n ...range(total - boundaries + 1, total),\n ]\n}\n\n// ─── Context ─────────────────────────────────────────────\n\nexport type PaginationSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl'\nexport type PaginationVariant = 'default' | 'outline' | 'ghost'\nexport type PaginationColor = 'default' | 'primary'\nexport type PaginationRadius = 'sm' | 'base' | 'md' | 'lg' | 'xl' | 'full'\n\ntype PaginationContextValue = {\n page: number\n total: number\n siblings: number\n boundaries: number\n size: PaginationSize\n variant: PaginationVariant\n color: PaginationColor\n radius: PaginationRadius\n disabled: boolean\n loop: boolean\n onPageChange: (page: number) => void\n paginationRange: PaginationRange\n}\n\nconst PaginationContext = React.createContext<PaginationContextValue | null>(null)\n\nfunction usePaginationContext() {\n const ctx = React.useContext(PaginationContext)\n if (!ctx) throw new Error('Pagination components must be used within <Pagination>')\n return ctx\n}\n\n// ─── Size Map ────────────────────────────────────────────\n\nconst paginationSizeMap = {\n xs: { item: 'h-7 min-w-7 text-xs', icon: 'icon-xs', gap: 'gap-1' },\n sm: { item: 'h-8 min-w-8 text-sm', icon: 'icon-xs', gap: 'gap-1' },\n default: { item: 'h-9 min-w-9 text-md', icon: 'icon-sm', gap: 'gap-1' },\n lg: { item: 'h-10 min-w-10 text-md', icon: 'icon-sm', gap: 'gap-1.5' },\n xl: { item: 'h-12 min-w-12 text-base', icon: 'icon-sm', gap: 'gap-1.5' },\n} as const\n\n// ─── Item Variants (CVA) ─────────────────────────────────\n\nconst paginationItemVariants = cva(\n 'inline-flex items-center justify-center select-none transition-colors duration-fast font-semibold focus-visible:focus-ring',\n {\n variants: {\n radius: {\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n full: 'rounded-full',\n },\n },\n defaultVariants: {\n radius: 'md',\n },\n }\n)\n\n// ─── Variant Style Helpers ───────────────────────────────\n\n// Active color maps\nconst activeColorMap = {\n default: 'bg-foreground text-background',\n primary: 'bg-primary text-primary-foreground',\n} as const\n\nconst ghostActiveColorMap = {\n default: 'bg-background-muted text-foreground font-bold',\n primary: 'bg-background-muted text-primary',\n} as const\n\nfunction getItemClasses(variant: PaginationVariant, color: PaginationColor, isActive: boolean, disabled: boolean) {\n if (disabled) {\n return variant === 'outline'\n ? 'border border-border text-disabled-foreground pointer-events-none opacity-50'\n : 'border border-transparent text-disabled-foreground pointer-events-none opacity-50'\n }\n if (isActive) {\n switch (variant) {\n case 'outline':\n return `border ${color === 'default' ? 'border-foreground' : 'border-primary'} ${activeColorMap[color]}`\n case 'ghost':\n return `border border-transparent ${ghostActiveColorMap[color]}`\n case 'default':\n default:\n return `border border-transparent ${activeColorMap[color]}`\n }\n }\n switch (variant) {\n case 'outline':\n return 'border border-border text-text-muted hover:bg-background-muted hover:text-foreground'\n case 'ghost':\n return 'border border-transparent text-text-muted hover:bg-background-muted hover:text-foreground'\n case 'default':\n default:\n return 'border border-transparent text-text-muted hover:bg-background-muted hover:text-foreground'\n }\n}\n\n// ─── Pagination (Root) ───────────────────────────────────\n\nexport interface PaginationProps extends Omit<React.ComponentPropsWithoutRef<'nav'>, 'onChange'> {\n /** Total number of pages */\n total?: number\n /** Controlled active page (1-based) */\n value?: number\n /** Initial page for uncontrolled mode */\n defaultValue?: number\n /** Page change callback */\n onChange?: (page: number) => void\n /** Number of siblings on each side of current page */\n siblings?: number\n /** Number of boundary pages at start/end */\n boundaries?: number\n /** Component size */\n size?: PaginationSize\n /** Visual variant */\n variant?: PaginationVariant\n /** Active page color */\n color?: PaginationColor\n /** Border radius */\n radius?: PaginationRadius\n /** Disable all interactions */\n disabled?: boolean\n /** Show previous/next controls */\n withControls?: boolean\n /** Show first/last controls */\n withEdges?: boolean\n /** Loop from last to first and vice versa */\n loop?: boolean\n}\n\nconst Pagination = React.forwardRef<HTMLElement, PaginationProps>(\n ({\n className,\n total = 1,\n value,\n defaultValue = 1,\n onChange,\n siblings = 1,\n boundaries = 1,\n size = 'default',\n variant = 'default',\n color = 'default',\n radius = 'md',\n disabled = false,\n withControls = true,\n withEdges = false,\n loop = false,\n children,\n ...props\n }, ref) => {\n // Controlled / Uncontrolled\n const [internalPage, setInternalPage] = React.useState(defaultValue)\n const isControlled = value !== undefined\n const page = isControlled ? value : internalPage\n\n const handlePageChange = React.useCallback((newPage: number) => {\n if (disabled) return\n const clamped = Math.max(1, Math.min(total, newPage))\n if (!isControlled) setInternalPage(clamped)\n onChange?.(clamped)\n }, [disabled, total, isControlled, onChange])\n\n const paginationRange = usePagination({ total, siblings, boundaries, page })\n\n const contextValue = React.useMemo<PaginationContextValue>(() => ({\n page,\n total,\n siblings,\n boundaries,\n size,\n variant,\n color,\n radius,\n disabled,\n loop,\n onPageChange: handlePageChange,\n paginationRange,\n }), [page, total, siblings, boundaries, size, variant, color, radius, disabled, loop, handlePageChange, paginationRange])\n\n return (\n <PaginationContext.Provider value={contextValue}>\n <nav\n ref={ref}\n role=\"navigation\"\n aria-label=\"pagination\"\n className={cn('', className)}\n {...props}\n >\n {children ?? (\n <PaginationContent>\n {withEdges && <PaginationItem><PaginationFirst /></PaginationItem>}\n {withControls && <PaginationItem><PaginationPrevious /></PaginationItem>}\n <PaginationItems />\n {withControls && <PaginationItem><PaginationNext /></PaginationItem>}\n {withEdges && <PaginationItem><PaginationLast /></PaginationItem>}\n </PaginationContent>\n )}\n </nav>\n </PaginationContext.Provider>\n )\n }\n)\nPagination.displayName = 'Pagination'\n\n// ─── PaginationContent ───────────────────────────────────\n\nconst PaginationContent = React.forwardRef<HTMLUListElement, React.ComponentPropsWithoutRef<'ul'>>(\n ({ className, ...props }, ref) => {\n const { size } = usePaginationContext()\n const sizeClass = paginationSizeMap[size]\n return (\n <ul\n ref={ref}\n className={cn('flex flex-wrap items-center', sizeClass.gap, className)}\n {...props}\n />\n )\n }\n)\nPaginationContent.displayName = 'PaginationContent'\n\n// ─── PaginationItem ──────────────────────────────────────\n\nconst PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentPropsWithoutRef<'li'>>(\n ({ className, ...props }, ref) => (\n <li ref={ref} className={cn('', className)} {...props} />\n )\n)\nPaginationItem.displayName = 'PaginationItem'\n\n// ─── PaginationLink ──────────────────────────────────────\n\nexport interface PaginationLinkProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Page number this link navigates to */\n page: number\n /** Whether this page is currently active (auto-detected from context if omitted) */\n isActive?: boolean\n}\n\nconst PaginationLink = React.forwardRef<HTMLButtonElement, PaginationLinkProps>(\n ({ className, page: targetPage, isActive: isActiveProp, ...props }, ref) => {\n const ctx = usePaginationContext()\n const isActive = isActiveProp ?? (ctx.page === targetPage)\n const sizeClass = paginationSizeMap[ctx.size]\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-current={isActive ? 'page' : undefined}\n aria-label={`Go to page ${targetPage}`}\n disabled={ctx.disabled}\n onClick={() => ctx.onPageChange(targetPage)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, isActive, ctx.disabled),\n className\n )}\n {...props}\n >\n {targetPage}\n </button>\n )\n }\n)\nPaginationLink.displayName = 'PaginationLink'\n\n// ─── PaginationPrevious ──────────────────────────────────\n\nexport interface PaginationPreviousProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationPrevious = React.forwardRef<HTMLButtonElement, PaginationPreviousProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || (!ctx.loop && ctx.page <= 1)\n\n const handleClick = () => {\n if (ctx.page <= 1) {\n if (ctx.loop) ctx.onPageChange(ctx.total)\n } else {\n ctx.onPageChange(ctx.page - 1)\n }\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to previous page\"\n disabled={isDisabled}\n onClick={handleClick}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronLeftIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationPrevious.displayName = 'PaginationPrevious'\n\n// ─── PaginationNext ──────────────────────────────────────\n\nexport interface PaginationNextProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationNext = React.forwardRef<HTMLButtonElement, PaginationNextProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || (!ctx.loop && ctx.page >= ctx.total)\n\n const handleClick = () => {\n if (ctx.page >= ctx.total) {\n if (ctx.loop) ctx.onPageChange(1)\n } else {\n ctx.onPageChange(ctx.page + 1)\n }\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to next page\"\n disabled={isDisabled}\n onClick={handleClick}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronRightIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationNext.displayName = 'PaginationNext'\n\n// ─── PaginationFirst ─────────────────────────────────────\n\nexport interface PaginationFirstProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationFirst = React.forwardRef<HTMLButtonElement, PaginationFirstProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || ctx.page <= 1\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to first page\"\n disabled={isDisabled}\n onClick={() => ctx.onPageChange(1)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronsLeftIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationFirst.displayName = 'PaginationFirst'\n\n// ─── PaginationLast ──────────────────────────────────────\n\nexport interface PaginationLastProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationLast = React.forwardRef<HTMLButtonElement, PaginationLastProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || ctx.page >= ctx.total\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to last page\"\n disabled={isDisabled}\n onClick={() => ctx.onPageChange(ctx.total)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronsRightIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationLast.displayName = 'PaginationLast'\n\n// ─── PaginationEllipsis ──────────────────────────────────\n\nconst PaginationEllipsis = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<'span'>>(\n ({ className, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n return (\n <span\n ref={ref}\n aria-hidden=\"true\"\n className={cn(\n 'inline-flex items-center justify-center text-text-muted',\n sizeClass.item,\n className\n )}\n {...props}\n >\n <EllipsisIcon className={sizeClass.icon} />\n <span className=\"sr-only\">More pages</span>\n </span>\n )\n }\n)\nPaginationEllipsis.displayName = 'PaginationEllipsis'\n\n// ─── PaginationItems (Convenience) ───────────────────────\n\nconst PaginationItems = React.forwardRef<HTMLDivElement, React.ComponentPropsWithoutRef<'div'>>(\n ({ className, ...props }, ref) => {\n const ctx = usePaginationContext()\n return (\n <div ref={ref} className={cn('contents', className)} {...props}>\n {ctx.paginationRange.map((item, index) => (\n <PaginationItem key={`${item}-${index}`}>\n {item === 'dots' ? (\n <PaginationEllipsis />\n ) : (\n <PaginationLink page={item} />\n )}\n </PaginationItem>\n ))}\n </div>\n )\n }\n)\nPaginationItems.displayName = 'PaginationItems'\n\n// ─── Exports ─────────────────────────────────────────────\n\nexport {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationLink,\n PaginationPrevious,\n PaginationNext,\n PaginationFirst,\n PaginationLast,\n PaginationEllipsis,\n PaginationItems,\n paginationItemVariants,\n paginationSizeMap,\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/ui/pagination.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\n// ─── Built-in Icons ──────────────────────────────────────\n\nfunction ChevronLeftIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n )\n}\n\nfunction ChevronRightIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n )\n}\n\nfunction ChevronsLeftIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11 17l-5-5 5-5M18 17l-5-5 5-5\" />\n </svg>\n )\n}\n\nfunction ChevronsRightIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M13 7l5 5-5 5M6 7l5 5-5 5\" />\n </svg>\n )\n}\n\nfunction EllipsisIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" />\n </svg>\n )\n}\n\n// ─── usePagination Hook ──────────────────────────────────\n\nexport type PaginationRange = (number | 'dots')[]\n\nexport interface UsePaginationProps {\n /** Total number of pages */\n total: number\n /** Number of siblings on each side of current page */\n siblings?: number\n /** Number of boundary pages at start/end */\n boundaries?: number\n /** Current active page (1-based) */\n page: number\n}\n\nfunction range(start: number, end: number): number[] {\n const result: number[] = []\n for (let i = start; i <= end; i++) result.push(i)\n return result\n}\n\nexport function usePagination({\n total,\n siblings = 1,\n boundaries = 1,\n page,\n}: UsePaginationProps): PaginationRange {\n if (total <= 0) return []\n\n const totalPageNumbers = siblings * 2 + 3 + boundaries * 2\n if (totalPageNumbers >= total) {\n return range(1, total)\n }\n\n const leftSiblingIndex = Math.max(page - siblings, boundaries + 1)\n const rightSiblingIndex = Math.min(page + siblings, total - boundaries)\n\n const showLeftDots = leftSiblingIndex > boundaries + 2\n const showRightDots = rightSiblingIndex < total - boundaries - 1\n\n if (!showLeftDots && showRightDots) {\n const leftItemCount = 3 + 2 * siblings + boundaries\n const leftRange = range(1, leftItemCount)\n return [...leftRange, 'dots' as const, ...range(total - boundaries + 1, total)]\n }\n\n if (showLeftDots && !showRightDots) {\n const rightItemCount = 3 + 2 * siblings + boundaries\n const rightRange = range(total - rightItemCount + 1, total)\n return [...range(1, boundaries), 'dots' as const, ...rightRange]\n }\n\n return [\n ...range(1, boundaries),\n 'dots' as const,\n ...range(leftSiblingIndex, rightSiblingIndex),\n 'dots' as const,\n ...range(total - boundaries + 1, total),\n ]\n}\n\n// ─── Context ─────────────────────────────────────────────\n\nexport type PaginationSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl'\nexport type PaginationVariant = 'default' | 'outline' | 'ghost'\nexport type PaginationColor = 'default' | 'primary'\nexport type PaginationRadius = 'sm' | 'base' | 'md' | 'lg' | 'xl' | 'full'\n\ntype PaginationContextValue = {\n page: number\n total: number\n siblings: number\n boundaries: number\n size: PaginationSize\n variant: PaginationVariant\n color: PaginationColor\n radius: PaginationRadius\n disabled: boolean\n loop: boolean\n onPageChange: (page: number) => void\n paginationRange: PaginationRange\n}\n\nconst PaginationContext = React.createContext<PaginationContextValue | null>(null)\n\nfunction usePaginationContext() {\n const ctx = React.useContext(PaginationContext)\n if (!ctx) throw new Error('Pagination components must be used within <Pagination>')\n return ctx\n}\n\n// ─── Size Map ────────────────────────────────────────────\n\nconst paginationSizeMap = {\n xs: { item: 'h-7 min-w-7 text-xs', icon: 'icon-xs', gap: 'gap-1' },\n sm: { item: 'h-8 min-w-8 text-sm', icon: 'icon-xs', gap: 'gap-1' },\n default: { item: 'h-9 min-w-9 text-md', icon: 'icon-sm', gap: 'gap-1' },\n lg: { item: 'h-10 min-w-10 text-md', icon: 'icon-sm', gap: 'gap-1.5' },\n xl: { item: 'h-12 min-w-12 text-base', icon: 'icon-sm', gap: 'gap-1.5' },\n} as const\n\n// ─── Item Variants (CVA) ─────────────────────────────────\n\nconst paginationItemVariants = cva(\n 'inline-flex items-center justify-center select-none transition-colors duration-fast font-semibold focus-visible:focus-ring',\n {\n variants: {\n radius: {\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n full: 'rounded-full',\n },\n },\n defaultVariants: {\n radius: 'md',\n },\n }\n)\n\n// ─── Variant Style Helpers ───────────────────────────────\n\n// Active color maps\nconst activeColorMap = {\n default: 'bg-foreground text-background',\n primary: 'bg-primary text-primary-foreground',\n} as const\n\nconst ghostActiveColorMap = {\n default: 'bg-background-muted text-foreground font-bold',\n primary: 'bg-background-muted text-primary',\n} as const\n\nfunction getItemClasses(variant: PaginationVariant, color: PaginationColor, isActive: boolean, disabled: boolean) {\n if (disabled) {\n return variant === 'outline'\n ? 'border border-border text-disabled-foreground pointer-events-none opacity-50'\n : 'border border-transparent text-disabled-foreground pointer-events-none opacity-50'\n }\n if (isActive) {\n switch (variant) {\n case 'outline':\n return `border ${color === 'default' ? 'border-foreground' : 'border-primary'} ${activeColorMap[color]}`\n case 'ghost':\n return `border border-transparent ${ghostActiveColorMap[color]}`\n case 'default':\n default:\n return `border border-transparent ${activeColorMap[color]}`\n }\n }\n switch (variant) {\n case 'outline':\n return 'border border-border text-text-muted hover:bg-background-muted hover:text-foreground'\n case 'ghost':\n return 'border border-transparent text-text-muted hover:bg-background-muted hover:text-foreground'\n case 'default':\n default:\n return 'border border-transparent text-text-muted hover:bg-background-muted hover:text-foreground'\n }\n}\n\n// ─── Pagination (Root) ───────────────────────────────────\n\nexport interface PaginationProps extends Omit<React.ComponentPropsWithoutRef<'nav'>, 'onChange'> {\n /** Total number of pages */\n total?: number\n /** Controlled active page (1-based) */\n value?: number\n /** Initial page for uncontrolled mode */\n defaultValue?: number\n /** Page change callback */\n onChange?: (page: number) => void\n /** Number of siblings on each side of current page */\n siblings?: number\n /** Number of boundary pages at start/end */\n boundaries?: number\n /** Component size */\n size?: PaginationSize\n /** Visual variant */\n variant?: PaginationVariant\n /** Active page color */\n color?: PaginationColor\n /** Border radius */\n radius?: PaginationRadius\n /** Disable all interactions */\n disabled?: boolean\n /** Show previous/next controls */\n withControls?: boolean\n /** Show first/last controls */\n withEdges?: boolean\n /** Loop from last to first and vice versa */\n loop?: boolean\n}\n\nconst Pagination = React.forwardRef<HTMLElement, PaginationProps>(\n ({\n className,\n total = 1,\n value,\n defaultValue = 1,\n onChange,\n siblings = 1,\n boundaries = 1,\n size = 'default',\n variant = 'default',\n color = 'default',\n radius = 'md',\n disabled = false,\n withControls = true,\n withEdges = false,\n loop = false,\n children,\n ...props\n }, ref) => {\n // Controlled / Uncontrolled\n const [internalPage, setInternalPage] = React.useState(defaultValue)\n const isControlled = value !== undefined\n const page = isControlled ? value : internalPage\n\n const handlePageChange = React.useCallback((newPage: number) => {\n if (disabled) return\n const clamped = Math.max(1, Math.min(total, newPage))\n if (!isControlled) setInternalPage(clamped)\n onChange?.(clamped)\n }, [disabled, total, isControlled, onChange])\n\n const paginationRange = usePagination({ total, siblings, boundaries, page })\n\n const contextValue = React.useMemo<PaginationContextValue>(() => ({\n page,\n total,\n siblings,\n boundaries,\n size,\n variant,\n color,\n radius,\n disabled,\n loop,\n onPageChange: handlePageChange,\n paginationRange,\n }), [page, total, siblings, boundaries, size, variant, color, radius, disabled, loop, handlePageChange, paginationRange])\n\n return (\n <PaginationContext.Provider value={contextValue}>\n <nav\n ref={ref}\n role=\"navigation\"\n aria-label=\"pagination\"\n className={cn('', className)}\n {...props}\n >\n {children ?? (\n <PaginationContent>\n {withEdges && <PaginationItem><PaginationFirst /></PaginationItem>}\n {withControls && <PaginationItem><PaginationPrevious /></PaginationItem>}\n <PaginationItems />\n {withControls && <PaginationItem><PaginationNext /></PaginationItem>}\n {withEdges && <PaginationItem><PaginationLast /></PaginationItem>}\n </PaginationContent>\n )}\n </nav>\n </PaginationContext.Provider>\n )\n }\n)\nPagination.displayName = 'Pagination'\n\n// ─── PaginationContent ───────────────────────────────────\n\nconst PaginationContent = React.forwardRef<HTMLUListElement, React.ComponentPropsWithoutRef<'ul'>>(\n ({ className, ...props }, ref) => {\n const { size } = usePaginationContext()\n const sizeClass = paginationSizeMap[size]\n return (\n <ul\n ref={ref}\n className={cn('flex flex-wrap items-center', sizeClass.gap, className)}\n {...props}\n />\n )\n }\n)\nPaginationContent.displayName = 'PaginationContent'\n\n// ─── PaginationItem ──────────────────────────────────────\n\nconst PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentPropsWithoutRef<'li'>>(\n ({ className, ...props }, ref) => (\n <li ref={ref} className={cn('', className)} {...props} />\n )\n)\nPaginationItem.displayName = 'PaginationItem'\n\n// ─── PaginationLink ──────────────────────────────────────\n\nexport interface PaginationLinkProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Page number this link navigates to */\n page: number\n /** Whether this page is currently active (auto-detected from context if omitted) */\n isActive?: boolean\n}\n\nconst PaginationLink = React.forwardRef<HTMLButtonElement, PaginationLinkProps>(\n ({ className, page: targetPage, isActive: isActiveProp, ...props }, ref) => {\n const ctx = usePaginationContext()\n const isActive = isActiveProp ?? (ctx.page === targetPage)\n const sizeClass = paginationSizeMap[ctx.size]\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-current={isActive ? 'page' : undefined}\n aria-label={`Go to page ${targetPage}`}\n disabled={ctx.disabled}\n onClick={() => ctx.onPageChange(targetPage)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, isActive, ctx.disabled),\n className\n )}\n {...props}\n >\n {targetPage}\n </button>\n )\n }\n)\nPaginationLink.displayName = 'PaginationLink'\n\n// ─── PaginationPrevious ──────────────────────────────────\n\nexport interface PaginationPreviousProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationPrevious = React.forwardRef<HTMLButtonElement, PaginationPreviousProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || (!ctx.loop && ctx.page <= 1)\n\n const handleClick = () => {\n if (ctx.page <= 1) {\n if (ctx.loop) ctx.onPageChange(ctx.total)\n } else {\n ctx.onPageChange(ctx.page - 1)\n }\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to previous page\"\n disabled={isDisabled}\n onClick={handleClick}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronLeftIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationPrevious.displayName = 'PaginationPrevious'\n\n// ─── PaginationNext ──────────────────────────────────────\n\nexport interface PaginationNextProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationNext = React.forwardRef<HTMLButtonElement, PaginationNextProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || (!ctx.loop && ctx.page >= ctx.total)\n\n const handleClick = () => {\n if (ctx.page >= ctx.total) {\n if (ctx.loop) ctx.onPageChange(1)\n } else {\n ctx.onPageChange(ctx.page + 1)\n }\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to next page\"\n disabled={isDisabled}\n onClick={handleClick}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronRightIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationNext.displayName = 'PaginationNext'\n\n// ─── PaginationFirst ─────────────────────────────────────\n\nexport interface PaginationFirstProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationFirst = React.forwardRef<HTMLButtonElement, PaginationFirstProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || ctx.page <= 1\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to first page\"\n disabled={isDisabled}\n onClick={() => ctx.onPageChange(1)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronsLeftIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationFirst.displayName = 'PaginationFirst'\n\n// ─── PaginationLast ──────────────────────────────────────\n\nexport interface PaginationLastProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationLast = React.forwardRef<HTMLButtonElement, PaginationLastProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || ctx.page >= ctx.total\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to last page\"\n disabled={isDisabled}\n onClick={() => ctx.onPageChange(ctx.total)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronsRightIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationLast.displayName = 'PaginationLast'\n\n// ─── PaginationEllipsis ──────────────────────────────────\n\nconst PaginationEllipsis = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<'span'>>(\n ({ className, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n return (\n <span\n ref={ref}\n aria-hidden=\"true\"\n className={cn(\n 'inline-flex items-center justify-center text-text-muted',\n sizeClass.item,\n className\n )}\n {...props}\n >\n <EllipsisIcon className={sizeClass.icon} />\n <span className=\"sr-only\">More pages</span>\n </span>\n )\n }\n)\nPaginationEllipsis.displayName = 'PaginationEllipsis'\n\n// ─── PaginationItems (Convenience) ───────────────────────\n\n// Renders the <li> items straight into PaginationContent's <ul>: a wrapper element\n// between them breaks the list structure for assistive technology (a `display:\n// contents` div used to sit here). The div props and ref stay in the signature for\n// compatibility but have no element to attach to.\nconst PaginationItems = React.forwardRef<HTMLDivElement, React.ComponentPropsWithoutRef<'div'>>(\n (_props, _ref) => {\n const ctx = usePaginationContext()\n return (\n <>\n {ctx.paginationRange.map((item, index) => (\n <PaginationItem key={`${item}-${index}`}>\n {item === 'dots' ? (\n <PaginationEllipsis />\n ) : (\n <PaginationLink page={item} />\n )}\n </PaginationItem>\n ))}\n </>\n )\n }\n)\nPaginationItems.displayName = 'PaginationItems'\n\n// ─── Exports ─────────────────────────────────────────────\n\nexport {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationLink,\n PaginationPrevious,\n PaginationNext,\n PaginationFirst,\n PaginationLast,\n PaginationEllipsis,\n PaginationItems,\n paginationItemVariants,\n paginationSizeMap,\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBM;AAfN,YAAuB;AACvB,sCAAuC;AACvC,mBAAmB;AAInB,SAAS,gBAAgB,EAAE,UAAU,GAA2B;AAC9D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,QAAO;AAAA,MACP,aAAa;AAAA,MAEb,sDAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,mBAAkB;AAAA;AAAA,EACzE;AAEJ;AAEA,SAAS,iBAAiB,EAAE,UAAU,GAA2B;AAC/D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,QAAO;AAAA,MACP,aAAa;AAAA,MAEb,sDAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,gBAAe;AAAA;AAAA,EACtE;AAEJ;AAEA,SAAS,iBAAiB,EAAE,UAAU,GAA2B;AAC/D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,QAAO;AAAA,MACP,aAAa;AAAA,MAEb,sDAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,kCAAiC;AAAA;AAAA,EACxF;AAEJ;AAEA,SAAS,kBAAkB,EAAE,UAAU,GAA2B;AAChE,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,QAAO;AAAA,MACP,aAAa;AAAA,MAEb,sDAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,6BAA4B;AAAA;AAAA,EACnF;AAEJ;AAEA,SAAS,aAAa,EAAE,UAAU,GAA2B;AAC3D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL,SAAQ;AAAA,MAER;AAAA,oDAAC,YAAO,IAAG,KAAI,IAAG,MAAK,GAAE,OAAM;AAAA,QAC/B,4CAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,OAAM;AAAA,QAChC,4CAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,OAAM;AAAA;AAAA;AAAA,EAClC;AAEJ;AAiBA,SAAS,MAAM,OAAe,KAAuB;AACnD,QAAM,SAAmB,CAAC;AAC1B,WAAS,IAAI,OAAO,KAAK,KAAK,IAAK,QAAO,KAAK,CAAC;AAChD,SAAO;AACT;AAEO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,WAAW;AAAA,EACX,aAAa;AAAA,EACb;AACF,GAAwC;AACtC,MAAI,SAAS,EAAG,QAAO,CAAC;AAExB,QAAM,mBAAmB,WAAW,IAAI,IAAI,aAAa;AACzD,MAAI,oBAAoB,OAAO;AAC7B,WAAO,MAAM,GAAG,KAAK;AAAA,EACvB;AAEA,QAAM,mBAAmB,KAAK,IAAI,OAAO,UAAU,aAAa,CAAC;AACjE,QAAM,oBAAoB,KAAK,IAAI,OAAO,UAAU,QAAQ,UAAU;AAEtE,QAAM,eAAe,mBAAmB,aAAa;AACrD,QAAM,gBAAgB,oBAAoB,QAAQ,aAAa;AAE/D,MAAI,CAAC,gBAAgB,eAAe;AAClC,UAAM,gBAAgB,IAAI,IAAI,WAAW;AACzC,UAAM,YAAY,MAAM,GAAG,aAAa;AACxC,WAAO,CAAC,GAAG,WAAW,QAAiB,GAAG,MAAM,QAAQ,aAAa,GAAG,KAAK,CAAC;AAAA,EAChF;AAEA,MAAI,gBAAgB,CAAC,eAAe;AAClC,UAAM,iBAAiB,IAAI,IAAI,WAAW;AAC1C,UAAM,aAAa,MAAM,QAAQ,iBAAiB,GAAG,KAAK;AAC1D,WAAO,CAAC,GAAG,MAAM,GAAG,UAAU,GAAG,QAAiB,GAAG,UAAU;AAAA,EACjE;AAEA,SAAO;AAAA,IACL,GAAG,MAAM,GAAG,UAAU;AAAA,IACtB;AAAA,IACA,GAAG,MAAM,kBAAkB,iBAAiB;AAAA,IAC5C;AAAA,IACA,GAAG,MAAM,QAAQ,aAAa,GAAG,KAAK;AAAA,EACxC;AACF;AAwBA,MAAM,oBAAoB,MAAM,cAA6C,IAAI;AAEjF,SAAS,uBAAuB;AAC9B,QAAM,MAAM,MAAM,WAAW,iBAAiB;AAC9C,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,wDAAwD;AAClF,SAAO;AACT;AAIA,MAAM,oBAAoB;AAAA,EACxB,IAAI,EAAE,MAAM,uBAAuB,MAAM,WAAW,KAAK,QAAQ;AAAA,EACjE,IAAI,EAAE,MAAM,uBAAuB,MAAM,WAAW,KAAK,QAAQ;AAAA,EACjE,SAAS,EAAE,MAAM,uBAAuB,MAAM,WAAW,KAAK,QAAQ;AAAA,EACtE,IAAI,EAAE,MAAM,yBAAyB,MAAM,WAAW,KAAK,UAAU;AAAA,EACrE,IAAI,EAAE,MAAM,2BAA2B,MAAM,WAAW,KAAK,UAAU;AACzE;AAIA,MAAM,6BAAyB;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,QAAQ;AAAA,QACN,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAKA,MAAM,iBAAiB;AAAA,EACrB,SAAS;AAAA,EACT,SAAS;AACX;AAEA,MAAM,sBAAsB;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AACX;AAEA,SAAS,eAAe,SAA4B,OAAwB,UAAmB,UAAmB;AAChH,MAAI,UAAU;AACZ,WAAO,YAAY,YACf,iFACA;AAAA,EACN;AACA,MAAI,UAAU;AACZ,YAAQ,SAAS;AAAA,MACf,KAAK;AACH,eAAO,UAAU,UAAU,YAAY,sBAAsB,gBAAgB,IAAI,eAAe,KAAK,CAAC;AAAA,MACxG,KAAK;AACH,eAAO,6BAA6B,oBAAoB,KAAK,CAAC;AAAA,MAChE,KAAK;AAAA,MACL;AACE,eAAO,6BAA6B,eAAe,KAAK,CAAC;AAAA,IAC7D;AAAA,EACF;AACA,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;AAmCA,MAAM,aAAa,MAAM;AAAA,EACvB,CAAC;AAAA,IACC;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA,WAAW;AAAA,IACX,aAAa;AAAA,IACb,OAAO;AAAA,IACP,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,IACX,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,OAAO;AAAA,IACP;AAAA,IACA,GAAG;AAAA,EACL,GAAG,QAAQ;AAET,UAAM,CAAC,cAAc,eAAe,IAAI,MAAM,SAAS,YAAY;AACnE,UAAM,eAAe,UAAU;AAC/B,UAAM,OAAO,eAAe,QAAQ;AAEpC,UAAM,mBAAmB,MAAM,YAAY,CAAC,YAAoB;AAC9D,UAAI,SAAU;AACd,YAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,OAAO,CAAC;AACpD,UAAI,CAAC,aAAc,iBAAgB,OAAO;AAC1C,iBAAW,OAAO;AAAA,IACpB,GAAG,CAAC,UAAU,OAAO,cAAc,QAAQ,CAAC;AAE5C,UAAM,kBAAkB,cAAc,EAAE,OAAO,UAAU,YAAY,KAAK,CAAC;AAE3E,UAAM,eAAe,MAAM,QAAgC,OAAO;AAAA,MAChE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd;AAAA,IACF,IAAI,CAAC,MAAM,OAAO,UAAU,YAAY,MAAM,SAAS,OAAO,QAAQ,UAAU,MAAM,kBAAkB,eAAe,CAAC;AAExH,WACE,4CAAC,kBAAkB,UAAlB,EAA2B,OAAO,cACjC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,cAAW;AAAA,QACX,eAAW,iBAAG,IAAI,SAAS;AAAA,QAC1B,GAAG;AAAA,QAEH,sBACC,6CAAC,qBACE;AAAA,uBAAa,4CAAC,kBAAe,sDAAC,mBAAgB,GAAE;AAAA,UAChD,gBAAgB,4CAAC,kBAAe,sDAAC,sBAAmB,GAAE;AAAA,UACvD,4CAAC,mBAAgB;AAAA,UAChB,gBAAgB,4CAAC,kBAAe,sDAAC,kBAAe,GAAE;AAAA,UAClD,aAAa,4CAAC,kBAAe,sDAAC,kBAAe,GAAE;AAAA,WAClD;AAAA;AAAA,IAEJ,GACF;AAAA,EAEJ;AACF;AACA,WAAW,cAAc;AAIzB,MAAM,oBAAoB,MAAM;AAAA,EAC9B,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ;AAChC,UAAM,EAAE,KAAK,IAAI,qBAAqB;AACtC,UAAM,YAAY,kBAAkB,IAAI;AACxC,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,eAAW,iBAAG,+BAA+B,UAAU,KAAK,SAAS;AAAA,QACpE,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AACA,kBAAkB,cAAc;AAIhC,MAAM,iBAAiB,MAAM;AAAA,EAC3B,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QACxB,4CAAC,QAAG,KAAU,eAAW,iBAAG,IAAI,SAAS,GAAI,GAAG,OAAO;AAE3D;AACA,eAAe,cAAc;AAW7B,MAAM,iBAAiB,MAAM;AAAA,EAC3B,CAAC,EAAE,WAAW,MAAM,YAAY,UAAU,cAAc,GAAG,MAAM,GAAG,QAAQ;AAC1E,UAAM,MAAM,qBAAqB;AACjC,UAAM,WAAW,gBAAiB,IAAI,SAAS;AAC/C,UAAM,YAAY,kBAAkB,IAAI,IAAI;AAE5C,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,gBAAc,WAAW,SAAS;AAAA,QAClC,cAAY,cAAc,UAAU;AAAA,QACpC,UAAU,IAAI;AAAA,QACd,SAAS,MAAM,IAAI,aAAa,UAAU;AAAA,QAC1C,eAAW;AAAA,UACT,uBAAuB,EAAE,QAAQ,IAAI,OAAO,CAAC;AAAA,UAC7C,UAAU;AAAA,UACV,eAAe,IAAI,SAAS,IAAI,OAAO,UAAU,IAAI,QAAQ;AAAA,UAC7D;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AACA,eAAe,cAAc;AAS7B,MAAM,qBAAqB,MAAM;AAAA,EAC/B,CAAC,EAAE,WAAW,MAAM,GAAG,MAAM,GAAG,QAAQ;AACtC,UAAM,MAAM,qBAAqB;AACjC,UAAM,YAAY,kBAAkB,IAAI,IAAI;AAC5C,UAAM,aAAa,IAAI,YAAa,CAAC,IAAI,QAAQ,IAAI,QAAQ;AAE7D,UAAM,cAAc,MAAM;AACxB,UAAI,IAAI,QAAQ,GAAG;AACjB,YAAI,IAAI,KAAM,KAAI,aAAa,IAAI,KAAK;AAAA,MAC1C,OAAO;AACL,YAAI,aAAa,IAAI,OAAO,CAAC;AAAA,MAC/B;AAAA,IACF;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,cAAW;AAAA,QACX,UAAU;AAAA,QACV,SAAS;AAAA,QACT,eAAW;AAAA,UACT,uBAAuB,EAAE,QAAQ,IAAI,OAAO,CAAC;AAAA,UAC7C,UAAU;AAAA,UACV,eAAe,IAAI,SAAS,IAAI,OAAO,OAAO,UAAU;AAAA,UACxD;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH,kBAAQ,4CAAC,mBAAgB,WAAW,UAAU,MAAM;AAAA;AAAA,IACvD;AAAA,EAEJ;AACF;AACA,mBAAmB,cAAc;AASjC,MAAM,iBAAiB,MAAM;AAAA,EAC3B,CAAC,EAAE,WAAW,MAAM,GAAG,MAAM,GAAG,QAAQ;AACtC,UAAM,MAAM,qBAAqB;AACjC,UAAM,YAAY,kBAAkB,IAAI,IAAI;AAC5C,UAAM,aAAa,IAAI,YAAa,CAAC,IAAI,QAAQ,IAAI,QAAQ,IAAI;AAEjE,UAAM,cAAc,MAAM;AACxB,UAAI,IAAI,QAAQ,IAAI,OAAO;AACzB,YAAI,IAAI,KAAM,KAAI,aAAa,CAAC;AAAA,MAClC,OAAO;AACL,YAAI,aAAa,IAAI,OAAO,CAAC;AAAA,MAC/B;AAAA,IACF;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,cAAW;AAAA,QACX,UAAU;AAAA,QACV,SAAS;AAAA,QACT,eAAW;AAAA,UACT,uBAAuB,EAAE,QAAQ,IAAI,OAAO,CAAC;AAAA,UAC7C,UAAU;AAAA,UACV,eAAe,IAAI,SAAS,IAAI,OAAO,OAAO,UAAU;AAAA,UACxD;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH,kBAAQ,4CAAC,oBAAiB,WAAW,UAAU,MAAM;AAAA;AAAA,IACxD;AAAA,EAEJ;AACF;AACA,eAAe,cAAc;AAS7B,MAAM,kBAAkB,MAAM;AAAA,EAC5B,CAAC,EAAE,WAAW,MAAM,GAAG,MAAM,GAAG,QAAQ;AACtC,UAAM,MAAM,qBAAqB;AACjC,UAAM,YAAY,kBAAkB,IAAI,IAAI;AAC5C,UAAM,aAAa,IAAI,YAAY,IAAI,QAAQ;AAE/C,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,cAAW;AAAA,QACX,UAAU;AAAA,QACV,SAAS,MAAM,IAAI,aAAa,CAAC;AAAA,QACjC,eAAW;AAAA,UACT,uBAAuB,EAAE,QAAQ,IAAI,OAAO,CAAC;AAAA,UAC7C,UAAU;AAAA,UACV,eAAe,IAAI,SAAS,IAAI,OAAO,OAAO,UAAU;AAAA,UACxD;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH,kBAAQ,4CAAC,oBAAiB,WAAW,UAAU,MAAM;AAAA;AAAA,IACxD;AAAA,EAEJ;AACF;AACA,gBAAgB,cAAc;AAS9B,MAAM,iBAAiB,MAAM;AAAA,EAC3B,CAAC,EAAE,WAAW,MAAM,GAAG,MAAM,GAAG,QAAQ;AACtC,UAAM,MAAM,qBAAqB;AACjC,UAAM,YAAY,kBAAkB,IAAI,IAAI;AAC5C,UAAM,aAAa,IAAI,YAAY,IAAI,QAAQ,IAAI;AAEnD,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,cAAW;AAAA,QACX,UAAU;AAAA,QACV,SAAS,MAAM,IAAI,aAAa,IAAI,KAAK;AAAA,QACzC,eAAW;AAAA,UACT,uBAAuB,EAAE,QAAQ,IAAI,OAAO,CAAC;AAAA,UAC7C,UAAU;AAAA,UACV,eAAe,IAAI,SAAS,IAAI,OAAO,OAAO,UAAU;AAAA,UACxD;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH,kBAAQ,4CAAC,qBAAkB,WAAW,UAAU,MAAM;AAAA;AAAA,IACzD;AAAA,EAEJ;AACF;AACA,eAAe,cAAc;AAI7B,MAAM,qBAAqB,MAAM;AAAA,EAC/B,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ;AAChC,UAAM,MAAM,qBAAqB;AACjC,UAAM,YAAY,kBAAkB,IAAI,IAAI;AAC5C,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,eAAY;AAAA,QACZ,eAAW;AAAA,UACT;AAAA,UACA,UAAU;AAAA,UACV;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ;AAAA,sDAAC,gBAAa,WAAW,UAAU,MAAM;AAAA,UACzC,4CAAC,UAAK,WAAU,WAAU,wBAAU;AAAA;AAAA;AAAA,IACtC;AAAA,EAEJ;AACF;AACA,mBAAmB,cAAc;AAQjC,MAAM,kBAAkB,MAAM;AAAA,EAC5B,CAAC,QAAQ,SAAS;AAChB,UAAM,MAAM,qBAAqB;AACjC,WACE,2EACG,cAAI,gBAAgB,IAAI,CAAC,MAAM,UAC9B,4CAAC,kBACE,mBAAS,SACR,4CAAC,sBAAmB,IAEpB,4CAAC,kBAAe,MAAM,MAAM,KAJX,GAAG,IAAI,IAAI,KAAK,EAMrC,CACD,GACH;AAAA,EAEJ;AACF;AACA,gBAAgB,cAAc;","names":[]}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { cva } from "class-variance-authority";
5
5
  import { cn } from "../../lib/utils.mjs";
@@ -425,9 +425,9 @@ const PaginationEllipsis = React.forwardRef(
425
425
  );
426
426
  PaginationEllipsis.displayName = "PaginationEllipsis";
427
427
  const PaginationItems = React.forwardRef(
428
- ({ className, ...props }, ref) => {
428
+ (_props, _ref) => {
429
429
  const ctx = usePaginationContext();
430
- return /* @__PURE__ */ jsx("div", { ref, className: cn("contents", className), ...props, children: ctx.paginationRange.map((item, index) => /* @__PURE__ */ jsx(PaginationItem, { children: item === "dots" ? /* @__PURE__ */ jsx(PaginationEllipsis, {}) : /* @__PURE__ */ jsx(PaginationLink, { page: item }) }, `${item}-${index}`)) });
430
+ return /* @__PURE__ */ jsx(Fragment, { children: ctx.paginationRange.map((item, index) => /* @__PURE__ */ jsx(PaginationItem, { children: item === "dots" ? /* @__PURE__ */ jsx(PaginationEllipsis, {}) : /* @__PURE__ */ jsx(PaginationLink, { page: item }) }, `${item}-${index}`)) });
431
431
  }
432
432
  );
433
433
  PaginationItems.displayName = "PaginationItems";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/pagination.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\n// ─── Built-in Icons ──────────────────────────────────────\n\nfunction ChevronLeftIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n )\n}\n\nfunction ChevronRightIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n )\n}\n\nfunction ChevronsLeftIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11 17l-5-5 5-5M18 17l-5-5 5-5\" />\n </svg>\n )\n}\n\nfunction ChevronsRightIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M13 7l5 5-5 5M6 7l5 5-5 5\" />\n </svg>\n )\n}\n\nfunction EllipsisIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" />\n </svg>\n )\n}\n\n// ─── usePagination Hook ──────────────────────────────────\n\nexport type PaginationRange = (number | 'dots')[]\n\nexport interface UsePaginationProps {\n /** Total number of pages */\n total: number\n /** Number of siblings on each side of current page */\n siblings?: number\n /** Number of boundary pages at start/end */\n boundaries?: number\n /** Current active page (1-based) */\n page: number\n}\n\nfunction range(start: number, end: number): number[] {\n const result: number[] = []\n for (let i = start; i <= end; i++) result.push(i)\n return result\n}\n\nexport function usePagination({\n total,\n siblings = 1,\n boundaries = 1,\n page,\n}: UsePaginationProps): PaginationRange {\n if (total <= 0) return []\n\n const totalPageNumbers = siblings * 2 + 3 + boundaries * 2\n if (totalPageNumbers >= total) {\n return range(1, total)\n }\n\n const leftSiblingIndex = Math.max(page - siblings, boundaries + 1)\n const rightSiblingIndex = Math.min(page + siblings, total - boundaries)\n\n const showLeftDots = leftSiblingIndex > boundaries + 2\n const showRightDots = rightSiblingIndex < total - boundaries - 1\n\n if (!showLeftDots && showRightDots) {\n const leftItemCount = 3 + 2 * siblings + boundaries\n const leftRange = range(1, leftItemCount)\n return [...leftRange, 'dots' as const, ...range(total - boundaries + 1, total)]\n }\n\n if (showLeftDots && !showRightDots) {\n const rightItemCount = 3 + 2 * siblings + boundaries\n const rightRange = range(total - rightItemCount + 1, total)\n return [...range(1, boundaries), 'dots' as const, ...rightRange]\n }\n\n return [\n ...range(1, boundaries),\n 'dots' as const,\n ...range(leftSiblingIndex, rightSiblingIndex),\n 'dots' as const,\n ...range(total - boundaries + 1, total),\n ]\n}\n\n// ─── Context ─────────────────────────────────────────────\n\nexport type PaginationSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl'\nexport type PaginationVariant = 'default' | 'outline' | 'ghost'\nexport type PaginationColor = 'default' | 'primary'\nexport type PaginationRadius = 'sm' | 'base' | 'md' | 'lg' | 'xl' | 'full'\n\ntype PaginationContextValue = {\n page: number\n total: number\n siblings: number\n boundaries: number\n size: PaginationSize\n variant: PaginationVariant\n color: PaginationColor\n radius: PaginationRadius\n disabled: boolean\n loop: boolean\n onPageChange: (page: number) => void\n paginationRange: PaginationRange\n}\n\nconst PaginationContext = React.createContext<PaginationContextValue | null>(null)\n\nfunction usePaginationContext() {\n const ctx = React.useContext(PaginationContext)\n if (!ctx) throw new Error('Pagination components must be used within <Pagination>')\n return ctx\n}\n\n// ─── Size Map ────────────────────────────────────────────\n\nconst paginationSizeMap = {\n xs: { item: 'h-7 min-w-7 text-xs', icon: 'icon-xs', gap: 'gap-1' },\n sm: { item: 'h-8 min-w-8 text-sm', icon: 'icon-xs', gap: 'gap-1' },\n default: { item: 'h-9 min-w-9 text-md', icon: 'icon-sm', gap: 'gap-1' },\n lg: { item: 'h-10 min-w-10 text-md', icon: 'icon-sm', gap: 'gap-1.5' },\n xl: { item: 'h-12 min-w-12 text-base', icon: 'icon-sm', gap: 'gap-1.5' },\n} as const\n\n// ─── Item Variants (CVA) ─────────────────────────────────\n\nconst paginationItemVariants = cva(\n 'inline-flex items-center justify-center select-none transition-colors duration-fast font-semibold focus-visible:focus-ring',\n {\n variants: {\n radius: {\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n full: 'rounded-full',\n },\n },\n defaultVariants: {\n radius: 'md',\n },\n }\n)\n\n// ─── Variant Style Helpers ───────────────────────────────\n\n// Active color maps\nconst activeColorMap = {\n default: 'bg-foreground text-background',\n primary: 'bg-primary text-primary-foreground',\n} as const\n\nconst ghostActiveColorMap = {\n default: 'bg-background-muted text-foreground font-bold',\n primary: 'bg-background-muted text-primary',\n} as const\n\nfunction getItemClasses(variant: PaginationVariant, color: PaginationColor, isActive: boolean, disabled: boolean) {\n if (disabled) {\n return variant === 'outline'\n ? 'border border-border text-disabled-foreground pointer-events-none opacity-50'\n : 'border border-transparent text-disabled-foreground pointer-events-none opacity-50'\n }\n if (isActive) {\n switch (variant) {\n case 'outline':\n return `border ${color === 'default' ? 'border-foreground' : 'border-primary'} ${activeColorMap[color]}`\n case 'ghost':\n return `border border-transparent ${ghostActiveColorMap[color]}`\n case 'default':\n default:\n return `border border-transparent ${activeColorMap[color]}`\n }\n }\n switch (variant) {\n case 'outline':\n return 'border border-border text-text-muted hover:bg-background-muted hover:text-foreground'\n case 'ghost':\n return 'border border-transparent text-text-muted hover:bg-background-muted hover:text-foreground'\n case 'default':\n default:\n return 'border border-transparent text-text-muted hover:bg-background-muted hover:text-foreground'\n }\n}\n\n// ─── Pagination (Root) ───────────────────────────────────\n\nexport interface PaginationProps extends Omit<React.ComponentPropsWithoutRef<'nav'>, 'onChange'> {\n /** Total number of pages */\n total?: number\n /** Controlled active page (1-based) */\n value?: number\n /** Initial page for uncontrolled mode */\n defaultValue?: number\n /** Page change callback */\n onChange?: (page: number) => void\n /** Number of siblings on each side of current page */\n siblings?: number\n /** Number of boundary pages at start/end */\n boundaries?: number\n /** Component size */\n size?: PaginationSize\n /** Visual variant */\n variant?: PaginationVariant\n /** Active page color */\n color?: PaginationColor\n /** Border radius */\n radius?: PaginationRadius\n /** Disable all interactions */\n disabled?: boolean\n /** Show previous/next controls */\n withControls?: boolean\n /** Show first/last controls */\n withEdges?: boolean\n /** Loop from last to first and vice versa */\n loop?: boolean\n}\n\nconst Pagination = React.forwardRef<HTMLElement, PaginationProps>(\n ({\n className,\n total = 1,\n value,\n defaultValue = 1,\n onChange,\n siblings = 1,\n boundaries = 1,\n size = 'default',\n variant = 'default',\n color = 'default',\n radius = 'md',\n disabled = false,\n withControls = true,\n withEdges = false,\n loop = false,\n children,\n ...props\n }, ref) => {\n // Controlled / Uncontrolled\n const [internalPage, setInternalPage] = React.useState(defaultValue)\n const isControlled = value !== undefined\n const page = isControlled ? value : internalPage\n\n const handlePageChange = React.useCallback((newPage: number) => {\n if (disabled) return\n const clamped = Math.max(1, Math.min(total, newPage))\n if (!isControlled) setInternalPage(clamped)\n onChange?.(clamped)\n }, [disabled, total, isControlled, onChange])\n\n const paginationRange = usePagination({ total, siblings, boundaries, page })\n\n const contextValue = React.useMemo<PaginationContextValue>(() => ({\n page,\n total,\n siblings,\n boundaries,\n size,\n variant,\n color,\n radius,\n disabled,\n loop,\n onPageChange: handlePageChange,\n paginationRange,\n }), [page, total, siblings, boundaries, size, variant, color, radius, disabled, loop, handlePageChange, paginationRange])\n\n return (\n <PaginationContext.Provider value={contextValue}>\n <nav\n ref={ref}\n role=\"navigation\"\n aria-label=\"pagination\"\n className={cn('', className)}\n {...props}\n >\n {children ?? (\n <PaginationContent>\n {withEdges && <PaginationItem><PaginationFirst /></PaginationItem>}\n {withControls && <PaginationItem><PaginationPrevious /></PaginationItem>}\n <PaginationItems />\n {withControls && <PaginationItem><PaginationNext /></PaginationItem>}\n {withEdges && <PaginationItem><PaginationLast /></PaginationItem>}\n </PaginationContent>\n )}\n </nav>\n </PaginationContext.Provider>\n )\n }\n)\nPagination.displayName = 'Pagination'\n\n// ─── PaginationContent ───────────────────────────────────\n\nconst PaginationContent = React.forwardRef<HTMLUListElement, React.ComponentPropsWithoutRef<'ul'>>(\n ({ className, ...props }, ref) => {\n const { size } = usePaginationContext()\n const sizeClass = paginationSizeMap[size]\n return (\n <ul\n ref={ref}\n className={cn('flex flex-wrap items-center', sizeClass.gap, className)}\n {...props}\n />\n )\n }\n)\nPaginationContent.displayName = 'PaginationContent'\n\n// ─── PaginationItem ──────────────────────────────────────\n\nconst PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentPropsWithoutRef<'li'>>(\n ({ className, ...props }, ref) => (\n <li ref={ref} className={cn('', className)} {...props} />\n )\n)\nPaginationItem.displayName = 'PaginationItem'\n\n// ─── PaginationLink ──────────────────────────────────────\n\nexport interface PaginationLinkProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Page number this link navigates to */\n page: number\n /** Whether this page is currently active (auto-detected from context if omitted) */\n isActive?: boolean\n}\n\nconst PaginationLink = React.forwardRef<HTMLButtonElement, PaginationLinkProps>(\n ({ className, page: targetPage, isActive: isActiveProp, ...props }, ref) => {\n const ctx = usePaginationContext()\n const isActive = isActiveProp ?? (ctx.page === targetPage)\n const sizeClass = paginationSizeMap[ctx.size]\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-current={isActive ? 'page' : undefined}\n aria-label={`Go to page ${targetPage}`}\n disabled={ctx.disabled}\n onClick={() => ctx.onPageChange(targetPage)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, isActive, ctx.disabled),\n className\n )}\n {...props}\n >\n {targetPage}\n </button>\n )\n }\n)\nPaginationLink.displayName = 'PaginationLink'\n\n// ─── PaginationPrevious ──────────────────────────────────\n\nexport interface PaginationPreviousProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationPrevious = React.forwardRef<HTMLButtonElement, PaginationPreviousProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || (!ctx.loop && ctx.page <= 1)\n\n const handleClick = () => {\n if (ctx.page <= 1) {\n if (ctx.loop) ctx.onPageChange(ctx.total)\n } else {\n ctx.onPageChange(ctx.page - 1)\n }\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to previous page\"\n disabled={isDisabled}\n onClick={handleClick}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronLeftIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationPrevious.displayName = 'PaginationPrevious'\n\n// ─── PaginationNext ──────────────────────────────────────\n\nexport interface PaginationNextProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationNext = React.forwardRef<HTMLButtonElement, PaginationNextProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || (!ctx.loop && ctx.page >= ctx.total)\n\n const handleClick = () => {\n if (ctx.page >= ctx.total) {\n if (ctx.loop) ctx.onPageChange(1)\n } else {\n ctx.onPageChange(ctx.page + 1)\n }\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to next page\"\n disabled={isDisabled}\n onClick={handleClick}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronRightIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationNext.displayName = 'PaginationNext'\n\n// ─── PaginationFirst ─────────────────────────────────────\n\nexport interface PaginationFirstProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationFirst = React.forwardRef<HTMLButtonElement, PaginationFirstProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || ctx.page <= 1\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to first page\"\n disabled={isDisabled}\n onClick={() => ctx.onPageChange(1)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronsLeftIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationFirst.displayName = 'PaginationFirst'\n\n// ─── PaginationLast ──────────────────────────────────────\n\nexport interface PaginationLastProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationLast = React.forwardRef<HTMLButtonElement, PaginationLastProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || ctx.page >= ctx.total\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to last page\"\n disabled={isDisabled}\n onClick={() => ctx.onPageChange(ctx.total)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronsRightIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationLast.displayName = 'PaginationLast'\n\n// ─── PaginationEllipsis ──────────────────────────────────\n\nconst PaginationEllipsis = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<'span'>>(\n ({ className, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n return (\n <span\n ref={ref}\n aria-hidden=\"true\"\n className={cn(\n 'inline-flex items-center justify-center text-text-muted',\n sizeClass.item,\n className\n )}\n {...props}\n >\n <EllipsisIcon className={sizeClass.icon} />\n <span className=\"sr-only\">More pages</span>\n </span>\n )\n }\n)\nPaginationEllipsis.displayName = 'PaginationEllipsis'\n\n// ─── PaginationItems (Convenience) ───────────────────────\n\nconst PaginationItems = React.forwardRef<HTMLDivElement, React.ComponentPropsWithoutRef<'div'>>(\n ({ className, ...props }, ref) => {\n const ctx = usePaginationContext()\n return (\n <div ref={ref} className={cn('contents', className)} {...props}>\n {ctx.paginationRange.map((item, index) => (\n <PaginationItem key={`${item}-${index}`}>\n {item === 'dots' ? (\n <PaginationEllipsis />\n ) : (\n <PaginationLink page={item} />\n )}\n </PaginationItem>\n ))}\n </div>\n )\n }\n)\nPaginationItems.displayName = 'PaginationItems'\n\n// ─── Exports ─────────────────────────────────────────────\n\nexport {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationLink,\n PaginationPrevious,\n PaginationNext,\n PaginationFirst,\n PaginationLast,\n PaginationEllipsis,\n PaginationItems,\n paginationItemVariants,\n paginationSizeMap,\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/ui/pagination.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\n// ─── Built-in Icons ──────────────────────────────────────\n\nfunction ChevronLeftIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n )\n}\n\nfunction ChevronRightIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n )\n}\n\nfunction ChevronsLeftIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11 17l-5-5 5-5M18 17l-5-5 5-5\" />\n </svg>\n )\n}\n\nfunction ChevronsRightIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M13 7l5 5-5 5M6 7l5 5-5 5\" />\n </svg>\n )\n}\n\nfunction EllipsisIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" />\n </svg>\n )\n}\n\n// ─── usePagination Hook ──────────────────────────────────\n\nexport type PaginationRange = (number | 'dots')[]\n\nexport interface UsePaginationProps {\n /** Total number of pages */\n total: number\n /** Number of siblings on each side of current page */\n siblings?: number\n /** Number of boundary pages at start/end */\n boundaries?: number\n /** Current active page (1-based) */\n page: number\n}\n\nfunction range(start: number, end: number): number[] {\n const result: number[] = []\n for (let i = start; i <= end; i++) result.push(i)\n return result\n}\n\nexport function usePagination({\n total,\n siblings = 1,\n boundaries = 1,\n page,\n}: UsePaginationProps): PaginationRange {\n if (total <= 0) return []\n\n const totalPageNumbers = siblings * 2 + 3 + boundaries * 2\n if (totalPageNumbers >= total) {\n return range(1, total)\n }\n\n const leftSiblingIndex = Math.max(page - siblings, boundaries + 1)\n const rightSiblingIndex = Math.min(page + siblings, total - boundaries)\n\n const showLeftDots = leftSiblingIndex > boundaries + 2\n const showRightDots = rightSiblingIndex < total - boundaries - 1\n\n if (!showLeftDots && showRightDots) {\n const leftItemCount = 3 + 2 * siblings + boundaries\n const leftRange = range(1, leftItemCount)\n return [...leftRange, 'dots' as const, ...range(total - boundaries + 1, total)]\n }\n\n if (showLeftDots && !showRightDots) {\n const rightItemCount = 3 + 2 * siblings + boundaries\n const rightRange = range(total - rightItemCount + 1, total)\n return [...range(1, boundaries), 'dots' as const, ...rightRange]\n }\n\n return [\n ...range(1, boundaries),\n 'dots' as const,\n ...range(leftSiblingIndex, rightSiblingIndex),\n 'dots' as const,\n ...range(total - boundaries + 1, total),\n ]\n}\n\n// ─── Context ─────────────────────────────────────────────\n\nexport type PaginationSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl'\nexport type PaginationVariant = 'default' | 'outline' | 'ghost'\nexport type PaginationColor = 'default' | 'primary'\nexport type PaginationRadius = 'sm' | 'base' | 'md' | 'lg' | 'xl' | 'full'\n\ntype PaginationContextValue = {\n page: number\n total: number\n siblings: number\n boundaries: number\n size: PaginationSize\n variant: PaginationVariant\n color: PaginationColor\n radius: PaginationRadius\n disabled: boolean\n loop: boolean\n onPageChange: (page: number) => void\n paginationRange: PaginationRange\n}\n\nconst PaginationContext = React.createContext<PaginationContextValue | null>(null)\n\nfunction usePaginationContext() {\n const ctx = React.useContext(PaginationContext)\n if (!ctx) throw new Error('Pagination components must be used within <Pagination>')\n return ctx\n}\n\n// ─── Size Map ────────────────────────────────────────────\n\nconst paginationSizeMap = {\n xs: { item: 'h-7 min-w-7 text-xs', icon: 'icon-xs', gap: 'gap-1' },\n sm: { item: 'h-8 min-w-8 text-sm', icon: 'icon-xs', gap: 'gap-1' },\n default: { item: 'h-9 min-w-9 text-md', icon: 'icon-sm', gap: 'gap-1' },\n lg: { item: 'h-10 min-w-10 text-md', icon: 'icon-sm', gap: 'gap-1.5' },\n xl: { item: 'h-12 min-w-12 text-base', icon: 'icon-sm', gap: 'gap-1.5' },\n} as const\n\n// ─── Item Variants (CVA) ─────────────────────────────────\n\nconst paginationItemVariants = cva(\n 'inline-flex items-center justify-center select-none transition-colors duration-fast font-semibold focus-visible:focus-ring',\n {\n variants: {\n radius: {\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n full: 'rounded-full',\n },\n },\n defaultVariants: {\n radius: 'md',\n },\n }\n)\n\n// ─── Variant Style Helpers ───────────────────────────────\n\n// Active color maps\nconst activeColorMap = {\n default: 'bg-foreground text-background',\n primary: 'bg-primary text-primary-foreground',\n} as const\n\nconst ghostActiveColorMap = {\n default: 'bg-background-muted text-foreground font-bold',\n primary: 'bg-background-muted text-primary',\n} as const\n\nfunction getItemClasses(variant: PaginationVariant, color: PaginationColor, isActive: boolean, disabled: boolean) {\n if (disabled) {\n return variant === 'outline'\n ? 'border border-border text-disabled-foreground pointer-events-none opacity-50'\n : 'border border-transparent text-disabled-foreground pointer-events-none opacity-50'\n }\n if (isActive) {\n switch (variant) {\n case 'outline':\n return `border ${color === 'default' ? 'border-foreground' : 'border-primary'} ${activeColorMap[color]}`\n case 'ghost':\n return `border border-transparent ${ghostActiveColorMap[color]}`\n case 'default':\n default:\n return `border border-transparent ${activeColorMap[color]}`\n }\n }\n switch (variant) {\n case 'outline':\n return 'border border-border text-text-muted hover:bg-background-muted hover:text-foreground'\n case 'ghost':\n return 'border border-transparent text-text-muted hover:bg-background-muted hover:text-foreground'\n case 'default':\n default:\n return 'border border-transparent text-text-muted hover:bg-background-muted hover:text-foreground'\n }\n}\n\n// ─── Pagination (Root) ───────────────────────────────────\n\nexport interface PaginationProps extends Omit<React.ComponentPropsWithoutRef<'nav'>, 'onChange'> {\n /** Total number of pages */\n total?: number\n /** Controlled active page (1-based) */\n value?: number\n /** Initial page for uncontrolled mode */\n defaultValue?: number\n /** Page change callback */\n onChange?: (page: number) => void\n /** Number of siblings on each side of current page */\n siblings?: number\n /** Number of boundary pages at start/end */\n boundaries?: number\n /** Component size */\n size?: PaginationSize\n /** Visual variant */\n variant?: PaginationVariant\n /** Active page color */\n color?: PaginationColor\n /** Border radius */\n radius?: PaginationRadius\n /** Disable all interactions */\n disabled?: boolean\n /** Show previous/next controls */\n withControls?: boolean\n /** Show first/last controls */\n withEdges?: boolean\n /** Loop from last to first and vice versa */\n loop?: boolean\n}\n\nconst Pagination = React.forwardRef<HTMLElement, PaginationProps>(\n ({\n className,\n total = 1,\n value,\n defaultValue = 1,\n onChange,\n siblings = 1,\n boundaries = 1,\n size = 'default',\n variant = 'default',\n color = 'default',\n radius = 'md',\n disabled = false,\n withControls = true,\n withEdges = false,\n loop = false,\n children,\n ...props\n }, ref) => {\n // Controlled / Uncontrolled\n const [internalPage, setInternalPage] = React.useState(defaultValue)\n const isControlled = value !== undefined\n const page = isControlled ? value : internalPage\n\n const handlePageChange = React.useCallback((newPage: number) => {\n if (disabled) return\n const clamped = Math.max(1, Math.min(total, newPage))\n if (!isControlled) setInternalPage(clamped)\n onChange?.(clamped)\n }, [disabled, total, isControlled, onChange])\n\n const paginationRange = usePagination({ total, siblings, boundaries, page })\n\n const contextValue = React.useMemo<PaginationContextValue>(() => ({\n page,\n total,\n siblings,\n boundaries,\n size,\n variant,\n color,\n radius,\n disabled,\n loop,\n onPageChange: handlePageChange,\n paginationRange,\n }), [page, total, siblings, boundaries, size, variant, color, radius, disabled, loop, handlePageChange, paginationRange])\n\n return (\n <PaginationContext.Provider value={contextValue}>\n <nav\n ref={ref}\n role=\"navigation\"\n aria-label=\"pagination\"\n className={cn('', className)}\n {...props}\n >\n {children ?? (\n <PaginationContent>\n {withEdges && <PaginationItem><PaginationFirst /></PaginationItem>}\n {withControls && <PaginationItem><PaginationPrevious /></PaginationItem>}\n <PaginationItems />\n {withControls && <PaginationItem><PaginationNext /></PaginationItem>}\n {withEdges && <PaginationItem><PaginationLast /></PaginationItem>}\n </PaginationContent>\n )}\n </nav>\n </PaginationContext.Provider>\n )\n }\n)\nPagination.displayName = 'Pagination'\n\n// ─── PaginationContent ───────────────────────────────────\n\nconst PaginationContent = React.forwardRef<HTMLUListElement, React.ComponentPropsWithoutRef<'ul'>>(\n ({ className, ...props }, ref) => {\n const { size } = usePaginationContext()\n const sizeClass = paginationSizeMap[size]\n return (\n <ul\n ref={ref}\n className={cn('flex flex-wrap items-center', sizeClass.gap, className)}\n {...props}\n />\n )\n }\n)\nPaginationContent.displayName = 'PaginationContent'\n\n// ─── PaginationItem ──────────────────────────────────────\n\nconst PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentPropsWithoutRef<'li'>>(\n ({ className, ...props }, ref) => (\n <li ref={ref} className={cn('', className)} {...props} />\n )\n)\nPaginationItem.displayName = 'PaginationItem'\n\n// ─── PaginationLink ──────────────────────────────────────\n\nexport interface PaginationLinkProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Page number this link navigates to */\n page: number\n /** Whether this page is currently active (auto-detected from context if omitted) */\n isActive?: boolean\n}\n\nconst PaginationLink = React.forwardRef<HTMLButtonElement, PaginationLinkProps>(\n ({ className, page: targetPage, isActive: isActiveProp, ...props }, ref) => {\n const ctx = usePaginationContext()\n const isActive = isActiveProp ?? (ctx.page === targetPage)\n const sizeClass = paginationSizeMap[ctx.size]\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-current={isActive ? 'page' : undefined}\n aria-label={`Go to page ${targetPage}`}\n disabled={ctx.disabled}\n onClick={() => ctx.onPageChange(targetPage)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, isActive, ctx.disabled),\n className\n )}\n {...props}\n >\n {targetPage}\n </button>\n )\n }\n)\nPaginationLink.displayName = 'PaginationLink'\n\n// ─── PaginationPrevious ──────────────────────────────────\n\nexport interface PaginationPreviousProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationPrevious = React.forwardRef<HTMLButtonElement, PaginationPreviousProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || (!ctx.loop && ctx.page <= 1)\n\n const handleClick = () => {\n if (ctx.page <= 1) {\n if (ctx.loop) ctx.onPageChange(ctx.total)\n } else {\n ctx.onPageChange(ctx.page - 1)\n }\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to previous page\"\n disabled={isDisabled}\n onClick={handleClick}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronLeftIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationPrevious.displayName = 'PaginationPrevious'\n\n// ─── PaginationNext ──────────────────────────────────────\n\nexport interface PaginationNextProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationNext = React.forwardRef<HTMLButtonElement, PaginationNextProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || (!ctx.loop && ctx.page >= ctx.total)\n\n const handleClick = () => {\n if (ctx.page >= ctx.total) {\n if (ctx.loop) ctx.onPageChange(1)\n } else {\n ctx.onPageChange(ctx.page + 1)\n }\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to next page\"\n disabled={isDisabled}\n onClick={handleClick}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronRightIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationNext.displayName = 'PaginationNext'\n\n// ─── PaginationFirst ─────────────────────────────────────\n\nexport interface PaginationFirstProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationFirst = React.forwardRef<HTMLButtonElement, PaginationFirstProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || ctx.page <= 1\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to first page\"\n disabled={isDisabled}\n onClick={() => ctx.onPageChange(1)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronsLeftIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationFirst.displayName = 'PaginationFirst'\n\n// ─── PaginationLast ──────────────────────────────────────\n\nexport interface PaginationLastProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationLast = React.forwardRef<HTMLButtonElement, PaginationLastProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || ctx.page >= ctx.total\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to last page\"\n disabled={isDisabled}\n onClick={() => ctx.onPageChange(ctx.total)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronsRightIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationLast.displayName = 'PaginationLast'\n\n// ─── PaginationEllipsis ──────────────────────────────────\n\nconst PaginationEllipsis = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<'span'>>(\n ({ className, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n return (\n <span\n ref={ref}\n aria-hidden=\"true\"\n className={cn(\n 'inline-flex items-center justify-center text-text-muted',\n sizeClass.item,\n className\n )}\n {...props}\n >\n <EllipsisIcon className={sizeClass.icon} />\n <span className=\"sr-only\">More pages</span>\n </span>\n )\n }\n)\nPaginationEllipsis.displayName = 'PaginationEllipsis'\n\n// ─── PaginationItems (Convenience) ───────────────────────\n\n// Renders the <li> items straight into PaginationContent's <ul>: a wrapper element\n// between them breaks the list structure for assistive technology (a `display:\n// contents` div used to sit here). The div props and ref stay in the signature for\n// compatibility but have no element to attach to.\nconst PaginationItems = React.forwardRef<HTMLDivElement, React.ComponentPropsWithoutRef<'div'>>(\n (_props, _ref) => {\n const ctx = usePaginationContext()\n return (\n <>\n {ctx.paginationRange.map((item, index) => (\n <PaginationItem key={`${item}-${index}`}>\n {item === 'dots' ? (\n <PaginationEllipsis />\n ) : (\n <PaginationLink page={item} />\n )}\n </PaginationItem>\n ))}\n </>\n )\n }\n)\nPaginationItems.displayName = 'PaginationItems'\n\n// ─── Exports ─────────────────────────────────────────────\n\nexport {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationLink,\n PaginationPrevious,\n PaginationNext,\n PaginationFirst,\n PaginationLast,\n PaginationEllipsis,\n PaginationItems,\n paginationItemVariants,\n paginationSizeMap,\n}\n"],"mappings":"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","names":[]}
@@ -66,6 +66,8 @@ const radioGroupVariants = (0, import_class_variance_authority.cva)("grid gap-3"
66
66
  const RadioGroup = React.forwardRef(({ className, orientation, size = "default", weight = "bold", color = "default", disabled, ...props }, ref) => {
67
67
  const fieldContext = (0, import_field.useFieldContext)();
68
68
  const resolvedDisabled = disabled ?? fieldContext?.disabled;
69
+ (0, import_field.useFieldControl)("labelled", Boolean(fieldContext));
70
+ const labelledBy = fieldContext?.hasLabel && !props["aria-label"] ? fieldContext.labelId : void 0;
69
71
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioGroupContext.Provider, { value: { size, weight, color, disabled: resolvedDisabled }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
70
72
  RadioGroupPrimitive.Root,
71
73
  {
@@ -73,6 +75,7 @@ const RadioGroup = React.forwardRef(({ className, orientation, size = "default",
73
75
  className: (0, import_utils.cn)(radioGroupVariants({ orientation }), className),
74
76
  orientation: orientation || void 0,
75
77
  disabled: resolvedDisabled,
78
+ "aria-labelledby": labelledBy,
76
79
  ...props
77
80
  }
78
81
  ) });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/radio-group.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\nimport { useFieldContext } from './field'\n\n// Color maps for checked state\nconst radioColorMap = {\n default: {\n border: 'data-[state=checked]:border-foreground',\n dot: 'bg-foreground',\n },\n primary: {\n border: 'data-[state=checked]:border-primary',\n dot: 'bg-primary',\n },\n} as const\n\nexport type RadioColor = keyof typeof radioColorMap\n\n// Context to pass size, weight, color from RadioGroup to RadioGroupItem\ntype RadioGroupContextValue = {\n size: 'sm' | 'default' | 'lg'\n weight: 'thin' | 'bold'\n color: RadioColor\n disabled?: boolean\n}\nconst RadioGroupContext = React.createContext<RadioGroupContextValue>({ size: 'default', weight: 'bold', color: 'default' })\n\n// RadioGroup container\nconst radioGroupVariants = cva('grid gap-3', {\n variants: {\n orientation: {\n vertical: 'grid-cols-1',\n horizontal: 'grid-flow-col auto-cols-max gap-4',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n})\n\nexport interface RadioGroupProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> {\n size?: 'sm' | 'default' | 'lg'\n weight?: 'thin' | 'bold'\n /** Checked state color */\n color?: RadioColor\n}\n\nconst RadioGroup = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n RadioGroupProps\n>(({ className, orientation, size = 'default', weight = 'bold', color = 'default', disabled, ...props }, ref) => {\n const fieldContext = useFieldContext()\n const resolvedDisabled = disabled ?? fieldContext?.disabled\n\n return (\n <RadioGroupContext.Provider value={{ size, weight, color, disabled: resolvedDisabled }}>\n <RadioGroupPrimitive.Root\n ref={ref}\n className={cn(radioGroupVariants({ orientation }), className)}\n orientation={orientation || undefined}\n disabled={resolvedDisabled}\n {...props}\n />\n </RadioGroupContext.Provider>\n )\n})\nRadioGroup.displayName = 'RadioGroup'\n\n// RadioGroupItem circle variants\nconst radioItemVariants = cva(\n [\n 'relative shrink-0 rounded-full border-border-form hover:border-border-form-strong transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n // Transparent hit area expansion via ::after\n \"after:absolute after:content-['']\",\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'w-3.5 h-3.5 after:-inset-[5px]', // 14px circle → 24px click\n default: 'w-4 h-4 after:-inset-2', // 16px circle → 32px click\n lg: 'w-5 h-5 after:-inset-2', // 20px circle → 36px click\n },\n weight: {\n thin: 'border', // 1px\n bold: 'border-2', // 2px\n },\n },\n defaultVariants: {\n size: 'default',\n weight: 'bold',\n },\n }\n)\n\n// Dot sizes per radio size\nconst dotSizes = {\n sm: 'w-1.5 h-1.5', // 6px\n default: 'w-2 h-2', // 8px\n lg: 'w-2.5 h-2.5', // 10px\n}\n\n// Label font sizes\nconst labelSizes = {\n sm: 'text-xs', // 12px\n default: 'text-md', // 14px\n lg: 'text-base', // 16px\n}\n\n// Gap between radio and label\nconst gapSizes = {\n sm: 'gap-1.5',\n default: 'gap-2',\n lg: 'gap-2.5',\n}\n\nexport interface RadioGroupItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> {\n label?: string\n}\n\nconst RadioGroupItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n RadioGroupItemProps\n>(({ className, label, disabled, ...props }, ref) => {\n const { size, weight, color, disabled: groupDisabled } = React.useContext(RadioGroupContext)\n const resolvedDisabled = disabled ?? groupDisabled\n const itemId = React.useId()\n\n const radio = (\n <RadioGroupPrimitive.Item\n ref={ref}\n id={label ? itemId : undefined}\n disabled={resolvedDisabled}\n className={cn(\n radioItemVariants({ size, weight }),\n radioColorMap[color].border,\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center animate-radio-enter\">\n <div className={cn('rounded-full', radioColorMap[color].dot, dotSizes[size])} />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n )\n\n if (!label) return radio\n\n return (\n <div className={cn('group flex items-center', gapSizes[size])}>\n <div className=\"flex items-center\">\n {radio}\n </div>\n <label\n htmlFor={itemId}\n className={cn(\n labelSizes[size],\n 'text-text-muted cursor-pointer select-none transition-colors duration-micro',\n 'group-hover:text-foreground',\n resolvedDisabled && 'opacity-50 cursor-not-allowed'\n )}\n >\n {label}\n </label>\n </div>\n )\n})\nRadioGroupItem.displayName = 'RadioGroupItem'\n\nexport { RadioGroup, RadioGroupItem, radioGroupVariants, radioItemVariants }\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/ui/radio-group.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\nimport { useFieldContext, useFieldControl } from './field'\n\n// Color maps for checked state\nconst radioColorMap = {\n default: {\n border: 'data-[state=checked]:border-foreground',\n dot: 'bg-foreground',\n },\n primary: {\n border: 'data-[state=checked]:border-primary',\n dot: 'bg-primary',\n },\n} as const\n\nexport type RadioColor = keyof typeof radioColorMap\n\n// Context to pass size, weight, color from RadioGroup to RadioGroupItem\ntype RadioGroupContextValue = {\n size: 'sm' | 'default' | 'lg'\n weight: 'thin' | 'bold'\n color: RadioColor\n disabled?: boolean\n}\nconst RadioGroupContext = React.createContext<RadioGroupContextValue>({ size: 'default', weight: 'bold', color: 'default' })\n\n// RadioGroup container\nconst radioGroupVariants = cva('grid gap-3', {\n variants: {\n orientation: {\n vertical: 'grid-cols-1',\n horizontal: 'grid-flow-col auto-cols-max gap-4',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n})\n\nexport interface RadioGroupProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> {\n size?: 'sm' | 'default' | 'lg'\n weight?: 'thin' | 'bold'\n /** Checked state color */\n color?: RadioColor\n}\n\nconst RadioGroup = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n RadioGroupProps\n>(({ className, orientation, size = 'default', weight = 'bold', color = 'default', disabled, ...props }, ref) => {\n const fieldContext = useFieldContext()\n const resolvedDisabled = disabled ?? fieldContext?.disabled\n // Inside a Field the FieldLabel names the radio group (items keep their own labels)\n useFieldControl('labelled', Boolean(fieldContext))\n const labelledBy = fieldContext?.hasLabel && !props['aria-label'] ? fieldContext.labelId : undefined\n\n return (\n <RadioGroupContext.Provider value={{ size, weight, color, disabled: resolvedDisabled }}>\n <RadioGroupPrimitive.Root\n ref={ref}\n className={cn(radioGroupVariants({ orientation }), className)}\n orientation={orientation || undefined}\n disabled={resolvedDisabled}\n aria-labelledby={labelledBy}\n {...props}\n />\n </RadioGroupContext.Provider>\n )\n})\nRadioGroup.displayName = 'RadioGroup'\n\n// RadioGroupItem circle variants\nconst radioItemVariants = cva(\n [\n 'relative shrink-0 rounded-full border-border-form hover:border-border-form-strong transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n // Transparent hit area expansion via ::after\n \"after:absolute after:content-['']\",\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'w-3.5 h-3.5 after:-inset-[5px]', // 14px circle → 24px click\n default: 'w-4 h-4 after:-inset-2', // 16px circle → 32px click\n lg: 'w-5 h-5 after:-inset-2', // 20px circle → 36px click\n },\n weight: {\n thin: 'border', // 1px\n bold: 'border-2', // 2px\n },\n },\n defaultVariants: {\n size: 'default',\n weight: 'bold',\n },\n }\n)\n\n// Dot sizes per radio size\nconst dotSizes = {\n sm: 'w-1.5 h-1.5', // 6px\n default: 'w-2 h-2', // 8px\n lg: 'w-2.5 h-2.5', // 10px\n}\n\n// Label font sizes\nconst labelSizes = {\n sm: 'text-xs', // 12px\n default: 'text-md', // 14px\n lg: 'text-base', // 16px\n}\n\n// Gap between radio and label\nconst gapSizes = {\n sm: 'gap-1.5',\n default: 'gap-2',\n lg: 'gap-2.5',\n}\n\nexport interface RadioGroupItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> {\n label?: string\n}\n\nconst RadioGroupItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n RadioGroupItemProps\n>(({ className, label, disabled, ...props }, ref) => {\n const { size, weight, color, disabled: groupDisabled } = React.useContext(RadioGroupContext)\n const resolvedDisabled = disabled ?? groupDisabled\n const itemId = React.useId()\n\n const radio = (\n <RadioGroupPrimitive.Item\n ref={ref}\n id={label ? itemId : undefined}\n disabled={resolvedDisabled}\n className={cn(\n radioItemVariants({ size, weight }),\n radioColorMap[color].border,\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center animate-radio-enter\">\n <div className={cn('rounded-full', radioColorMap[color].dot, dotSizes[size])} />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n )\n\n if (!label) return radio\n\n return (\n <div className={cn('group flex items-center', gapSizes[size])}>\n <div className=\"flex items-center\">\n {radio}\n </div>\n <label\n htmlFor={itemId}\n className={cn(\n labelSizes[size],\n 'text-text-muted cursor-pointer select-none transition-colors duration-micro',\n 'group-hover:text-foreground',\n resolvedDisabled && 'opacity-50 cursor-not-allowed'\n )}\n >\n {label}\n </label>\n </div>\n )\n})\nRadioGroupItem.displayName = 'RadioGroupItem'\n\nexport { RadioGroup, RadioGroupItem, radioGroupVariants, radioItemVariants }\n"],"mappings":"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","names":[]}
@@ -4,7 +4,7 @@ import * as React from "react";
4
4
  import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
5
5
  import { cva } from "class-variance-authority";
6
6
  import { cn } from "../../lib/utils.mjs";
7
- import { useFieldContext } from "./field.mjs";
7
+ import { useFieldContext, useFieldControl } from "./field.mjs";
8
8
  const radioColorMap = {
9
9
  default: {
10
10
  border: "data-[state=checked]:border-foreground",
@@ -30,6 +30,8 @@ const radioGroupVariants = cva("grid gap-3", {
30
30
  const RadioGroup = React.forwardRef(({ className, orientation, size = "default", weight = "bold", color = "default", disabled, ...props }, ref) => {
31
31
  const fieldContext = useFieldContext();
32
32
  const resolvedDisabled = disabled ?? fieldContext?.disabled;
33
+ useFieldControl("labelled", Boolean(fieldContext));
34
+ const labelledBy = fieldContext?.hasLabel && !props["aria-label"] ? fieldContext.labelId : void 0;
33
35
  return /* @__PURE__ */ jsx(RadioGroupContext.Provider, { value: { size, weight, color, disabled: resolvedDisabled }, children: /* @__PURE__ */ jsx(
34
36
  RadioGroupPrimitive.Root,
35
37
  {
@@ -37,6 +39,7 @@ const RadioGroup = React.forwardRef(({ className, orientation, size = "default",
37
39
  className: cn(radioGroupVariants({ orientation }), className),
38
40
  orientation: orientation || void 0,
39
41
  disabled: resolvedDisabled,
42
+ "aria-labelledby": labelledBy,
40
43
  ...props
41
44
  }
42
45
  ) });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/radio-group.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\nimport { useFieldContext } from './field'\n\n// Color maps for checked state\nconst radioColorMap = {\n default: {\n border: 'data-[state=checked]:border-foreground',\n dot: 'bg-foreground',\n },\n primary: {\n border: 'data-[state=checked]:border-primary',\n dot: 'bg-primary',\n },\n} as const\n\nexport type RadioColor = keyof typeof radioColorMap\n\n// Context to pass size, weight, color from RadioGroup to RadioGroupItem\ntype RadioGroupContextValue = {\n size: 'sm' | 'default' | 'lg'\n weight: 'thin' | 'bold'\n color: RadioColor\n disabled?: boolean\n}\nconst RadioGroupContext = React.createContext<RadioGroupContextValue>({ size: 'default', weight: 'bold', color: 'default' })\n\n// RadioGroup container\nconst radioGroupVariants = cva('grid gap-3', {\n variants: {\n orientation: {\n vertical: 'grid-cols-1',\n horizontal: 'grid-flow-col auto-cols-max gap-4',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n})\n\nexport interface RadioGroupProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> {\n size?: 'sm' | 'default' | 'lg'\n weight?: 'thin' | 'bold'\n /** Checked state color */\n color?: RadioColor\n}\n\nconst RadioGroup = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n RadioGroupProps\n>(({ className, orientation, size = 'default', weight = 'bold', color = 'default', disabled, ...props }, ref) => {\n const fieldContext = useFieldContext()\n const resolvedDisabled = disabled ?? fieldContext?.disabled\n\n return (\n <RadioGroupContext.Provider value={{ size, weight, color, disabled: resolvedDisabled }}>\n <RadioGroupPrimitive.Root\n ref={ref}\n className={cn(radioGroupVariants({ orientation }), className)}\n orientation={orientation || undefined}\n disabled={resolvedDisabled}\n {...props}\n />\n </RadioGroupContext.Provider>\n )\n})\nRadioGroup.displayName = 'RadioGroup'\n\n// RadioGroupItem circle variants\nconst radioItemVariants = cva(\n [\n 'relative shrink-0 rounded-full border-border-form hover:border-border-form-strong transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n // Transparent hit area expansion via ::after\n \"after:absolute after:content-['']\",\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'w-3.5 h-3.5 after:-inset-[5px]', // 14px circle → 24px click\n default: 'w-4 h-4 after:-inset-2', // 16px circle → 32px click\n lg: 'w-5 h-5 after:-inset-2', // 20px circle → 36px click\n },\n weight: {\n thin: 'border', // 1px\n bold: 'border-2', // 2px\n },\n },\n defaultVariants: {\n size: 'default',\n weight: 'bold',\n },\n }\n)\n\n// Dot sizes per radio size\nconst dotSizes = {\n sm: 'w-1.5 h-1.5', // 6px\n default: 'w-2 h-2', // 8px\n lg: 'w-2.5 h-2.5', // 10px\n}\n\n// Label font sizes\nconst labelSizes = {\n sm: 'text-xs', // 12px\n default: 'text-md', // 14px\n lg: 'text-base', // 16px\n}\n\n// Gap between radio and label\nconst gapSizes = {\n sm: 'gap-1.5',\n default: 'gap-2',\n lg: 'gap-2.5',\n}\n\nexport interface RadioGroupItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> {\n label?: string\n}\n\nconst RadioGroupItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n RadioGroupItemProps\n>(({ className, label, disabled, ...props }, ref) => {\n const { size, weight, color, disabled: groupDisabled } = React.useContext(RadioGroupContext)\n const resolvedDisabled = disabled ?? groupDisabled\n const itemId = React.useId()\n\n const radio = (\n <RadioGroupPrimitive.Item\n ref={ref}\n id={label ? itemId : undefined}\n disabled={resolvedDisabled}\n className={cn(\n radioItemVariants({ size, weight }),\n radioColorMap[color].border,\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center animate-radio-enter\">\n <div className={cn('rounded-full', radioColorMap[color].dot, dotSizes[size])} />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n )\n\n if (!label) return radio\n\n return (\n <div className={cn('group flex items-center', gapSizes[size])}>\n <div className=\"flex items-center\">\n {radio}\n </div>\n <label\n htmlFor={itemId}\n className={cn(\n labelSizes[size],\n 'text-text-muted cursor-pointer select-none transition-colors duration-micro',\n 'group-hover:text-foreground',\n resolvedDisabled && 'opacity-50 cursor-not-allowed'\n )}\n >\n {label}\n </label>\n </div>\n )\n})\nRadioGroupItem.displayName = 'RadioGroupItem'\n\nexport { RadioGroup, RadioGroupItem, radioGroupVariants, radioItemVariants }\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/ui/radio-group.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\nimport { useFieldContext, useFieldControl } from './field'\n\n// Color maps for checked state\nconst radioColorMap = {\n default: {\n border: 'data-[state=checked]:border-foreground',\n dot: 'bg-foreground',\n },\n primary: {\n border: 'data-[state=checked]:border-primary',\n dot: 'bg-primary',\n },\n} as const\n\nexport type RadioColor = keyof typeof radioColorMap\n\n// Context to pass size, weight, color from RadioGroup to RadioGroupItem\ntype RadioGroupContextValue = {\n size: 'sm' | 'default' | 'lg'\n weight: 'thin' | 'bold'\n color: RadioColor\n disabled?: boolean\n}\nconst RadioGroupContext = React.createContext<RadioGroupContextValue>({ size: 'default', weight: 'bold', color: 'default' })\n\n// RadioGroup container\nconst radioGroupVariants = cva('grid gap-3', {\n variants: {\n orientation: {\n vertical: 'grid-cols-1',\n horizontal: 'grid-flow-col auto-cols-max gap-4',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n})\n\nexport interface RadioGroupProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> {\n size?: 'sm' | 'default' | 'lg'\n weight?: 'thin' | 'bold'\n /** Checked state color */\n color?: RadioColor\n}\n\nconst RadioGroup = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n RadioGroupProps\n>(({ className, orientation, size = 'default', weight = 'bold', color = 'default', disabled, ...props }, ref) => {\n const fieldContext = useFieldContext()\n const resolvedDisabled = disabled ?? fieldContext?.disabled\n // Inside a Field the FieldLabel names the radio group (items keep their own labels)\n useFieldControl('labelled', Boolean(fieldContext))\n const labelledBy = fieldContext?.hasLabel && !props['aria-label'] ? fieldContext.labelId : undefined\n\n return (\n <RadioGroupContext.Provider value={{ size, weight, color, disabled: resolvedDisabled }}>\n <RadioGroupPrimitive.Root\n ref={ref}\n className={cn(radioGroupVariants({ orientation }), className)}\n orientation={orientation || undefined}\n disabled={resolvedDisabled}\n aria-labelledby={labelledBy}\n {...props}\n />\n </RadioGroupContext.Provider>\n )\n})\nRadioGroup.displayName = 'RadioGroup'\n\n// RadioGroupItem circle variants\nconst radioItemVariants = cva(\n [\n 'relative shrink-0 rounded-full border-border-form hover:border-border-form-strong transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n // Transparent hit area expansion via ::after\n \"after:absolute after:content-['']\",\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'w-3.5 h-3.5 after:-inset-[5px]', // 14px circle → 24px click\n default: 'w-4 h-4 after:-inset-2', // 16px circle → 32px click\n lg: 'w-5 h-5 after:-inset-2', // 20px circle → 36px click\n },\n weight: {\n thin: 'border', // 1px\n bold: 'border-2', // 2px\n },\n },\n defaultVariants: {\n size: 'default',\n weight: 'bold',\n },\n }\n)\n\n// Dot sizes per radio size\nconst dotSizes = {\n sm: 'w-1.5 h-1.5', // 6px\n default: 'w-2 h-2', // 8px\n lg: 'w-2.5 h-2.5', // 10px\n}\n\n// Label font sizes\nconst labelSizes = {\n sm: 'text-xs', // 12px\n default: 'text-md', // 14px\n lg: 'text-base', // 16px\n}\n\n// Gap between radio and label\nconst gapSizes = {\n sm: 'gap-1.5',\n default: 'gap-2',\n lg: 'gap-2.5',\n}\n\nexport interface RadioGroupItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> {\n label?: string\n}\n\nconst RadioGroupItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n RadioGroupItemProps\n>(({ className, label, disabled, ...props }, ref) => {\n const { size, weight, color, disabled: groupDisabled } = React.useContext(RadioGroupContext)\n const resolvedDisabled = disabled ?? groupDisabled\n const itemId = React.useId()\n\n const radio = (\n <RadioGroupPrimitive.Item\n ref={ref}\n id={label ? itemId : undefined}\n disabled={resolvedDisabled}\n className={cn(\n radioItemVariants({ size, weight }),\n radioColorMap[color].border,\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center animate-radio-enter\">\n <div className={cn('rounded-full', radioColorMap[color].dot, dotSizes[size])} />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n )\n\n if (!label) return radio\n\n return (\n <div className={cn('group flex items-center', gapSizes[size])}>\n <div className=\"flex items-center\">\n {radio}\n </div>\n <label\n htmlFor={itemId}\n className={cn(\n labelSizes[size],\n 'text-text-muted cursor-pointer select-none transition-colors duration-micro',\n 'group-hover:text-foreground',\n resolvedDisabled && 'opacity-50 cursor-not-allowed'\n )}\n >\n {label}\n </label>\n </div>\n )\n})\nRadioGroupItem.displayName = 'RadioGroupItem'\n\nexport { RadioGroup, RadioGroupItem, radioGroupVariants, radioItemVariants }\n"],"mappings":"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","names":[]}
@@ -3,7 +3,7 @@ import * as SelectPrimitive from '@radix-ui/react-select';
3
3
 
4
4
  type SelectRadius = 'none' | 'sm' | 'base' | 'default' | 'lg' | 'xl' | '2xl' | '3xl' | 'full';
5
5
  type SelectSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl';
6
- declare const Select: ({ size, radius, ...props }: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Root> & {
6
+ declare const Select: ({ size, radius, disabled, ...props }: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Root> & {
7
7
  size?: SelectSize;
8
8
  radius?: SelectRadius;
9
9
  }) => React.JSX.Element;
@@ -3,7 +3,7 @@ import * as SelectPrimitive from '@radix-ui/react-select';
3
3
 
4
4
  type SelectRadius = 'none' | 'sm' | 'base' | 'default' | 'lg' | 'xl' | '2xl' | '3xl' | 'full';
5
5
  type SelectSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl';
6
- declare const Select: ({ size, radius, ...props }: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Root> & {
6
+ declare const Select: ({ size, radius, disabled, ...props }: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Root> & {
7
7
  size?: SelectSize;
8
8
  radius?: SelectRadius;
9
9
  }) => React.JSX.Element;
@@ -43,6 +43,7 @@ var import_jsx_runtime = require("react/jsx-runtime");
43
43
  var React = __toESM(require("react"));
44
44
  var SelectPrimitive = __toESM(require("@radix-ui/react-select"));
45
45
  var import_utils = require("../../lib/utils");
46
+ var import_field = require("./field");
46
47
  const triggerRadiusMap = {
47
48
  none: "rounded-none",
48
49
  sm: "rounded-sm",
@@ -147,16 +148,23 @@ const SelectStyleContext = React.createContext({ contentRadius: "xl", itemSize:
147
148
  const Select = ({
148
149
  size = "default",
149
150
  radius = "default",
151
+ disabled,
150
152
  ...props
151
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContext.Provider, { value: { size, radius }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectPrimitive.Root, { ...props }) });
153
+ }) => {
154
+ const fieldContext = (0, import_field.useFieldContext)();
155
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContext.Provider, { value: { size, radius }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectPrimitive.Root, { disabled: disabled ?? fieldContext?.disabled, ...props }) });
156
+ };
152
157
  const SelectValue = SelectPrimitive.Value;
153
158
  const SelectGroup = SelectPrimitive.Group;
154
- const SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => {
159
+ const SelectTrigger = React.forwardRef(({ className, children, id, ...props }, ref) => {
155
160
  const { size, radius } = React.useContext(SelectContext);
161
+ const fieldContext = (0, import_field.useFieldContext)();
162
+ (0, import_field.useFieldControl)("single", Boolean(fieldContext) && !id);
156
163
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
157
164
  SelectPrimitive.Trigger,
158
165
  {
159
166
  ref,
167
+ id: id ?? fieldContext?.id,
160
168
  className: (0, import_utils.cn)(
161
169
  "flex w-full items-center justify-between bg-background text-foreground hover:bg-background-muted",
162
170
  "border border-border-form",