@karakuri-ui/react 0.3.2 → 0.3.4

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 (148) hide show
  1. package/README.md +27 -4
  2. package/dist/components/ui/accordion.js +27 -24
  3. package/dist/components/ui/accordion.js.map +1 -1
  4. package/dist/components/ui/accordion.mjs +27 -24
  5. package/dist/components/ui/accordion.mjs.map +1 -1
  6. package/dist/components/ui/alert.js +45 -27
  7. package/dist/components/ui/alert.js.map +1 -1
  8. package/dist/components/ui/alert.mjs +45 -27
  9. package/dist/components/ui/alert.mjs.map +1 -1
  10. package/dist/components/ui/avatar.js +41 -32
  11. package/dist/components/ui/avatar.js.map +1 -1
  12. package/dist/components/ui/avatar.mjs +41 -32
  13. package/dist/components/ui/avatar.mjs.map +1 -1
  14. package/dist/components/ui/badge.js +46 -43
  15. package/dist/components/ui/badge.js.map +1 -1
  16. package/dist/components/ui/badge.mjs +46 -43
  17. package/dist/components/ui/badge.mjs.map +1 -1
  18. package/dist/components/ui/breadcrumb.js +30 -25
  19. package/dist/components/ui/breadcrumb.js.map +1 -1
  20. package/dist/components/ui/breadcrumb.mjs +30 -25
  21. package/dist/components/ui/breadcrumb.mjs.map +1 -1
  22. package/dist/components/ui/button-group.js +6 -5
  23. package/dist/components/ui/button-group.js.map +1 -1
  24. package/dist/components/ui/button-group.mjs +6 -5
  25. package/dist/components/ui/button-group.mjs.map +1 -1
  26. package/dist/components/ui/button.js +24 -14
  27. package/dist/components/ui/button.js.map +1 -1
  28. package/dist/components/ui/button.mjs +24 -14
  29. package/dist/components/ui/button.mjs.map +1 -1
  30. package/dist/components/ui/card.js +53 -39
  31. package/dist/components/ui/card.js.map +1 -1
  32. package/dist/components/ui/card.mjs +53 -39
  33. package/dist/components/ui/card.mjs.map +1 -1
  34. package/dist/components/ui/chart.d.mts +1 -1
  35. package/dist/components/ui/chart.d.ts +1 -1
  36. package/dist/components/ui/chart.js +154 -130
  37. package/dist/components/ui/chart.js.map +1 -1
  38. package/dist/components/ui/chart.mjs +154 -130
  39. package/dist/components/ui/chart.mjs.map +1 -1
  40. package/dist/components/ui/checkbox.js +47 -40
  41. package/dist/components/ui/checkbox.js.map +1 -1
  42. package/dist/components/ui/checkbox.mjs +47 -40
  43. package/dist/components/ui/checkbox.mjs.map +1 -1
  44. package/dist/components/ui/divider.js +16 -13
  45. package/dist/components/ui/divider.js.map +1 -1
  46. package/dist/components/ui/divider.mjs +16 -13
  47. package/dist/components/ui/divider.mjs.map +1 -1
  48. package/dist/components/ui/drawer.js +44 -35
  49. package/dist/components/ui/drawer.js.map +1 -1
  50. package/dist/components/ui/drawer.mjs +44 -35
  51. package/dist/components/ui/drawer.mjs.map +1 -1
  52. package/dist/components/ui/dropdown.js +31 -24
  53. package/dist/components/ui/dropdown.js.map +1 -1
  54. package/dist/components/ui/dropdown.mjs +31 -24
  55. package/dist/components/ui/dropdown.mjs.map +1 -1
  56. package/dist/components/ui/field.js +18 -15
  57. package/dist/components/ui/field.js.map +1 -1
  58. package/dist/components/ui/field.mjs +18 -15
  59. package/dist/components/ui/field.mjs.map +1 -1
  60. package/dist/components/ui/icon-button.js +17 -14
  61. package/dist/components/ui/icon-button.js.map +1 -1
  62. package/dist/components/ui/icon-button.mjs +17 -14
  63. package/dist/components/ui/icon-button.mjs.map +1 -1
  64. package/dist/components/ui/input.js +34 -29
  65. package/dist/components/ui/input.js.map +1 -1
  66. package/dist/components/ui/input.mjs +34 -29
  67. package/dist/components/ui/input.mjs.map +1 -1
  68. package/dist/components/ui/metric-card.js +24 -21
  69. package/dist/components/ui/metric-card.js.map +1 -1
  70. package/dist/components/ui/metric-card.mjs +24 -21
  71. package/dist/components/ui/metric-card.mjs.map +1 -1
  72. package/dist/components/ui/modal.js +91 -74
  73. package/dist/components/ui/modal.js.map +1 -1
  74. package/dist/components/ui/modal.mjs +91 -74
  75. package/dist/components/ui/modal.mjs.map +1 -1
  76. package/dist/components/ui/navigation-menu.js +114 -93
  77. package/dist/components/ui/navigation-menu.js.map +1 -1
  78. package/dist/components/ui/navigation-menu.mjs +114 -93
  79. package/dist/components/ui/navigation-menu.mjs.map +1 -1
  80. package/dist/components/ui/pagination.js +66 -55
  81. package/dist/components/ui/pagination.js.map +1 -1
  82. package/dist/components/ui/pagination.mjs +66 -55
  83. package/dist/components/ui/pagination.mjs.map +1 -1
  84. package/dist/components/ui/popover.js +39 -36
  85. package/dist/components/ui/popover.js.map +1 -1
  86. package/dist/components/ui/popover.mjs +39 -36
  87. package/dist/components/ui/popover.mjs.map +1 -1
  88. package/dist/components/ui/progress.js +73 -64
  89. package/dist/components/ui/progress.js.map +1 -1
  90. package/dist/components/ui/progress.mjs +73 -64
  91. package/dist/components/ui/progress.mjs.map +1 -1
  92. package/dist/components/ui/radio-group.js +23 -19
  93. package/dist/components/ui/radio-group.js.map +1 -1
  94. package/dist/components/ui/radio-group.mjs +23 -19
  95. package/dist/components/ui/radio-group.mjs.map +1 -1
  96. package/dist/components/ui/segmented.js +7 -6
  97. package/dist/components/ui/segmented.js.map +1 -1
  98. package/dist/components/ui/segmented.mjs +7 -6
  99. package/dist/components/ui/segmented.mjs.map +1 -1
  100. package/dist/components/ui/select.js +55 -48
  101. package/dist/components/ui/select.js.map +1 -1
  102. package/dist/components/ui/select.mjs +55 -48
  103. package/dist/components/ui/select.mjs.map +1 -1
  104. package/dist/components/ui/skeleton.js +20 -19
  105. package/dist/components/ui/skeleton.js.map +1 -1
  106. package/dist/components/ui/skeleton.mjs +20 -19
  107. package/dist/components/ui/skeleton.mjs.map +1 -1
  108. package/dist/components/ui/slider.js +68 -58
  109. package/dist/components/ui/slider.js.map +1 -1
  110. package/dist/components/ui/slider.mjs +68 -58
  111. package/dist/components/ui/slider.mjs.map +1 -1
  112. package/dist/components/ui/spinner.js +185 -176
  113. package/dist/components/ui/spinner.js.map +1 -1
  114. package/dist/components/ui/spinner.mjs +185 -176
  115. package/dist/components/ui/spinner.mjs.map +1 -1
  116. package/dist/components/ui/switch.js +39 -28
  117. package/dist/components/ui/switch.js.map +1 -1
  118. package/dist/components/ui/switch.mjs +39 -28
  119. package/dist/components/ui/switch.mjs.map +1 -1
  120. package/dist/components/ui/table.js +26 -23
  121. package/dist/components/ui/table.js.map +1 -1
  122. package/dist/components/ui/table.mjs +26 -23
  123. package/dist/components/ui/table.mjs.map +1 -1
  124. package/dist/components/ui/tabs.js +25 -9
  125. package/dist/components/ui/tabs.js.map +1 -1
  126. package/dist/components/ui/tabs.mjs +25 -9
  127. package/dist/components/ui/tabs.mjs.map +1 -1
  128. package/dist/components/ui/textarea.js +2 -1
  129. package/dist/components/ui/textarea.js.map +1 -1
  130. package/dist/components/ui/textarea.mjs +2 -1
  131. package/dist/components/ui/textarea.mjs.map +1 -1
  132. package/dist/components/ui/toast.js +104 -80
  133. package/dist/components/ui/toast.js.map +1 -1
  134. package/dist/components/ui/toast.mjs +104 -80
  135. package/dist/components/ui/toast.mjs.map +1 -1
  136. package/dist/components/ui/toggle-group.js +9 -8
  137. package/dist/components/ui/toggle-group.js.map +1 -1
  138. package/dist/components/ui/toggle-group.mjs +9 -8
  139. package/dist/components/ui/toggle-group.mjs.map +1 -1
  140. package/dist/components/ui/toggle.js +3 -2
  141. package/dist/components/ui/toggle.js.map +1 -1
  142. package/dist/components/ui/toggle.mjs +3 -2
  143. package/dist/components/ui/toggle.mjs.map +1 -1
  144. package/dist/components/ui/tooltip.js +18 -15
  145. package/dist/components/ui/tooltip.js.map +1 -1
  146. package/dist/components/ui/tooltip.mjs +18 -15
  147. package/dist/components/ui/tooltip.mjs.map +1 -1
  148. package/package.json +27 -19
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/table.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// Size variants for table density\ntype TableSize = 'sm' | 'default' | 'lg'\n\n// Visual style variants\ntype TableVariant = 'default' | 'bordered' | 'striped'\n\n// Root context — set at Root, consumed by children\nconst TableContext = React.createContext<{\n size: TableSize\n variant: TableVariant\n stickyHeader: boolean\n}>({ size: 'default', variant: 'default', stickyHeader: false })\n\n// Cell padding per size\nconst cellPaddingMap: Record<TableSize, string> = {\n sm: 'px-3 py-2 text-sm',\n default: 'px-4 py-3 text-sm',\n lg: 'px-6 py-4 text-base',\n}\n\n// Head cell padding per size\nconst headPaddingMap: Record<TableSize, string> = {\n sm: 'px-3 py-2 text-xs',\n default: 'px-4 py-3 text-xs',\n lg: 'px-6 py-3.5 text-sm',\n}\n\n// Checkbox column padding override per size (right padding removed — next column's left padding handles the gap)\nconst checkboxPaddingMap: Record<TableSize, string> = {\n sm: '[&:has([role=checkbox])]:pl-1 [&:has([role=checkbox])]:pr-0',\n default: '[&:has([role=checkbox])]:pl-2 [&:has([role=checkbox])]:pr-0',\n lg: '[&:has([role=checkbox])]:pl-3 [&:has([role=checkbox])]:pr-0',\n}\n\nconst tableVariants = cva(\n 'w-full caption-bottom text-sm',\n {\n variants: {\n variant: {\n default: '',\n bordered: 'border border-border',\n striped: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n)\n\n// ─── Root ────────────────────────────────────────────────────────\nexport interface TableProps\n extends React.HTMLAttributes<HTMLTableElement>,\n VariantProps<typeof tableVariants> {\n /** Table density */\n size?: TableSize\n /** Visual style */\n variant?: TableVariant\n /** Sticky header when scrolling */\n stickyHeader?: boolean\n /** Additional className for the scroll wrapper (e.g. max-h-[400px]) */\n wrapperClassName?: string\n}\n\nconst Table = React.forwardRef<HTMLTableElement, TableProps>(\n ({ className, size = 'default', variant = 'default', stickyHeader = false, wrapperClassName, ...props }, ref) => (\n <TableContext.Provider value={{ size, variant, stickyHeader }}>\n <div className={cn('relative w-full overflow-auto', wrapperClassName)}>\n <table\n ref={ref}\n className={cn(tableVariants({ variant }), className)}\n {...props}\n />\n </div>\n </TableContext.Provider>\n )\n)\nTable.displayName = 'Table'\n\n// ─── Header ──────────────────────────────────────────────────────\nconst TableHeader = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => {\n const { stickyHeader } = React.useContext(TableContext)\n return (\n <thead\n ref={ref}\n className={cn(\n '[&_tr]:border-b [&_tr]:border-border',\n stickyHeader && 'sticky top-0 z-10 bg-background',\n className\n )}\n {...props}\n />\n )\n})\nTableHeader.displayName = 'TableHeader'\n\n// ─── Body ────────────────────────────────────────────────────────\nconst TableBody = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => {\n const { variant } = React.useContext(TableContext)\n return (\n <tbody\n ref={ref}\n className={cn(\n '[&_tr:last-child]:border-b-0',\n variant === 'striped' && '[&_tr:nth-child(even)]:bg-background-muted',\n className\n )}\n {...props}\n />\n )\n})\nTableBody.displayName = 'TableBody'\n\n// ─── Footer ──────────────────────────────────────────────────────\nconst TableFooter = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'border-t border-border bg-background-muted/50 font-normal [&>tr]:last:border-b-0',\n className\n )}\n {...props}\n />\n))\nTableFooter.displayName = 'TableFooter'\n\n// ─── Row ─────────────────────────────────────────────────────────\nexport interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {\n /** Enable hover highlight */\n interactive?: boolean\n /** Selected state background */\n selected?: boolean\n}\n\nconst TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(\n ({ className, interactive = false, selected = false, ...props }, ref) => (\n <tr\n ref={ref}\n data-selected={selected || undefined}\n className={cn(\n 'border-b border-border transition-colors duration-fast',\n interactive && 'hover:bg-background-muted/50 cursor-pointer',\n className\n )}\n {...props}\n />\n )\n)\nTableRow.displayName = 'TableRow'\n\n// ─── Head Cell ───────────────────────────────────────────────────\ntype SortDirection = 'asc' | 'desc' | null\n\n// Default sort icons\nconst defaultSortIcons = {\n asc: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 15l7-7 7 7\" />\n </svg>\n ),\n desc: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n ),\n default: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" />\n </svg>\n ),\n}\n\nexport interface SortIconSet {\n /** Icon for ascending state */\n asc?: React.ReactNode\n /** Icon for descending state */\n desc?: React.ReactNode\n /** Icon for unsorted (default) state */\n default?: React.ReactNode\n}\n\nexport interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n /** Enable sort indicator */\n sortable?: boolean\n /** Current sort direction */\n sortDirection?: SortDirection\n /** Sort click handler */\n onSort?: () => void\n /** Custom sort icons (overrides built-in icons) */\n sortIcon?: SortIconSet\n}\n\nconst TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(\n ({ className, align = 'left', sortable = false, sortDirection = null, onSort, sortIcon, children, ...props }, ref) => {\n const { size } = React.useContext(TableContext)\n const icons = { ...defaultSortIcons, ...sortIcon }\n\n const content = sortable ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1.5 hover:text-foreground transition-colors duration-fast group\"\n onClick={onSort}\n >\n {children}\n <span className={cn(\n 'shrink-0 transition-colors duration-fast',\n sortDirection ? 'text-foreground' : 'text-text-muted'\n )}>\n {sortDirection === 'asc' ? icons.asc\n : sortDirection === 'desc' ? icons.desc\n : icons.default}\n </span>\n </button>\n ) : children\n\n return (\n <th\n ref={ref}\n className={cn(\n 'text-left align-middle font-semibold text-text-muted whitespace-nowrap',\n headPaddingMap[size],\n checkboxPaddingMap[size],\n align === 'center' && 'text-center',\n align === 'right' && 'text-right',\n sortable && 'select-none',\n className\n )}\n aria-sort={sortDirection === 'asc' ? 'ascending' : sortDirection === 'desc' ? 'descending' : undefined}\n {...props}\n >\n {content}\n </th>\n )\n }\n)\nTableHead.displayName = 'TableHead'\n\n// ─── Data Cell ───────────────────────────────────────────────────\nexport interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n}\n\nconst TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(\n ({ className, align = 'left', ...props }, ref) => {\n const { size } = React.useContext(TableContext)\n return (\n <td\n ref={ref}\n className={cn(\n 'text-foreground align-middle',\n cellPaddingMap[size],\n checkboxPaddingMap[size],\n align === 'center' && 'text-center',\n align === 'right' && 'text-right',\n className\n )}\n {...props}\n />\n )\n }\n)\nTableCell.displayName = 'TableCell'\n\n// ─── Caption ─────────────────────────────────────────────────────\nconst TableCaption = React.forwardRef<\n HTMLTableCaptionElement,\n React.HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn('mt-4 text-sm text-text-muted', className)}\n {...props}\n />\n))\nTableCaption.displayName = 'TableCaption'\n\nexport type { TableSize, TableVariant, SortDirection }\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableRow,\n TableHead,\n TableCell,\n TableCaption,\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/ui/table.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// Size variants for table density\ntype TableSize = 'sm' | 'default' | 'lg'\n\n// Visual style variants\ntype TableVariant = 'default' | 'bordered' | 'striped'\n\n// Root context — set at Root, consumed by children\nconst TableContext = React.createContext<{\n size: TableSize\n variant: TableVariant\n stickyHeader: boolean\n}>({ size: 'default', variant: 'default', stickyHeader: false })\n\n// Cell padding per size\nconst cellPaddingMap: Record<TableSize, string> = {\n sm: 'px-3 py-2 text-sm',\n default: 'px-4 py-3 text-sm',\n lg: 'px-6 py-4 text-base',\n}\n\n// Head cell padding per size\nconst headPaddingMap: Record<TableSize, string> = {\n sm: 'px-3 py-2 text-xs',\n default: 'px-4 py-3 text-xs',\n lg: 'px-6 py-3.5 text-sm',\n}\n\n// Checkbox column padding override per size (right padding removed — next column's left padding handles the gap)\nconst checkboxPaddingMap: Record<TableSize, string> = {\n sm: '[&:has([role=checkbox])]:pl-1 [&:has([role=checkbox])]:pr-0',\n default: '[&:has([role=checkbox])]:pl-2 [&:has([role=checkbox])]:pr-0',\n lg: '[&:has([role=checkbox])]:pl-3 [&:has([role=checkbox])]:pr-0',\n}\n\nconst tableVariants = cva(\n 'w-full caption-bottom text-sm',\n {\n variants: {\n variant: {\n default: '',\n bordered: 'border border-border',\n striped: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n)\n\n// ─── Root ────────────────────────────────────────────────────────\nexport interface TableProps\n extends React.HTMLAttributes<HTMLTableElement>,\n VariantProps<typeof tableVariants> {\n /** Table density */\n size?: TableSize\n /** Visual style */\n variant?: TableVariant\n /** Sticky header when scrolling */\n stickyHeader?: boolean\n /** Additional className for the scroll wrapper (e.g. max-h-[400px]) */\n wrapperClassName?: string\n}\n\nconst Table = React.forwardRef<HTMLTableElement, TableProps>(\n ({ className, size = 'default', variant = 'default', stickyHeader = false, wrapperClassName, ...props }, ref) => (\n <TableContext.Provider value={{ size, variant, stickyHeader }}>\n <div className={cn('relative w-full overflow-auto', wrapperClassName)}>\n <table\n ref={ref}\n className={cn(tableVariants({ variant }), className)}\n {...props}\n />\n </div>\n </TableContext.Provider>\n )\n)\nTable.displayName = 'Table'\n\n// ─── Header ──────────────────────────────────────────────────────\nconst TableHeader = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => {\n const { stickyHeader } = React.useContext(TableContext)\n return (\n <thead\n ref={ref}\n className={cn(\n '[&_tr]:border-b [&_tr]:border-border',\n stickyHeader && 'sticky top-0 z-10 bg-background',\n className\n )}\n {...props}\n />\n )\n})\nTableHeader.displayName = 'TableHeader'\n\n// ─── Body ────────────────────────────────────────────────────────\nconst TableBody = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => {\n const { variant } = React.useContext(TableContext)\n return (\n <tbody\n ref={ref}\n className={cn(\n '[&_tr:last-child]:border-b-0',\n variant === 'striped' && '[&_tr:nth-child(even)]:bg-background-muted',\n className\n )}\n {...props}\n />\n )\n})\nTableBody.displayName = 'TableBody'\n\n// ─── Footer ──────────────────────────────────────────────────────\nconst TableFooter = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'border-t border-border bg-background-muted/50 font-normal [&>tr]:last:border-b-0',\n className\n )}\n {...props}\n />\n))\nTableFooter.displayName = 'TableFooter'\n\n// ─── Row ─────────────────────────────────────────────────────────\nexport interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {\n /** Enable hover highlight */\n interactive?: boolean\n /** Selected state background */\n selected?: boolean\n}\n\nconst TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(\n ({ className, interactive = false, selected = false, ...props }, ref) => (\n <tr\n ref={ref}\n data-selected={selected || undefined}\n className={cn(\n 'border-b border-border transition-colors duration-fast',\n interactive && 'hover:bg-background-muted/50 cursor-pointer',\n className\n )}\n {...props}\n />\n )\n)\nTableRow.displayName = 'TableRow'\n\n// ─── Head Cell ───────────────────────────────────────────────────\ntype SortDirection = 'asc' | 'desc' | null\n\n// Default sort icons\nconst defaultSortIcons = {\n asc: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 15l7-7 7 7\" />\n </svg>\n ),\n desc: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n ),\n default: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" />\n </svg>\n ),\n}\n\nexport interface SortIconSet {\n /** Icon for ascending state */\n asc?: React.ReactNode\n /** Icon for descending state */\n desc?: React.ReactNode\n /** Icon for unsorted (default) state */\n default?: React.ReactNode\n}\n\nexport interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n /** Enable sort indicator */\n sortable?: boolean\n /** Current sort direction */\n sortDirection?: SortDirection\n /** Sort click handler */\n onSort?: () => void\n /** Custom sort icons (overrides built-in icons) */\n sortIcon?: SortIconSet\n}\n\nconst TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(\n ({ className, align = 'left', sortable = false, sortDirection = null, onSort, sortIcon, children, ...props }, ref) => {\n const { size } = React.useContext(TableContext)\n const icons = { ...defaultSortIcons, ...sortIcon }\n\n const content = sortable ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1.5 hover:text-foreground transition-colors duration-fast group\"\n onClick={onSort}\n >\n {children}\n <span className={cn(\n 'shrink-0 transition-colors duration-fast',\n sortDirection ? 'text-foreground' : 'text-text-muted'\n )}>\n {sortDirection === 'asc' ? icons.asc\n : sortDirection === 'desc' ? icons.desc\n : icons.default}\n </span>\n </button>\n ) : children\n\n return (\n <th\n ref={ref}\n className={cn(\n 'text-left align-middle font-semibold text-text-muted whitespace-nowrap',\n headPaddingMap[size],\n checkboxPaddingMap[size],\n align === 'center' && 'text-center',\n align === 'right' && 'text-right',\n sortable && 'select-none',\n className\n )}\n aria-sort={sortDirection === 'asc' ? 'ascending' : sortDirection === 'desc' ? 'descending' : undefined}\n {...props}\n >\n {content}\n </th>\n )\n }\n)\nTableHead.displayName = 'TableHead'\n\n// ─── Data Cell ───────────────────────────────────────────────────\nexport interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n}\n\nconst TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(\n ({ className, align = 'left', ...props }, ref) => {\n const { size } = React.useContext(TableContext)\n return (\n <td\n ref={ref}\n className={cn(\n 'text-foreground align-middle',\n cellPaddingMap[size],\n checkboxPaddingMap[size],\n align === 'center' && 'text-center',\n align === 'right' && 'text-right',\n className\n )}\n {...props}\n />\n )\n }\n)\nTableCell.displayName = 'TableCell'\n\n// ─── Caption ─────────────────────────────────────────────────────\nconst TableCaption = React.forwardRef<\n HTMLTableCaptionElement,\n React.HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn('mt-4 text-sm text-text-muted', className)}\n {...props}\n />\n))\nTableCaption.displayName = 'TableCaption'\n\nexport type { TableSize, TableVariant, SortDirection }\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableRow,\n TableHead,\n TableCell,\n TableCaption,\n}\n"],"mappings":"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","names":[]}
@@ -1,4 +1,5 @@
1
1
  "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
