@fanvue/ui 2.17.0 → 2.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/Checkbox/Checkbox.cjs +19 -6
- package/dist/cjs/components/Checkbox/Checkbox.cjs.map +1 -1
- package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs +189 -11
- package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs.map +1 -1
- package/dist/cjs/components/Icons/{AiCallIcon.cjs → AICallIcon.cjs} +1 -1
- package/dist/cjs/components/Icons/{AiCallIcon.cjs.map → AICallIcon.cjs.map} +1 -1
- package/dist/cjs/components/Icons/CardIcon.cjs +8 -7
- package/dist/cjs/components/Icons/CardIcon.cjs.map +1 -1
- package/dist/cjs/components/Icons/Pin2Icon.cjs +101 -0
- package/dist/cjs/components/Icons/Pin2Icon.cjs.map +1 -0
- package/dist/cjs/components/Icons/PrivacyIcon.cjs +1 -1
- package/dist/cjs/components/Icons/PrivacyIcon.cjs.map +1 -1
- package/dist/cjs/components/Icons/ShareIcon.cjs +1 -1
- package/dist/cjs/components/Icons/ShareIcon.cjs.map +1 -1
- package/dist/cjs/components/Icons/TickCircleIcon.cjs +1 -1
- package/dist/cjs/components/Icons/TickCircleIcon.cjs.map +1 -1
- package/dist/cjs/components/Icons/ToolsIcon.cjs +1 -1
- package/dist/cjs/components/Icons/ToolsIcon.cjs.map +1 -1
- package/dist/cjs/components/Table/Table.cjs +66 -46
- package/dist/cjs/components/Table/Table.cjs.map +1 -1
- package/dist/cjs/components/Table/TablePagination.cjs +7 -7
- package/dist/cjs/components/Table/TablePagination.cjs.map +1 -1
- package/dist/cjs/index.cjs +8 -2
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/components/Checkbox/Checkbox.mjs +19 -6
- package/dist/components/Checkbox/Checkbox.mjs.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.mjs +189 -11
- package/dist/components/DropdownMenu/DropdownMenu.mjs.map +1 -1
- package/dist/components/Icons/{AiCallIcon.mjs → AICallIcon.mjs} +1 -1
- package/dist/components/Icons/{AiCallIcon.mjs.map → AICallIcon.mjs.map} +1 -1
- package/dist/components/Icons/CardIcon.mjs +8 -7
- package/dist/components/Icons/CardIcon.mjs.map +1 -1
- package/dist/components/Icons/Pin2Icon.mjs +84 -0
- package/dist/components/Icons/Pin2Icon.mjs.map +1 -0
- package/dist/components/Icons/PrivacyIcon.mjs +1 -1
- package/dist/components/Icons/PrivacyIcon.mjs.map +1 -1
- package/dist/components/Icons/ShareIcon.mjs +1 -1
- package/dist/components/Icons/ShareIcon.mjs.map +1 -1
- package/dist/components/Icons/TickCircleIcon.mjs +1 -1
- package/dist/components/Icons/TickCircleIcon.mjs.map +1 -1
- package/dist/components/Icons/ToolsIcon.mjs +1 -1
- package/dist/components/Icons/ToolsIcon.mjs.map +1 -1
- package/dist/components/Table/Table.mjs +66 -46
- package/dist/components/Table/Table.mjs.map +1 -1
- package/dist/components/Table/TablePagination.mjs +7 -7
- package/dist/components/Table/TablePagination.mjs.map +1 -1
- package/dist/index.d.ts +237 -31
- package/dist/index.mjs +9 -3
- package/dist/index.mjs.map +1 -1
- package/dist/styles/base.css +2 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.cjs","sources":["../../../../src/components/Table/Table.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { Select, SelectContent, SelectItem } from \"../Select/Select\";\n\n/** Row density for body cells — `md` (60px min height) or `lg` (80px). */\nexport type TableSize = \"md\" | \"lg\";\n\nexport interface TableCardProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Row density applied to {@link TableCell} descendants. @default \"md\" */\n size?: TableSize;\n}\n\nconst TableSizeContext = React.createContext<TableSize>(\"md\");\n\nfunction useTableSize(): TableSize {\n return React.useContext(TableSizeContext);\n}\n\n/**\n * Surface wrapper for data tables: rounded container, spacing, and size\n * context for {@link TableCell} descendants. Compose with {@link TableScrollArea},\n * {@link Table}, {@link TableHeader}, {@link TableBody}, {@link TableRow},\n * {@link TableHead}, and {@link TableCell}.\n *\n * @example\n * ```tsx\n * <TableCard size=\"md\">\n * <TableScrollArea>\n * <Table>\n * <TableHeader>\n * <TableRow>\n * <TableHead>Name</TableHead>\n * </TableRow>\n * </TableHeader>\n * <TableBody>\n * <TableRow>\n * <TableCell>Jane Doe</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n * </TableScrollArea>\n * </TableCard>\n * ```\n */\nexport const TableCard = React.forwardRef<HTMLDivElement, TableCardProps>(\n ({ className, size = \"md\", ...props }, ref) => {\n return (\n <TableSizeContext.Provider value={size}>\n <div\n ref={ref}\n className={cn(\n \"isolate flex flex-col gap-4 overflow-hidden rounded-md bg-bg-primary pb-4\",\n className,\n )}\n {...props}\n />\n </TableSizeContext.Provider>\n );\n },\n);\nTableCard.displayName = \"TableCard\";\n\nexport interface TableToolbarProps extends React.HTMLAttributes<HTMLDivElement> {}\n\n/**\n * Optional toolbar row above the table (e.g. bulk selection actions).\n */\nexport const TableToolbar = React.forwardRef<HTMLDivElement, TableToolbarProps>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n \"flex flex-wrap items-center gap-4 rounded-t-md bg-bg-primary px-6\",\n className,\n )}\n {...props}\n />\n );\n },\n);\nTableToolbar.displayName = \"TableToolbar\";\n\nexport interface TableScrollAreaProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Rounds the top of the table block to match {@link TableCard}. Set `false` when {@link TableToolbar} is above this scroll area. @default true */\n roundTop?: boolean;\n}\n\n/**\n * Horizontal scroll container for wide tables. Uses an inner scrollport so the\n * table respects the card radius (plain `overflow-x-auto` on the table\n * wrapper often loses rounded corners with `border-collapse`).\n */\nexport const TableScrollArea = React.forwardRef<HTMLDivElement, TableScrollAreaProps>(\n ({ className, roundTop = true, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n \"relative w-full min-w-0 overflow-hidden\",\n roundTop && \"rounded-t-md\",\n className,\n )}\n {...props}\n >\n <div className=\"overflow-x-auto\">{children}</div>\n </div>\n );\n },\n);\nTableScrollArea.displayName = \"TableScrollArea\";\n\nexport interface TableProps extends React.TableHTMLAttributes<HTMLTableElement> {}\n\n/**\n * Semantic `<table>` element. Place inside {@link TableScrollArea}.\n */\nexport const Table = React.forwardRef<HTMLTableElement, TableProps>(\n ({ className, ...props }, ref) => {\n return (\n <table\n ref={ref}\n className={cn(\n \"w-full caption-bottom border-separate border-spacing-0 text-left\",\n className,\n )}\n {...props}\n />\n );\n },\n);\nTable.displayName = \"Table\";\n\nexport interface TableHeaderProps extends React.HTMLAttributes<HTMLTableSectionElement> {}\n\nexport const TableHeader = React.forwardRef<HTMLTableSectionElement, TableHeaderProps>(\n ({ className, ...props }, ref) => {\n return (\n <thead\n ref={ref}\n className={cn(\n \"[&_tr:first-child_th:first-child]:rounded-tl-md [&_tr:first-child_th:last-child]:rounded-tr-md\",\n className,\n )}\n {...props}\n />\n );\n },\n);\nTableHeader.displayName = \"TableHeader\";\n\nexport interface TableBodyProps extends React.HTMLAttributes<HTMLTableSectionElement> {}\n\nexport const TableBody = React.forwardRef<HTMLTableSectionElement, TableBodyProps>(\n ({ className, ...props }, ref) => {\n return <tbody ref={ref} className={cn(className)} {...props} />;\n },\n);\nTableBody.displayName = \"TableBody\";\n\nexport interface TableFooterProps extends React.HTMLAttributes<HTMLTableSectionElement> {}\n\nexport const TableFooter = React.forwardRef<HTMLTableSectionElement, TableFooterProps>(\n ({ className, ...props }, ref) => {\n return <tfoot ref={ref} className={cn(className)} {...props} />;\n },\n);\nTableFooter.displayName = \"TableFooter\";\n\nexport interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {}\n\nexport const TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(\n ({ className, ...props }, ref) => {\n return <tr ref={ref} className={cn(className)} {...props} />;\n },\n);\nTableRow.displayName = \"TableRow\";\n\n/** Column layout preset for {@link TableHead}. */\nexport type TableHeadIntent = \"default\" | \"checkbox\" | \"sort\" | \"leading\";\n\nconst HEAD_INTENT_CLASSES: Record<TableHeadIntent, string> = {\n default: \"text-left\",\n checkbox: \"w-8 min-w-8 max-w-8 text-center\",\n sort: \"text-right\",\n leading: \"min-w-0 w-2/5 text-left\",\n};\n\nexport interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {\n /** Layout preset for common column types. @default \"default\" */\n intent?: TableHeadIntent;\n}\n\nexport const TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(\n ({ className, intent = \"default\", scope = \"col\", ...props }, ref) => {\n return (\n <th\n ref={ref}\n scope={scope}\n className={cn(\n \"typography-semibold-body-sm box-border h-8 min-h-8 bg-surface-secondary px-2 py-2 align-middle text-content-primary\",\n HEAD_INTENT_CLASSES[intent],\n className,\n )}\n {...props}\n />\n );\n },\n);\nTableHead.displayName = \"TableHead\";\n\nconst CELL_MIN_HEIGHT: Record<TableSize, string> = {\n md: \"min-h-[60px]\",\n lg: \"min-h-[80px]\",\n};\n\n/** Bottom border and padding preset for body cells (Figma table cell component). */\nexport type TableCellVariant = \"default\" | \"chip\" | \"pillProgress\";\n\nconst CELL_VARIANT_CLASSES: Record<TableCellVariant, string> = {\n default: \"border-border-primary border-b px-2 py-2\",\n chip: \"border-border-primary border-b px-2 py-2\",\n pillProgress: \"border-border-primary border-b px-4 py-2\",\n};\n\n/** Layout / typography preset for {@link TableCell} (orthogonal to {@link TableCellVariant}). */\nexport type TableCellIntent = \"default\" | \"checkbox\" | \"stacked\" | \"multiline\" | \"sideLabel\";\n\nconst CELL_INTENT_CLASSES: Record<TableCellIntent, string> = {\n default: \"\",\n checkbox: \"text-center\",\n stacked: \"align-top\",\n multiline: \"max-w-[240px]\",\n sideLabel: \"\",\n};\n\nexport interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {\n /** `pillProgress` uses wider horizontal padding; row dividers match the default weight for visibility. @default \"default\" */\n cellVariant?: TableCellVariant;\n /** Alignment and typography preset for common cell types. @default \"default\" */\n intent?: TableCellIntent;\n}\n\nexport const TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(\n ({ className, cellVariant = \"default\", intent = \"default\", ...props }, ref) => {\n const size = useTableSize();\n const typo =\n intent === \"sideLabel\" ? \"typography-semibold-body-md\" : \"typography-regular-body-md\";\n return (\n <td\n ref={ref}\n className={cn(\n typo,\n \"align-middle text-content-primary\",\n CELL_VARIANT_CLASSES[cellVariant],\n CELL_MIN_HEIGHT[size],\n CELL_INTENT_CLASSES[intent],\n className,\n )}\n {...props}\n />\n );\n },\n);\nTableCell.displayName = \"TableCell\";\n\nexport interface TableCellGroupProps extends React.HTMLAttributes<HTMLDivElement> {}\n\n/**\n * Horizontal group for icons, chips, and metadata inside a {@link TableCell} (Figma `gap-[10px]`).\n */\nexport const TableCellGroup = React.forwardRef<HTMLDivElement, TableCellGroupProps>(\n ({ className, ...props }, ref) => {\n return <div ref={ref} className={cn(\"flex items-center gap-2.5\", className)} {...props} />;\n },\n);\nTableCellGroup.displayName = \"TableCellGroup\";\n\nexport interface TableMediaThumbnailProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"children\"> {\n /** Image URL. */\n src: string;\n /** Alt text for the image. @default \"\" */\n alt?: string;\n /** Applies the table’s blurred-media treatment. @default false */\n blurred?: boolean;\n /** `center` uses the fixed media column width from the lg spec. @default \"start\" */\n align?: \"start\" | \"center\";\n}\n\n/**\n * Rounded thumbnail sized from {@link TableCard} `size` (`md` vs `lg`).\n */\nexport const TableMediaThumbnail = React.forwardRef<HTMLDivElement, TableMediaThumbnailProps>(\n ({ className, src, alt = \"\", blurred, align = \"start\", ...props }, ref) => {\n const tableSize = useTableSize();\n const frame =\n tableSize === \"lg\"\n ? \"h-[62px] w-11 overflow-hidden rounded-xs bg-neutral-alphas-200\"\n : \"h-10 w-[29px] overflow-hidden rounded-xs bg-neutral-alphas-200\";\n return (\n <div\n ref={ref}\n className={cn(\n align === \"center\" && \"flex w-16 shrink-0 justify-center\",\n align === \"start\" && \"inline-flex shrink-0\",\n )}\n >\n <div className={cn(frame, blurred && \"blur-[2px]\", className)} {...props}>\n <img alt={alt} className=\"size-full object-cover\" src={src} />\n </div>\n </div>\n );\n },\n);\nTableMediaThumbnail.displayName = \"TableMediaThumbnail\";\n\nexport interface TableStatusDotProps extends React.HTMLAttributes<HTMLDivElement> {}\n\n/**\n * Small status indicator dot for table cells (Figma status column).\n */\nexport const TableStatusDot = React.forwardRef<HTMLDivElement, TableStatusDotProps>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"size-2 shrink-0 rounded-full bg-info-content\", className)}\n {...props}\n />\n );\n },\n);\nTableStatusDot.displayName = \"TableStatusDot\";\n\nexport interface TableProgressTrackProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Fill width from 0–100. @default 0 */\n value?: number;\n}\n\n/**\n * Thin progress track used with badges in table cells (Figma pill + progress).\n * Renders with `role=\"progressbar\"` and a default `aria-label` of `\"Progress\"`.\n */\nexport const TableProgressTrack = React.forwardRef<HTMLDivElement, TableProgressTrackProps>(\n ({ className, value = 0, \"aria-label\": ariaLabel = \"Progress\", ...props }, ref) => {\n const width = Math.min(100, Math.max(0, value));\n const rounded = Math.round(width);\n return (\n <div\n ref={ref}\n role=\"progressbar\"\n aria-valuenow={rounded}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={ariaLabel}\n className={cn(\n \"relative h-1 w-full overflow-hidden rounded-full bg-neutral-alphas-200\",\n className,\n )}\n {...props}\n >\n <div\n className=\"absolute top-0 left-0 h-1 rounded-full bg-buttons-primary\"\n style={{ width: `${width}%` }}\n aria-hidden\n />\n </div>\n );\n },\n);\nTableProgressTrack.displayName = \"TableProgressTrack\";\n\nexport interface TablePillProgressLayoutProps extends React.HTMLAttributes<HTMLDivElement> {}\n\n/**\n * Vertical layout for pill label + {@link TableProgressTrack} in a cell.\n */\nexport const TablePillProgressLayout = React.forwardRef<\n HTMLDivElement,\n TablePillProgressLayoutProps\n>(({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"flex min-w-[120px] flex-col items-center gap-3\", className)}\n {...props}\n />\n );\n});\nTablePillProgressLayout.displayName = \"TablePillProgressLayout\";\n\nexport interface TableSortLabelProps extends React.HTMLAttributes<HTMLSpanElement> {\n children: React.ReactNode;\n}\n\n/**\n * Sortable column label with caption typography and a sort affordance.\n */\nexport const TableSortLabel = React.forwardRef<HTMLSpanElement, TableSortLabelProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <span ref={ref} className={cn(\"inline-flex items-center gap-2.5\", className)} {...props}>\n <span className=\"typography-semibold-body-sm\">{children}</span>\n <span className=\"text-content-secondary\" aria-hidden>\n ↕\n </span>\n </span>\n );\n },\n);\nTableSortLabel.displayName = \"TableSortLabel\";\n\nexport interface TableStackedTextProps {\n /** Primary line (semibold body). */\n title: React.ReactNode;\n /** Secondary line (caption, muted). */\n subtitle: React.ReactNode;\n}\n\n/**\n * Two-line primary + secondary text block for “cell + info” patterns.\n */\nexport function TableStackedText({ title, subtitle }: TableStackedTextProps) {\n return (\n <div className=\"flex flex-col gap-1\">\n <span className=\"typography-semibold-body-md\">{title}</span>\n <span className=\"typography-regular-body-sm text-content-secondary\">{subtitle}</span>\n </div>\n );\n}\n\nTableStackedText.displayName = \"TableStackedText\";\n\nexport interface TableLineClampProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Number of lines before ellipsis. @default 2 */\n lines?: 1 | 2 | 3;\n}\n\n/**\n * Clamps child text to a fixed number of lines inside a {@link TableCell}.\n */\nexport const TableLineClamp = React.forwardRef<HTMLDivElement, TableLineClampProps>(\n ({ className, lines = 2, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n lines === 1 && \"line-clamp-1\",\n lines === 2 && \"line-clamp-2\",\n lines === 3 && \"line-clamp-3\",\n className,\n )}\n {...props}\n />\n );\n },\n);\nTableLineClamp.displayName = \"TableLineClamp\";\n\nexport interface TableRowsPerPageSelectProps {\n /** Passed to the trigger for forms and labels. */\n id?: string;\n /** Accessible name for the trigger when no visible label. @default \"Rows per page\" */\n \"aria-label\"?: string;\n}\n\n/**\n * Rows-per-page {@link Select} styled for {@link TablePagination} (Figma field).\n */\nexport function TableRowsPerPageSelect(props: TableRowsPerPageSelectProps) {\n const { id, \"aria-label\": ariaLabel = \"Rows per page\" } = props;\n return (\n <Select\n defaultValue=\"10\"\n size=\"32\"\n aria-label={ariaLabel}\n className=\"w-[154px] [&_button]:rounded-xs [&_button]:border-transparent [&_button]:bg-transparent\"\n id={id}\n >\n <SelectContent>\n <SelectItem value=\"10\">10 rows per page</SelectItem>\n <SelectItem value=\"25\">25 rows per page</SelectItem>\n <SelectItem value=\"50\">50 rows per page</SelectItem>\n </SelectContent>\n </Select>\n );\n}\n"],"names":["React","jsx","cn","jsxs","Select","SelectContent","SelectItem"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Table.cjs","sources":["../../../../src/components/Table/Table.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { ArrowDownIcon } from \"../Icons/ArrowDownIcon\";\nimport { ArrowUpIcon } from \"../Icons/ArrowUpIcon\";\nimport { Select, SelectContent, SelectItem } from \"../Select/Select\";\n\n/**\n * Row density for body cells.\n *\n * - `\"md\"` (default) → 64px Figma `V2 Table Cell` Small.\n * - `\"lg\"` → 80px Figma `V2 Table Cell` Large.\n *\n * `\"default\"` is the v2 numeric-token equivalent of `\"md\"` and is preferred\n * for new code.\n */\nexport type TableSize = \"md\" | \"lg\" | \"default\";\n\nexport interface TableCardProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Row density applied to {@link TableCell} descendants. @default \"md\" */\n size?: TableSize;\n}\n\nconst TableSizeContext = React.createContext<TableSize>(\"md\");\n\nfunction useTableSize(): TableSize {\n return React.useContext(TableSizeContext);\n}\n\n/**\n * Surface wrapper for data tables: rounded 24px container with a strong\n * outer border, inner spacing, and size context for {@link TableCell}\n * descendants. Compose with {@link TableScrollArea}, {@link Table},\n * {@link TableHeader}, {@link TableBody}, {@link TableRow},\n * {@link TableHead}, and {@link TableCell}.\n *\n * @example\n * ```tsx\n * <TableCard>\n * <TableScrollArea>\n * <Table>\n * <TableHeader>\n * <TableRow>\n * <TableHead>Name</TableHead>\n * </TableRow>\n * </TableHeader>\n * <TableBody>\n * <TableRow>\n * <TableCell>Jane Doe</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n * </TableScrollArea>\n * </TableCard>\n * ```\n */\nexport const TableCard = React.forwardRef<HTMLDivElement, TableCardProps>(\n ({ className, size = \"md\", ...props }, ref) => {\n return (\n <TableSizeContext.Provider value={size}>\n <div\n ref={ref}\n className={cn(\n \"isolate flex flex-col gap-2 overflow-hidden rounded-3xl border border-border-strong px-3 py-1\",\n className,\n )}\n {...props}\n />\n </TableSizeContext.Provider>\n );\n },\n);\nTableCard.displayName = \"TableCard\";\n\nexport interface TableToolbarProps extends React.HTMLAttributes<HTMLDivElement> {}\n\n/**\n * Optional toolbar row above the table (e.g. bulk selection actions).\n */\nexport const TableToolbar = React.forwardRef<HTMLDivElement, TableToolbarProps>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"flex flex-wrap items-center gap-4 px-4 py-3\", className)}\n {...props}\n />\n );\n },\n);\nTableToolbar.displayName = \"TableToolbar\";\n\nexport interface TableScrollAreaProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * No longer needed in v2 — {@link TableCard} handles corner rounding via\n * its own `overflow-hidden rounded-3xl`. Accepted for back-compat.\n *\n * @deprecated v2 ignores this prop; safe to remove.\n */\n roundTop?: boolean;\n}\n\n/**\n * Horizontal scroll container for wide tables. The inner scrollport keeps\n * `border-collapse` styles intact when the table wraps.\n */\nexport const TableScrollArea = React.forwardRef<HTMLDivElement, TableScrollAreaProps>(\n ({ className, children, roundTop: _roundTop, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"relative w-full min-w-0 overflow-hidden\", className)}\n {...props}\n >\n <div className=\"overflow-x-auto\">{children}</div>\n </div>\n );\n },\n);\nTableScrollArea.displayName = \"TableScrollArea\";\n\nexport interface TableProps extends React.TableHTMLAttributes<HTMLTableElement> {}\n\n/**\n * Semantic `<table>` element. Place inside {@link TableScrollArea}.\n */\nexport const Table = React.forwardRef<HTMLTableElement, TableProps>(\n ({ className, ...props }, ref) => {\n return (\n <table\n ref={ref}\n className={cn(\n \"w-full caption-bottom border-separate border-spacing-0 text-left\",\n className,\n )}\n {...props}\n />\n );\n },\n);\nTable.displayName = \"Table\";\n\nexport interface TableHeaderProps extends React.HTMLAttributes<HTMLTableSectionElement> {}\n\nexport const TableHeader = React.forwardRef<HTMLTableSectionElement, TableHeaderProps>(\n ({ className, ...props }, ref) => {\n return <thead ref={ref} className={cn(className)} {...props} />;\n },\n);\nTableHeader.displayName = \"TableHeader\";\n\nexport interface TableBodyProps extends React.HTMLAttributes<HTMLTableSectionElement> {}\n\n/**\n * `<tbody>` wrapper. Removes the bottom border on cells in the final row to\n * match the Figma `V2 Table Final Row` treatment.\n */\nexport const TableBody = React.forwardRef<HTMLTableSectionElement, TableBodyProps>(\n ({ className, ...props }, ref) => {\n return (\n <tbody ref={ref} className={cn(\"[&_tr:last-child_td]:border-b-0\", className)} {...props} />\n );\n },\n);\nTableBody.displayName = \"TableBody\";\n\nexport interface TableFooterProps extends React.HTMLAttributes<HTMLTableSectionElement> {}\n\nexport const TableFooter = React.forwardRef<HTMLTableSectionElement, TableFooterProps>(\n ({ className, ...props }, ref) => {\n return <tfoot ref={ref} className={cn(className)} {...props} />;\n },\n);\nTableFooter.displayName = \"TableFooter\";\n\nexport interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {}\n\nexport const TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(\n ({ className, ...props }, ref) => {\n return <tr ref={ref} className={cn(className)} {...props} />;\n },\n);\nTableRow.displayName = \"TableRow\";\n\n/** Column layout preset for {@link TableHead}. */\nexport type TableHeadIntent = \"default\" | \"checkbox\" | \"sort\" | \"leading\";\n\nconst HEAD_INTENT_CLASSES: Record<TableHeadIntent, string> = {\n default: \"text-left\",\n checkbox: \"w-12 min-w-12 max-w-12 text-center\",\n sort: \"text-right\",\n leading: \"min-w-0 w-2/5 text-left\",\n};\n\nexport interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {\n /** Layout preset for common column types. @default \"default\" */\n intent?: TableHeadIntent;\n}\n\n/**\n * Header cell. v2: transparent background, 48px min height, tertiary text,\n * `border-border-primary` bottom rule.\n */\nexport const TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(\n ({ className, intent = \"default\", scope = \"col\", ...props }, ref) => {\n return (\n <th\n ref={ref}\n scope={scope}\n className={cn(\n \"typography-semibold-body-sm box-border min-h-12 border-b border-border-primary px-4 py-3 align-middle text-content-tertiary\",\n HEAD_INTENT_CLASSES[intent],\n className,\n )}\n {...props}\n />\n );\n },\n);\nTableHead.displayName = \"TableHead\";\n\nconst CELL_MIN_HEIGHT: Record<TableSize, string> = {\n md: \"h-16 min-h-16\",\n default: \"h-16 min-h-16\",\n lg: \"h-20 min-h-20\",\n};\n\n/** Bottom border and padding preset for body cells (Figma table cell component). */\nexport type TableCellVariant = \"default\" | \"chip\" | \"pillProgress\";\n\nconst CELL_VARIANT_CLASSES: Record<TableCellVariant, string> = {\n default: \"border-b border-border-primary px-4 py-3\",\n chip: \"border-b border-border-primary px-4 py-3\",\n pillProgress: \"border-b border-border-primary px-4 py-3\",\n};\n\n/** Layout / typography preset for {@link TableCell} (orthogonal to {@link TableCellVariant}). */\nexport type TableCellIntent = \"default\" | \"checkbox\" | \"stacked\" | \"multiline\" | \"sideLabel\";\n\nconst CELL_INTENT_CLASSES: Record<TableCellIntent, string> = {\n default: \"\",\n checkbox: \"w-12 min-w-12 max-w-12 text-center\",\n stacked: \"align-top\",\n multiline: \"max-w-[240px]\",\n sideLabel: \"\",\n};\n\nexport interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {\n /** Padding preset for the cell. v2 uses identical padding across variants; values are kept for back-compat. @default \"default\" */\n cellVariant?: TableCellVariant;\n /** Alignment and typography preset for common cell types. @default \"default\" */\n intent?: TableCellIntent;\n}\n\n/**\n * Body cell. v2: `h-16` (or `h-20` when the parent {@link TableCard} uses\n * `size=\"lg\"`), `px-4 py-3` padding, body-sm typography, and a single\n * `border-border-primary` rule that is zeroed by {@link TableBody} for the\n * final row.\n */\nexport const TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(\n ({ className, cellVariant = \"default\", intent = \"default\", ...props }, ref) => {\n const size = useTableSize();\n const typo =\n intent === \"sideLabel\" ? \"typography-semibold-body-sm\" : \"typography-regular-body-sm\";\n return (\n <td\n ref={ref}\n className={cn(\n typo,\n \"align-middle text-content-primary\",\n CELL_VARIANT_CLASSES[cellVariant],\n CELL_MIN_HEIGHT[size],\n CELL_INTENT_CLASSES[intent],\n className,\n )}\n {...props}\n />\n );\n },\n);\nTableCell.displayName = \"TableCell\";\n\nexport interface TableCellGroupProps extends React.HTMLAttributes<HTMLDivElement> {}\n\n/**\n * Horizontal group for icons, chips, and metadata inside a {@link TableCell}\n * (Figma `gap-[4px]`).\n */\nexport const TableCellGroup = React.forwardRef<HTMLDivElement, TableCellGroupProps>(\n ({ className, ...props }, ref) => {\n return <div ref={ref} className={cn(\"flex items-center gap-1\", className)} {...props} />;\n },\n);\nTableCellGroup.displayName = \"TableCellGroup\";\n\nexport interface TableCellContentProps {\n /** Primary line (semibold body-sm). */\n primary: React.ReactNode;\n /** Optional secondary line (regular body-sm, secondary color). */\n secondary?: React.ReactNode;\n /** Inline node rendered next to the primary line (icon, chip). */\n primaryAdornment?: React.ReactNode;\n /** Inline node rendered next to the secondary line. */\n secondaryAdornment?: React.ReactNode;\n /** Class for the outer wrapper. */\n className?: string;\n}\n\n/**\n * Two-line content slot matching Figma `V2 Table Content` — primary line\n * (semibold) over an optional secondary line (regular, muted) with a 2px\n * gap. Use inside {@link TableCell} for the common stacked-text pattern.\n */\nexport function TableCellContent({\n primary,\n secondary,\n primaryAdornment,\n secondaryAdornment,\n className,\n}: TableCellContentProps) {\n return (\n <div className={cn(\"flex flex-col gap-0.5\", className)}>\n <div className=\"flex items-center gap-1\">\n <span className=\"typography-semibold-body-sm text-content-primary\">{primary}</span>\n {primaryAdornment}\n </div>\n {(secondary != null || secondaryAdornment != null) && (\n <div className=\"flex items-center gap-1\">\n {secondary != null && (\n <span className=\"typography-regular-body-sm text-content-secondary\">{secondary}</span>\n )}\n {secondaryAdornment}\n </div>\n )}\n </div>\n );\n}\nTableCellContent.displayName = \"TableCellContent\";\n\nexport interface TableMediaThumbnailProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"children\"> {\n /** Image URL. */\n src: string;\n /** Alt text for the image. @default \"\" */\n alt?: string;\n /** Applies the table's blurred-media treatment. @default false */\n blurred?: boolean;\n /** `center` uses the fixed media column width from the lg spec. @default \"start\" */\n align?: \"start\" | \"center\";\n}\n\n/**\n * Square 48px thumbnail used inside {@link TableCell} for media columns\n * (Figma `V2 Media Thumbnail Item`).\n */\nexport const TableMediaThumbnail = React.forwardRef<HTMLDivElement, TableMediaThumbnailProps>(\n ({ className, src, alt = \"\", blurred, align = \"start\", ...props }, ref) => {\n const frame = \"size-12 overflow-hidden rounded-sm bg-neutral-alphas-200\";\n return (\n <div\n ref={ref}\n className={cn(\n align === \"center\" && \"flex w-16 shrink-0 justify-center\",\n align === \"start\" && \"inline-flex shrink-0\",\n )}\n >\n <div className={cn(frame, blurred && \"blur-[2px]\", className)} {...props}>\n <img alt={alt} className=\"size-full object-cover\" src={src} />\n </div>\n </div>\n );\n },\n);\nTableMediaThumbnail.displayName = \"TableMediaThumbnail\";\n\nexport interface TableStatusDotProps extends React.HTMLAttributes<HTMLDivElement> {}\n\n/**\n * Small status indicator dot for table cells (Figma status column).\n */\nexport const TableStatusDot = React.forwardRef<HTMLDivElement, TableStatusDotProps>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"size-2 shrink-0 rounded-full bg-info-content\", className)}\n {...props}\n />\n );\n },\n);\nTableStatusDot.displayName = \"TableStatusDot\";\n\nexport interface TableProgressTrackProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Fill width from 0–100. @default 0 */\n value?: number;\n}\n\n/**\n * Thin progress track used with badges in table cells (Figma pill + progress).\n * Renders with `role=\"progressbar\"` and a default `aria-label` of `\"Progress\"`.\n */\nexport const TableProgressTrack = React.forwardRef<HTMLDivElement, TableProgressTrackProps>(\n ({ className, value = 0, \"aria-label\": ariaLabel = \"Progress\", ...props }, ref) => {\n const width = Math.min(100, Math.max(0, value));\n const rounded = Math.round(width);\n return (\n <div\n ref={ref}\n role=\"progressbar\"\n aria-valuenow={rounded}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={ariaLabel}\n className={cn(\n \"relative h-1 w-full overflow-hidden rounded-full bg-neutral-alphas-200\",\n className,\n )}\n {...props}\n >\n <div\n className=\"absolute top-0 left-0 h-1 rounded-full bg-buttons-primary\"\n style={{ width: `${width}%` }}\n aria-hidden\n />\n </div>\n );\n },\n);\nTableProgressTrack.displayName = \"TableProgressTrack\";\n\nexport interface TablePillProgressLayoutProps extends React.HTMLAttributes<HTMLDivElement> {}\n\n/**\n * Vertical layout for pill label + {@link TableProgressTrack} in a cell.\n */\nexport const TablePillProgressLayout = React.forwardRef<\n HTMLDivElement,\n TablePillProgressLayoutProps\n>(({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"flex min-w-[120px] flex-col items-start gap-2\", className)}\n {...props}\n />\n );\n});\nTablePillProgressLayout.displayName = \"TablePillProgressLayout\";\n\n/** Current sort direction of a {@link TableSortLabel}. `null` means unsorted. */\nexport type TableSortDirection = \"asc\" | \"desc\" | null;\n\nexport interface TableSortLabelProps extends React.HTMLAttributes<HTMLSpanElement> {\n children: React.ReactNode;\n /**\n * Visual indicator of the column's sort state. When set to `\"asc\"` or\n * `\"desc\"`, a 1px underline accent appears beneath the label and a small\n * directional arrow is shown next to it. @default null\n */\n direction?: TableSortDirection;\n}\n\n/**\n * Sortable column label. v2 expresses the sort state with a 1px underline\n * beneath the label plus a directional arrow when sorted.\n */\nexport const TableSortLabel = React.forwardRef<HTMLSpanElement, TableSortLabelProps>(\n ({ className, children, direction = null, ...props }, ref) => {\n const Icon = direction === \"desc\" ? ArrowDownIcon : ArrowUpIcon;\n return (\n <span\n ref={ref}\n className={cn(\"inline-flex items-center gap-1 text-content-primary\", className)}\n {...props}\n >\n <span\n className={cn(\n \"typography-semibold-body-sm\",\n direction != null && \"border-b border-content-primary pb-px\",\n )}\n >\n {children}\n </span>\n {direction != null && <Icon className=\"size-4 shrink-0\" aria-hidden />}\n </span>\n );\n },\n);\nTableSortLabel.displayName = \"TableSortLabel\";\n\nexport interface TableStackedTextProps {\n /** Primary line (semibold body). */\n title: React.ReactNode;\n /** Secondary line (caption, muted). */\n subtitle: React.ReactNode;\n}\n\n/**\n * Two-line primary + secondary text block for \"cell + info\" patterns.\n *\n * @deprecated Prefer {@link TableCellContent} which supports adornments and\n * matches the Figma `V2 Table Content` slot.\n */\nexport function TableStackedText({ title, subtitle }: TableStackedTextProps) {\n return <TableCellContent primary={title} secondary={subtitle} />;\n}\n\nTableStackedText.displayName = \"TableStackedText\";\n\nexport interface TableLineClampProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Number of lines before ellipsis. @default 2 */\n lines?: 1 | 2 | 3;\n}\n\n/**\n * Clamps child text to a fixed number of lines inside a {@link TableCell}.\n */\nexport const TableLineClamp = React.forwardRef<HTMLDivElement, TableLineClampProps>(\n ({ className, lines = 2, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n lines === 1 && \"line-clamp-1\",\n lines === 2 && \"line-clamp-2\",\n lines === 3 && \"line-clamp-3\",\n className,\n )}\n {...props}\n />\n );\n },\n);\nTableLineClamp.displayName = \"TableLineClamp\";\n\nexport interface TableRowsPerPageSelectProps {\n /** Passed to the trigger for forms and labels. */\n id?: string;\n /** Accessible name for the trigger when no visible label. @default \"Rows per page\" */\n \"aria-label\"?: string;\n}\n\n/**\n * Rows-per-page {@link Select} styled for {@link TablePagination}. v2 uses a\n * subtle pill trigger with the table's secondary-surface background.\n */\nexport function TableRowsPerPageSelect(props: TableRowsPerPageSelectProps) {\n const { id, \"aria-label\": ariaLabel = \"Rows per page\" } = props;\n return (\n <Select\n defaultValue=\"10\"\n size=\"32\"\n aria-label={ariaLabel}\n className=\"w-[154px] [&_button]:rounded-sm [&_button]:border-transparent [&_button]:bg-surface-inputs\"\n id={id}\n >\n <SelectContent>\n <SelectItem value=\"10\">10 rows per page</SelectItem>\n <SelectItem value=\"25\">25 rows per page</SelectItem>\n <SelectItem value=\"50\">50 rows per page</SelectItem>\n </SelectContent>\n </Select>\n );\n}\n"],"names":["React","jsx","cn","jsxs","ArrowDownIcon","ArrowUpIcon","Select","SelectContent","SelectItem"],"mappings":"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"}
|
|
@@ -28,16 +28,16 @@ const TablePagination = React__namespace.forwardRef(
|
|
|
28
28
|
"div",
|
|
29
29
|
{
|
|
30
30
|
ref,
|
|
31
|
-
className: cn.cn("flex w-full max-w-full flex-col gap-
|
|
31
|
+
className: cn.cn("flex w-full max-w-full flex-col gap-4 px-3 py-3", className),
|
|
32
32
|
...props,
|
|
33
33
|
children: [
|
|
34
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-2
|
|
35
|
-
leadingSlot != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 shrink-0 items-center
|
|
34
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-2", children: [
|
|
35
|
+
leadingSlot != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 shrink-0 items-center", children: leadingSlot }) : null,
|
|
36
36
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
37
37
|
"div",
|
|
38
38
|
{
|
|
39
39
|
className: cn.cn(
|
|
40
|
-
"typography-regular-body-
|
|
40
|
+
"typography-regular-body-sm min-w-0 flex-1 text-content-secondary",
|
|
41
41
|
leadingSlot == null && "text-left",
|
|
42
42
|
leadingSlot != null && "text-right"
|
|
43
43
|
),
|
|
@@ -54,12 +54,12 @@ const TablePagination = React__namespace.forwardRef(
|
|
|
54
54
|
"div",
|
|
55
55
|
{
|
|
56
56
|
ref,
|
|
57
|
-
className: cn.cn("flex w-full flex-wrap items-center gap-3 px-
|
|
57
|
+
className: cn.cn("flex w-full flex-wrap items-center gap-3 px-3 py-3", className),
|
|
58
58
|
...props,
|
|
59
59
|
children: [
|
|
60
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-0 min-w-0 flex-1
|
|
60
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-0 min-w-0 flex-1 items-center", children: leadingSlot }),
|
|
61
61
|
paginationSlot != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 items-center justify-center", children: paginationSlot }) : null,
|
|
62
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "typography-regular-body-
|
|
62
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "typography-regular-body-sm min-w-0 flex-1 text-right text-content-secondary", children: summary })
|
|
63
63
|
]
|
|
64
64
|
}
|
|
65
65
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TablePagination.cjs","sources":["../../../../src/components/Table/TablePagination.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\n\n/** Layout preset for the pagination bar — desktop (range on the right) or stacked mobile. */\nexport type TablePaginationLayout = \"desktop\" | \"mobile\";\n\nexport interface TablePaginationProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Layout preset. @default \"desktop\" */\n layout?: TablePaginationLayout;\n /** Left (desktop) or top row (mobile) content, e.g. rows-per-page {@link Select}. */\n leadingSlot?: React.ReactNode;\n /** Center (desktop) or bottom row (mobile) content, e.g. {@link Pagination}. */\n paginationSlot?: React.ReactNode;\n /** Summary text or node (e.g. current range and total). */\n summary: React.ReactNode;\n}\n\n/**\n * Footer bar for data tables: rows-per-page control, page navigation, and
|
|
1
|
+
{"version":3,"file":"TablePagination.cjs","sources":["../../../../src/components/Table/TablePagination.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\n\n/** Layout preset for the pagination bar — desktop (range on the right) or stacked mobile. */\nexport type TablePaginationLayout = \"desktop\" | \"mobile\";\n\nexport interface TablePaginationProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Layout preset. @default \"desktop\" */\n layout?: TablePaginationLayout;\n /** Left (desktop) or top row (mobile) content, e.g. rows-per-page {@link Select}. */\n leadingSlot?: React.ReactNode;\n /** Center (desktop) or bottom row (mobile) content, e.g. {@link Pagination}. */\n paginationSlot?: React.ReactNode;\n /** Summary text or node (e.g. current range and total). */\n summary: React.ReactNode;\n}\n\n/**\n * Footer bar for data tables: rows-per-page control, page navigation, and\n * range summary. Pair `paginationSlot` with {@link Pagination} for numbered\n * controls.\n *\n * v2 sits flush inside {@link TableCard} (`px-3` matches the card's inner\n * gutter); the chip styling now lives on the {@link TableRowsPerPageSelect}\n * trigger itself.\n *\n * @example\n * ```tsx\n * <TablePagination\n * leadingSlot={<TableRowsPerPageSelect />}\n * paginationSlot={<Pagination totalPages={5} currentPage={2} onPageChange={setPage} />}\n * summary=\"20–30 of 100 rows\"\n * />\n * ```\n */\nexport const TablePagination = React.forwardRef<HTMLDivElement, TablePaginationProps>(\n ({ className, layout = \"desktop\", leadingSlot, paginationSlot, summary, ...props }, ref) => {\n if (layout === \"mobile\") {\n return (\n <div\n ref={ref}\n className={cn(\"flex w-full max-w-full flex-col gap-4 px-3 py-3\", className)}\n {...props}\n >\n <div className=\"flex w-full items-center gap-2\">\n {leadingSlot != null ? (\n <div className=\"flex min-w-0 shrink-0 items-center\">{leadingSlot}</div>\n ) : null}\n <div\n className={cn(\n \"typography-regular-body-sm min-w-0 flex-1 text-content-secondary\",\n leadingSlot == null && \"text-left\",\n leadingSlot != null && \"text-right\",\n )}\n >\n {summary}\n </div>\n </div>\n {paginationSlot != null ? (\n <div className=\"flex justify-center\">{paginationSlot}</div>\n ) : null}\n </div>\n );\n }\n\n return (\n <div\n ref={ref}\n className={cn(\"flex w-full flex-wrap items-center gap-3 px-3 py-3\", className)}\n {...props}\n >\n <div className=\"flex min-h-0 min-w-0 flex-1 items-center\">{leadingSlot}</div>\n {paginationSlot != null ? (\n <div className=\"flex shrink-0 items-center justify-center\">{paginationSlot}</div>\n ) : null}\n <div className=\"typography-regular-body-sm min-w-0 flex-1 text-right text-content-secondary\">\n {summary}\n </div>\n </div>\n );\n },\n);\nTablePagination.displayName = \"TablePagination\";\n"],"names":["React","jsxs","cn","jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAmCO,MAAM,kBAAkBA,iBAAM;AAAA,EACnC,CAAC,EAAE,WAAW,SAAS,WAAW,aAAa,gBAAgB,SAAS,GAAG,MAAA,GAAS,QAAQ;AAC1F,QAAI,WAAW,UAAU;AACvB,aACEC,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA,WAAWC,GAAAA,GAAG,mDAAmD,SAAS;AAAA,UACzE,GAAG;AAAA,UAEJ,UAAA;AAAA,YAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,kCACZ,UAAA;AAAA,cAAA,eAAe,OACdE,2BAAAA,IAAC,OAAA,EAAI,WAAU,sCAAsC,uBAAY,IAC/D;AAAA,cACJA,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAWD,GAAAA;AAAAA,oBACT;AAAA,oBACA,eAAe,QAAQ;AAAA,oBACvB,eAAe,QAAQ;AAAA,kBAAA;AAAA,kBAGxB,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YACH,GACF;AAAA,YACC,kBAAkB,OACjBC,2BAAAA,IAAC,SAAI,WAAU,uBAAuB,0BAAe,IACnD;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAGV;AAEA,WACEF,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAWC,GAAAA,GAAG,sDAAsD,SAAS;AAAA,QAC5E,GAAG;AAAA,QAEJ,UAAA;AAAA,UAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,4CAA4C,UAAA,aAAY;AAAA,UACtE,kBAAkB,OACjBA,2BAAAA,IAAC,SAAI,WAAU,6CAA6C,0BAAe,IACzE;AAAA,UACJA,2BAAAA,IAAC,OAAA,EAAI,WAAU,+EACZ,UAAA,QAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AACA,gBAAgB,cAAc;;"}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -34,9 +34,9 @@ const EmptyState = require("./components/EmptyState/EmptyState.cjs");
|
|
|
34
34
|
const IconButton = require("./components/IconButton/IconButton.cjs");
|
|
35
35
|
const AddIcon = require("./components/Icons/AddIcon.cjs");
|
|
36
36
|
const AI2Icon = require("./components/Icons/AI2Icon.cjs");
|
|
37
|
+
const AICallIcon = require("./components/Icons/AICallIcon.cjs");
|
|
37
38
|
const AIDisclosureIcon = require("./components/Icons/AIDisclosureIcon.cjs");
|
|
38
39
|
const AIIcon = require("./components/Icons/AIIcon.cjs");
|
|
39
|
-
const AiCallIcon = require("./components/Icons/AiCallIcon.cjs");
|
|
40
40
|
const AlertIcon = require("./components/Icons/AlertIcon.cjs");
|
|
41
41
|
const AppsIcon = require("./components/Icons/AppsIcon.cjs");
|
|
42
42
|
const ArrowDownIcon = require("./components/Icons/ArrowDownIcon.cjs");
|
|
@@ -136,6 +136,7 @@ const PauseIcon = require("./components/Icons/PauseIcon.cjs");
|
|
|
136
136
|
const PeopleIcon = require("./components/Icons/PeopleIcon.cjs");
|
|
137
137
|
const PhoneIcon = require("./components/Icons/PhoneIcon.cjs");
|
|
138
138
|
const PhoneOffIcon = require("./components/Icons/PhoneOffIcon.cjs");
|
|
139
|
+
const Pin2Icon = require("./components/Icons/Pin2Icon.cjs");
|
|
139
140
|
const PinIcon = require("./components/Icons/PinIcon.cjs");
|
|
140
141
|
const PlayIcon = require("./components/Icons/PlayIcon.cjs");
|
|
141
142
|
const PlusIcon = require("./components/Icons/PlusIcon.cjs");
|
|
@@ -293,17 +294,20 @@ exports.DrawerTrigger = Drawer.DrawerTrigger;
|
|
|
293
294
|
exports.DropdownMenu = DropdownMenu.DropdownMenu;
|
|
294
295
|
exports.DropdownMenuContent = DropdownMenu.DropdownMenuContent;
|
|
295
296
|
exports.DropdownMenuGroup = DropdownMenu.DropdownMenuGroup;
|
|
297
|
+
exports.DropdownMenuHeader = DropdownMenu.DropdownMenuHeader;
|
|
296
298
|
exports.DropdownMenuItem = DropdownMenu.DropdownMenuItem;
|
|
297
299
|
exports.DropdownMenuLabel = DropdownMenu.DropdownMenuLabel;
|
|
300
|
+
exports.DropdownMenuRadioGroup = DropdownMenu.DropdownMenuRadioGroup;
|
|
301
|
+
exports.DropdownMenuRadioItem = DropdownMenu.DropdownMenuRadioItem;
|
|
298
302
|
exports.DropdownMenuSeparator = DropdownMenu.DropdownMenuSeparator;
|
|
299
303
|
exports.DropdownMenuTrigger = DropdownMenu.DropdownMenuTrigger;
|
|
300
304
|
exports.EmptyState = EmptyState.EmptyState;
|
|
301
305
|
exports.IconButton = IconButton.IconButton;
|
|
302
306
|
exports.AddIcon = AddIcon.AddIcon;
|
|
303
307
|
exports.AI2Icon = AI2Icon.AI2Icon;
|
|
308
|
+
exports.AICallIcon = AICallIcon.AICallIcon;
|
|
304
309
|
exports.AIDisclosureIcon = AIDisclosureIcon.AIDisclosureIcon;
|
|
305
310
|
exports.AIIcon = AIIcon.AIIcon;
|
|
306
|
-
exports.AICallIcon = AiCallIcon.AICallIcon;
|
|
307
311
|
exports.AlertIcon = AlertIcon.AlertIcon;
|
|
308
312
|
exports.AppsIcon = AppsIcon.AppsIcon;
|
|
309
313
|
exports.ArrowDownIcon = ArrowDownIcon.ArrowDownIcon;
|
|
@@ -403,6 +407,7 @@ exports.PauseIcon = PauseIcon.PauseIcon;
|
|
|
403
407
|
exports.PeopleIcon = PeopleIcon.PeopleIcon;
|
|
404
408
|
exports.PhoneIcon = PhoneIcon.PhoneIcon;
|
|
405
409
|
exports.PhoneOffIcon = PhoneOffIcon.PhoneOffIcon;
|
|
410
|
+
exports.Pin2Icon = Pin2Icon.Pin2Icon;
|
|
406
411
|
exports.PinIcon = PinIcon.PinIcon;
|
|
407
412
|
exports.PlayIcon = PlayIcon.PlayIcon;
|
|
408
413
|
exports.PlusIcon = PlusIcon.PlusIcon;
|
|
@@ -491,6 +496,7 @@ exports.Table = Table.Table;
|
|
|
491
496
|
exports.TableBody = Table.TableBody;
|
|
492
497
|
exports.TableCard = Table.TableCard;
|
|
493
498
|
exports.TableCell = Table.TableCell;
|
|
499
|
+
exports.TableCellContent = Table.TableCellContent;
|
|
494
500
|
exports.TableCellGroup = Table.TableCellGroup;
|
|
495
501
|
exports.TableFooter = Table.TableFooter;
|
|
496
502
|
exports.TableHead = Table.TableHead;
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -5,11 +5,21 @@ import * as React from "react";
|
|
|
5
5
|
import { cn } from "../../utils/cn.mjs";
|
|
6
6
|
import { CheckIcon } from "../Icons/CheckIcon.mjs";
|
|
7
7
|
import { MinusIcon } from "../Icons/MinusIcon.mjs";
|
|
8
|
+
const BOX_SIZE_CLASS = {
|
|
9
|
+
"20": "size-5",
|
|
10
|
+
"16": "size-4"
|
|
11
|
+
};
|
|
12
|
+
const INDICATOR_SIZE_CLASS = {
|
|
13
|
+
"20": "size-3",
|
|
14
|
+
"16": "size-2.5"
|
|
15
|
+
};
|
|
8
16
|
const Checkbox = React.forwardRef(
|
|
9
|
-
({ className, size = "
|
|
17
|
+
({ className, size = "20", label, helperText, disabled, name, ...props }, ref) => {
|
|
10
18
|
const id = React.useId();
|
|
11
19
|
const helperTextId = helperText ? `${id}-helper` : void 0;
|
|
12
20
|
const hasLabel = Boolean(label || helperText);
|
|
21
|
+
const boxSize = size === "16" ? "16" : "20";
|
|
22
|
+
const useSmallLabelTypography = size === "small";
|
|
13
23
|
if (process.env.NODE_ENV !== "production" && !label && !props["aria-label"] && !props["aria-labelledby"]) {
|
|
14
24
|
console.warn(
|
|
15
25
|
"Checkbox: No accessible name provided. Add a `label`, `aria-label`, or `aria-labelledby` prop so screen readers can announce this checkbox."
|
|
@@ -29,7 +39,8 @@ const Checkbox = React.forwardRef(
|
|
|
29
39
|
"span",
|
|
30
40
|
{
|
|
31
41
|
className: cn(
|
|
32
|
-
"relative inline-flex
|
|
42
|
+
"relative inline-flex shrink-0",
|
|
43
|
+
BOX_SIZE_CLASS[boxSize],
|
|
33
44
|
// Alignment when used with label
|
|
34
45
|
label && (helperText ? "mt-1" : "mt-0.5")
|
|
35
46
|
),
|
|
@@ -60,7 +71,8 @@ const Checkbox = React.forwardRef(
|
|
|
60
71
|
onCheckedChange: handleCheckedChange,
|
|
61
72
|
className: cn(
|
|
62
73
|
// Base styles
|
|
63
|
-
"flex
|
|
74
|
+
"flex items-center justify-center rounded border-2",
|
|
75
|
+
BOX_SIZE_CLASS[boxSize],
|
|
64
76
|
"transition-[border-color,background-color,color,box-shadow] duration-150",
|
|
65
77
|
// Default state
|
|
66
78
|
"border-content-primary bg-transparent text-transparent",
|
|
@@ -83,7 +95,8 @@ const Checkbox = React.forwardRef(
|
|
|
83
95
|
{
|
|
84
96
|
forceMount: true,
|
|
85
97
|
className: cn(
|
|
86
|
-
"flex
|
|
98
|
+
"flex items-center justify-center text-content-primary-inverted",
|
|
99
|
+
INDICATOR_SIZE_CLASS[boxSize],
|
|
87
100
|
"data-[state=unchecked]:invisible"
|
|
88
101
|
),
|
|
89
102
|
children: props.checked === "indeterminate" ? /* @__PURE__ */ jsx(MinusIcon, {}) : /* @__PURE__ */ jsx(CheckIcon, {})
|
|
@@ -115,7 +128,7 @@ const Checkbox = React.forwardRef(
|
|
|
115
128
|
className: cn(
|
|
116
129
|
"cursor-pointer select-none text-content-primary",
|
|
117
130
|
"group-has-disabled:cursor-not-allowed group-has-disabled:text-content-tertiary",
|
|
118
|
-
|
|
131
|
+
useSmallLabelTypography ? "typography-semibold-body-md" : "typography-semibold-body-lg"
|
|
119
132
|
),
|
|
120
133
|
children: label
|
|
121
134
|
}
|
|
@@ -128,7 +141,7 @@ const Checkbox = React.forwardRef(
|
|
|
128
141
|
className: cn(
|
|
129
142
|
"ml-7 text-content-secondary",
|
|
130
143
|
"in-[.is-disabled]:cursor-not-allowed in-[.is-disabled]:text-content-tertiary",
|
|
131
|
-
|
|
144
|
+
useSmallLabelTypography ? "typography-regular-body-sm" : "typography-regular-body-md"
|
|
132
145
|
),
|
|
133
146
|
children: helperText
|
|
134
147
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.mjs","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { CheckIcon } from \"../Icons/CheckIcon\";\nimport { MinusIcon } from \"../Icons/MinusIcon\";\n\n/** Size variant controlling label and helper text typography. */\nexport type CheckboxSize = \"default\" | \"small\";\n\nexport interface CheckboxProps\n extends Omit<React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>, \"asChild\"> {\n /** Size variant that controls label and helper text typography. @default \"default\" */\n size?: CheckboxSize;\n /** Label text displayed next to the checkbox. */\n label?: string;\n /** Descriptive text displayed below the label. */\n helperText?: string;\n}\n\n/**\n * A checkbox input with optional label and helper text. Supports checked,\n * unchecked, and indeterminate states.\n *\n * The ref type is intentionally `HTMLInputElement` (not `HTMLButtonElement`) for\n * form-library compatibility — libraries like react-hook-form call `register()`\n * which expects an `HTMLInputElement` ref. A hidden `<input>` is synced to the\n * Radix checkbox state via `useImperativeHandle`.\n *\n * @example\n * ```tsx\n * <Checkbox label=\"Accept terms\" helperText=\"Required to continue\" />\n * ```\n */\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ className, size = \"default\", label, helperText, disabled, name, ...props }, ref) => {\n const id = React.useId();\n const helperTextId = helperText ? `${id}-helper` : undefined;\n const hasLabel = Boolean(label || helperText);\n\n if (\n process.env.NODE_ENV !== \"production\" &&\n !label &&\n !props[\"aria-label\"] &&\n !props[\"aria-labelledby\"]\n ) {\n console.warn(\n \"Checkbox: No accessible name provided. Add a `label`, `aria-label`, or `aria-labelledby` prop so screen readers can announce this checkbox.\",\n );\n }\n\n // Hidden input for form library compatibility (e.g. react-hook-form register)\n const inputRef = React.useRef<HTMLInputElement>(null);\n React.useImperativeHandle(ref, () => inputRef.current as HTMLInputElement);\n\n const handleCheckedChange = (value: boolean | \"indeterminate\") => {\n const checked = value === true;\n if (inputRef.current) {\n inputRef.current.checked = checked;\n inputRef.current.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n props.onCheckedChange?.(value);\n };\n\n const checkboxElement = (\n <span\n className={cn(\n \"relative inline-flex size-5 shrink-0\",\n // Alignment when used with label\n label && (helperText ? \"mt-1\" : \"mt-0.5\"),\n )}\n >\n <input\n ref={inputRef}\n type=\"checkbox\"\n name={name}\n disabled={disabled}\n aria-hidden\n tabIndex={-1}\n onChange={() => {}}\n className=\"pointer-events-none absolute size-px overflow-hidden opacity-0\"\n style={{ clip: \"rect(0,0,0,0)\" }}\n />\n <CheckboxPrimitive.Root\n id={id}\n disabled={disabled}\n aria-describedby={helperTextId}\n data-testid=\"checkbox\"\n {...props}\n onCheckedChange={handleCheckedChange}\n className={cn(\n // Base styles\n \"flex size-5 items-center justify-center rounded border-2\",\n \"transition-[border-color,background-color,color,box-shadow] duration-150\",\n // Default state\n \"border-content-primary bg-transparent text-transparent\",\n // Checked state\n \"data-[state=checked]:border-content-primary data-[state=checked]:bg-content-primary data-[state=checked]:text-content-primary-inverted\",\n // Indeterminate state\n \"data-[state=indeterminate]:border-content-primary data-[state=indeterminate]:bg-content-primary data-[state=indeterminate]:text-content-primary-inverted\",\n // Hover & active state\n \"hover:ring-2 hover:ring-brand-primary-default group-hover:ring-2 group-hover:ring-brand-primary-default\",\n \"not-disabled:active:ring-2 not-disabled:active:ring-brand-primary-default\",\n // Focus state\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-interaction-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary\",\n // Disabled state\n \"disabled:cursor-not-allowed disabled:border-neutral-alphas-600 disabled:ring-0 disabled:group-hover:ring-0\",\n \"disabled:data-[state=checked]:border-neutral-alphas-600 disabled:data-[state=checked]:bg-neutral-alphas-600 disabled:data-[state=checked]:text-content-tertiary\",\n !hasLabel && className,\n )}\n >\n <CheckboxPrimitive.Indicator\n forceMount\n className={cn(\n \"flex size-3 items-center justify-center text-content-primary-inverted\",\n \"data-[state=unchecked]:invisible\",\n )}\n >\n {props.checked === \"indeterminate\" ? <MinusIcon /> : <CheckIcon />}\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n </span>\n );\n\n if (!hasLabel) {\n return checkboxElement;\n }\n\n return (\n <div\n className={cn(\n \"inline-flex flex-col gap-0.5\",\n disabled && \"is-disabled cursor-not-allowed\",\n className,\n )}\n >\n <div className=\"group inline-flex items-start gap-2\">\n {checkboxElement}\n {label && (\n <label\n htmlFor={id}\n className={cn(\n \"cursor-pointer select-none text-content-primary\",\n \"group-has-disabled:cursor-not-allowed group-has-disabled:text-content-tertiary\",\n size === \"small\" ? \"typography-semibold-body-md\" : \"typography-semibold-body-lg\",\n )}\n >\n {label}\n </label>\n )}\n </div>\n {helperText && (\n <span\n id={helperTextId}\n className={cn(\n \"ml-7 text-content-secondary\",\n \"in-[.is-disabled]:cursor-not-allowed in-[.is-disabled]:text-content-tertiary\",\n size === \"small\" ? \"typography-regular-body-sm\" : \"typography-regular-body-md\",\n )}\n >\n {helperText}\n </span>\n )}\n </div>\n );\n },\n);\n\nCheckbox.displayName = \"Checkbox\";\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Checkbox.mjs","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { CheckIcon } from \"../Icons/CheckIcon\";\nimport { MinusIcon } from \"../Icons/MinusIcon\";\n\n/**\n * Size variant for the checkbox.\n *\n * - `\"20\"` (default) — 20px box, body-lg label.\n * - `\"16\"` — 16px box, body-md label, used in compact contexts like data tables.\n * - `\"default\"` and `\"small\"` are legacy aliases retained for back-compat\n * (`\"default\"` → `\"20\"`, `\"small\"` → `\"20\"` with smaller label typography).\n */\nexport type CheckboxSize =\n | \"20\"\n | \"16\"\n /** @deprecated Use `\"20\"` instead. */\n | \"default\"\n /** @deprecated Use `\"20\"` (the smaller-typography variant remains via `\"small\"`). */\n | \"small\";\n\nconst BOX_SIZE_CLASS: Record<\"20\" | \"16\", string> = {\n \"20\": \"size-5\",\n \"16\": \"size-4\",\n};\n\nconst INDICATOR_SIZE_CLASS: Record<\"20\" | \"16\", string> = {\n \"20\": \"size-3\",\n \"16\": \"size-2.5\",\n};\n\nexport interface CheckboxProps\n extends Omit<React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>, \"asChild\"> {\n /** Size variant. @default \"20\" */\n size?: CheckboxSize;\n /** Label text displayed next to the checkbox. */\n label?: string;\n /** Descriptive text displayed below the label. */\n helperText?: string;\n}\n\n/**\n * A checkbox input with optional label and helper text. Supports checked,\n * unchecked, and indeterminate states.\n *\n * The ref type is intentionally `HTMLInputElement` (not `HTMLButtonElement`) for\n * form-library compatibility — libraries like react-hook-form call `register()`\n * which expects an `HTMLInputElement` ref. A hidden `<input>` is synced to the\n * Radix checkbox state via `useImperativeHandle`.\n *\n * @example\n * ```tsx\n * <Checkbox label=\"Accept terms\" helperText=\"Required to continue\" />\n * ```\n */\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ className, size = \"20\", label, helperText, disabled, name, ...props }, ref) => {\n const id = React.useId();\n const helperTextId = helperText ? `${id}-helper` : undefined;\n const hasLabel = Boolean(label || helperText);\n const boxSize: \"20\" | \"16\" = size === \"16\" ? \"16\" : \"20\";\n const useSmallLabelTypography = size === \"small\";\n\n if (\n process.env.NODE_ENV !== \"production\" &&\n !label &&\n !props[\"aria-label\"] &&\n !props[\"aria-labelledby\"]\n ) {\n console.warn(\n \"Checkbox: No accessible name provided. Add a `label`, `aria-label`, or `aria-labelledby` prop so screen readers can announce this checkbox.\",\n );\n }\n\n // Hidden input for form library compatibility (e.g. react-hook-form register)\n const inputRef = React.useRef<HTMLInputElement>(null);\n React.useImperativeHandle(ref, () => inputRef.current as HTMLInputElement);\n\n const handleCheckedChange = (value: boolean | \"indeterminate\") => {\n const checked = value === true;\n if (inputRef.current) {\n inputRef.current.checked = checked;\n inputRef.current.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n props.onCheckedChange?.(value);\n };\n\n const checkboxElement = (\n <span\n className={cn(\n \"relative inline-flex shrink-0\",\n BOX_SIZE_CLASS[boxSize],\n // Alignment when used with label\n label && (helperText ? \"mt-1\" : \"mt-0.5\"),\n )}\n >\n <input\n ref={inputRef}\n type=\"checkbox\"\n name={name}\n disabled={disabled}\n aria-hidden\n tabIndex={-1}\n onChange={() => {}}\n className=\"pointer-events-none absolute size-px overflow-hidden opacity-0\"\n style={{ clip: \"rect(0,0,0,0)\" }}\n />\n <CheckboxPrimitive.Root\n id={id}\n disabled={disabled}\n aria-describedby={helperTextId}\n data-testid=\"checkbox\"\n {...props}\n onCheckedChange={handleCheckedChange}\n className={cn(\n // Base styles\n \"flex items-center justify-center rounded border-2\",\n BOX_SIZE_CLASS[boxSize],\n \"transition-[border-color,background-color,color,box-shadow] duration-150\",\n // Default state\n \"border-content-primary bg-transparent text-transparent\",\n // Checked state\n \"data-[state=checked]:border-content-primary data-[state=checked]:bg-content-primary data-[state=checked]:text-content-primary-inverted\",\n // Indeterminate state\n \"data-[state=indeterminate]:border-content-primary data-[state=indeterminate]:bg-content-primary data-[state=indeterminate]:text-content-primary-inverted\",\n // Hover & active state\n \"hover:ring-2 hover:ring-brand-primary-default group-hover:ring-2 group-hover:ring-brand-primary-default\",\n \"not-disabled:active:ring-2 not-disabled:active:ring-brand-primary-default\",\n // Focus state\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-interaction-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary\",\n // Disabled state\n \"disabled:cursor-not-allowed disabled:border-neutral-alphas-600 disabled:ring-0 disabled:group-hover:ring-0\",\n \"disabled:data-[state=checked]:border-neutral-alphas-600 disabled:data-[state=checked]:bg-neutral-alphas-600 disabled:data-[state=checked]:text-content-tertiary\",\n !hasLabel && className,\n )}\n >\n <CheckboxPrimitive.Indicator\n forceMount\n className={cn(\n \"flex items-center justify-center text-content-primary-inverted\",\n INDICATOR_SIZE_CLASS[boxSize],\n \"data-[state=unchecked]:invisible\",\n )}\n >\n {props.checked === \"indeterminate\" ? <MinusIcon /> : <CheckIcon />}\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n </span>\n );\n\n if (!hasLabel) {\n return checkboxElement;\n }\n\n return (\n <div\n className={cn(\n \"inline-flex flex-col gap-0.5\",\n disabled && \"is-disabled cursor-not-allowed\",\n className,\n )}\n >\n <div className=\"group inline-flex items-start gap-2\">\n {checkboxElement}\n {label && (\n <label\n htmlFor={id}\n className={cn(\n \"cursor-pointer select-none text-content-primary\",\n \"group-has-disabled:cursor-not-allowed group-has-disabled:text-content-tertiary\",\n useSmallLabelTypography\n ? \"typography-semibold-body-md\"\n : \"typography-semibold-body-lg\",\n )}\n >\n {label}\n </label>\n )}\n </div>\n {helperText && (\n <span\n id={helperTextId}\n className={cn(\n \"ml-7 text-content-secondary\",\n \"in-[.is-disabled]:cursor-not-allowed in-[.is-disabled]:text-content-tertiary\",\n useSmallLabelTypography ? \"typography-regular-body-sm\" : \"typography-regular-body-md\",\n )}\n >\n {helperText}\n </span>\n )}\n </div>\n );\n },\n);\n\nCheckbox.displayName = \"Checkbox\";\n"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,19 @@ import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { cn } from "../../utils/cn.mjs";
|
|
7
7
|
import { FLOATING_CONTENT_COLLISION_PADDING } from "../../utils/floatingContentCollisionPadding.mjs";
|
|
8
|
+
import { IconButton } from "../IconButton/IconButton.mjs";
|
|
9
|
+
import { CloseIcon } from "../Icons/CloseIcon.mjs";
|
|
10
|
+
import { SearchIcon } from "../Icons/SearchIcon.mjs";
|
|
8
11
|
const TAP_MOVEMENT_THRESHOLD_PX = 10;
|
|
12
|
+
const NAVIGATION_KEYS = /* @__PURE__ */ new Set([
|
|
13
|
+
"ArrowDown",
|
|
14
|
+
"ArrowUp",
|
|
15
|
+
"ArrowLeft",
|
|
16
|
+
"ArrowRight",
|
|
17
|
+
"Escape",
|
|
18
|
+
"Tab",
|
|
19
|
+
"Enter"
|
|
20
|
+
]);
|
|
9
21
|
const ToggleOpenContext = React.createContext(null);
|
|
10
22
|
function DropdownMenu({
|
|
11
23
|
open: openProp,
|
|
@@ -91,7 +103,7 @@ const DropdownMenuContent = React.forwardRef(
|
|
|
91
103
|
sideOffset,
|
|
92
104
|
collisionPadding,
|
|
93
105
|
className: cn(
|
|
94
|
-
"w-max min-w-(--radix-dropdown-menu-trigger-width) max-w-(--radix-dropdown-menu-content-available-width) overflow-y-auto rounded-
|
|
106
|
+
"w-max min-w-(--radix-dropdown-menu-trigger-width) max-w-(--radix-dropdown-menu-content-available-width) overflow-y-auto rounded-sm border border-neutral-alphas-200 bg-surface-primary p-1 text-content-primary shadow-lg",
|
|
95
107
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
96
108
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
97
109
|
"data-[side=top]:slide-in-from-bottom-2 data-[side=bottom]:slide-in-from-top-2",
|
|
@@ -110,18 +122,36 @@ const DropdownMenuContent = React.forwardRef(
|
|
|
110
122
|
DropdownMenuContent.displayName = "DropdownMenuContent";
|
|
111
123
|
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
112
124
|
DropdownMenuGroup.displayName = "DropdownMenuGroup";
|
|
113
|
-
const DropdownMenuLabel = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
125
|
+
const DropdownMenuLabel = React.forwardRef(({ className, position = "default", ...props }, ref) => /* @__PURE__ */ jsx(
|
|
114
126
|
DropdownMenuPrimitive.Label,
|
|
115
127
|
{
|
|
116
128
|
ref,
|
|
117
|
-
className: cn(
|
|
129
|
+
className: cn(
|
|
130
|
+
"typography-regular-body-sm flex items-center px-3 text-content-secondary",
|
|
131
|
+
position === "top" ? "py-2" : "pb-2 pt-4",
|
|
132
|
+
className
|
|
133
|
+
),
|
|
118
134
|
...props
|
|
119
135
|
}
|
|
120
136
|
));
|
|
121
137
|
DropdownMenuLabel.displayName = "DropdownMenuLabel";
|
|
138
|
+
const SIZE_NORMALIZED = {
|
|
139
|
+
"40": "40",
|
|
140
|
+
md: "40",
|
|
141
|
+
"32": "32",
|
|
142
|
+
sm: "32"
|
|
143
|
+
};
|
|
144
|
+
const ITEM_SIZE_CLASSES = {
|
|
145
|
+
"40": "min-h-10 py-2 typography-regular-body-lg",
|
|
146
|
+
"32": "min-h-8 py-[7px] typography-regular-body-md"
|
|
147
|
+
};
|
|
148
|
+
const ITEM_SELECTED_TYPOGRAPHY = {
|
|
149
|
+
"40": "typography-semibold-body-lg",
|
|
150
|
+
"32": "typography-semibold-body-md"
|
|
151
|
+
};
|
|
122
152
|
const DropdownMenuItem = React.forwardRef(
|
|
123
153
|
({
|
|
124
|
-
size = "
|
|
154
|
+
size = "40",
|
|
125
155
|
destructive,
|
|
126
156
|
leadingIcon,
|
|
127
157
|
trailingIcon,
|
|
@@ -131,14 +161,18 @@ const DropdownMenuItem = React.forwardRef(
|
|
|
131
161
|
asChild,
|
|
132
162
|
...props
|
|
133
163
|
}, ref) => {
|
|
164
|
+
const normalizedSize = SIZE_NORMALIZED[size];
|
|
134
165
|
const itemClassName = cn(
|
|
135
|
-
"flex w-full cursor-pointer items-center gap-
|
|
136
|
-
|
|
137
|
-
"data-[highlighted]:bg-neutral-alphas-
|
|
138
|
-
|
|
139
|
-
size === "sm" ? "typography-medium-body-sm" : "typography-medium-body-md",
|
|
166
|
+
"flex w-full cursor-pointer items-center gap-2 rounded-xs px-3 outline-none",
|
|
167
|
+
ITEM_SIZE_CLASSES[normalizedSize],
|
|
168
|
+
"data-[highlighted]:bg-neutral-alphas-50",
|
|
169
|
+
"data-[disabled]:cursor-not-allowed data-[disabled]:text-content-disabled",
|
|
140
170
|
destructive && "text-error-content",
|
|
141
|
-
selected &&
|
|
171
|
+
selected && [
|
|
172
|
+
"bg-buttons-primary text-content-primary-inverted",
|
|
173
|
+
"data-[highlighted]:bg-buttons-primary",
|
|
174
|
+
ITEM_SELECTED_TYPOGRAPHY[normalizedSize]
|
|
175
|
+
],
|
|
142
176
|
className
|
|
143
177
|
);
|
|
144
178
|
if (asChild) {
|
|
@@ -146,7 +180,7 @@ const DropdownMenuItem = React.forwardRef(
|
|
|
146
180
|
}
|
|
147
181
|
return /* @__PURE__ */ jsxs(DropdownMenuPrimitive.Item, { ref, className: itemClassName, ...props, children: [
|
|
148
182
|
leadingIcon,
|
|
149
|
-
/* @__PURE__ */ jsx("span", { className: "flex-1", children }),
|
|
183
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children }),
|
|
150
184
|
trailingIcon
|
|
151
185
|
] });
|
|
152
186
|
}
|
|
@@ -161,12 +195,156 @@ const DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) =>
|
|
|
161
195
|
}
|
|
162
196
|
));
|
|
163
197
|
DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
|
|
198
|
+
const DropdownMenuHeader = React.forwardRef(
|
|
199
|
+
({
|
|
200
|
+
type = "default",
|
|
201
|
+
size = "40",
|
|
202
|
+
title,
|
|
203
|
+
searchProps,
|
|
204
|
+
showClose = true,
|
|
205
|
+
onClose,
|
|
206
|
+
closeLabel = "Close menu",
|
|
207
|
+
className,
|
|
208
|
+
children,
|
|
209
|
+
...props
|
|
210
|
+
}, ref) => {
|
|
211
|
+
const titleTypography = size === "32" ? "typography-semibold-body-md" : "typography-semibold-body-lg";
|
|
212
|
+
const toggleOpen = React.useContext(ToggleOpenContext);
|
|
213
|
+
const handleClose = () => {
|
|
214
|
+
onClose?.();
|
|
215
|
+
toggleOpen?.(() => false);
|
|
216
|
+
};
|
|
217
|
+
return /* @__PURE__ */ jsxs(
|
|
218
|
+
"div",
|
|
219
|
+
{
|
|
220
|
+
ref,
|
|
221
|
+
className: cn(
|
|
222
|
+
"flex flex-col px-1 pt-1 mb-1",
|
|
223
|
+
// Search needs an 8px gap between the input and the divider; the
|
|
224
|
+
// default (title) variant uses 4px because the title baseline sits
|
|
225
|
+
// closer to the divider naturally.
|
|
226
|
+
type === "search" ? "gap-2" : "gap-1",
|
|
227
|
+
className
|
|
228
|
+
),
|
|
229
|
+
...props,
|
|
230
|
+
children: [
|
|
231
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 pl-2", children: [
|
|
232
|
+
type === "default" ? /* @__PURE__ */ jsx("div", { className: cn("min-w-0 flex-1 truncate text-content-primary", titleTypography), children: children ?? title }) : /* @__PURE__ */ jsx(SearchInput, { ...searchProps }),
|
|
233
|
+
showClose && /* @__PURE__ */ jsx(
|
|
234
|
+
IconButton,
|
|
235
|
+
{
|
|
236
|
+
variant: "tertiary",
|
|
237
|
+
size: "32",
|
|
238
|
+
icon: /* @__PURE__ */ jsx(CloseIcon, {}),
|
|
239
|
+
onClick: handleClose,
|
|
240
|
+
"aria-label": closeLabel
|
|
241
|
+
}
|
|
242
|
+
)
|
|
243
|
+
] }),
|
|
244
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, { className: "my-0" })
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
);
|
|
250
|
+
DropdownMenuHeader.displayName = "DropdownMenuHeader";
|
|
251
|
+
function SearchInput({
|
|
252
|
+
value,
|
|
253
|
+
defaultValue,
|
|
254
|
+
onChange,
|
|
255
|
+
placeholder = "Search…",
|
|
256
|
+
"aria-label": ariaLabel = "Search"
|
|
257
|
+
} = {}) {
|
|
258
|
+
return /* @__PURE__ */ jsxs(
|
|
259
|
+
"label",
|
|
260
|
+
{
|
|
261
|
+
className: cn(
|
|
262
|
+
"flex min-w-0 flex-1 items-center gap-2 rounded-xs border border-border-primary",
|
|
263
|
+
"bg-neutral-alphas-50 px-3 py-1 text-content-primary",
|
|
264
|
+
"focus-within:shadow-focus-ring focus-within:outline-none"
|
|
265
|
+
),
|
|
266
|
+
children: [
|
|
267
|
+
/* @__PURE__ */ jsx(SearchIcon, { className: "size-4 shrink-0 text-content-tertiary", "aria-hidden": "true" }),
|
|
268
|
+
/* @__PURE__ */ jsx(
|
|
269
|
+
"input",
|
|
270
|
+
{
|
|
271
|
+
type: "search",
|
|
272
|
+
className: cn(
|
|
273
|
+
"typography-regular-body-lg min-w-0 flex-1 bg-transparent outline-none",
|
|
274
|
+
"placeholder:text-content-tertiary"
|
|
275
|
+
),
|
|
276
|
+
value,
|
|
277
|
+
defaultValue,
|
|
278
|
+
placeholder,
|
|
279
|
+
"aria-label": ariaLabel,
|
|
280
|
+
onChange: (event) => onChange?.(event.target.value),
|
|
281
|
+
onKeyDown: (event) => {
|
|
282
|
+
if (!NAVIGATION_KEYS.has(event.key)) event.stopPropagation();
|
|
283
|
+
},
|
|
284
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
285
|
+
onMouseDown: (event) => event.stopPropagation()
|
|
286
|
+
}
|
|
287
|
+
)
|
|
288
|
+
]
|
|
289
|
+
}
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
293
|
+
const DropdownMenuRadioItem = React.forwardRef(({ className, children, helper, size: _size = "40", ...props }, ref) => {
|
|
294
|
+
return /* @__PURE__ */ jsxs(
|
|
295
|
+
DropdownMenuPrimitive.RadioItem,
|
|
296
|
+
{
|
|
297
|
+
ref,
|
|
298
|
+
className: cn(
|
|
299
|
+
"group flex w-full cursor-pointer items-start gap-3 rounded-xs px-4 py-2 outline-none",
|
|
300
|
+
"data-[highlighted]:bg-neutral-alphas-50",
|
|
301
|
+
"data-[disabled]:cursor-not-allowed data-[disabled]:text-content-disabled",
|
|
302
|
+
"data-[state=checked]:bg-buttons-primary data-[state=checked]:text-content-primary-inverted",
|
|
303
|
+
"data-[state=checked]:data-[highlighted]:bg-buttons-primary",
|
|
304
|
+
className
|
|
305
|
+
),
|
|
306
|
+
...props,
|
|
307
|
+
children: [
|
|
308
|
+
/* @__PURE__ */ jsx(
|
|
309
|
+
"span",
|
|
310
|
+
{
|
|
311
|
+
className: cn(
|
|
312
|
+
"mt-1 flex size-4 shrink-0 items-center justify-center rounded-full border border-icons-primary",
|
|
313
|
+
"group-data-[disabled]:border-content-disabled",
|
|
314
|
+
"group-data-[state=checked]:border-icons-primary-inverted"
|
|
315
|
+
),
|
|
316
|
+
"aria-hidden": "true",
|
|
317
|
+
children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "size-2 rounded-full bg-content-primary-inverted" }) })
|
|
318
|
+
}
|
|
319
|
+
),
|
|
320
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
321
|
+
/* @__PURE__ */ jsx("span", { className: "typography-semibold-body-lg truncate", children }),
|
|
322
|
+
helper && /* @__PURE__ */ jsx(
|
|
323
|
+
"span",
|
|
324
|
+
{
|
|
325
|
+
className: cn(
|
|
326
|
+
"typography-regular-body-sm text-content-secondary",
|
|
327
|
+
"group-data-[state=checked]:text-content-primary-inverted",
|
|
328
|
+
"group-data-[disabled]:text-content-disabled"
|
|
329
|
+
),
|
|
330
|
+
children: helper
|
|
331
|
+
}
|
|
332
|
+
)
|
|
333
|
+
] })
|
|
334
|
+
]
|
|
335
|
+
}
|
|
336
|
+
);
|
|
337
|
+
});
|
|
338
|
+
DropdownMenuRadioItem.displayName = "DropdownMenuRadioItem";
|
|
164
339
|
export {
|
|
165
340
|
DropdownMenu,
|
|
166
341
|
DropdownMenuContent,
|
|
167
342
|
DropdownMenuGroup,
|
|
343
|
+
DropdownMenuHeader,
|
|
168
344
|
DropdownMenuItem,
|
|
169
345
|
DropdownMenuLabel,
|
|
346
|
+
DropdownMenuRadioGroup,
|
|
347
|
+
DropdownMenuRadioItem,
|
|
170
348
|
DropdownMenuSeparator,
|
|
171
349
|
DropdownMenuTrigger
|
|
172
350
|
};
|