@jiwambe/components 0.3.4 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +10 -0
- package/dist/client.js.map +1 -1
- package/dist/components/Accordion/Accordion.test.d.ts +2 -0
- package/dist/components/Accordion/Accordion.test.d.ts.map +1 -0
- package/dist/components/BarGraph/BarGraph.d.ts +66 -0
- package/dist/components/BarGraph/BarGraph.d.ts.map +1 -0
- package/dist/components/BarGraph/BarGraph.js +151 -0
- package/dist/components/BarGraph/BarGraph.js.map +1 -0
- package/dist/components/BarGraph/BarGraph.test.d.ts +1 -0
- package/dist/components/BarGraph/BarGraph.test.d.ts.map +1 -0
- package/dist/components/BarGraph/BarGraphSkeleton.d.ts +12 -0
- package/dist/components/BarGraph/BarGraphSkeleton.d.ts.map +1 -0
- package/dist/components/BarGraph/BarGraphSkeleton.js +36 -0
- package/dist/components/BarGraph/BarGraphSkeleton.js.map +1 -0
- package/dist/components/Box/Box.test.d.ts +15 -0
- package/dist/components/Box/Box.test.d.ts.map +1 -0
- package/dist/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
- package/dist/components/Breadcrumb/Breadcrumb.js +89 -0
- package/dist/components/Breadcrumb/Breadcrumb.js.map +1 -0
- package/dist/components/Button/Button.test.d.ts +2 -0
- package/dist/components/Button/Button.test.d.ts.map +1 -0
- package/dist/components/Card/Card.d.ts +57 -43
- package/dist/components/Card/Card.d.ts.map +1 -1
- package/dist/components/Card/Card.js +51 -89
- package/dist/components/Card/Card.js.map +1 -1
- package/dist/components/Card/Card.test.d.ts +2 -0
- package/dist/components/Card/Card.test.d.ts.map +1 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.test.d.ts +2 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.test.d.ts.map +1 -0
- package/dist/components/Container/Container.test.d.ts +2 -0
- package/dist/components/Container/Container.test.d.ts.map +1 -0
- package/dist/components/DataTable/DataTable.d.ts +74 -0
- package/dist/components/DataTable/DataTable.d.ts.map +1 -0
- package/dist/components/DataTable/DataTable.js +183 -0
- package/dist/components/DataTable/DataTable.js.map +1 -0
- package/dist/components/DataTable/DataTable.test.d.ts +2 -0
- package/dist/components/DataTable/DataTable.test.d.ts.map +1 -0
- package/dist/components/DataTable/DataTableCell.d.ts +15 -0
- package/dist/components/DataTable/DataTableCell.d.ts.map +1 -0
- package/dist/components/DataTable/DataTableCell.js +24 -0
- package/dist/components/DataTable/DataTableCell.js.map +1 -0
- package/dist/components/DataTable/DataTableHeader.d.ts +31 -0
- package/dist/components/DataTable/DataTableHeader.d.ts.map +1 -0
- package/dist/components/DataTable/DataTableHeader.js +83 -0
- package/dist/components/DataTable/DataTableHeader.js.map +1 -0
- package/dist/components/DataTable/DataTablePagination.d.ts +26 -0
- package/dist/components/DataTable/DataTablePagination.d.ts.map +1 -0
- package/dist/components/DataTable/DataTablePagination.js +115 -0
- package/dist/components/DataTable/DataTablePagination.js.map +1 -0
- package/dist/components/DataTable/DataTableReviewerCell.d.ts +18 -0
- package/dist/components/DataTable/DataTableReviewerCell.d.ts.map +1 -0
- package/dist/components/DataTable/DataTableReviewerCell.js +31 -0
- package/dist/components/DataTable/DataTableReviewerCell.js.map +1 -0
- package/dist/components/DataTable/DataTableRow.d.ts +35 -0
- package/dist/components/DataTable/DataTableRow.d.ts.map +1 -0
- package/dist/components/DataTable/DataTableRow.js +77 -0
- package/dist/components/DataTable/DataTableRow.js.map +1 -0
- package/dist/components/DataTable/DataTableRowMenu.d.ts +25 -0
- package/dist/components/DataTable/DataTableRowMenu.d.ts.map +1 -0
- package/dist/components/DataTable/DataTableRowMenu.js +60 -0
- package/dist/components/DataTable/DataTableRowMenu.js.map +1 -0
- package/dist/components/DataTable/DataTableStatusBadge.d.ts +16 -0
- package/dist/components/DataTable/DataTableStatusBadge.d.ts.map +1 -0
- package/dist/components/DataTable/DataTableStatusBadge.js +37 -0
- package/dist/components/DataTable/DataTableStatusBadge.js.map +1 -0
- package/dist/components/DataTable/DataTableToolbar.d.ts +32 -0
- package/dist/components/DataTable/DataTableToolbar.d.ts.map +1 -0
- package/dist/components/DataTable/DataTableToolbar.js +37 -0
- package/dist/components/DataTable/DataTableToolbar.js.map +1 -0
- package/dist/components/DateInput/DateInput.test.d.ts +2 -0
- package/dist/components/DateInput/DateInput.test.d.ts.map +1 -0
- package/dist/components/Dialog/Dialog.d.ts +28 -0
- package/dist/components/Dialog/Dialog.d.ts.map +1 -0
- package/dist/components/Dialog/Dialog.js +34 -0
- package/dist/components/Dialog/Dialog.js.map +1 -0
- package/dist/components/Dialog/Dialog.test.d.ts +2 -0
- package/dist/components/Dialog/Dialog.test.d.ts.map +1 -0
- package/dist/components/Divider/Divider.test.d.ts +2 -0
- package/dist/components/Divider/Divider.test.d.ts.map +1 -0
- package/dist/components/Drawer/Drawer.test.d.ts +2 -0
- package/dist/components/Drawer/Drawer.test.d.ts.map +1 -0
- package/dist/components/FAQ/FAQ.test.d.ts +2 -0
- package/dist/components/FAQ/FAQ.test.d.ts.map +1 -0
- package/dist/components/Grid/Grid.d.ts +6 -6
- package/dist/components/Grid/Grid.js.map +1 -1
- package/dist/components/Grid/Grid.test.d.ts +2 -0
- package/dist/components/Grid/Grid.test.d.ts.map +1 -0
- package/dist/components/Icon/Icon.d.ts +17 -13
- package/dist/components/Icon/Icon.d.ts.map +1 -1
- package/dist/components/Icon/Icon.js +12 -162
- package/dist/components/Icon/Icon.js.map +1 -1
- package/dist/components/Icon/Icon.test.d.ts +2 -0
- package/dist/components/Icon/Icon.test.d.ts.map +1 -0
- package/dist/components/JiwambeCard/JiwambeCard.d.ts +54 -0
- package/dist/components/JiwambeCard/JiwambeCard.d.ts.map +1 -0
- package/dist/components/JiwambeCard/JiwambeCard.js +101 -0
- package/dist/components/JiwambeCard/JiwambeCard.js.map +1 -0
- package/dist/components/JiwambeCard/JiwambeCard.test.d.ts +2 -0
- package/dist/components/JiwambeCard/JiwambeCard.test.d.ts.map +1 -0
- package/dist/components/LineGraph/LineGraph.d.ts +40 -0
- package/dist/components/LineGraph/LineGraph.d.ts.map +1 -0
- package/dist/components/LineGraph/LineGraph.js +176 -0
- package/dist/components/LineGraph/LineGraph.js.map +1 -0
- package/dist/components/LineGraph/LineGraph.test.d.ts +1 -0
- package/dist/components/LineGraph/LineGraph.test.d.ts.map +1 -0
- package/dist/components/LineGraph/LineGraphLegend.d.ts +17 -0
- package/dist/components/LineGraph/LineGraphLegend.d.ts.map +1 -0
- package/dist/components/LineGraph/LineGraphLegend.js +56 -0
- package/dist/components/LineGraph/LineGraphLegend.js.map +1 -0
- package/dist/components/LineGraph/LineGraphSkeleton.d.ts +12 -0
- package/dist/components/LineGraph/LineGraphSkeleton.d.ts.map +1 -0
- package/dist/components/LineGraph/LineGraphSkeleton.js +21 -0
- package/dist/components/LineGraph/LineGraphSkeleton.js.map +1 -0
- package/dist/components/LineGraph/LineGraphTooltip.d.ts +12 -0
- package/dist/components/LineGraph/LineGraphTooltip.d.ts.map +1 -0
- package/dist/components/LineGraph/LineGraphTooltip.js +41 -0
- package/dist/components/LineGraph/LineGraphTooltip.js.map +1 -0
- package/dist/components/LineGraph/lineGraphUtils.d.ts +33 -0
- package/dist/components/LineGraph/lineGraphUtils.d.ts.map +1 -0
- package/dist/components/LineGraph/lineGraphUtils.js +62 -0
- package/dist/components/LineGraph/lineGraphUtils.js.map +1 -0
- package/dist/components/LineGraph/types.d.ts +21 -0
- package/dist/components/LineGraph/types.d.ts.map +1 -0
- package/dist/components/Link/Link.test.d.ts +2 -0
- package/dist/components/Link/Link.test.d.ts.map +1 -0
- package/dist/components/List/List.d.ts +5 -3
- package/dist/components/List/List.d.ts.map +1 -1
- package/dist/components/List/List.js +35 -6
- package/dist/components/List/List.js.map +1 -1
- package/dist/components/List/List.test.d.ts +2 -0
- package/dist/components/List/List.test.d.ts.map +1 -0
- package/dist/components/Overlay/Overlay.test.d.ts +2 -0
- package/dist/components/Overlay/Overlay.test.d.ts.map +1 -0
- package/dist/components/PhoneInput/PhoneInput.test.d.ts +2 -0
- package/dist/components/PhoneInput/PhoneInput.test.d.ts.map +1 -0
- package/dist/components/Popover/Popover.test.d.ts +2 -0
- package/dist/components/Popover/Popover.test.d.ts.map +1 -0
- package/dist/components/ProductCard/ProductCard.d.ts +12 -0
- package/dist/components/ProductCard/ProductCard.d.ts.map +1 -1
- package/dist/components/ProductCard/ProductCard.js +25 -10
- package/dist/components/ProductCard/ProductCard.js.map +1 -1
- package/dist/components/ProductCard/ProductCard.test.d.ts +2 -0
- package/dist/components/ProductCard/ProductCard.test.d.ts.map +1 -0
- package/dist/components/ProductImage/ProductImage.test.d.ts +2 -0
- package/dist/components/ProductImage/ProductImage.test.d.ts.map +1 -0
- package/dist/components/RadioGroup/RadioGroup.test.d.ts +2 -0
- package/dist/components/RadioGroup/RadioGroup.test.d.ts.map +1 -0
- package/dist/components/Section/Section.test.d.ts +2 -0
- package/dist/components/Section/Section.test.d.ts.map +1 -0
- package/dist/components/Select/Select.test.d.ts +2 -0
- package/dist/components/Select/Select.test.d.ts.map +1 -0
- package/dist/components/SelectTab/SelectTab.test.d.ts +2 -0
- package/dist/components/SelectTab/SelectTab.test.d.ts.map +1 -0
- package/dist/components/Skeleton/Skeleton.d.ts +4 -4
- package/dist/components/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/components/Skeleton/Skeleton.js +1 -1
- package/dist/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.test.d.ts +2 -0
- package/dist/components/Skeleton/Skeleton.test.d.ts.map +1 -0
- package/dist/components/Slider/Slider.test.d.ts +2 -0
- package/dist/components/Slider/Slider.test.d.ts.map +1 -0
- package/dist/components/Stack/Stack.test.d.ts +2 -0
- package/dist/components/Stack/Stack.test.d.ts.map +1 -0
- package/dist/components/Tab/Tab.test.d.ts +2 -0
- package/dist/components/Tab/Tab.test.d.ts.map +1 -0
- package/dist/components/TextArea/TextArea.test.d.ts +2 -0
- package/dist/components/TextArea/TextArea.test.d.ts.map +1 -0
- package/dist/components/TextInput/TextInput.test.d.ts +2 -0
- package/dist/components/TextInput/TextInput.test.d.ts.map +1 -0
- package/dist/components/Toggle/Toggle.test.d.ts +2 -0
- package/dist/components/Toggle/Toggle.test.d.ts.map +1 -0
- package/dist/components/Typography/Typography.test.d.ts +15 -0
- package/dist/components/Typography/Typography.test.d.ts.map +1 -0
- package/dist/components/UploadInput/UploadInput.test.d.ts +2 -0
- package/dist/components/UploadInput/UploadInput.test.d.ts.map +1 -0
- package/dist/components/index.d.ts +18 -3
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/node_modules/.pnpm/@jiwambe_icons@0.3.1_react@19.2.4/node_modules/@jiwambe/icons/dist/icons/Check.js +10 -0
- package/dist/node_modules/.pnpm/@jiwambe_icons@0.3.1_react@19.2.4/node_modules/@jiwambe/icons/dist/icons/Check.js.map +1 -0
- package/dist/node_modules/.pnpm/@jiwambe_icons@0.3.1_react@19.2.4/node_modules/@jiwambe/icons/dist/icons/ChevronLeft.js +10 -0
- package/dist/node_modules/.pnpm/@jiwambe_icons@0.3.1_react@19.2.4/node_modules/@jiwambe/icons/dist/icons/ChevronLeft.js.map +1 -0
- package/dist/node_modules/.pnpm/@jiwambe_icons@0.3.1_react@19.2.4/node_modules/@jiwambe/icons/dist/icons/ChevronRight.js +10 -0
- package/dist/node_modules/.pnpm/@jiwambe_icons@0.3.1_react@19.2.4/node_modules/@jiwambe/icons/dist/icons/ChevronRight.js.map +1 -0
- package/dist/plugin/jiwambe-plugin.d.ts.map +1 -1
- package/dist/plugin/jiwambe-plugin.js +5 -0
- package/dist/plugin/jiwambe-plugin.js.map +1 -1
- package/dist/server.d.ts +3 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -2
- package/dist/types/list.d.ts +4 -3
- package/dist/types/list.d.ts.map +1 -1
- package/dist/types/list.js.map +1 -1
- package/dist/utils/layoutClasses.test.d.ts +2 -0
- package/dist/utils/layoutClasses.test.d.ts.map +1 -0
- package/dist/utils/spacing.test.d.ts +2 -0
- package/dist/utils/spacing.test.d.ts.map +1 -0
- package/package.json +5 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTable.js","sources":["../../../src/components/DataTable/DataTable.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useCallback, useMemo } from 'react';\nimport { DataTableToolbar, DataTableTab } from './DataTableToolbar';\nimport { DataTableHeader, ColumnDef } from './DataTableHeader';\nimport { DataTableRow } from './DataTableRow';\nimport { DataTablePagination } from './DataTablePagination';\nimport { DataTableStatusBadge } from './DataTableStatusBadge';\nimport { DataTableReviewerCell } from './DataTableReviewerCell';\nimport { DataTableCell } from './DataTableCell';\nimport { DataTableRowMenu } from './DataTableRowMenu';\nimport type { DataTableAction } from './DataTableRowMenu';\nimport { Skeleton } from '../Skeleton/Skeleton';\n\n/**\n * Props for the DataTable component.\n */\nexport interface DataTableProps<TRow extends Record<string, unknown>> {\n /** All rows of data. */\n rows: TRow[];\n /** Column definitions. */\n columns: ColumnDef<TRow>[];\n /** Tab definitions rendered in the toolbar. @default [] */\n tabs?: DataTableTab[];\n /** Currently active tab id. @default undefined */\n activeTab?: string;\n /** Fired when the active tab changes. */\n onTabChange?: (tabId: string) => void;\n /** Called when row order changes after drag-and-drop. */\n onRowReorder?: (fromIndex: number, toIndex: number) => void;\n /** Called when row selection changes. */\n onSelectionChange?: (selectedRows: TRow[]) => void;\n /** Controlled page index (0-based). @default 0 */\n page?: number;\n /** Fired when the page changes. */\n onPageChange?: (page: number) => void;\n /** Controlled rows per page. @default 10 */\n pageSize?: number;\n /** Fired when the number of rows per page changes. */\n onPageSizeChange?: (size: number) => void;\n /** Total row count for server-side pagination. @default rows.length */\n totalRows?: number;\n /** Show skeleton loading rows. @default false */\n loading?: boolean;\n /** Number of skeleton rows to render while loading. @default 5 */\n loadingRowCount?: number;\n /** Label shown in selection summary. @default 'row(s) selected' */\n selectionLabel?: string;\n /** When false, hides row and header checkboxes. @default true */\n selectable?: boolean;\n /** Actions for each row’s trailing ⋮ menu (built-in column). */\n getRowActions?: (row: TRow) => DataTableAction[];\n /** Additional class names for the wrapper. */\n className?: string;\n}\n\n/**\n * A comprehensive Data Table component with support for tabs, selection,\n * sorting, pagination, and drag-and-drop reordering. Follows Jiwambe design tokens.\n *\n * @example\n * <DataTable\n * rows={data}\n * columns={columns}\n * tabs={[{ id: 'all', label: 'All', count: 12 }, { id: 'pending', label: 'Pending' }]}\n * activeTab=\"all\"\n * loading={isLoading}\n * />\n */\nexport function DataTable<TRow extends Record<string, unknown>>({\n rows,\n columns,\n tabs = [],\n activeTab,\n onTabChange,\n onRowReorder,\n onSelectionChange,\n page = 0,\n onPageChange,\n pageSize = 10,\n onPageSizeChange,\n totalRows,\n loading = false,\n loadingRowCount = 5,\n selectionLabel = 'row(s) selected',\n selectable = true,\n getRowActions,\n className = '',\n}: DataTableProps<TRow>) {\n // --- Selection State ---\n const [selectedIds, setSelectedIds] = useState<Set<string | number>>(new Set());\n\n const handleSelectRow = useCallback((row: TRow, isSelected: boolean) => {\n const idField = 'id' in row ? (row.id as string | number) : JSON.stringify(row);\n setSelectedIds(prev => {\n const next = new Set(prev);\n if (isSelected) next.add(idField);\n else next.delete(idField);\n \n // Notify parent\n const selectedRows = rows.filter(r => {\n const rId = 'id' in r ? (r.id as string | number) : JSON.stringify(r);\n return next.has(rId);\n });\n onSelectionChange?.(selectedRows);\n \n return next;\n });\n }, [rows, onSelectionChange]);\n\n const handleSelectAll = useCallback((isSelected: boolean) => {\n if (isSelected) {\n const allIds = rows.map(r => ('id' in r ? (r.id as string | number) : JSON.stringify(r)));\n setSelectedIds(new Set(allIds));\n onSelectionChange?.(rows);\n } else {\n setSelectedIds(new Set());\n onSelectionChange?.([]);\n }\n }, [rows, onSelectionChange]);\n\n const allSelected = useMemo(() => \n rows.length > 0 && selectedIds.size === rows.length,\n [rows.length, selectedIds.size]);\n\n // --- Sorting State (local for demonstration, usually parent-controlled) ---\n const [sortCol, setSortCol] = useState<string | undefined>();\n const [sortDir, setSortDir] = useState<'asc' | 'desc' | undefined>();\n\n const handleSort = (columnId: string) => {\n if (sortCol === columnId) {\n setSortDir(prev => prev === 'asc' ? 'desc' : 'asc');\n } else {\n setSortCol(columnId);\n setSortDir('asc');\n }\n };\n\n // --- Drag and Drop State ---\n const [draggedIndex, setDraggedIndex] = useState<number | null>(null);\n\n const handleDragStart = (e: React.DragEvent, index: number) => {\n setDraggedIndex(index);\n e.dataTransfer.effectAllowed = 'move';\n // Required for some browsers\n e.dataTransfer.setData('text/plain', index.toString());\n };\n\n const handleDragOver = (e: React.DragEvent) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n };\n\n const handleDrop = (e: React.DragEvent, index: number) => {\n e.preventDefault();\n if (draggedIndex !== null && draggedIndex !== index) {\n onRowReorder?.(draggedIndex, index);\n }\n setDraggedIndex(null);\n };\n\n return (\n <div className={['flex flex-col w-full border border-border-light rounded-rad-md overflow-hidden bg-fill-bg-primary', className].filter(Boolean).join(' ')}>\n {/* Toolbar */}\n {(tabs.length > 0 || onTabChange) && (\n <DataTableToolbar\n tabs={tabs}\n activeTab={activeTab}\n onTabChange={onTabChange}\n className=\"px-space-4\"\n />\n )}\n\n {/* Table Container */}\n <div className=\"overflow-x-auto\">\n <table className=\"w-full border-collapse\">\n <DataTableHeader\n columns={columns}\n allSelected={allSelected}\n onSelectAll={handleSelectAll}\n sortColumn={sortCol}\n sortDirection={sortDir}\n onSort={handleSort}\n reorderable={!!onRowReorder}\n selectable={selectable}\n />\n <tbody>\n {loading ? (\n // Skeleton Loading State\n Array.from({ length: loadingRowCount }).map((_, idx) => (\n <tr key={`skeleton-${idx}`} className=\"border-b border-border-light last:border-none\">\n {selectable && (\n <td className=\"p-space-4 w-[80px]\">\n <div className=\"flex items-center gap-space-2 text-left\">\n {onRowReorder && <Skeleton width=\"1rem\" height=\"1rem\" radius=\"xs\" />}\n <Skeleton width=\"1.25rem\" height=\"1.25rem\" radius=\"xs\" />\n </div>\n </td>\n )}\n {columns.map((col) => (\n <td key={col.id} className=\"p-space-4\">\n <Skeleton.Text width=\"70%\" />\n </td>\n ))}\n <td className=\"p-space-4 w-[60px]\"></td>\n </tr>\n ))\n ) : rows.length === 0 ? (\n // Empty State\n <tr>\n <td\n colSpan={columns.length + (selectable ? 1 : 0) + 1}\n className=\"p-space-12 text-center text-text-secondary\"\n >\n No data found.\n </td>\n </tr>\n ) : (\n // Data Rows\n rows.map((row, idx) => {\n const id = 'id' in row ? (row.id as string | number) : JSON.stringify(row);\n return (\n <DataTableRow\n key={id}\n row={row}\n rowIndex={idx}\n columns={columns}\n selected={selectedIds.has(id)}\n onSelect={(isSelected) => handleSelectRow(row, isSelected)}\n onDragStart={onRowReorder ? handleDragStart : undefined}\n onDragOver={onRowReorder ? handleDragOver : undefined}\n onDrop={onRowReorder ? handleDrop : undefined}\n reorderable={!!onRowReorder}\n selectable={selectable}\n actions={getRowActions?.(row) ?? []}\n />\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n {/* Pagination Footer */}\n {(onPageChange || onPageSizeChange) && (\n <DataTablePagination\n page={page}\n pageSize={pageSize}\n totalRows={totalRows ?? rows.length}\n selectedCount={selectedIds.size}\n selectionLabel={selectionLabel}\n onPageChange={onPageChange!}\n onPageSizeChange={onPageSizeChange!}\n hideSelectionSummary={!selectable}\n />\n )}\n </div>\n );\n}\n\n// --- Compound Components ---\nDataTable.Header = DataTableHeader;\nDataTable.Row = DataTableRow;\nDataTable.Cell = DataTableCell;\nDataTable.Toolbar = DataTableToolbar;\nDataTable.Pagination = DataTablePagination;\nDataTable.StatusBadge = DataTableStatusBadge;\nDataTable.ReviewerCell = DataTableReviewerCell;\nDataTable.RowMenu = DataTableRowMenu;\n"],"names":[],"mappings":";;;;;;;;;;;;AAqEO;AAAyD;AAC9D;AACA;AACO;AACP;AACA;AACA;AACA;AACO;AACP;AACW;AACX;AACA;AACU;AACQ;AACD;AACJ;AACb;AAEF;AAEE;AAEA;AACE;AACA;AACE;AACA;AAAgC;AAIhC;AACE;AACA;AAAmB;AAErB;AAEA;AAAO;AACR;AAGH;AACE;AACE;AACA;AACA;AAAoB;AAEpB;AACA;AAAoB;AACtB;AAGF;AAAoB;AAC2B;AACjB;AAG9B;AACA;AAEA;AACE;AACE;AAAkD;AAElD;AACA;AAAgB;AAClB;AAIF;AAEA;AACE;AACA;AAEA;AAAqD;AAGvD;AACE;AACA;AAA4B;AAG9B;AACE;AACA;AACE;AAA6B;AAE/B;AAAoB;AAGtB;AAGM;AACA;AAAC;AAAA;AACC;AACA;AACA;AACU;AAAA;AAAA;AAOV;AAAA;AAAC;AAAA;AACC;AACA;AACa;AACD;AACG;AACP;AACO;AACf;AAAA;AAAA;AAGC;AAAA;AAIM;AAGM;AAAiE;AACX;AAE3D;AAMD;AACkC;AAEtC;AACiB;AAAA;AAGhB;AAAC;AAAA;AACkD;AACvC;AACX;AAAA;AAGH;AAAA;AAAA;AAIE;AACA;AACE;AAAC;AAAA;AAEC;AACU;AACV;AAC4B;AAC6B;AACX;AACF;AACR;AACrB;AACf;AACiC;AAAC;AAX7B;AAAA;AAcV;AAEL;AAEJ;AAIE;AAAC;AAAA;AACC;AACA;AAC6B;AACF;AAC3B;AACA;AACA;AACuB;AAAA;AAAA;AAKjC;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTable.test.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/DataTable.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Props for the DataTableCell component.
|
|
4
|
+
*/
|
|
5
|
+
export interface DataTableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {
|
|
6
|
+
/** Alignment of cell content. @default 'left' */
|
|
7
|
+
align?: 'left' | 'center' | 'right';
|
|
8
|
+
/** Children to render inside the cell. */
|
|
9
|
+
children?: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Generic table cell component (<td>) with alignment support.
|
|
13
|
+
*/
|
|
14
|
+
export declare function DataTableCell({ align, children, className, ...rest }: DataTableCellProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=DataTableCell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTableCell.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/DataTableCell.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;IACtF,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAc,EACd,QAAQ,EACR,SAAc,EACd,GAAG,IAAI,EACR,EAAE,kBAAkB,2CAkBpB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
function DataTableCell({
|
|
4
|
+
align = "left",
|
|
5
|
+
children,
|
|
6
|
+
className = "",
|
|
7
|
+
...rest
|
|
8
|
+
}) {
|
|
9
|
+
const textClass = {
|
|
10
|
+
left: "text-left",
|
|
11
|
+
center: "text-center",
|
|
12
|
+
right: "text-right"
|
|
13
|
+
}[align];
|
|
14
|
+
const classes = [
|
|
15
|
+
"p-space-4 align-middle whitespace-nowrap",
|
|
16
|
+
textClass,
|
|
17
|
+
className
|
|
18
|
+
].filter(Boolean).join(" ");
|
|
19
|
+
return /* @__PURE__ */ jsx("td", { className: classes, ...rest, children });
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
DataTableCell
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=DataTableCell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTableCell.js","sources":["../../../src/components/DataTable/DataTableCell.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\n\n/**\n * Props for the DataTableCell component.\n */\nexport interface DataTableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {\n /** Alignment of cell content. @default 'left' */\n align?: 'left' | 'center' | 'right';\n /** Children to render inside the cell. */\n children?: React.ReactNode;\n}\n\n/**\n * Generic table cell component (<td>) with alignment support.\n */\nexport function DataTableCell({\n align = 'left',\n children,\n className = '',\n ...rest\n}: DataTableCellProps) {\n const textClass = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n }[align];\n\n const classes = [\n 'p-space-4 align-middle whitespace-nowrap',\n textClass,\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <td className={classes} {...rest}>\n {children}\n </td>\n );\n}\n"],"names":[],"mappings":";;AAiBO;AAAuB;AACpB;AACR;AACY;AAEd;AACE;AAAkB;AACV;AACE;AACD;AAGT;AAAgB;AACd;AACA;AACA;AAGF;AAKF;;;;"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Column definition for the DataTable.
|
|
4
|
+
*/
|
|
5
|
+
export interface ColumnDef<TRow> {
|
|
6
|
+
id: string;
|
|
7
|
+
header: string;
|
|
8
|
+
cell?: (row: TRow, rowIndex: number) => React.ReactNode;
|
|
9
|
+
sortable?: boolean;
|
|
10
|
+
width?: string;
|
|
11
|
+
align?: 'left' | 'center' | 'right';
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Props for the DataTableHeader component.
|
|
15
|
+
*/
|
|
16
|
+
export interface DataTableHeaderProps<TRow> {
|
|
17
|
+
columns: ColumnDef<TRow>[];
|
|
18
|
+
allSelected: boolean;
|
|
19
|
+
onSelectAll: (selected: boolean) => void;
|
|
20
|
+
sortColumn?: string;
|
|
21
|
+
sortDirection?: 'asc' | 'desc';
|
|
22
|
+
onSort?: (columnId: string) => void;
|
|
23
|
+
reorderable?: boolean;
|
|
24
|
+
/** When false, the bulk-select column is omitted. @default true */
|
|
25
|
+
selectable?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Header component for the DataTable. Renders <thead><tr>...</tr></thead>.
|
|
29
|
+
*/
|
|
30
|
+
export declare function DataTableHeader<TRow>({ columns, allSelected, onSelectAll, sortColumn, sortDirection, onSort, reorderable, selectable, }: DataTableHeaderProps<TRow>): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
//# sourceMappingURL=DataTableHeader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTableHeader.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/DataTableHeader.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAW1B;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,IAAI;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,IAAI;IACxC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,EACpC,OAAO,EACP,WAAW,EACX,WAAW,EACX,UAAU,EACV,aAAa,EACb,MAAM,EACN,WAAmB,EACnB,UAAiB,GAClB,EAAE,oBAAoB,CAAC,IAAI,CAAC,2CAmF5B"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Typography } from "../Typography/Typography.js";
|
|
4
|
+
import { Icon } from "../Icon/Icon.js";
|
|
5
|
+
function SortIcon({ direction }) {
|
|
6
|
+
if (direction === "asc") return /* @__PURE__ */ jsx(Icon, { icon: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "m18 15-6-6-6 6" }) }), size: 16 });
|
|
7
|
+
if (direction === "desc") return /* @__PURE__ */ jsx(Icon, { icon: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" }) }), size: 16 });
|
|
8
|
+
return /* @__PURE__ */ jsx(Icon, { icon: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "m7 15 5 5 5-5M7 9l5-5 5 5" }) }), size: 16, className: "text-icon-primary-disabled" });
|
|
9
|
+
}
|
|
10
|
+
function DataTableHeader({
|
|
11
|
+
columns,
|
|
12
|
+
allSelected,
|
|
13
|
+
onSelectAll,
|
|
14
|
+
sortColumn,
|
|
15
|
+
sortDirection,
|
|
16
|
+
onSort,
|
|
17
|
+
reorderable = false,
|
|
18
|
+
selectable = true
|
|
19
|
+
}) {
|
|
20
|
+
return /* @__PURE__ */ jsx("thead", { className: "bg-fill-bg-secondary border-b border-border-light", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
21
|
+
selectable && /* @__PURE__ */ jsxs("th", { className: "w-[80px] p-space-4 text-left", "aria-label": "Selection and drag", children: [
|
|
22
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Selection and drag" }),
|
|
23
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-space-2", children: [
|
|
24
|
+
reorderable && /* @__PURE__ */ jsx("div", { className: "w-4 h-4 shrink-0", "aria-hidden": "true" }),
|
|
25
|
+
/* @__PURE__ */ jsxs("label", { className: "relative flex cursor-pointer items-center justify-center h-5 w-5", htmlFor: "select-all-checkbox", children: [
|
|
26
|
+
/* @__PURE__ */ jsx(
|
|
27
|
+
"input",
|
|
28
|
+
{
|
|
29
|
+
id: "select-all-checkbox",
|
|
30
|
+
type: "checkbox",
|
|
31
|
+
className: "peer sr-only",
|
|
32
|
+
checked: allSelected,
|
|
33
|
+
onChange: (e) => onSelectAll(e.target.checked),
|
|
34
|
+
"aria-label": "Select all rows"
|
|
35
|
+
}
|
|
36
|
+
),
|
|
37
|
+
/* @__PURE__ */ jsx("span", { className: [
|
|
38
|
+
"pointer-events-none absolute inset-0 rounded-sm border-2 transition-all flex items-center justify-center",
|
|
39
|
+
allSelected ? "border-fill-action-primary bg-fill-action-primary" : "border-border-form-primary bg-fill-bg-primary",
|
|
40
|
+
"peer-focus-visible:ring-2 peer-focus-visible:ring-border-focus peer-focus-visible:ring-offset-2"
|
|
41
|
+
].filter(Boolean).join(" "), children: allSelected && /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "white", strokeWidth: "2", strokeLinecap: "round", className: "w-3 h-3", children: /* @__PURE__ */ jsx("path", { d: "M13.3332 4L5.99984 11.3333L2.6665 8" }) }) })
|
|
42
|
+
] })
|
|
43
|
+
] })
|
|
44
|
+
] }),
|
|
45
|
+
columns.map((col) => {
|
|
46
|
+
const isSorted = sortColumn === col.id;
|
|
47
|
+
const isRightAligned = col.align === "right";
|
|
48
|
+
const alignClass = {
|
|
49
|
+
left: "text-left",
|
|
50
|
+
center: "text-center",
|
|
51
|
+
right: "text-right"
|
|
52
|
+
}[col.align || "left"];
|
|
53
|
+
return /* @__PURE__ */ jsx(
|
|
54
|
+
"th",
|
|
55
|
+
{
|
|
56
|
+
className: ["p-space-4 select-none", alignClass, col.width || ""].filter(Boolean).join(" "),
|
|
57
|
+
children: /* @__PURE__ */ jsxs(
|
|
58
|
+
"div",
|
|
59
|
+
{
|
|
60
|
+
className: [
|
|
61
|
+
"flex items-center gap-space-2",
|
|
62
|
+
col.align === "center" ? "justify-center" : isRightAligned ? "justify-end" : "justify-start",
|
|
63
|
+
col.sortable ? "cursor-pointer" : ""
|
|
64
|
+
].filter(Boolean).join(" "),
|
|
65
|
+
onClick: () => col.sortable && (onSort == null ? void 0 : onSort(col.id)),
|
|
66
|
+
children: [
|
|
67
|
+
col.sortable && isRightAligned && /* @__PURE__ */ jsx(SortIcon, { direction: isSorted ? sortDirection : void 0 }),
|
|
68
|
+
/* @__PURE__ */ jsx(Typography, { variant: "text-xs", as: "span", className: "font-semibold text-text-secondary uppercase tracking-wider", children: col.header }),
|
|
69
|
+
col.sortable && !isRightAligned && /* @__PURE__ */ jsx(SortIcon, { direction: isSorted ? sortDirection : void 0 })
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
},
|
|
74
|
+
col.id
|
|
75
|
+
);
|
|
76
|
+
}),
|
|
77
|
+
/* @__PURE__ */ jsx("th", { className: "w-[60px] p-space-4 text-left", "aria-label": "Actions", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Actions" }) })
|
|
78
|
+
] }) });
|
|
79
|
+
}
|
|
80
|
+
export {
|
|
81
|
+
DataTableHeader
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=DataTableHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTableHeader.js","sources":["../../../src/components/DataTable/DataTableHeader.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\nimport { Typography } from '../Typography/Typography';\nimport { Icon } from '../Icon/Icon';\n\n// Mock icons for sorting (ideally imported from @jiwambe/icons)\nfunction SortIcon({ direction }: { direction?: 'asc' | 'desc' }) {\n if (direction === 'asc') return <Icon icon={<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"m18 15-6-6-6 6\"/></svg>} size={16} />;\n if (direction === 'desc') return <Icon icon={<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"m6 9 6 6 6-6\"/></svg>} size={16} />;\n return <Icon icon={<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"m7 15 5 5 5-5M7 9l5-5 5 5\"/></svg>} size={16} className=\"text-icon-primary-disabled\" />;\n}\n\n/**\n * Column definition for the DataTable.\n */\nexport interface ColumnDef<TRow> {\n id: string;\n header: string;\n cell?: (row: TRow, rowIndex: number) => React.ReactNode;\n sortable?: boolean;\n width?: string;\n align?: 'left' | 'center' | 'right';\n}\n\n/**\n * Props for the DataTableHeader component.\n */\nexport interface DataTableHeaderProps<TRow> {\n columns: ColumnDef<TRow>[];\n allSelected: boolean;\n onSelectAll: (selected: boolean) => void;\n sortColumn?: string;\n sortDirection?: 'asc' | 'desc';\n onSort?: (columnId: string) => void;\n reorderable?: boolean;\n /** When false, the bulk-select column is omitted. @default true */\n selectable?: boolean;\n}\n\n/**\n * Header component for the DataTable. Renders <thead><tr>...</tr></thead>.\n */\nexport function DataTableHeader<TRow>({\n columns,\n allSelected,\n onSelectAll,\n sortColumn,\n sortDirection,\n onSort,\n reorderable = false,\n selectable = true,\n}: DataTableHeaderProps<TRow>) {\n return (\n <thead className=\"bg-fill-bg-secondary border-b border-border-light\">\n <tr>\n {/* Bulk select checkbox + gutter space for drag handle */}\n {selectable && (\n <th className=\"w-[80px] p-space-4 text-left\" aria-label=\"Selection and drag\">\n <span className=\"sr-only\">Selection and drag</span>\n <div className=\"flex items-center gap-space-2\">\n {reorderable && (\n <div className=\"w-4 h-4 shrink-0\" aria-hidden=\"true\" /> /* Placeholder for drag handle icon width (16px) */\n )}\n <label className=\"relative flex cursor-pointer items-center justify-center h-5 w-5\" htmlFor=\"select-all-checkbox\">\n <input\n id=\"select-all-checkbox\"\n type=\"checkbox\"\n className=\"peer sr-only\"\n checked={allSelected}\n onChange={(e) => onSelectAll(e.target.checked)}\n aria-label=\"Select all rows\"\n />\n <span className={[\n 'pointer-events-none absolute inset-0 rounded-sm border-2 transition-all flex items-center justify-center',\n allSelected ? 'border-fill-action-primary bg-fill-action-primary' : 'border-border-form-primary bg-fill-bg-primary',\n 'peer-focus-visible:ring-2 peer-focus-visible:ring-border-focus peer-focus-visible:ring-offset-2'\n ].filter(Boolean).join(' ')}>\n {allSelected && (\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" className=\"w-3 h-3\">\n <path d=\"M13.3332 4L5.99984 11.3333L2.6665 8\" />\n </svg>\n )}\n </span>\n </label>\n </div>\n </th>\n )}\n\n {/* Column headers */}\n {columns.map((col) => {\n const isSorted = sortColumn === col.id;\n const isRightAligned = col.align === 'right';\n const alignClass = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n }[col.align || 'left'];\n \n return (\n <th\n key={col.id}\n className={['p-space-4 select-none', alignClass, col.width || ''].filter(Boolean).join(' ')}\n >\n <div\n className={[\n 'flex items-center gap-space-2',\n col.align === 'center' ? 'justify-center' : isRightAligned ? 'justify-end' : 'justify-start',\n col.sortable ? 'cursor-pointer' : ''\n ].filter(Boolean).join(' ')}\n onClick={() => col.sortable && onSort?.(col.id)}\n >\n {/* For right-aligned columns, put sort icon on the left to keep text aligned with right-aligned data */}\n {col.sortable && isRightAligned && (\n <SortIcon direction={isSorted ? sortDirection : undefined} />\n )}\n \n <Typography variant=\"text-xs\" as=\"span\" className=\"font-semibold text-text-secondary uppercase tracking-wider\">\n {col.header}\n </Typography>\n \n {col.sortable && !isRightAligned && (\n <SortIcon direction={isSorted ? sortDirection : undefined} />\n )}\n </div>\n </th>\n );\n })}\n {/* Actions Menu gutter */}\n <th className=\"w-[60px] p-space-4 text-left\" aria-label=\"Actions\">\n <span className=\"sr-only\">Actions</span>\n </th>\n </tr>\n </thead>\n );\n}\n"],"names":[],"mappings":";;;;AAOA;AACE;AACA;AACA;AACF;AAgCO;AAA+B;AACpC;AACA;AACA;AACA;AACA;AACA;AACc;AAEhB;AACE;AAIO;AAEG;AAA4C;AAEzC;AACsD;AAGrD;AAAA;AAAC;AAAA;AACI;AACE;AACK;AACD;AACoC;AAClC;AAAA;AAAA;AAEI;AACf;AACoE;AACpE;AAOF;AACF;AACF;AACF;AAKA;AACA;AACA;AAAmB;AACX;AACE;AACD;AAGT;AACE;AAAC;AAAA;AAE2F;AAE1F;AAAC;AAAA;AACY;AACT;AAC6E;AAC3C;AACV;AACkB;AAG3C;AAC4D;AAK7D;AAG6D;AAAA;AAAA;AAAA;AAE/D;AAvBS;AAAA;AA0Bd;AAID;AAIR;;;;"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Props for the DataTablePagination component.
|
|
3
|
+
*/
|
|
4
|
+
export interface DataTablePaginationProps {
|
|
5
|
+
/** Current page index (0-based). */
|
|
6
|
+
page: number;
|
|
7
|
+
/** Number of rows per page. */
|
|
8
|
+
pageSize: number;
|
|
9
|
+
/** Total number of rows across all pages. */
|
|
10
|
+
totalRows: number;
|
|
11
|
+
/** Number of currently selected rows. */
|
|
12
|
+
selectedCount?: number;
|
|
13
|
+
/** Label for selection summary. @default 'row(s) selected' */
|
|
14
|
+
selectionLabel?: string;
|
|
15
|
+
/** Fired when the page changes. */
|
|
16
|
+
onPageChange: (page: number) => void;
|
|
17
|
+
/** Fired when rows-per-page changes. */
|
|
18
|
+
onPageSizeChange: (size: number) => void;
|
|
19
|
+
/** When true, hides the “X of Y row(s) selected” summary. @default false */
|
|
20
|
+
hideSelectionSummary?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Pagination footer for the DataTable.
|
|
24
|
+
*/
|
|
25
|
+
export declare function DataTablePagination({ page, pageSize, totalRows, selectedCount, selectionLabel, onPageChange, onPageSizeChange, hideSelectionSummary, }: DataTablePaginationProps): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
//# sourceMappingURL=DataTablePagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTablePagination.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/DataTablePagination.tsx"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mCAAmC;IACnC,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,wCAAwC;IACxC,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,4EAA4E;IAC5E,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAQD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,aAAiB,EACjB,cAAkC,EAClC,YAAY,EACZ,gBAAgB,EAChB,oBAA4B,GAC7B,EAAE,wBAAwB,2CA6E1B"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Typography } from "../Typography/Typography.js";
|
|
4
|
+
import { Select } from "../Select/Select.js";
|
|
5
|
+
import { Button } from "../Button/Button.js";
|
|
6
|
+
import { Icon } from "../Icon/Icon.js";
|
|
7
|
+
function ChevronLeft() {
|
|
8
|
+
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "m15 18-6-6 6-6" }) });
|
|
9
|
+
}
|
|
10
|
+
function ChevronRight() {
|
|
11
|
+
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "m9 18 6-6-6-6" }) });
|
|
12
|
+
}
|
|
13
|
+
function ChevronsLeft() {
|
|
14
|
+
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "m11 17-5-5 5-5m7 10-5-5 5-5" }) });
|
|
15
|
+
}
|
|
16
|
+
function ChevronsRight() {
|
|
17
|
+
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "m6 17 5-5-5-5m7 10 5-5-5-5" }) });
|
|
18
|
+
}
|
|
19
|
+
function DataTablePagination({
|
|
20
|
+
page,
|
|
21
|
+
pageSize,
|
|
22
|
+
totalRows,
|
|
23
|
+
selectedCount = 0,
|
|
24
|
+
selectionLabel = "row(s) selected",
|
|
25
|
+
onPageChange,
|
|
26
|
+
onPageSizeChange,
|
|
27
|
+
hideSelectionSummary = false
|
|
28
|
+
}) {
|
|
29
|
+
const totalPages = Math.ceil(totalRows / pageSize) || 1;
|
|
30
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-space-4 border-t border-border-light bg-fill-bg-primary", children: [
|
|
31
|
+
!hideSelectionSummary && /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxs(Typography, { variant: "text-xs", className: "text-text-secondary", children: [
|
|
32
|
+
selectedCount,
|
|
33
|
+
" of ",
|
|
34
|
+
totalRows,
|
|
35
|
+
" ",
|
|
36
|
+
selectionLabel
|
|
37
|
+
] }) }),
|
|
38
|
+
hideSelectionSummary && /* @__PURE__ */ jsx("div", { className: "flex-1", "aria-hidden": true }),
|
|
39
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-space-3", children: [
|
|
40
|
+
/* @__PURE__ */ jsx(Typography, { variant: "text-xs", className: "text-text-secondary whitespace-nowrap", children: "Rows per page" }),
|
|
41
|
+
/* @__PURE__ */ jsx("div", { className: "w-20", children: /* @__PURE__ */ jsx(
|
|
42
|
+
Select,
|
|
43
|
+
{
|
|
44
|
+
"aria-label": "Rows per page",
|
|
45
|
+
value: pageSize.toString(),
|
|
46
|
+
onChange: (e) => onPageSizeChange(parseInt(e.target.value, 10)),
|
|
47
|
+
options: [
|
|
48
|
+
{ value: "5", label: "5" },
|
|
49
|
+
{ value: "10", label: "10" },
|
|
50
|
+
{ value: "20", label: "20" },
|
|
51
|
+
{ value: "50", label: "50" }
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
) })
|
|
55
|
+
] }),
|
|
56
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex items-center justify-end gap-space-4", children: [
|
|
57
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "text-xs", className: "text-text-secondary whitespace-nowrap", children: [
|
|
58
|
+
"Page ",
|
|
59
|
+
page + 1,
|
|
60
|
+
" of ",
|
|
61
|
+
totalPages
|
|
62
|
+
] }),
|
|
63
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-space-1", children: [
|
|
64
|
+
/* @__PURE__ */ jsx(
|
|
65
|
+
Button,
|
|
66
|
+
{
|
|
67
|
+
variant: "ghost",
|
|
68
|
+
size: "small",
|
|
69
|
+
iconOnly: /* @__PURE__ */ jsx(Icon, { icon: /* @__PURE__ */ jsx(ChevronsLeft, {}), size: 16 }),
|
|
70
|
+
disabled: page === 0,
|
|
71
|
+
onClick: () => onPageChange(0),
|
|
72
|
+
"aria-label": "First page"
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
/* @__PURE__ */ jsx(
|
|
76
|
+
Button,
|
|
77
|
+
{
|
|
78
|
+
variant: "ghost",
|
|
79
|
+
size: "small",
|
|
80
|
+
iconOnly: /* @__PURE__ */ jsx(Icon, { icon: /* @__PURE__ */ jsx(ChevronLeft, {}), size: 16 }),
|
|
81
|
+
disabled: page === 0,
|
|
82
|
+
onClick: () => onPageChange(page - 1),
|
|
83
|
+
"aria-label": "Previous page"
|
|
84
|
+
}
|
|
85
|
+
),
|
|
86
|
+
/* @__PURE__ */ jsx(
|
|
87
|
+
Button,
|
|
88
|
+
{
|
|
89
|
+
variant: "ghost",
|
|
90
|
+
size: "small",
|
|
91
|
+
iconOnly: /* @__PURE__ */ jsx(Icon, { icon: /* @__PURE__ */ jsx(ChevronRight, {}), size: 16 }),
|
|
92
|
+
disabled: page >= totalPages - 1,
|
|
93
|
+
onClick: () => onPageChange(page + 1),
|
|
94
|
+
"aria-label": "Next page"
|
|
95
|
+
}
|
|
96
|
+
),
|
|
97
|
+
/* @__PURE__ */ jsx(
|
|
98
|
+
Button,
|
|
99
|
+
{
|
|
100
|
+
variant: "ghost",
|
|
101
|
+
size: "small",
|
|
102
|
+
iconOnly: /* @__PURE__ */ jsx(Icon, { icon: /* @__PURE__ */ jsx(ChevronsRight, {}), size: 16 }),
|
|
103
|
+
disabled: page >= totalPages - 1,
|
|
104
|
+
onClick: () => onPageChange(totalPages - 1),
|
|
105
|
+
"aria-label": "Last page"
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
] })
|
|
109
|
+
] })
|
|
110
|
+
] });
|
|
111
|
+
}
|
|
112
|
+
export {
|
|
113
|
+
DataTablePagination
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=DataTablePagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTablePagination.js","sources":["../../../src/components/DataTable/DataTablePagination.tsx"],"sourcesContent":["'use client';\n\nimport { Typography } from '../Typography/Typography';\nimport { Select } from '../Select/Select';\nimport { Button } from '../Button/Button';\nimport { Icon } from '../Icon/Icon';\n\n/**\n * Props for the DataTablePagination component.\n */\nexport interface DataTablePaginationProps {\n /** Current page index (0-based). */\n page: number;\n /** Number of rows per page. */\n pageSize: number;\n /** Total number of rows across all pages. */\n totalRows: number;\n /** Number of currently selected rows. */\n selectedCount?: number;\n /** Label for selection summary. @default 'row(s) selected' */\n selectionLabel?: string;\n /** Fired when the page changes. */\n onPageChange: (page: number) => void;\n /** Fired when rows-per-page changes. */\n onPageSizeChange: (size: number) => void;\n /** When true, hides the “X of Y row(s) selected” summary. @default false */\n hideSelectionSummary?: boolean;\n}\n\n// Mock icons for pagination\nfunction ChevronLeft() { return <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"m15 18-6-6 6-6\"/></svg>; }\nfunction ChevronRight() { return <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"m9 18 6-6-6-6\"/></svg>; }\nfunction ChevronsLeft() { return <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"m11 17-5-5 5-5m7 10-5-5 5-5\"/></svg>; }\nfunction ChevronsRight() { return <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"m6 17 5-5-5-5m7 10 5-5-5-5\"/></svg>; }\n\n/**\n * Pagination footer for the DataTable.\n */\nexport function DataTablePagination({\n page,\n pageSize,\n totalRows,\n selectedCount = 0,\n selectionLabel = 'row(s) selected',\n onPageChange,\n onPageSizeChange,\n hideSelectionSummary = false,\n}: DataTablePaginationProps) {\n const totalPages = Math.ceil(totalRows / pageSize) || 1;\n\n return (\n <div className=\"flex items-center justify-between p-space-4 border-t border-border-light bg-fill-bg-primary\">\n {/* Selection Summary */}\n {!hideSelectionSummary && (\n <div className=\"flex-1\">\n <Typography variant=\"text-xs\" className=\"text-text-secondary\">\n {selectedCount} of {totalRows} {selectionLabel}\n </Typography>\n </div>\n )}\n {hideSelectionSummary && <div className=\"flex-1\" aria-hidden />}\n\n {/* Rows per page */}\n <div className=\"flex items-center gap-space-3\">\n <Typography variant=\"text-xs\" className=\"text-text-secondary whitespace-nowrap\">\n Rows per page\n </Typography>\n <div className=\"w-20\">\n <Select\n aria-label=\"Rows per page\"\n value={pageSize.toString()}\n onChange={(e) => onPageSizeChange(parseInt(e.target.value, 10))}\n options={[\n { value: '5', label: '5' },\n { value: '10', label: '10' },\n { value: '20', label: '20' },\n { value: '50', label: '50' },\n ]}\n />\n </div>\n </div>\n\n {/* Page controls */}\n <div className=\"flex-1 flex items-center justify-end gap-space-4\">\n <Typography variant=\"text-xs\" className=\"text-text-secondary whitespace-nowrap\">\n Page {page + 1} of {totalPages}\n </Typography>\n <div className=\"flex items-center gap-space-1\">\n <Button\n variant=\"ghost\"\n size=\"small\"\n iconOnly={<Icon icon={<ChevronsLeft />} size={16} />}\n disabled={page === 0}\n onClick={() => onPageChange(0)}\n aria-label=\"First page\"\n />\n <Button\n variant=\"ghost\"\n size=\"small\"\n iconOnly={<Icon icon={<ChevronLeft />} size={16} />}\n disabled={page === 0}\n onClick={() => onPageChange(page - 1)}\n aria-label=\"Previous page\"\n />\n <Button\n variant=\"ghost\"\n size=\"small\"\n iconOnly={<Icon icon={<ChevronRight />} size={16} />}\n disabled={page >= totalPages - 1}\n onClick={() => onPageChange(page + 1)}\n aria-label=\"Next page\"\n />\n <Button\n variant=\"ghost\"\n size=\"small\"\n iconOnly={<Icon icon={<ChevronsRight />} size={16} />}\n disabled={page >= totalPages - 1}\n onClick={() => onPageChange(totalPages - 1)}\n aria-label=\"Last page\"\n />\n </div>\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":";;;;;;AA8BA;AAAyB;AAAoH;AAC7I;AAA0B;AAAmH;AAC7I;AAA0B;AAAiI;AAC3J;AAA2B;AAAgI;AAKpJ;AAA6B;AAClC;AACA;AACA;AACgB;AACC;AACjB;AACA;AAEF;AACE;AAEA;AAGK;AAGM;AAAA;AAAc;AAAK;AAAU;AAAE;AAEpC;AAE2D;AAI3D;AAEA;AAEE;AAAC;AAAA;AACY;AACK;AAC8C;AACrD;AACc;AACC;AACA;AACA;AAAK;AAC7B;AAEJ;AACF;AAIE;AAAgF;AAAA;AACjE;AAAE;AAAK;AACtB;AAEE;AAAA;AAAC;AAAA;AACS;AACH;AAC6C;AAC/B;AACU;AAClB;AAAA;AAAA;AAEb;AAAC;AAAA;AACS;AACH;AAC4C;AAC9B;AACiB;AACzB;AAAA;AAAA;AAEb;AAAC;AAAA;AACS;AACH;AAC6C;AACnB;AACK;AACzB;AAAA;AAAA;AAEb;AAAC;AAAA;AACS;AACH;AAC8C;AACpB;AACW;AAC/B;AAAA;AAAA;AAEf;AACF;AAGN;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Props for the DataTableReviewerCell component.
|
|
3
|
+
*/
|
|
4
|
+
export interface DataTableReviewerCellProps {
|
|
5
|
+
/** Current reviewer's name or null/empty. */
|
|
6
|
+
value: string | null;
|
|
7
|
+
/** List of reviewer options for the dropdown. */
|
|
8
|
+
options: string[];
|
|
9
|
+
/** Fired when a reviewer is selected. */
|
|
10
|
+
onChange: (value: string) => void;
|
|
11
|
+
/** When true, prevents changes and renders as text only. @default false */
|
|
12
|
+
readOnly?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Specialized cell for reviewer assignment. Renders as text or a Select trigger.
|
|
16
|
+
*/
|
|
17
|
+
export declare function DataTableReviewerCell({ value, options, onChange, readOnly, }: DataTableReviewerCellProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
//# sourceMappingURL=DataTableReviewerCell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTableReviewerCell.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/DataTableReviewerCell.tsx"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,6CAA6C;IAC7C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iDAAiD;IACjD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yCAAyC;IACzC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,OAAO,EACP,QAAQ,EACR,QAAgB,GACjB,EAAE,0BAA0B,2CA8B5B"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Select } from "../Select/Select.js";
|
|
4
|
+
import { Typography } from "../Typography/Typography.js";
|
|
5
|
+
function DataTableReviewerCell({
|
|
6
|
+
value,
|
|
7
|
+
options,
|
|
8
|
+
onChange,
|
|
9
|
+
readOnly = false
|
|
10
|
+
}) {
|
|
11
|
+
if (value && value.length > 0) {
|
|
12
|
+
return /* @__PURE__ */ jsx("div", { className: "flex items-center w-full overflow-hidden", children: /* @__PURE__ */ jsx(Typography, { variant: "text-sm", as: "span", className: "text-text-primary truncate", children: value }) });
|
|
13
|
+
}
|
|
14
|
+
if (readOnly) {
|
|
15
|
+
return /* @__PURE__ */ jsx(Typography, { variant: "text-sm", as: "span", className: "text-text-disabled", children: "—" });
|
|
16
|
+
}
|
|
17
|
+
return /* @__PURE__ */ jsx("div", { className: "w-full max-w-[200px]", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx(
|
|
18
|
+
Select,
|
|
19
|
+
{
|
|
20
|
+
"aria-label": "Assign reviewer",
|
|
21
|
+
placeholder: "Assign reviewer",
|
|
22
|
+
options: options.map((opt) => ({ value: opt, label: opt })),
|
|
23
|
+
onChange: (e) => onChange(e.target.value),
|
|
24
|
+
className: "text-xs min-h-[32px] py-space-1 hover:border-border-form-primary-hover focus:border-border-form-primary-active border-border-form-primary"
|
|
25
|
+
}
|
|
26
|
+
) });
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
DataTableReviewerCell
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=DataTableReviewerCell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTableReviewerCell.js","sources":["../../../src/components/DataTable/DataTableReviewerCell.tsx"],"sourcesContent":["'use client';\n\nimport { Select } from '../Select/Select';\nimport { Typography } from '../Typography/Typography';\n\n/**\n * Props for the DataTableReviewerCell component.\n */\nexport interface DataTableReviewerCellProps {\n /** Current reviewer's name or null/empty. */\n value: string | null;\n /** List of reviewer options for the dropdown. */\n options: string[];\n /** Fired when a reviewer is selected. */\n onChange: (value: string) => void;\n /** When true, prevents changes and renders as text only. @default false */\n readOnly?: boolean;\n}\n\n/**\n * Specialized cell for reviewer assignment. Renders as text or a Select trigger.\n */\nexport function DataTableReviewerCell({\n value,\n options,\n onChange,\n readOnly = false,\n}: DataTableReviewerCellProps) {\n if (value && value.length > 0) {\n return (\n <div className=\"flex items-center w-full overflow-hidden\">\n <Typography variant=\"text-sm\" as=\"span\" className=\"text-text-primary truncate\">\n {value}\n </Typography>\n </div>\n );\n }\n\n if (readOnly) {\n return (\n <Typography variant=\"text-sm\" as=\"span\" className=\"text-text-disabled\">\n —\n </Typography>\n );\n }\n\n return (\n <div className=\"w-full max-w-[200px]\" onClick={(e) => e.stopPropagation()}>\n <Select\n aria-label=\"Assign reviewer\"\n placeholder=\"Assign reviewer\"\n options={options.map(opt => ({ value: opt, label: opt }))}\n onChange={(e) => onChange(e.target.value)}\n className=\"text-xs min-h-[32px] py-space-1 hover:border-border-form-primary-hover focus:border-border-form-primary-active border-border-form-primary\"\n />\n </div>\n );\n}\n"],"names":[],"mappings":";;;;AAsBO;AAA+B;AACpC;AACA;AACA;AAEF;AACE;AACE;AAKE;AAIJ;AACE;AAGE;AAIJ;AAEI;AAAC;AAAA;AACY;AACC;AAC4C;AAChB;AAC9B;AAAA;AAIlB;;;;"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { DataTableAction } from './DataTableRowMenu';
|
|
3
|
+
import { ColumnDef } from './DataTableHeader';
|
|
4
|
+
/**
|
|
5
|
+
* Props for the DataTableRow component.
|
|
6
|
+
*/
|
|
7
|
+
export interface DataTableRowProps<TRow> {
|
|
8
|
+
/** The data for this individual row. */
|
|
9
|
+
row: TRow;
|
|
10
|
+
/** Index of the row in the current page. */
|
|
11
|
+
rowIndex: number;
|
|
12
|
+
/** Column definitions. */
|
|
13
|
+
columns: ColumnDef<TRow>[];
|
|
14
|
+
/** Whether the row is currently selected. */
|
|
15
|
+
selected: boolean;
|
|
16
|
+
/** Fired when the row's selection state changes. */
|
|
17
|
+
onSelect: (selected: boolean) => void;
|
|
18
|
+
/** Context menu actions for this row. @default [] */
|
|
19
|
+
actions?: DataTableAction[];
|
|
20
|
+
/** Fired when a native drag starts. */
|
|
21
|
+
onDragStart?: (e: React.DragEvent, index: number) => void;
|
|
22
|
+
/** Fired when another row is dragged over this row. */
|
|
23
|
+
onDragOver?: (e: React.DragEvent, index: number) => void;
|
|
24
|
+
/** Fired when a row is dropped onto this row. */
|
|
25
|
+
onDrop?: (e: React.DragEvent, index: number) => void;
|
|
26
|
+
/** Whether the table supports reordering. @default false */
|
|
27
|
+
reorderable?: boolean;
|
|
28
|
+
/** When false, the row checkbox column is omitted. @default true */
|
|
29
|
+
selectable?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Single data row (<tr>) for the DataTable.
|
|
33
|
+
*/
|
|
34
|
+
export declare function DataTableRow<TRow>({ row, rowIndex, columns, selected, onSelect, actions, onDragStart, onDragOver, onDrop, reorderable, selectable, }: DataTableRowProps<TRow>): import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
//# sourceMappingURL=DataTableRow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTableRow.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/DataTableRow.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAoB,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,IAAI;IACrC,wCAAwC;IACxC,GAAG,EAAE,IAAI,CAAC;IACV,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;IAC3B,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAC;IAClB,oDAAoD;IACpD,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,qDAAqD;IACrD,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,uCAAuC;IACvC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,uDAAuD;IACvD,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,iDAAiD;IACjD,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,4DAA4D;IAC5D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAgBD;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,EACjC,GAAG,EACH,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAY,EACZ,WAAW,EACX,UAAU,EACV,MAAM,EACN,WAAmB,EACnB,UAAiB,GAClB,EAAE,iBAAiB,CAAC,IAAI,CAAC,2CAwEzB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Icon } from "../Icon/Icon.js";
|
|
4
|
+
import { DataTableCell } from "./DataTableCell.js";
|
|
5
|
+
import { DataTableRowMenu } from "./DataTableRowMenu.js";
|
|
6
|
+
function GripVertical() {
|
|
7
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
|
|
8
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "5", r: "1" }),
|
|
9
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "12", r: "1" }),
|
|
10
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "19", r: "1" }),
|
|
11
|
+
/* @__PURE__ */ jsx("circle", { cx: "15", cy: "5", r: "1" }),
|
|
12
|
+
/* @__PURE__ */ jsx("circle", { cx: "15", cy: "12", r: "1" }),
|
|
13
|
+
/* @__PURE__ */ jsx("circle", { cx: "15", cy: "19", r: "1" })
|
|
14
|
+
] });
|
|
15
|
+
}
|
|
16
|
+
function DataTableRow({
|
|
17
|
+
row,
|
|
18
|
+
rowIndex,
|
|
19
|
+
columns,
|
|
20
|
+
selected,
|
|
21
|
+
onSelect,
|
|
22
|
+
actions = [],
|
|
23
|
+
onDragStart,
|
|
24
|
+
onDragOver,
|
|
25
|
+
onDrop,
|
|
26
|
+
reorderable = false,
|
|
27
|
+
selectable = true
|
|
28
|
+
}) {
|
|
29
|
+
const trClasses = [
|
|
30
|
+
"group transition-colors border-b border-border-light last:border-none",
|
|
31
|
+
selected ? "bg-fill-bg-secondary" : "bg-fill-bg-primary hover:bg-fill-bg-secondary"
|
|
32
|
+
].filter(Boolean).join(" ");
|
|
33
|
+
const rowId = row.id || rowIndex;
|
|
34
|
+
const checkboxId = `select-row-${rowId}`;
|
|
35
|
+
return /* @__PURE__ */ jsxs(
|
|
36
|
+
"tr",
|
|
37
|
+
{
|
|
38
|
+
className: trClasses,
|
|
39
|
+
draggable: !!onDragStart,
|
|
40
|
+
onDragStart: (e) => onDragStart == null ? void 0 : onDragStart(e, rowIndex),
|
|
41
|
+
onDragOver: (e) => onDragOver == null ? void 0 : onDragOver(e, rowIndex),
|
|
42
|
+
onDrop: (e) => onDrop == null ? void 0 : onDrop(e, rowIndex),
|
|
43
|
+
children: [
|
|
44
|
+
selectable && /* @__PURE__ */ jsx(DataTableCell, { className: "w-[80px]", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-space-2", children: [
|
|
45
|
+
reorderable && /* @__PURE__ */ jsx("div", { className: "opacity-0 group-hover:opacity-100 transition-opacity cursor-grab active:cursor-grabbing", children: /* @__PURE__ */ jsx(Icon, { icon: /* @__PURE__ */ jsx(GripVertical, {}), size: 16, className: "text-icon-primary-disabled" }) }),
|
|
46
|
+
/* @__PURE__ */ jsxs("label", { className: "relative flex cursor-pointer items-center justify-center h-5 w-5", htmlFor: checkboxId, children: [
|
|
47
|
+
/* @__PURE__ */ jsx(
|
|
48
|
+
"input",
|
|
49
|
+
{
|
|
50
|
+
id: checkboxId,
|
|
51
|
+
type: "checkbox",
|
|
52
|
+
className: "peer sr-only",
|
|
53
|
+
checked: selected,
|
|
54
|
+
onChange: (e) => onSelect(e.target.checked),
|
|
55
|
+
"aria-label": `Select row ${rowIndex + 1}`
|
|
56
|
+
}
|
|
57
|
+
),
|
|
58
|
+
/* @__PURE__ */ jsx("span", { className: [
|
|
59
|
+
"pointer-events-none absolute inset-0 rounded-sm border-2 transition-all flex items-center justify-center",
|
|
60
|
+
selected ? "border-fill-action-primary bg-fill-action-primary" : "border-border-form-primary bg-fill-bg-primary",
|
|
61
|
+
"peer-focus-visible:ring-2 peer-focus-visible:ring-border-focus peer-focus-visible:ring-offset-2"
|
|
62
|
+
].filter(Boolean).join(" "), children: selected && /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "white", strokeWidth: "2", strokeLinecap: "round", className: "w-3 h-3", children: /* @__PURE__ */ jsx("path", { d: "M13.3332 4L5.99984 11.3333L2.6665 8" }) }) })
|
|
63
|
+
] })
|
|
64
|
+
] }) }),
|
|
65
|
+
columns.map((col) => {
|
|
66
|
+
const content = col.cell ? col.cell(row, rowIndex) : row[col.id];
|
|
67
|
+
return /* @__PURE__ */ jsx(DataTableCell, { align: col.align, children: content }, col.id);
|
|
68
|
+
}),
|
|
69
|
+
/* @__PURE__ */ jsx(DataTableCell, { className: "w-[60px]", children: actions.length > 0 && /* @__PURE__ */ jsx(DataTableRowMenu, { actions }) })
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
export {
|
|
75
|
+
DataTableRow
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=DataTableRow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTableRow.js","sources":["../../../src/components/DataTable/DataTableRow.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\nimport { Icon } from '../Icon/Icon';\nimport { DataTableCell } from './DataTableCell';\nimport { DataTableRowMenu, DataTableAction } from './DataTableRowMenu';\nimport { ColumnDef } from './DataTableHeader';\n\n/**\n * Props for the DataTableRow component.\n */\nexport interface DataTableRowProps<TRow> {\n /** The data for this individual row. */\n row: TRow;\n /** Index of the row in the current page. */\n rowIndex: number;\n /** Column definitions. */\n columns: ColumnDef<TRow>[];\n /** Whether the row is currently selected. */\n selected: boolean;\n /** Fired when the row's selection state changes. */\n onSelect: (selected: boolean) => void;\n /** Context menu actions for this row. @default [] */\n actions?: DataTableAction[];\n /** Fired when a native drag starts. */\n onDragStart?: (e: React.DragEvent, index: number) => void;\n /** Fired when another row is dragged over this row. */\n onDragOver?: (e: React.DragEvent, index: number) => void;\n /** Fired when a row is dropped onto this row. */\n onDrop?: (e: React.DragEvent, index: number) => void;\n /** Whether the table supports reordering. @default false */\n reorderable?: boolean;\n /** When false, the row checkbox column is omitted. @default true */\n selectable?: boolean;\n}\n\n// Mock drag handle icon\nfunction GripVertical() {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <circle cx=\"9\" cy=\"5\" r=\"1\" />\n <circle cx=\"9\" cy=\"12\" r=\"1\" />\n <circle cx=\"9\" cy=\"19\" r=\"1\" />\n <circle cx=\"15\" cy=\"5\" r=\"1\" />\n <circle cx=\"15\" cy=\"12\" r=\"1\" />\n <circle cx=\"15\" cy=\"19\" r=\"1\" />\n </svg>\n );\n}\n\n/**\n * Single data row (<tr>) for the DataTable.\n */\nexport function DataTableRow<TRow>({\n row,\n rowIndex,\n columns,\n selected,\n onSelect,\n actions = [],\n onDragStart,\n onDragOver,\n onDrop,\n reorderable = false,\n selectable = true,\n}: DataTableRowProps<TRow>) {\n const trClasses = [\n 'group transition-colors border-b border-border-light last:border-none',\n selected ? 'bg-fill-bg-secondary' : 'bg-fill-bg-primary hover:bg-fill-bg-secondary',\n ].filter(Boolean).join(' ');\n\n const rowId = (row as any).id || rowIndex;\n const checkboxId = `select-row-${rowId}`;\n\n return (\n <tr\n className={trClasses}\n draggable={!!onDragStart}\n onDragStart={(e) => onDragStart?.(e, rowIndex)}\n onDragOver={(e) => onDragOver?.(e, rowIndex)}\n onDrop={(e) => onDrop?.(e, rowIndex)}\n >\n {/* Interaction Gutter: Drag handle + Checkbox */}\n {selectable && (\n <DataTableCell className=\"w-[80px]\">\n <div className=\"flex items-center gap-space-2\">\n {/* Drag Handle - only visible on row hover and if reorderable */}\n {reorderable && (\n <div className=\"opacity-0 group-hover:opacity-100 transition-opacity cursor-grab active:cursor-grabbing\">\n <Icon icon={<GripVertical />} size={16} className=\"text-icon-primary-disabled\" />\n </div>\n )}\n \n {/* Custom Checkbox */}\n <label className=\"relative flex cursor-pointer items-center justify-center h-5 w-5\" htmlFor={checkboxId}>\n <input\n id={checkboxId}\n type=\"checkbox\"\n className=\"peer sr-only\"\n checked={selected}\n onChange={(e) => onSelect(e.target.checked)}\n aria-label={`Select row ${rowIndex + 1}`}\n />\n <span className={[\n 'pointer-events-none absolute inset-0 rounded-sm border-2 transition-all flex items-center justify-center',\n selected ? 'border-fill-action-primary bg-fill-action-primary' : 'border-border-form-primary bg-fill-bg-primary',\n 'peer-focus-visible:ring-2 peer-focus-visible:ring-border-focus peer-focus-visible:ring-offset-2'\n ].filter(Boolean).join(' ')}>\n {selected && (\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" className=\"w-3 h-3\">\n <path d=\"M13.3332 4L5.99984 11.3333L2.6665 8\" />\n </svg>\n )}\n </span>\n </label>\n </div>\n </DataTableCell>\n )}\n\n {/* Data Cells */}\n {columns.map((col) => {\n const content = col.cell ? col.cell(row, rowIndex) : (row as any)[col.id];\n return (\n <DataTableCell key={col.id} align={col.align}>\n {content}\n </DataTableCell>\n );\n })}\n\n {/* Row Menu Action */}\n <DataTableCell className=\"w-[60px]\">\n {actions.length > 0 && (\n <DataTableRowMenu actions={actions} />\n )}\n </DataTableCell>\n </tr>\n );\n}\n"],"names":[],"mappings":";;;;;AAqCA;AACE;AAEI;AAA4B;AACC;AACA;AACA;AACC;AACA;AAGpC;AAKO;AAA4B;AACjC;AACA;AACA;AACA;AACA;AACU;AACV;AACA;AACA;AACc;AAEhB;AACE;AAAkB;AAChB;AACoC;AAGtC;AACA;AAEA;AACE;AAAC;AAAA;AACY;AACE;AACwB;AACF;AACR;AAG1B;AAIM;AAGC;AAKA;AAAA;AAAC;AAAA;AACK;AACC;AACK;AACD;AACiC;AACJ;AAAA;AAAA;AAEvB;AACf;AACiE;AACjE;AAOF;AACF;AAEJ;AAKA;AACA;AAGE;AAEH;AAOD;AAAA;AAAA;AAGN;;;;"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shape of a single action in the DataTableRowMenu.
|
|
3
|
+
*/
|
|
4
|
+
export interface DataTableAction {
|
|
5
|
+
/** Label displayed in the menu. */
|
|
6
|
+
label: string;
|
|
7
|
+
/** Callback fired when the action is selected. */
|
|
8
|
+
onSelect: () => void;
|
|
9
|
+
/** When true, applies error/danger styling. @default false */
|
|
10
|
+
destructive?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Props for the DataTableRowMenu component.
|
|
14
|
+
*/
|
|
15
|
+
export interface DataTableRowMenuProps {
|
|
16
|
+
/** Array of actions to display in the menu. */
|
|
17
|
+
actions: DataTableAction[];
|
|
18
|
+
/** Fired when the menu is opened. */
|
|
19
|
+
onOpen?: () => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Row context menu (three-dot dropdown). Renders a trigger button and a Popover panel.
|
|
23
|
+
*/
|
|
24
|
+
export declare function DataTableRowMenu({ actions, onOpen }: DataTableRowMenuProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
//# sourceMappingURL=DataTableRowMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTableRowMenu.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/DataTableRowMenu.tsx"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,qBAAqB,2CAyD1E"}
|