2
3
  import * as React from "react";
3
4
  import { cva } from "class-variance-authority";
4
5
  import { cn } from "../../lib/utils";
@@ -34,19 +35,19 @@ const tableVariants = cva(
34
35
  }
35
36
  );
36
37
  const Table = React.forwardRef(
37
- ({ className, size = "default", variant = "default", stickyHeader = false, wrapperClassName, ...props }, ref) => /* @__PURE__ */ React.createElement(TableContext.Provider, { value: { size, variant, stickyHeader } }, /* @__PURE__ */ React.createElement("div", { className: cn("relative w-full overflow-auto", wrapperClassName) }, /* @__PURE__ */ React.createElement(
38
+ ({ className, size = "default", variant = "default", stickyHeader = false, wrapperClassName, ...props }, ref) => /* @__PURE__ */ jsx(TableContext.Provider, { value: { size, variant, stickyHeader }, children: /* @__PURE__ */ jsx("div", { className: cn("relative w-full overflow-auto", wrapperClassName), children: /* @__PURE__ */ jsx(
38
39
  "table",
39
40
  {
40
41
  ref,
41
42
  className: cn(tableVariants({ variant }), className),
42
43
  ...props
43
44
  }
44
- )))
45
+ ) }) })
45
46
  );
46
47
  Table.displayName = "Table";
47
48
  const TableHeader = React.forwardRef(({ className, ...props }, ref) => {
48
49
  const { stickyHeader } = React.useContext(TableContext);
49
- return /* @__PURE__ */ React.createElement(
50
+ return /* @__PURE__ */ jsx(
50
51
  "thead",
51
52
  {
52
53
  ref,
@@ -62,7 +63,7 @@ const TableHeader = React.forwardRef(({ className, ...props }, ref) => {
62
63
  TableHeader.displayName = "TableHeader";
63
64
  const TableBody = React.forwardRef(({ className, ...props }, ref) => {
64
65
  const { variant } = React.useContext(TableContext);
65
- return /* @__PURE__ */ React.createElement(
66
+ return /* @__PURE__ */ jsx(
66
67
  "tbody",
67
68
  {
68
69
  ref,
@@ -76,7 +77,7 @@ const TableBody = React.forwardRef(({ className, ...props }, ref) => {
76
77
  );
77
78
  });
78
79
  TableBody.displayName = "TableBody";
79
- const TableFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
80
+ const TableFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
80
81
  "tfoot",
81
82
  {
82
83
  ref,
@@ -89,7 +90,7 @@ const TableFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PUR
89
90
  ));
90
91
  TableFooter.displayName = "TableFooter";
91
92
  const TableRow = React.forwardRef(
92
- ({ className, interactive = false, selected = false, ...props }, ref) => /* @__PURE__ */ React.createElement(
93
+ ({ className, interactive = false, selected = false, ...props }, ref) => /* @__PURE__ */ jsx(
93
94
  "tr",
94
95
  {
95
96
  ref,
@@ -105,28 +106,30 @@ const TableRow = React.forwardRef(
105
106
  );
106
107
  TableRow.displayName = "TableRow";
107
108
  const defaultSortIcons = {
108
- asc: /* @__PURE__ */ React.createElement("svg", { className: "icon-xs", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 15l7-7 7 7" })),
109
- desc: /* @__PURE__ */ React.createElement("svg", { className: "icon-xs", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })),
110
- default: /* @__PURE__ */ React.createElement("svg", { className: "icon-xs", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }))
109
+ asc: /* @__PURE__ */ jsx("svg", { className: "icon-xs", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 15l7-7 7 7" }) }),
110
+ desc: /* @__PURE__ */ jsx("svg", { className: "icon-xs", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) }),
111
+ default: /* @__PURE__ */ jsx("svg", { className: "icon-xs", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }) })
111
112
  };
112
113
  const TableHead = React.forwardRef(
113
114
  ({ className, align = "left", sortable = false, sortDirection = null, onSort, sortIcon, children, ...props }, ref) => {
114
115
  const { size } = React.useContext(TableContext);
115
116
  const icons = { ...defaultSortIcons, ...sortIcon };
116
- const content = sortable ? /* @__PURE__ */ React.createElement(
117
+ const content = sortable ? /* @__PURE__ */ jsxs(
117
118
  "button",
118
119
  {
119
120
  type: "button",
120
121
  className: "inline-flex items-center gap-1.5 hover:text-foreground transition-colors duration-fast group",
121
- onClick: onSort
122
- },
123
- children,
124
- /* @__PURE__ */ React.createElement("span", { className: cn(
125
- "shrink-0 transition-colors duration-fast",
126
- sortDirection ? "text-foreground" : "text-text-muted"
127
- ) }, sortDirection === "asc" ? icons.asc : sortDirection === "desc" ? icons.desc : icons.default)
122
+ onClick: onSort,
123
+ children: [
124
+ children,
125
+ /* @__PURE__ */ jsx("span", { className: cn(
126
+ "shrink-0 transition-colors duration-fast",
127
+ sortDirection ? "text-foreground" : "text-text-muted"
128
+ ), children: sortDirection === "asc" ? icons.asc : sortDirection === "desc" ? icons.desc : icons.default })
129
+ ]
130
+ }
128
131
  ) : children;
129
- return /* @__PURE__ */ React.createElement(
132
+ return /* @__PURE__ */ jsx(
130
133
  "th",
131
134
  {
132
135
  ref,
@@ -140,9 +143,9 @@ const TableHead = React.forwardRef(
140
143
  className
141
144
  ),
142
145
  "aria-sort": sortDirection === "asc" ? "ascending" : sortDirection === "desc" ? "descending" : void 0,
143
- ...props
144
- },
145
- content
146
+ ...props,
147
+ children: content
148
+ }
146
149
  );
147
150
  }
148
151
  );
@@ -150,7 +153,7 @@ TableHead.displayName = "TableHead";
150
153
  const TableCell = React.forwardRef(
151
154
  ({ className, align = "left", ...props }, ref) => {
152
155
  const { size } = React.useContext(TableContext);
153
- return /* @__PURE__ */ React.createElement(
156
+ return /* @__PURE__ */ jsx(
154
157
  "td",
155
158
  {
156
159
  ref,
@@ -168,7 +171,7 @@ const TableCell = React.forwardRef(
168
171
  }
169
172
  );
170
173
  TableCell.displayName = "TableCell";
171
- const TableCaption = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
174
+ const TableCaption = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
172
175
  "caption",
173
176
  {
174
177
  ref,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/table.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// Size variants for table density\ntype TableSize = 'sm' | 'default' | 'lg'\n\n// Visual style variants\ntype TableVariant = 'default' | 'bordered' | 'striped'\n\n// Root context — set at Root, consumed by children\nconst TableContext = React.createContext<{\n size: TableSize\n variant: TableVariant\n stickyHeader: boolean\n}>({ size: 'default', variant: 'default', stickyHeader: false })\n\n// Cell padding per size\nconst cellPaddingMap: Record<TableSize, string> = {\n sm: 'px-3 py-2 text-sm',\n default: 'px-4 py-3 text-sm',\n lg: 'px-6 py-4 text-base',\n}\n\n// Head cell padding per size\nconst headPaddingMap: Record<TableSize, string> = {\n sm: 'px-3 py-2 text-xs',\n default: 'px-4 py-3 text-xs',\n lg: 'px-6 py-3.5 text-sm',\n}\n\n// Checkbox column padding override per size (right padding removed — next column's left padding handles the gap)\nconst checkboxPaddingMap: Record<TableSize, string> = {\n sm: '[&:has([role=checkbox])]:pl-1 [&:has([role=checkbox])]:pr-0',\n default: '[&:has([role=checkbox])]:pl-2 [&:has([role=checkbox])]:pr-0',\n lg: '[&:has([role=checkbox])]:pl-3 [&:has([role=checkbox])]:pr-0',\n}\n\nconst tableVariants = cva(\n 'w-full caption-bottom text-sm',\n {\n variants: {\n variant: {\n default: '',\n bordered: 'border border-border',\n striped: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n)\n\n// ─── Root ────────────────────────────────────────────────────────\nexport interface TableProps\n extends React.HTMLAttributes<HTMLTableElement>,\n VariantProps<typeof tableVariants> {\n /** Table density */\n size?: TableSize\n /** Visual style */\n variant?: TableVariant\n /** Sticky header when scrolling */\n stickyHeader?: boolean\n /** Additional className for the scroll wrapper (e.g. max-h-[400px]) */\n wrapperClassName?: string\n}\n\nconst Table = React.forwardRef<HTMLTableElement, TableProps>(\n ({ className, size = 'default', variant = 'default', stickyHeader = false, wrapperClassName, ...props }, ref) => (\n <TableContext.Provider value={{ size, variant, stickyHeader }}>\n <div className={cn('relative w-full overflow-auto', wrapperClassName)}>\n <table\n ref={ref}\n className={cn(tableVariants({ variant }), className)}\n {...props}\n />\n </div>\n </TableContext.Provider>\n )\n)\nTable.displayName = 'Table'\n\n// ─── Header ──────────────────────────────────────────────────────\nconst TableHeader = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => {\n const { stickyHeader } = React.useContext(TableContext)\n return (\n <thead\n ref={ref}\n className={cn(\n '[&_tr]:border-b [&_tr]:border-border',\n stickyHeader && 'sticky top-0 z-10 bg-background',\n className\n )}\n {...props}\n />\n )\n})\nTableHeader.displayName = 'TableHeader'\n\n// ─── Body ────────────────────────────────────────────────────────\nconst TableBody = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => {\n const { variant } = React.useContext(TableContext)\n return (\n <tbody\n ref={ref}\n className={cn(\n '[&_tr:last-child]:border-b-0',\n variant === 'striped' && '[&_tr:nth-child(even)]:bg-background-muted',\n className\n )}\n {...props}\n />\n )\n})\nTableBody.displayName = 'TableBody'\n\n// ─── Footer ──────────────────────────────────────────────────────\nconst TableFooter = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'border-t border-border bg-background-muted/50 font-normal [&>tr]:last:border-b-0',\n className\n )}\n {...props}\n />\n))\nTableFooter.displayName = 'TableFooter'\n\n// ─── Row ─────────────────────────────────────────────────────────\nexport interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {\n /** Enable hover highlight */\n interactive?: boolean\n /** Selected state background */\n selected?: boolean\n}\n\nconst TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(\n ({ className, interactive = false, selected = false, ...props }, ref) => (\n <tr\n ref={ref}\n data-selected={selected || undefined}\n className={cn(\n 'border-b border-border transition-colors duration-fast',\n interactive && 'hover:bg-background-muted/50 cursor-pointer',\n className\n )}\n {...props}\n />\n )\n)\nTableRow.displayName = 'TableRow'\n\n// ─── Head Cell ───────────────────────────────────────────────────\ntype SortDirection = 'asc' | 'desc' | null\n\n// Default sort icons\nconst defaultSortIcons = {\n asc: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 15l7-7 7 7\" />\n </svg>\n ),\n desc: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n ),\n default: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" />\n </svg>\n ),\n}\n\nexport interface SortIconSet {\n /** Icon for ascending state */\n asc?: React.ReactNode\n /** Icon for descending state */\n desc?: React.ReactNode\n /** Icon for unsorted (default) state */\n default?: React.ReactNode\n}\n\nexport interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n /** Enable sort indicator */\n sortable?: boolean\n /** Current sort direction */\n sortDirection?: SortDirection\n /** Sort click handler */\n onSort?: () => void\n /** Custom sort icons (overrides built-in icons) */\n sortIcon?: SortIconSet\n}\n\nconst TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(\n ({ className, align = 'left', sortable = false, sortDirection = null, onSort, sortIcon, children, ...props }, ref) => {\n const { size } = React.useContext(TableContext)\n const icons = { ...defaultSortIcons, ...sortIcon }\n\n const content = sortable ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1.5 hover:text-foreground transition-colors duration-fast group\"\n onClick={onSort}\n >\n {children}\n <span className={cn(\n 'shrink-0 transition-colors duration-fast',\n sortDirection ? 'text-foreground' : 'text-text-muted'\n )}>\n {sortDirection === 'asc' ? icons.asc\n : sortDirection === 'desc' ? icons.desc\n : icons.default}\n </span>\n </button>\n ) : children\n\n return (\n <th\n ref={ref}\n className={cn(\n 'text-left align-middle font-semibold text-text-muted whitespace-nowrap',\n headPaddingMap[size],\n checkboxPaddingMap[size],\n align === 'center' && 'text-center',\n align === 'right' && 'text-right',\n sortable && 'select-none',\n className\n )}\n aria-sort={sortDirection === 'asc' ? 'ascending' : sortDirection === 'desc' ? 'descending' : undefined}\n {...props}\n >\n {content}\n </th>\n )\n }\n)\nTableHead.displayName = 'TableHead'\n\n// ─── Data Cell ───────────────────────────────────────────────────\nexport interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n}\n\nconst TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(\n ({ className, align = 'left', ...props }, ref) => {\n const { size } = React.useContext(TableContext)\n return (\n <td\n ref={ref}\n className={cn(\n 'text-foreground align-middle',\n cellPaddingMap[size],\n checkboxPaddingMap[size],\n align === 'center' && 'text-center',\n align === 'right' && 'text-right',\n className\n )}\n {...props}\n />\n )\n }\n)\nTableCell.displayName = 'TableCell'\n\n// ─── Caption ─────────────────────────────────────────────────────\nconst TableCaption = React.forwardRef<\n HTMLTableCaptionElement,\n React.HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn('mt-4 text-sm text-text-muted', className)}\n {...props}\n />\n))\nTableCaption.displayName = 'TableCaption'\n\nexport type { TableSize, TableVariant, SortDirection }\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableRow,\n TableHead,\n TableCell,\n TableCaption,\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/ui/table.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// Size variants for table density\ntype TableSize = 'sm' | 'default' | 'lg'\n\n// Visual style variants\ntype TableVariant = 'default' | 'bordered' | 'striped'\n\n// Root context — set at Root, consumed by children\nconst TableContext = React.createContext<{\n size: TableSize\n variant: TableVariant\n stickyHeader: boolean\n}>({ size: 'default', variant: 'default', stickyHeader: false })\n\n// Cell padding per size\nconst cellPaddingMap: Record<TableSize, string> = {\n sm: 'px-3 py-2 text-sm',\n default: 'px-4 py-3 text-sm',\n lg: 'px-6 py-4 text-base',\n}\n\n// Head cell padding per size\nconst headPaddingMap: Record<TableSize, string> = {\n sm: 'px-3 py-2 text-xs',\n default: 'px-4 py-3 text-xs',\n lg: 'px-6 py-3.5 text-sm',\n}\n\n// Checkbox column padding override per size (right padding removed — next column's left padding handles the gap)\nconst checkboxPaddingMap: Record<TableSize, string> = {\n sm: '[&:has([role=checkbox])]:pl-1 [&:has([role=checkbox])]:pr-0',\n default: '[&:has([role=checkbox])]:pl-2 [&:has([role=checkbox])]:pr-0',\n lg: '[&:has([role=checkbox])]:pl-3 [&:has([role=checkbox])]:pr-0',\n}\n\nconst tableVariants = cva(\n 'w-full caption-bottom text-sm',\n {\n variants: {\n variant: {\n default: '',\n bordered: 'border border-border',\n striped: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n)\n\n// ─── Root ────────────────────────────────────────────────────────\nexport interface TableProps\n extends React.HTMLAttributes<HTMLTableElement>,\n VariantProps<typeof tableVariants> {\n /** Table density */\n size?: TableSize\n /** Visual style */\n variant?: TableVariant\n /** Sticky header when scrolling */\n stickyHeader?: boolean\n /** Additional className for the scroll wrapper (e.g. max-h-[400px]) */\n wrapperClassName?: string\n}\n\nconst Table = React.forwardRef<HTMLTableElement, TableProps>(\n ({ className, size = 'default', variant = 'default', stickyHeader = false, wrapperClassName, ...props }, ref) => (\n <TableContext.Provider value={{ size, variant, stickyHeader }}>\n <div className={cn('relative w-full overflow-auto', wrapperClassName)}>\n <table\n ref={ref}\n className={cn(tableVariants({ variant }), className)}\n {...props}\n />\n </div>\n </TableContext.Provider>\n )\n)\nTable.displayName = 'Table'\n\n// ─── Header ──────────────────────────────────────────────────────\nconst TableHeader = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => {\n const { stickyHeader } = React.useContext(TableContext)\n return (\n <thead\n ref={ref}\n className={cn(\n '[&_tr]:border-b [&_tr]:border-border',\n stickyHeader && 'sticky top-0 z-10 bg-background',\n className\n )}\n {...props}\n />\n )\n})\nTableHeader.displayName = 'TableHeader'\n\n// ─── Body ────────────────────────────────────────────────────────\nconst TableBody = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => {\n const { variant } = React.useContext(TableContext)\n return (\n <tbody\n ref={ref}\n className={cn(\n '[&_tr:last-child]:border-b-0',\n variant === 'striped' && '[&_tr:nth-child(even)]:bg-background-muted',\n className\n )}\n {...props}\n />\n )\n})\nTableBody.displayName = 'TableBody'\n\n// ─── Footer ──────────────────────────────────────────────────────\nconst TableFooter = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'border-t border-border bg-background-muted/50 font-normal [&>tr]:last:border-b-0',\n className\n )}\n {...props}\n />\n))\nTableFooter.displayName = 'TableFooter'\n\n// ─── Row ─────────────────────────────────────────────────────────\nexport interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {\n /** Enable hover highlight */\n interactive?: boolean\n /** Selected state background */\n selected?: boolean\n}\n\nconst TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(\n ({ className, interactive = false, selected = false, ...props }, ref) => (\n <tr\n ref={ref}\n data-selected={selected || undefined}\n className={cn(\n 'border-b border-border transition-colors duration-fast',\n interactive && 'hover:bg-background-muted/50 cursor-pointer',\n className\n )}\n {...props}\n />\n )\n)\nTableRow.displayName = 'TableRow'\n\n// ─── Head Cell ───────────────────────────────────────────────────\ntype SortDirection = 'asc' | 'desc' | null\n\n// Default sort icons\nconst defaultSortIcons = {\n asc: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 15l7-7 7 7\" />\n </svg>\n ),\n desc: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n ),\n default: (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" />\n </svg>\n ),\n}\n\nexport interface SortIconSet {\n /** Icon for ascending state */\n asc?: React.ReactNode\n /** Icon for descending state */\n desc?: React.ReactNode\n /** Icon for unsorted (default) state */\n default?: React.ReactNode\n}\n\nexport interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n /** Enable sort indicator */\n sortable?: boolean\n /** Current sort direction */\n sortDirection?: SortDirection\n /** Sort click handler */\n onSort?: () => void\n /** Custom sort icons (overrides built-in icons) */\n sortIcon?: SortIconSet\n}\n\nconst TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(\n ({ className, align = 'left', sortable = false, sortDirection = null, onSort, sortIcon, children, ...props }, ref) => {\n const { size } = React.useContext(TableContext)\n const icons = { ...defaultSortIcons, ...sortIcon }\n\n const content = sortable ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1.5 hover:text-foreground transition-colors duration-fast group\"\n onClick={onSort}\n >\n {children}\n <span className={cn(\n 'shrink-0 transition-colors duration-fast',\n sortDirection ? 'text-foreground' : 'text-text-muted'\n )}>\n {sortDirection === 'asc' ? icons.asc\n : sortDirection === 'desc' ? icons.desc\n : icons.default}\n </span>\n </button>\n ) : children\n\n return (\n <th\n ref={ref}\n className={cn(\n 'text-left align-middle font-semibold text-text-muted whitespace-nowrap',\n headPaddingMap[size],\n checkboxPaddingMap[size],\n align === 'center' && 'text-center',\n align === 'right' && 'text-right',\n sortable && 'select-none',\n className\n )}\n aria-sort={sortDirection === 'asc' ? 'ascending' : sortDirection === 'desc' ? 'descending' : undefined}\n {...props}\n >\n {content}\n </th>\n )\n }\n)\nTableHead.displayName = 'TableHead'\n\n// ─── Data Cell ───────────────────────────────────────────────────\nexport interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n}\n\nconst TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(\n ({ className, align = 'left', ...props }, ref) => {\n const { size } = React.useContext(TableContext)\n return (\n <td\n ref={ref}\n className={cn(\n 'text-foreground align-middle',\n cellPaddingMap[size],\n checkboxPaddingMap[size],\n align === 'center' && 'text-center',\n align === 'right' && 'text-right',\n className\n )}\n {...props}\n />\n )\n }\n)\nTableCell.displayName = 'TableCell'\n\n// ─── Caption ─────────────────────────────────────────────────────\nconst TableCaption = React.forwardRef<\n HTMLTableCaptionElement,\n React.HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn('mt-4 text-sm text-text-muted', className)}\n {...props}\n />\n))\nTableCaption.displayName = 'TableCaption'\n\nexport type { TableSize, TableVariant, SortDirection }\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableRow,\n TableHead,\n TableCell,\n TableCaption,\n}\n"],"mappings":"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","names":[]}
@@ -37,6 +37,7 @@ __export(tabs_exports, {
37
37
  tabsTriggerVariants: () => tabsTriggerVariants
38
38
  });
39
39
  module.exports = __toCommonJS(tabs_exports);
40
+ var import_jsx_runtime = require("react/jsx-runtime");
40
41
  var React = __toESM(require("react"));
41
42
  var TabsPrimitive = __toESM(require("@radix-ui/react-tabs"));
42
43
  var import_class_variance_authority = require("class-variance-authority");
@@ -65,7 +66,7 @@ const tabsListVariants = (0, import_class_variance_authority.cva)(
65
66
  );
66
67
  const TabsList = React.forwardRef(({ className, variant, size, fitted, color, radius, ...props }, ref) => {
67
68
  const resolvedVariant = variant || "line";
68
- return /* @__PURE__ */ React.createElement(TabsStyleContext.Provider, { value: { variant: resolvedVariant, size: size || "default", fitted: fitted ?? false, color: color || "default", radius: radius || "md" } }, /* @__PURE__ */ React.createElement(
69
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsStyleContext.Provider, { value: { variant: resolvedVariant, size: size || "default", fitted: fitted ?? false, color: color || "default", radius: radius || "md" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
69
70
  TabsPrimitive.List,
70
71
  {
71
72
  ref,
@@ -76,14 +77,15 @@ const TabsList = React.forwardRef(({ className, variant, size, fitted, color, ra
76
77
  ),
77
78
  ...props
78
79
  }
79
- ));
80
+ ) });
80
81
  });
81
82
  TabsList.displayName = "TabsList";
82
83
  const tabsTriggerVariants = (0, import_class_variance_authority.cva)(
83
84
  [
84
85
  "inline-flex items-center justify-center gap-2 whitespace-nowrap",
85
86
  "transition-all duration-micro ease-out cursor-pointer",
86
- "focus-visible:focus-ring",
87
+ // Keyboard-only focus ring: see pointer tracking in TabsTrigger
88
+ "[&:focus-visible:not([data-pointer-focus])]:focus-ring",
87
89
  "disabled:pointer-events-none disabled:text-text-subtle disabled:opacity-50"
88
90
  ].join(" "),
89
91
  {
@@ -187,10 +189,11 @@ const pillItemRadiusClasses = {
187
189
  "3xl": "rounded-2xl",
188
190
  full: "rounded-full"
189
191
  };
190
- const TabsTrigger = React.forwardRef(({ className, children, ...props }, ref) => {
192
+ const TabsTrigger = React.forwardRef(({ className, children, onPointerDown, onKeyDown, onBlur, ...props }, ref) => {
191
193
  const { variant, size, fitted, color, radius } = useTabsStyleContext();
192
194
  const resolvedSize = size || "default";
193
- return /* @__PURE__ */ React.createElement(
195
+ const [pointerFocus, setPointerFocus] = React.useState(false);
196
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
194
197
  TabsPrimitive.Trigger,
195
198
  {
196
199
  ref,
@@ -202,13 +205,26 @@ const TabsTrigger = React.forwardRef(({ className, children, ...props }, ref) =>
202
205
  variant === "pill" && pillItemRadiusClasses[radius || "md"],
203
206
  className
204
207
  ),
205
- ...props
206
- },
207
- children
208
+ "data-pointer-focus": pointerFocus ? "" : void 0,
209
+ onPointerDown: (event) => {
210
+ setPointerFocus(true);
211
+ onPointerDown?.(event);
212
+ },
213
+ onKeyDown: (event) => {
214
+ setPointerFocus(false);
215
+ onKeyDown?.(event);
216
+ },
217
+ onBlur: (event) => {
218
+ setPointerFocus(false);
219
+ onBlur?.(event);
220
+ },
221
+ ...props,
222
+ children
223
+ }
208
224
  );
209
225
  });
210
226
  TabsTrigger.displayName = "TabsTrigger";
211
- const TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
227
+ const TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
212
228
  TabsPrimitive.Content,
213
229
  {
214
230
  ref,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/tabs.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as TabsPrimitive from '@radix-ui/react-tabs'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\n// Context to pass style props from TabsList to TabsTrigger\ntype TabsStyleContextValue = {\n variant?: 'line' | 'enclosed' | 'pill'\n size?: 'sm' | 'md' | 'default' | 'lg'\n fitted?: boolean\n color?: 'default' | 'primary'\n radius?: 'none' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\nconst TabsStyleContext = React.createContext<TabsStyleContextValue>({})\nconst useTabsStyleContext = () => React.useContext(TabsStyleContext)\n\n// ─── TabsList ────────────────────────────────────────────────\n\nconst tabsListVariants = cva(\n 'inline-flex items-center text-text-subtle',\n {\n variants: {\n variant: {\n line: 'border-b border-border bg-transparent gap-0',\n enclosed: 'border-b border-border bg-transparent gap-0',\n pill: 'bg-background-muted p-1 gap-1',\n },\n fitted: {\n true: 'w-full',\n false: '',\n },\n },\n defaultVariants: {\n variant: 'line',\n fitted: false,\n },\n }\n)\n\nexport interface TabsListProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>,\n VariantProps<typeof tabsListVariants> {\n size?: 'sm' | 'md' | 'default' | 'lg'\n /** Indicator color for line variant */\n color?: 'default' | 'primary'\n /** Top border-radius for enclosed variant, container radius for pill variant */\n radius?: 'none' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\n\nconst TabsList = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.List>,\n TabsListProps\n>(({ className, variant, size, fitted, color, radius, ...props }, ref) => {\n const resolvedVariant = variant || 'line'\n return (\n <TabsStyleContext.Provider value={{ variant: resolvedVariant, size: size || 'default', fitted: fitted ?? false, color: color || 'default', radius: radius || 'md' }}>\n <TabsPrimitive.List\n ref={ref}\n className={cn(\n tabsListVariants({ variant, fitted }),\n resolvedVariant === 'pill' && pillListRadiusClasses[radius || 'md'],\n className\n )}\n {...props}\n />\n </TabsStyleContext.Provider>\n )\n})\nTabsList.displayName = 'TabsList'\n\n// ─── TabsTrigger ─────────────────────────────────────────────\n\nconst tabsTriggerVariants = cva(\n [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap',\n 'transition-all duration-micro ease-out cursor-pointer',\n 'focus-visible:focus-ring',\n 'disabled:pointer-events-none disabled:text-text-subtle disabled:opacity-50',\n ].join(' '),\n {\n variants: {\n variant: {\n line: [\n 'border-b-2 border-transparent -mb-px',\n 'hover:text-foreground hover:border-border',\n 'data-[state=active]:text-foreground data-[state=active]:font-semibold',\n ].join(' '),\n enclosed: [\n 'border border-transparent -mb-px',\n 'hover:text-foreground',\n 'data-[state=active]:text-foreground data-[state=active]:font-semibold data-[state=active]:bg-background',\n 'data-[state=active]:border-border data-[state=active]:border-b-background',\n ].join(' '),\n pill: [\n 'hover:text-foreground',\n 'data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:font-semibold data-[state=active]:shadow-sm',\n ].join(' '),\n },\n size: {\n sm: 'h-8 text-sm', // 32px, 13px\n md: 'h-9 text-sm', // 36px, 13px\n default: 'h-10 text-md', // 40px, 14px\n lg: 'h-12 text-base', // 48px, 16px\n },\n fitted: {\n true: 'flex-1',\n false: '',\n },\n },\n compoundVariants: [\n // Padding per variant × size\n { variant: 'line', size: 'sm', className: 'px-3' },\n { variant: 'line', size: 'md', className: 'px-3.5' },\n { variant: 'line', size: 'default', className: 'px-4' },\n { variant: 'line', size: 'lg', className: 'px-6' },\n { variant: 'enclosed', size: 'sm', className: 'px-3' },\n { variant: 'enclosed', size: 'md', className: 'px-3.5' },\n { variant: 'enclosed', size: 'default', className: 'px-4' },\n { variant: 'enclosed', size: 'lg', className: 'px-6' },\n // Pill: reduced height + Segmented-matching font/padding\n { variant: 'pill', size: 'sm', className: 'h-6 text-xs px-3.5' },\n { variant: 'pill', size: 'md', className: 'h-7 text-sm px-3.5' },\n { variant: 'pill', size: 'default', className: 'h-8 text-sm px-4' },\n { variant: 'pill', size: 'lg', className: 'h-10 text-md px-6' },\n ],\n defaultVariants: {\n variant: 'line',\n size: 'default',\n fitted: false,\n },\n }\n)\n\n// Icon size mapping for tabs (same as Button icon+text pattern)\nconst triggerIconSizeClasses = {\n sm: '[&>svg]:icon-xs', // 14px\n md: '[&>svg]:icon-sm', // 16px\n default: '[&>svg]:icon-sm', // 16px\n lg: '[&>svg]:icon-sm', // 16px\n} as const\n\nexport interface TabsTriggerProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>,\n Omit<VariantProps<typeof tabsTriggerVariants>, 'variant' | 'size' | 'fitted'> {}\n\n// Line variant: active indicator color\nconst lineColorClasses = {\n default: 'data-[state=active]:border-foreground',\n primary: 'data-[state=active]:border-primary',\n} as const\n\n// Enclosed variant: top border-radius\nconst enclosedRadiusClasses = {\n none: 'rounded-t-none',\n sm: 'rounded-t-sm',\n base: 'rounded-t',\n md: 'rounded-t-md',\n lg: 'rounded-t-lg',\n xl: 'rounded-t-xl',\n} as const\n\n// Pill variant: container radius (applied to TabsList, matches Segmented scale)\nconst pillListRadiusClasses = {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n '3xl': 'rounded-3xl',\n full: 'rounded-full',\n} as const\n\n// Pill variant: item radius (one step smaller than container, matches Segmented item scale)\nconst pillItemRadiusClasses = {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-md',\n xl: 'rounded-lg',\n '2xl': 'rounded-xl',\n '3xl': 'rounded-2xl',\n full: 'rounded-full',\n} as const\n\nconst TabsTrigger = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Trigger>,\n TabsTriggerProps\n>(({ className, children, ...props }, ref) => {\n const { variant, size, fitted, color, radius } = useTabsStyleContext()\n const resolvedSize = size || 'default'\n\n return (\n <TabsPrimitive.Trigger\n ref={ref}\n className={cn(\n tabsTriggerVariants({ variant, size: resolvedSize, fitted }),\n triggerIconSizeClasses[resolvedSize],\n variant === 'line' && lineColorClasses[color || 'default'],\n variant === 'enclosed' && enclosedRadiusClasses[(radius || 'md') as keyof typeof enclosedRadiusClasses],\n variant === 'pill' && pillItemRadiusClasses[radius || 'md'],\n className\n )}\n {...props}\n >\n {children}\n </TabsPrimitive.Trigger>\n )\n})\nTabsTrigger.displayName = 'TabsTrigger'\n\n// ─── TabsContent ─────────────────────────────────────────────\n\nexport interface TabsContentProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content> {}\n\nconst TabsContent = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Content>,\n TabsContentProps\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.Content\n ref={ref}\n className={cn(\n 'mt-4 focus-visible:focus-ring',\n className\n )}\n {...props}\n />\n))\nTabsContent.displayName = 'TabsContent'\n\n// ─── Tabs (Root) ─────────────────────────────────────────────\n\nconst Tabs = TabsPrimitive.Root\n\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n tabsListVariants,\n tabsTriggerVariants,\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/ui/tabs.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as TabsPrimitive from '@radix-ui/react-tabs'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\n// Context to pass style props from TabsList to TabsTrigger\ntype TabsStyleContextValue = {\n variant?: 'line' | 'enclosed' | 'pill'\n size?: 'sm' | 'md' | 'default' | 'lg'\n fitted?: boolean\n color?: 'default' | 'primary'\n radius?: 'none' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\nconst TabsStyleContext = React.createContext<TabsStyleContextValue>({})\nconst useTabsStyleContext = () => React.useContext(TabsStyleContext)\n\n// ─── TabsList ────────────────────────────────────────────────\n\nconst tabsListVariants = cva(\n 'inline-flex items-center text-text-subtle',\n {\n variants: {\n variant: {\n line: 'border-b border-border bg-transparent gap-0',\n enclosed: 'border-b border-border bg-transparent gap-0',\n pill: 'bg-background-muted p-1 gap-1',\n },\n fitted: {\n true: 'w-full',\n false: '',\n },\n },\n defaultVariants: {\n variant: 'line',\n fitted: false,\n },\n }\n)\n\nexport interface TabsListProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>,\n VariantProps<typeof tabsListVariants> {\n size?: 'sm' | 'md' | 'default' | 'lg'\n /** Indicator color for line variant */\n color?: 'default' | 'primary'\n /** Top border-radius for enclosed variant, container radius for pill variant */\n radius?: 'none' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\n\nconst TabsList = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.List>,\n TabsListProps\n>(({ className, variant, size, fitted, color, radius, ...props }, ref) => {\n const resolvedVariant = variant || 'line'\n return (\n <TabsStyleContext.Provider value={{ variant: resolvedVariant, size: size || 'default', fitted: fitted ?? false, color: color || 'default', radius: radius || 'md' }}>\n <TabsPrimitive.List\n ref={ref}\n className={cn(\n tabsListVariants({ variant, fitted }),\n resolvedVariant === 'pill' && pillListRadiusClasses[radius || 'md'],\n className\n )}\n {...props}\n />\n </TabsStyleContext.Provider>\n )\n})\nTabsList.displayName = 'TabsList'\n\n// ─── TabsTrigger ─────────────────────────────────────────────\n\nconst tabsTriggerVariants = cva(\n [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap',\n 'transition-all duration-micro ease-out cursor-pointer',\n // Keyboard-only focus ring: see pointer tracking in TabsTrigger\n '[&:focus-visible:not([data-pointer-focus])]:focus-ring',\n 'disabled:pointer-events-none disabled:text-text-subtle disabled:opacity-50',\n ].join(' '),\n {\n variants: {\n variant: {\n line: [\n 'border-b-2 border-transparent -mb-px',\n 'hover:text-foreground hover:border-border',\n 'data-[state=active]:text-foreground data-[state=active]:font-semibold',\n ].join(' '),\n enclosed: [\n 'border border-transparent -mb-px',\n 'hover:text-foreground',\n 'data-[state=active]:text-foreground data-[state=active]:font-semibold data-[state=active]:bg-background',\n 'data-[state=active]:border-border data-[state=active]:border-b-background',\n ].join(' '),\n pill: [\n 'hover:text-foreground',\n 'data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:font-semibold data-[state=active]:shadow-sm',\n ].join(' '),\n },\n size: {\n sm: 'h-8 text-sm', // 32px, 13px\n md: 'h-9 text-sm', // 36px, 13px\n default: 'h-10 text-md', // 40px, 14px\n lg: 'h-12 text-base', // 48px, 16px\n },\n fitted: {\n true: 'flex-1',\n false: '',\n },\n },\n compoundVariants: [\n // Padding per variant × size\n { variant: 'line', size: 'sm', className: 'px-3' },\n { variant: 'line', size: 'md', className: 'px-3.5' },\n { variant: 'line', size: 'default', className: 'px-4' },\n { variant: 'line', size: 'lg', className: 'px-6' },\n { variant: 'enclosed', size: 'sm', className: 'px-3' },\n { variant: 'enclosed', size: 'md', className: 'px-3.5' },\n { variant: 'enclosed', size: 'default', className: 'px-4' },\n { variant: 'enclosed', size: 'lg', className: 'px-6' },\n // Pill: reduced height + Segmented-matching font/padding\n { variant: 'pill', size: 'sm', className: 'h-6 text-xs px-3.5' },\n { variant: 'pill', size: 'md', className: 'h-7 text-sm px-3.5' },\n { variant: 'pill', size: 'default', className: 'h-8 text-sm px-4' },\n { variant: 'pill', size: 'lg', className: 'h-10 text-md px-6' },\n ],\n defaultVariants: {\n variant: 'line',\n size: 'default',\n fitted: false,\n },\n }\n)\n\n// Icon size mapping for tabs (same as Button icon+text pattern)\nconst triggerIconSizeClasses = {\n sm: '[&>svg]:icon-xs', // 14px\n md: '[&>svg]:icon-sm', // 16px\n default: '[&>svg]:icon-sm', // 16px\n lg: '[&>svg]:icon-sm', // 16px\n} as const\n\nexport interface TabsTriggerProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>,\n Omit<VariantProps<typeof tabsTriggerVariants>, 'variant' | 'size' | 'fitted'> {}\n\n// Line variant: active indicator color\nconst lineColorClasses = {\n default: 'data-[state=active]:border-foreground',\n primary: 'data-[state=active]:border-primary',\n} as const\n\n// Enclosed variant: top border-radius\nconst enclosedRadiusClasses = {\n none: 'rounded-t-none',\n sm: 'rounded-t-sm',\n base: 'rounded-t',\n md: 'rounded-t-md',\n lg: 'rounded-t-lg',\n xl: 'rounded-t-xl',\n} as const\n\n// Pill variant: container radius (applied to TabsList, matches Segmented scale)\nconst pillListRadiusClasses = {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n '3xl': 'rounded-3xl',\n full: 'rounded-full',\n} as const\n\n// Pill variant: item radius (one step smaller than container, matches Segmented item scale)\nconst pillItemRadiusClasses = {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-md',\n xl: 'rounded-lg',\n '2xl': 'rounded-xl',\n '3xl': 'rounded-2xl',\n full: 'rounded-full',\n} as const\n\nconst TabsTrigger = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Trigger>,\n TabsTriggerProps\n>(({ className, children, onPointerDown, onKeyDown, onBlur, ...props }, ref) => {\n const { variant, size, fitted, color, radius } = useTabsStyleContext()\n const resolvedSize = size || 'default'\n // Radix Tabs 1.2+ calls focus() on mouse down, so :focus-visible matches after any\n // earlier keyboard input. Mark pointer-initiated focus to keep the ring keyboard-only.\n const [pointerFocus, setPointerFocus] = React.useState(false)\n\n return (\n <TabsPrimitive.Trigger\n ref={ref}\n className={cn(\n tabsTriggerVariants({ variant, size: resolvedSize, fitted }),\n triggerIconSizeClasses[resolvedSize],\n variant === 'line' && lineColorClasses[color || 'default'],\n variant === 'enclosed' && enclosedRadiusClasses[(radius || 'md') as keyof typeof enclosedRadiusClasses],\n variant === 'pill' && pillItemRadiusClasses[radius || 'md'],\n className\n )}\n data-pointer-focus={pointerFocus ? '' : undefined}\n onPointerDown={(event) => {\n setPointerFocus(true)\n onPointerDown?.(event)\n }}\n onKeyDown={(event) => {\n setPointerFocus(false)\n onKeyDown?.(event)\n }}\n onBlur={(event) => {\n setPointerFocus(false)\n onBlur?.(event)\n }}\n {...props}\n >\n {children}\n </TabsPrimitive.Trigger>\n )\n})\nTabsTrigger.displayName = 'TabsTrigger'\n\n// ─── TabsContent ─────────────────────────────────────────────\n\nexport interface TabsContentProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content> {}\n\nconst TabsContent = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Content>,\n TabsContentProps\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.Content\n ref={ref}\n className={cn(\n 'mt-4 focus-visible:focus-ring',\n className\n )}\n {...props}\n />\n))\nTabsContent.displayName = 'TabsContent'\n\n// ─── Tabs (Root) ─────────────────────────────────────────────\n\nconst Tabs = TabsPrimitive.Root\n\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n tabsListVariants,\n tabsTriggerVariants,\n}\n"],"mappings":"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","names":[]}
@@ -1,4 +1,5 @@
1
1
  "use client";
2
+ import { jsx } from "react/jsx-runtime";
2
3
  import * as React from "react";
3
4
  import * as TabsPrimitive from "@radix-ui/react-tabs";
4
5
  import { cva } from "class-variance-authority";
@@ -27,7 +28,7 @@ const tabsListVariants = cva(
27
28
  );
28
29
  const TabsList = React.forwardRef(({ className, variant, size, fitted, color, radius, ...props }, ref) => {
29
30
  const resolvedVariant = variant || "line";
30
- return /* @__PURE__ */ React.createElement(TabsStyleContext.Provider, { value: { variant: resolvedVariant, size: size || "default", fitted: fitted ?? false, color: color || "default", radius: radius || "md" } }, /* @__PURE__ */ React.createElement(
31
+ return /* @__PURE__ */ jsx(TabsStyleContext.Provider, { value: { variant: resolvedVariant, size: size || "default", fitted: fitted ?? false, color: color || "default", radius: radius || "md" }, children: /* @__PURE__ */ jsx(
31
32
  TabsPrimitive.List,
32
33
  {
33
34
  ref,
@@ -38,14 +39,15 @@ const TabsList = React.forwardRef(({ className, variant, size, fitted, color, ra
38
39
  ),
39
40
  ...props
40
41
  }
41
- ));
42
+ ) });
42
43
  });
43
44
  TabsList.displayName = "TabsList";
44
45
  const tabsTriggerVariants = cva(
45
46
  [
46
47
  "inline-flex items-center justify-center gap-2 whitespace-nowrap",
47
48
  "transition-all duration-micro ease-out cursor-pointer",
48
- "focus-visible:focus-ring",
49
+ // Keyboard-only focus ring: see pointer tracking in TabsTrigger
50
+ "[&:focus-visible:not([data-pointer-focus])]:focus-ring",
49
51
  "disabled:pointer-events-none disabled:text-text-subtle disabled:opacity-50"
50
52
  ].join(" "),
51
53
  {
@@ -149,10 +151,11 @@ const pillItemRadiusClasses = {
149
151
  "3xl": "rounded-2xl",
150
152
  full: "rounded-full"
151
153
  };
152
- const TabsTrigger = React.forwardRef(({ className, children, ...props }, ref) => {
154
+ const TabsTrigger = React.forwardRef(({ className, children, onPointerDown, onKeyDown, onBlur, ...props }, ref) => {
153
155
  const { variant, size, fitted, color, radius } = useTabsStyleContext();
154
156
  const resolvedSize = size || "default";
155
- return /* @__PURE__ */ React.createElement(
157
+ const [pointerFocus, setPointerFocus] = React.useState(false);
158
+ return /* @__PURE__ */ jsx(
156
159
  TabsPrimitive.Trigger,
157
160
  {
158
161
  ref,
@@ -164,13 +167,26 @@ const TabsTrigger = React.forwardRef(({ className, children, ...props }, ref) =>
164
167
  variant === "pill" && pillItemRadiusClasses[radius || "md"],
165
168
  className
166
169
  ),
167
- ...props
168
- },
169
- children
170
+ "data-pointer-focus": pointerFocus ? "" : void 0,
171
+ onPointerDown: (event) => {
172
+ setPointerFocus(true);
173
+ onPointerDown?.(event);
174
+ },
175
+ onKeyDown: (event) => {
176
+ setPointerFocus(false);
177
+ onKeyDown?.(event);
178
+ },
179
+ onBlur: (event) => {
180
+ setPointerFocus(false);
181
+ onBlur?.(event);
182
+ },
183
+ ...props,
184
+ children
185
+ }
170
186
  );
171
187
  });
172
188
  TabsTrigger.displayName = "TabsTrigger";
173
- const TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
189
+ const TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
174
190
  TabsPrimitive.Content,
175
191
  {
176
192
  ref,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/tabs.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as TabsPrimitive from '@radix-ui/react-tabs'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\n// Context to pass style props from TabsList to TabsTrigger\ntype TabsStyleContextValue = {\n variant?: 'line' | 'enclosed' | 'pill'\n size?: 'sm' | 'md' | 'default' | 'lg'\n fitted?: boolean\n color?: 'default' | 'primary'\n radius?: 'none' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\nconst TabsStyleContext = React.createContext<TabsStyleContextValue>({})\nconst useTabsStyleContext = () => React.useContext(TabsStyleContext)\n\n// ─── TabsList ────────────────────────────────────────────────\n\nconst tabsListVariants = cva(\n 'inline-flex items-center text-text-subtle',\n {\n variants: {\n variant: {\n line: 'border-b border-border bg-transparent gap-0',\n enclosed: 'border-b border-border bg-transparent gap-0',\n pill: 'bg-background-muted p-1 gap-1',\n },\n fitted: {\n true: 'w-full',\n false: '',\n },\n },\n defaultVariants: {\n variant: 'line',\n fitted: false,\n },\n }\n)\n\nexport interface TabsListProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>,\n VariantProps<typeof tabsListVariants> {\n size?: 'sm' | 'md' | 'default' | 'lg'\n /** Indicator color for line variant */\n color?: 'default' | 'primary'\n /** Top border-radius for enclosed variant, container radius for pill variant */\n radius?: 'none' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\n\nconst TabsList = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.List>,\n TabsListProps\n>(({ className, variant, size, fitted, color, radius, ...props }, ref) => {\n const resolvedVariant = variant || 'line'\n return (\n <TabsStyleContext.Provider value={{ variant: resolvedVariant, size: size || 'default', fitted: fitted ?? false, color: color || 'default', radius: radius || 'md' }}>\n <TabsPrimitive.List\n ref={ref}\n className={cn(\n tabsListVariants({ variant, fitted }),\n resolvedVariant === 'pill' && pillListRadiusClasses[radius || 'md'],\n className\n )}\n {...props}\n />\n </TabsStyleContext.Provider>\n )\n})\nTabsList.displayName = 'TabsList'\n\n// ─── TabsTrigger ─────────────────────────────────────────────\n\nconst tabsTriggerVariants = cva(\n [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap',\n 'transition-all duration-micro ease-out cursor-pointer',\n 'focus-visible:focus-ring',\n 'disabled:pointer-events-none disabled:text-text-subtle disabled:opacity-50',\n ].join(' '),\n {\n variants: {\n variant: {\n line: [\n 'border-b-2 border-transparent -mb-px',\n 'hover:text-foreground hover:border-border',\n 'data-[state=active]:text-foreground data-[state=active]:font-semibold',\n ].join(' '),\n enclosed: [\n 'border border-transparent -mb-px',\n 'hover:text-foreground',\n 'data-[state=active]:text-foreground data-[state=active]:font-semibold data-[state=active]:bg-background',\n 'data-[state=active]:border-border data-[state=active]:border-b-background',\n ].join(' '),\n pill: [\n 'hover:text-foreground',\n 'data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:font-semibold data-[state=active]:shadow-sm',\n ].join(' '),\n },\n size: {\n sm: 'h-8 text-sm', // 32px, 13px\n md: 'h-9 text-sm', // 36px, 13px\n default: 'h-10 text-md', // 40px, 14px\n lg: 'h-12 text-base', // 48px, 16px\n },\n fitted: {\n true: 'flex-1',\n false: '',\n },\n },\n compoundVariants: [\n // Padding per variant × size\n { variant: 'line', size: 'sm', className: 'px-3' },\n { variant: 'line', size: 'md', className: 'px-3.5' },\n { variant: 'line', size: 'default', className: 'px-4' },\n { variant: 'line', size: 'lg', className: 'px-6' },\n { variant: 'enclosed', size: 'sm', className: 'px-3' },\n { variant: 'enclosed', size: 'md', className: 'px-3.5' },\n { variant: 'enclosed', size: 'default', className: 'px-4' },\n { variant: 'enclosed', size: 'lg', className: 'px-6' },\n // Pill: reduced height + Segmented-matching font/padding\n { variant: 'pill', size: 'sm', className: 'h-6 text-xs px-3.5' },\n { variant: 'pill', size: 'md', className: 'h-7 text-sm px-3.5' },\n { variant: 'pill', size: 'default', className: 'h-8 text-sm px-4' },\n { variant: 'pill', size: 'lg', className: 'h-10 text-md px-6' },\n ],\n defaultVariants: {\n variant: 'line',\n size: 'default',\n fitted: false,\n },\n }\n)\n\n// Icon size mapping for tabs (same as Button icon+text pattern)\nconst triggerIconSizeClasses = {\n sm: '[&>svg]:icon-xs', // 14px\n md: '[&>svg]:icon-sm', // 16px\n default: '[&>svg]:icon-sm', // 16px\n lg: '[&>svg]:icon-sm', // 16px\n} as const\n\nexport interface TabsTriggerProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>,\n Omit<VariantProps<typeof tabsTriggerVariants>, 'variant' | 'size' | 'fitted'> {}\n\n// Line variant: active indicator color\nconst lineColorClasses = {\n default: 'data-[state=active]:border-foreground',\n primary: 'data-[state=active]:border-primary',\n} as const\n\n// Enclosed variant: top border-radius\nconst enclosedRadiusClasses = {\n none: 'rounded-t-none',\n sm: 'rounded-t-sm',\n base: 'rounded-t',\n md: 'rounded-t-md',\n lg: 'rounded-t-lg',\n xl: 'rounded-t-xl',\n} as const\n\n// Pill variant: container radius (applied to TabsList, matches Segmented scale)\nconst pillListRadiusClasses = {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n '3xl': 'rounded-3xl',\n full: 'rounded-full',\n} as const\n\n// Pill variant: item radius (one step smaller than container, matches Segmented item scale)\nconst pillItemRadiusClasses = {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-md',\n xl: 'rounded-lg',\n '2xl': 'rounded-xl',\n '3xl': 'rounded-2xl',\n full: 'rounded-full',\n} as const\n\nconst TabsTrigger = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Trigger>,\n TabsTriggerProps\n>(({ className, children, ...props }, ref) => {\n const { variant, size, fitted, color, radius } = useTabsStyleContext()\n const resolvedSize = size || 'default'\n\n return (\n <TabsPrimitive.Trigger\n ref={ref}\n className={cn(\n tabsTriggerVariants({ variant, size: resolvedSize, fitted }),\n triggerIconSizeClasses[resolvedSize],\n variant === 'line' && lineColorClasses[color || 'default'],\n variant === 'enclosed' && enclosedRadiusClasses[(radius || 'md') as keyof typeof enclosedRadiusClasses],\n variant === 'pill' && pillItemRadiusClasses[radius || 'md'],\n className\n )}\n {...props}\n >\n {children}\n </TabsPrimitive.Trigger>\n )\n})\nTabsTrigger.displayName = 'TabsTrigger'\n\n// ─── TabsContent ─────────────────────────────────────────────\n\nexport interface TabsContentProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content> {}\n\nconst TabsContent = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Content>,\n TabsContentProps\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.Content\n ref={ref}\n className={cn(\n 'mt-4 focus-visible:focus-ring',\n className\n )}\n {...props}\n />\n))\nTabsContent.displayName = 'TabsContent'\n\n// ─── Tabs (Root) ─────────────────────────────────────────────\n\nconst Tabs = TabsPrimitive.Root\n\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n tabsListVariants,\n tabsTriggerVariants,\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/ui/tabs.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as TabsPrimitive from '@radix-ui/react-tabs'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\n// Context to pass style props from TabsList to TabsTrigger\ntype TabsStyleContextValue = {\n variant?: 'line' | 'enclosed' | 'pill'\n size?: 'sm' | 'md' | 'default' | 'lg'\n fitted?: boolean\n color?: 'default' | 'primary'\n radius?: 'none' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\nconst TabsStyleContext = React.createContext<TabsStyleContextValue>({})\nconst useTabsStyleContext = () => React.useContext(TabsStyleContext)\n\n// ─── TabsList ────────────────────────────────────────────────\n\nconst tabsListVariants = cva(\n 'inline-flex items-center text-text-subtle',\n {\n variants: {\n variant: {\n line: 'border-b border-border bg-transparent gap-0',\n enclosed: 'border-b border-border bg-transparent gap-0',\n pill: 'bg-background-muted p-1 gap-1',\n },\n fitted: {\n true: 'w-full',\n false: '',\n },\n },\n defaultVariants: {\n variant: 'line',\n fitted: false,\n },\n }\n)\n\nexport interface TabsListProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>,\n VariantProps<typeof tabsListVariants> {\n size?: 'sm' | 'md' | 'default' | 'lg'\n /** Indicator color for line variant */\n color?: 'default' | 'primary'\n /** Top border-radius for enclosed variant, container radius for pill variant */\n radius?: 'none' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\n\nconst TabsList = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.List>,\n TabsListProps\n>(({ className, variant, size, fitted, color, radius, ...props }, ref) => {\n const resolvedVariant = variant || 'line'\n return (\n <TabsStyleContext.Provider value={{ variant: resolvedVariant, size: size || 'default', fitted: fitted ?? false, color: color || 'default', radius: radius || 'md' }}>\n <TabsPrimitive.List\n ref={ref}\n className={cn(\n tabsListVariants({ variant, fitted }),\n resolvedVariant === 'pill' && pillListRadiusClasses[radius || 'md'],\n className\n )}\n {...props}\n />\n </TabsStyleContext.Provider>\n )\n})\nTabsList.displayName = 'TabsList'\n\n// ─── TabsTrigger ─────────────────────────────────────────────\n\nconst tabsTriggerVariants = cva(\n [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap',\n 'transition-all duration-micro ease-out cursor-pointer',\n // Keyboard-only focus ring: see pointer tracking in TabsTrigger\n '[&:focus-visible:not([data-pointer-focus])]:focus-ring',\n 'disabled:pointer-events-none disabled:text-text-subtle disabled:opacity-50',\n ].join(' '),\n {\n variants: {\n variant: {\n line: [\n 'border-b-2 border-transparent -mb-px',\n 'hover:text-foreground hover:border-border',\n 'data-[state=active]:text-foreground data-[state=active]:font-semibold',\n ].join(' '),\n enclosed: [\n 'border border-transparent -mb-px',\n 'hover:text-foreground',\n 'data-[state=active]:text-foreground data-[state=active]:font-semibold data-[state=active]:bg-background',\n 'data-[state=active]:border-border data-[state=active]:border-b-background',\n ].join(' '),\n pill: [\n 'hover:text-foreground',\n 'data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:font-semibold data-[state=active]:shadow-sm',\n ].join(' '),\n },\n size: {\n sm: 'h-8 text-sm', // 32px, 13px\n md: 'h-9 text-sm', // 36px, 13px\n default: 'h-10 text-md', // 40px, 14px\n lg: 'h-12 text-base', // 48px, 16px\n },\n fitted: {\n true: 'flex-1',\n false: '',\n },\n },\n compoundVariants: [\n // Padding per variant × size\n { variant: 'line', size: 'sm', className: 'px-3' },\n { variant: 'line', size: 'md', className: 'px-3.5' },\n { variant: 'line', size: 'default', className: 'px-4' },\n { variant: 'line', size: 'lg', className: 'px-6' },\n { variant: 'enclosed', size: 'sm', className: 'px-3' },\n { variant: 'enclosed', size: 'md', className: 'px-3.5' },\n { variant: 'enclosed', size: 'default', className: 'px-4' },\n { variant: 'enclosed', size: 'lg', className: 'px-6' },\n // Pill: reduced height + Segmented-matching font/padding\n { variant: 'pill', size: 'sm', className: 'h-6 text-xs px-3.5' },\n { variant: 'pill', size: 'md', className: 'h-7 text-sm px-3.5' },\n { variant: 'pill', size: 'default', className: 'h-8 text-sm px-4' },\n { variant: 'pill', size: 'lg', className: 'h-10 text-md px-6' },\n ],\n defaultVariants: {\n variant: 'line',\n size: 'default',\n fitted: false,\n },\n }\n)\n\n// Icon size mapping for tabs (same as Button icon+text pattern)\nconst triggerIconSizeClasses = {\n sm: '[&>svg]:icon-xs', // 14px\n md: '[&>svg]:icon-sm', // 16px\n default: '[&>svg]:icon-sm', // 16px\n lg: '[&>svg]:icon-sm', // 16px\n} as const\n\nexport interface TabsTriggerProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>,\n Omit<VariantProps<typeof tabsTriggerVariants>, 'variant' | 'size' | 'fitted'> {}\n\n// Line variant: active indicator color\nconst lineColorClasses = {\n default: 'data-[state=active]:border-foreground',\n primary: 'data-[state=active]:border-primary',\n} as const\n\n// Enclosed variant: top border-radius\nconst enclosedRadiusClasses = {\n none: 'rounded-t-none',\n sm: 'rounded-t-sm',\n base: 'rounded-t',\n md: 'rounded-t-md',\n lg: 'rounded-t-lg',\n xl: 'rounded-t-xl',\n} as const\n\n// Pill variant: container radius (applied to TabsList, matches Segmented scale)\nconst pillListRadiusClasses = {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n '3xl': 'rounded-3xl',\n full: 'rounded-full',\n} as const\n\n// Pill variant: item radius (one step smaller than container, matches Segmented item scale)\nconst pillItemRadiusClasses = {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-md',\n xl: 'rounded-lg',\n '2xl': 'rounded-xl',\n '3xl': 'rounded-2xl',\n full: 'rounded-full',\n} as const\n\nconst TabsTrigger = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Trigger>,\n TabsTriggerProps\n>(({ className, children, onPointerDown, onKeyDown, onBlur, ...props }, ref) => {\n const { variant, size, fitted, color, radius } = useTabsStyleContext()\n const resolvedSize = size || 'default'\n // Radix Tabs 1.2+ calls focus() on mouse down, so :focus-visible matches after any\n // earlier keyboard input. Mark pointer-initiated focus to keep the ring keyboard-only.\n const [pointerFocus, setPointerFocus] = React.useState(false)\n\n return (\n <TabsPrimitive.Trigger\n ref={ref}\n className={cn(\n tabsTriggerVariants({ variant, size: resolvedSize, fitted }),\n triggerIconSizeClasses[resolvedSize],\n variant === 'line' && lineColorClasses[color || 'default'],\n variant === 'enclosed' && enclosedRadiusClasses[(radius || 'md') as keyof typeof enclosedRadiusClasses],\n variant === 'pill' && pillItemRadiusClasses[radius || 'md'],\n className\n )}\n data-pointer-focus={pointerFocus ? '' : undefined}\n onPointerDown={(event) => {\n setPointerFocus(true)\n onPointerDown?.(event)\n }}\n onKeyDown={(event) => {\n setPointerFocus(false)\n onKeyDown?.(event)\n }}\n onBlur={(event) => {\n setPointerFocus(false)\n onBlur?.(event)\n }}\n {...props}\n >\n {children}\n </TabsPrimitive.Trigger>\n )\n})\nTabsTrigger.displayName = 'TabsTrigger'\n\n// ─── TabsContent ─────────────────────────────────────────────\n\nexport interface TabsContentProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content> {}\n\nconst TabsContent = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Content>,\n TabsContentProps\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.Content\n ref={ref}\n className={cn(\n 'mt-4 focus-visible:focus-ring',\n className\n )}\n {...props}\n />\n))\nTabsContent.displayName = 'TabsContent'\n\n// ─── Tabs (Root) ─────────────────────────────────────────────\n\nconst Tabs = TabsPrimitive.Root\n\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n tabsListVariants,\n tabsTriggerVariants,\n}\n"],"mappings":"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","names":[]}
@@ -33,6 +33,7 @@ __export(textarea_exports, {
33
33
  textareaVariants: () => textareaVariants
34
34
  });
35
35
  module.exports = __toCommonJS(textarea_exports);
36
+ var import_jsx_runtime = require("react/jsx-runtime");
36
37
  var React = __toESM(require("react"));
37
38
  var import_class_variance_authority = require("class-variance-authority");
38
39
  var import_utils = require("../../lib/utils");
@@ -150,7 +151,7 @@ const Textarea = React.forwardRef(
150
151
  const ariaDescribedBy = fieldContext ? [
151
152
  resolvedError ? `${fieldContext.id}-error` : null
152
153
  ].filter(Boolean).join(" ") || void 0 : void 0;
153
- return /* @__PURE__ */ React.createElement(
154
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
154
155
  "textarea",
155
156
  {
156
157
  id: textareaId,