boneless-table 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/boneless-table.tsx","../src/column-filter.tsx","../src/column-menu.tsx","../src/class-names.ts","../src/settings.ts","../src/columns.ts","../src/table-skeleton.tsx","../src/row-link.ts","../src/index.ts"],"sourcesContent":["'use client'\n\nimport {\n flexRender,\n getExpandedRowModel,\n getCoreRowModel,\n getFilteredRowModel,\n getSortedRowModel,\n useReactTable,\n type ColumnFiltersState,\n type ColumnOrderState,\n type ExpandedState,\n type RowData,\n type SortingState,\n type Table,\n type TableOptions,\n type TableState,\n type VisibilityState,\n} from '@tanstack/react-table'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport {\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n} from 'react'\nimport './types'\nimport { ColumnFilter } from './column-filter'\nimport { ColumnMenu, type ColumnMenuIcons } from './column-menu'\nimport { cn } from './class-names'\nimport { getColumnIds, resolveColumns, withDefaultCells } from './columns'\nimport {\n mergeBonelessTableSettings,\n resolveColumnSettings,\n type BonelessTableSettings,\n} from './settings'\nimport { TableSkeleton } from './table-skeleton'\nimport { resolveRowHref, resolveRowLinkLabel, type BonelessTableRowLink } from './row-link'\nimport type { BonelessTableColumn, DeepPartial } from './types'\n\nexport type BonelessTableToolbarLayout<TData extends RowData> = (context: {\n table: Table<TData>\n summary: ReactNode\n actions: ReactNode\n}) => ReactNode\n\nexport type BonelessTableSlot<TData extends RowData> =\n boolean | ReactNode | ((table: Table<TData>) => ReactNode)\n\nexport type BonelessTableRowClickEvent = MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n\n/**\n * Named hooks for your stylesheet. The renderer applies no default class names or visual styles.\n */\nexport type BonelessTableClassNames = Partial<{\n root: string\n toolbar: string\n toolbarSummary: string\n toolbarHint: string\n toolbarActions: string\n scroller: string\n table: string\n headerGroup: string\n headerRow: string\n header: string\n headerButton: string\n sortIndicator: string\n rowGroup: string\n row: string\n cell: string\n footer: string\n filter: string\n columnMenu: string\n rowLink: string\n emptyState: string\n skeleton: string\n}>\n\n/** Optional consumer-owned icons. Omit these for a text-only renderer. */\nexport type BonelessTableIcons = ColumnMenuIcons & {\n reset?: ReactNode\n columns?: ReactNode\n search?: ReactNode\n sort?: (direction: false | 'asc' | 'desc') => ReactNode\n expand?: ReactNode\n collapse?: ReactNode\n}\n\nexport type BonelessTableTreeOptions = {\n /** Column that receives the in-cell indentation and row control. Defaults to the first visible column. */\n columnId?: string\n /** Pixel increment per tree level. Indentation stays inside the cell and never changes the grid. */\n indentPx?: number\n expandAllLabel?: string\n collapseAllLabel?: string\n}\n\nexport type BonelessTablePresentationOptions<TData extends RowData> = {\n settings?: DeepPartial<BonelessTableSettings>\n className?: string\n classNames?: BonelessTableClassNames\n icons?: BonelessTableIcons\n /** Enables nested row controls when used with TanStack's getSubRows option. */\n tree?: boolean | BonelessTableTreeOptions\n isLoading?: boolean\n isFetchingMore?: boolean\n skeletonRows?: number\n skeletonLabel?: string\n onNearEnd?: () => void\n /** Enables onNearEnd. Keep this false while there is no next page or a request is in flight. */\n canLoadMore?: boolean\n nearEndOffset?: number\n /** Delay text-filter updates to avoid recomputing large client-side row models on every keystroke. */\n filterDebounceMs?: number\n /** Content-sized by default. Use fill only inside a parent that provides a stable height. */\n scroller?: 'fill' | 'auto'\n toolbar?: BonelessTableSlot<TData>\n /** Reposition the default summary and action controls without rebuilding their behavior. */\n toolbarLayout?: BonelessTableToolbarLayout<TData>\n footer?: BonelessTableSlot<TData>\n totalCount?: number\n resultLabel?: string\n resultHint?: string\n onReset?: () => void\n onRowClick?: (row: TData, event: BonelessTableRowClickEvent) => void\n scrollToTopOn?: unknown\n rowLink?: BonelessTableRowLink<TData>\n /** Content shown when loading is complete and no rows match the current table state. */\n emptyState?: ReactNode | ((table: Table<TData>) => ReactNode)\n /** Set to false to render every row, or configure virtual rows when scroller is \"fill\". */\n virtualization?: false | { estimateSize?: number; overscan?: number }\n}\n\n/**\n * TanStack options supported by this renderer. Grouping, pagination, selection,\n * pinning, sizing, and faceting are intentionally outside this component's UI contract.\n * Nested expansion is supported through getSubRows together with the tree presentation option.\n */\nexport type BonelessTableOptions<TData extends RowData> = Omit<\n Pick<\n TableOptions<TData>,\n | 'getRowId'\n | 'getCoreRowModel'\n | 'getFilteredRowModel'\n | 'getSortedRowModel'\n | 'getSubRows'\n | 'onSortingChange'\n | 'onColumnFiltersChange'\n | 'onColumnVisibilityChange'\n | 'onColumnOrderChange'\n | 'onExpandedChange'\n | 'manualSorting'\n | 'manualFiltering'\n | 'enableSorting'\n | 'enableMultiSort'\n | 'enableSortingRemoval'\n | 'enableMultiRemove'\n | 'maxMultiSortColCount'\n | 'filterFromLeafRows'\n | 'maxLeafRowFilterDepth'\n | 'isMultiSortEvent'\n | 'sortDescFirst'\n | 'sortingFns'\n | 'enableFilters'\n | 'filterFns'\n | 'defaultColumn'\n | 'renderFallbackValue'\n | 'meta'\n | 'debugTable'\n | 'debugHeaders'\n | 'debugColumns'\n >,\n 'getCoreRowModel' | 'getFilteredRowModel' | 'getSortedRowModel'\n> &\n Partial<\n Pick<TableOptions<TData>, 'getCoreRowModel' | 'getFilteredRowModel' | 'getSortedRowModel'>\n > & {\n state?: Partial<\n Pick<\n TableState,\n 'sorting' | 'columnFilters' | 'columnVisibility' | 'columnOrder' | 'expanded'\n >\n >\n initialState?: Partial<\n Pick<\n TableState,\n 'sorting' | 'columnFilters' | 'columnVisibility' | 'columnOrder' | 'expanded'\n >\n >\n }\n\nexport type BonelessTableProps<TData extends RowData> = BonelessTableOptions<TData> &\n BonelessTablePresentationOptions<TData> & {\n data: TData[]\n columns: BonelessTableColumn<TData>[]\n }\n\nfunction moveItem(order: string[], id: string, direction: -1 | 1) {\n const index = order.indexOf(id)\n const target = index + direction\n if (index < 0 || target < 0 || target >= order.length) return order\n const next = [...order]\n ;[next[index], next[target]] = [next[target], next[index]]\n return next\n}\n\nfunction renderSlot<TData extends RowData>(\n slot: BonelessTableSlot<TData> | undefined,\n table: Table<TData>,\n fallback: ReactNode,\n) {\n if (slot === false) return null\n if (typeof slot === 'function') return slot(table)\n if (slot && slot !== true) return slot\n return fallback\n}\n\nexport function BonelessTable<TData extends RowData>({\n data,\n columns,\n settings: settingsOverride,\n className,\n classNames = {},\n icons,\n tree: treeOption,\n isLoading = false,\n isFetchingMore = false,\n skeletonRows = 8,\n skeletonLabel = 'Loading rows',\n onNearEnd,\n canLoadMore = true,\n nearEndOffset = 220,\n filterDebounceMs = 150,\n scroller = 'auto',\n toolbar = true,\n toolbarLayout,\n footer = true,\n totalCount,\n resultLabel = 'rows',\n resultHint,\n onReset,\n onRowClick,\n scrollToTopOn,\n rowLink,\n emptyState,\n virtualization = {},\n ...tableOptions\n}: BonelessTableProps<TData>) {\n const settings = useMemo(() => mergeBonelessTableSettings(settingsOverride), [settingsOverride])\n const resolvedColumns = useMemo(() => withDefaultCells(resolveColumns(columns)), [columns])\n const defaultOrder = useMemo(() => getColumnIds(resolvedColumns), [resolvedColumns])\n const scrollerRef = useRef<HTMLDivElement>(null)\n const headerScrollerRef = useRef<HTMLDivElement>(null)\n const columnsButtonRef = useRef<HTMLButtonElement>(null)\n const nearEndTriggeredRef = useRef(false)\n const columnMenuId = useId()\n const [showColumns, setShowColumns] = useState(false)\n const [headerScrollbarGutter, setHeaderScrollbarGutter] = useState(0)\n const [sorting, setSorting] = useState<SortingState>(tableOptions.initialState?.sorting ?? [])\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>(\n tableOptions.initialState?.columnFilters ?? [],\n )\n const [columnVisibility, setColumnVisibility] = useState<VisibilityState>(\n tableOptions.initialState?.columnVisibility ?? {},\n )\n const [columnOrder, setColumnOrder] = useState<ColumnOrderState>(\n tableOptions.initialState?.columnOrder ?? defaultOrder,\n )\n const [expanded, setExpanded] = useState<ExpandedState>(tableOptions.initialState?.expanded ?? {})\n\n const {\n state: controlledState,\n onSortingChange,\n onColumnFiltersChange,\n onColumnVisibilityChange,\n onColumnOrderChange,\n onExpandedChange,\n getCoreRowModel: getCoreRowModelOption,\n getSortedRowModel: getSortedRowModelOption,\n getFilteredRowModel: getFilteredRowModelOption,\n getSubRows,\n manualSorting,\n manualFiltering,\n initialState,\n ...restTableOptions\n } = tableOptions\n\n useEffect(() => {\n if (scrollToTopOn !== undefined) scrollerRef.current?.scrollTo({ top: 0 })\n }, [scrollToTopOn])\n\n useEffect(() => {\n const scroller = scrollerRef.current\n if (!scroller) return\n const syncHeaderScrollbarGutter = () => {\n setHeaderScrollbarGutter(Math.max(0, scroller.offsetWidth - scroller.clientWidth))\n }\n syncHeaderScrollbarGutter()\n if (typeof ResizeObserver === 'undefined') return\n const observer = new ResizeObserver(syncHeaderScrollbarGutter)\n observer.observe(scroller)\n return () => observer.disconnect()\n }, [])\n\n const table = useReactTable({\n ...restTableOptions,\n data,\n columns: resolvedColumns,\n initialState,\n state: {\n sorting,\n columnFilters,\n columnVisibility,\n columnOrder,\n expanded,\n ...controlledState,\n },\n onSortingChange: onSortingChange ?? setSorting,\n onColumnFiltersChange: onColumnFiltersChange ?? setColumnFilters,\n onColumnVisibilityChange: onColumnVisibilityChange ?? setColumnVisibility,\n onColumnOrderChange: onColumnOrderChange ?? setColumnOrder,\n onExpandedChange: onExpandedChange ?? setExpanded,\n getCoreRowModel: getCoreRowModelOption ?? getCoreRowModel(),\n getSortedRowModel: getSortedRowModelOption ?? (manualSorting ? undefined : getSortedRowModel()),\n getFilteredRowModel:\n getFilteredRowModelOption ?? (manualFiltering ? undefined : getFilteredRowModel()),\n getExpandedRowModel: treeOption ? getExpandedRowModel() : undefined,\n getSubRows,\n manualSorting,\n manualFiltering,\n })\n\n const visibleColumns = table.getVisibleLeafColumns()\n const allColumns = table.getAllFlatColumns()\n const columnSettingsById = useMemo(\n () => new Map(allColumns.map((column) => [column.id, resolveColumnSettings(settings, column)])),\n [allColumns, settings],\n )\n const getColumnSettings = (column: (typeof allColumns)[number]) =>\n columnSettingsById.get(column.id) ?? resolveColumnSettings(settings, column)\n const grid = visibleColumns\n .map((column) => {\n const columnSettings = getColumnSettings(column)\n if ('widthPx' in columnSettings.sizing) return `${columnSettings.sizing.widthPx}px`\n return `minmax(${columnSettings.sizing.minPx}px, ${columnSettings.sizing.flex}fr)`\n })\n .join(' ')\n const minWidth = visibleColumns.reduce((width, column) => {\n const { sizing } = getColumnSettings(column)\n return width + ('widthPx' in sizing ? sizing.widthPx : sizing.minPx)\n }, 0)\n const gridStyle = {\n '--boneless-table-grid': grid,\n minWidth: `${minWidth}px`,\n } as CSSProperties\n const tree: BonelessTableTreeOptions | undefined =\n treeOption === true ? {} : treeOption === false ? undefined : treeOption\n const treeColumnId = tree?.columnId ?? visibleColumns[0]?.id\n const treeIndentPx = tree?.indentPx ?? 16\n const preExpandedRowModel = tree ? table.getPreExpandedRowModel() : undefined\n const expandableRows = useMemo(\n () => preExpandedRowModel?.flatRows.filter((row) => row.getCanExpand()) ?? [],\n [preExpandedRowModel],\n )\n const allTreeRowsExpanded = useMemo(\n () => expandableRows.length > 0 && expandableRows.every((row) => row.getIsExpanded()),\n [expandableRows, expanded],\n )\n\n useEffect(() => {\n if (!isFetchingMore || !canLoadMore) nearEndTriggeredRef.current = false\n }, [canLoadMore, isFetchingMore])\n\n function handleScroll() {\n const element = scrollerRef.current\n if (!element) return\n if (headerScrollerRef.current) headerScrollerRef.current.scrollLeft = element.scrollLeft\n const isNearEnd =\n element.scrollHeight - element.scrollTop - element.clientHeight < nearEndOffset\n if (!isNearEnd) {\n nearEndTriggeredRef.current = false\n return\n }\n if (!onNearEnd || !canLoadMore || isFetchingMore || nearEndTriggeredRef.current) return\n nearEndTriggeredRef.current = true\n onNearEnd()\n }\n\n function resetTable() {\n if (onReset) return onReset()\n table.resetSorting()\n table.resetColumnFilters()\n table.resetColumnVisibility()\n table.setColumnOrder(defaultOrder)\n table.resetExpanded()\n }\n\n function moveColumn(id: string, direction: -1 | 1) {\n const current = table.getState().columnOrder\n table.setColumnOrder(moveItem(current.length ? current : defaultOrder, id, direction))\n }\n\n const shown = table.getRowModel().rows.length\n const total = totalCount ?? shown\n const rows = table.getRowModel().rows\n // A content-sized scroller has no bounded vertical viewport, so it must render every row.\n // `fill` establishes the viewport contract by requiring a stable-height parent.\n const isVirtualized = scroller === 'fill' && virtualization !== false\n const rowVirtualizer = useVirtualizer({\n count: rows.length,\n getScrollElement: () => scrollerRef.current,\n estimateSize: () => (virtualization === false ? 58 : (virtualization.estimateSize ?? 58)),\n overscan: isVirtualized ? (virtualization.overscan ?? 5) : 0,\n enabled: isVirtualized,\n initialRect: { width: 0, height: 600 },\n })\n const estimatedRowSize = virtualization === false ? 58 : (virtualization.estimateSize ?? 58)\n const virtualRows = !isVirtualized\n ? rows.map((row, index) => ({ index, start: index * 58, key: row.id }))\n : rowVirtualizer.getVirtualItems().length > 0\n ? rowVirtualizer.getVirtualItems()\n : rows\n .slice(0, Math.ceil(600 / estimatedRowSize) + (virtualization.overscan ?? 5))\n .map((row, index) => ({\n index,\n start: index * estimatedRowSize,\n key: row.id,\n }))\n\n function closeColumnMenu() {\n setShowColumns(false)\n columnsButtonRef.current?.focus()\n }\n\n const toolbarSummary = (\n <div className={classNames.toolbarSummary} data-slot=\"toolbar-summary\">\n <strong>{total.toLocaleString()}</strong> {resultLabel}\n {resultHint ? (\n <span className={classNames.toolbarHint} data-slot=\"toolbar-hint\">\n {resultHint}\n </span>\n ) : null}\n </div>\n )\n const toolbarActions = (\n <div className={classNames.toolbarActions} data-slot=\"toolbar-actions\">\n {tree && expandableRows.length > 0 ? (\n <button\n data-slot=\"tree-toggle-all\"\n onClick={() => table.toggleAllRowsExpanded(!allTreeRowsExpanded)}\n >\n {allTreeRowsExpanded ? icons?.collapse : icons?.expand}\n {allTreeRowsExpanded\n ? (tree.collapseAllLabel ?? 'Collapse all')\n : (tree.expandAllLabel ?? 'Expand all')}\n </button>\n ) : null}\n <button data-slot=\"reset\" onClick={resetTable} title=\"Reset table settings\">\n {icons?.reset}\n Reset\n </button>\n <div data-slot=\"column-settings\">\n <button\n data-slot=\"columns-button\"\n onClick={() => setShowColumns((value) => !value)}\n aria-expanded={showColumns}\n aria-haspopup=\"dialog\"\n aria-controls={columnMenuId}\n ref={columnsButtonRef}\n >\n {icons?.columns}\n Columns\n </button>\n {showColumns ? (\n <ColumnMenu\n table={table}\n onClose={closeColumnMenu}\n onMoveColumn={moveColumn}\n className={classNames.columnMenu}\n icons={icons}\n id={columnMenuId}\n triggerRef={columnsButtonRef}\n />\n ) : null}\n </div>\n </div>\n )\n const defaultToolbar = toolbarLayout ? (\n toolbarLayout({ table, summary: toolbarSummary, actions: toolbarActions })\n ) : (\n <div className={classNames.toolbar} data-slot=\"toolbar\">\n {toolbarSummary}\n {toolbarActions}\n </div>\n )\n\n const defaultFooter = (\n <footer className={classNames.footer} data-slot=\"footer\">\n Showing {shown.toLocaleString()} of {total.toLocaleString()} {resultLabel}\n </footer>\n )\n const rootStyle =\n scroller === 'fill'\n ? { display: 'flex', flexDirection: 'column' as const, minHeight: 0 }\n : undefined\n const scrollerStyle: CSSProperties = {\n overflowX: settings.interactions.horizontalOverflow,\n ...(scroller === 'fill' ? { flex: '1 1 auto', minHeight: 0, overflowY: 'auto' } : {}),\n }\n const tableStyle: CSSProperties = {\n '--boneless-table-grid': grid,\n ...(scroller === 'fill'\n ? { display: 'flex', flexDirection: 'column', flex: '1 1 auto', minHeight: 0 }\n : {}),\n } as CSSProperties\n\n return (\n <div className={cn(className, classNames.root)} data-slot=\"root\" style={rootStyle}>\n {renderSlot(toolbar, table, defaultToolbar)}\n <div\n className={classNames.table}\n data-slot=\"table\"\n style={tableStyle}\n aria-busy={isLoading || isFetchingMore}\n role=\"table\"\n >\n <div\n data-slot=\"header-scroller\"\n ref={headerScrollerRef}\n style={{\n flex: '0 0 auto',\n minWidth: 0,\n overflow: 'hidden',\n paddingInlineEnd: headerScrollbarGutter || undefined,\n }}\n >\n <div\n className={classNames.headerGroup}\n data-slot=\"header-group\"\n role=\"rowgroup\"\n style={gridStyle}\n >\n {table.getHeaderGroups().map((headerGroup) => (\n <div\n className={classNames.headerRow}\n data-slot=\"header-row\"\n key={headerGroup.id}\n role=\"row\"\n style={{ display: 'grid', gridTemplateColumns: 'var(--boneless-table-grid)' }}\n >\n {headerGroup.headers.map((header) => {\n const columnSettings = getColumnSettings(header.column)\n const direction = header.column.getIsSorted()\n const isSortable =\n !header.isPlaceholder &&\n header.column.getCanSort() &&\n columnSettings.sorting.enabled\n return (\n <div\n className={classNames.header}\n data-slot=\"header\"\n data-align={columnSettings.align}\n data-borders={columnSettings.borders}\n key={header.id}\n role=\"columnheader\"\n aria-colspan={header.colSpan > 1 ? header.colSpan : undefined}\n aria-sort={\n direction === 'asc'\n ? 'ascending'\n : direction === 'desc'\n ? 'descending'\n : isSortable\n ? 'none'\n : undefined\n }\n style={{ gridColumn: `span ${header.colSpan}` }}\n >\n {header.isPlaceholder ? null : isSortable ? (\n <button\n className={classNames.headerButton}\n data-align={columnSettings.align}\n data-slot=\"header-button\"\n onClick={header.column.getToggleSortingHandler()}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {icons?.sort ? (\n <span\n className={classNames.sortIndicator}\n data-align={columnSettings.align}\n data-slot=\"sort-indicator\"\n data-reveal={columnSettings.sorting.reveal}\n >\n {icons.sort(direction)}\n </span>\n ) : null}\n </button>\n ) : (\n flexRender(header.column.columnDef.header, header.getContext())\n )}\n {!header.isPlaceholder && columnSettings.filtering ? (\n <div\n className={classNames.filter}\n data-slot=\"filter\"\n data-reveal={\n columnSettings.filtering.reveal ?? settings.interactions.filterReveal\n }\n >\n <ColumnFilter\n column={header.column}\n settings={columnSettings.filtering}\n icon={icons?.search}\n debounceMs={filterDebounceMs}\n />\n </div>\n ) : null}\n </div>\n )\n })}\n </div>\n ))}\n </div>\n </div>\n <div\n className={classNames.scroller}\n data-slot=\"scroller\"\n ref={scrollerRef}\n onScroll={handleScroll}\n style={scrollerStyle}\n >\n {isLoading ? (\n <TableSkeleton\n columnCount={visibleColumns.length}\n rows={skeletonRows}\n label={skeletonLabel}\n classNames={classNames}\n />\n ) : rows.length === 0 ? (\n <div className={classNames.emptyState} data-slot=\"empty-state\" role=\"status\">\n {emptyState\n ? typeof emptyState === 'function'\n ? emptyState(table)\n : emptyState\n : table.getState().columnFilters.length > 0\n ? 'No rows match the current filters.'\n : 'No rows to display.'}\n </div>\n ) : (\n <div\n className={classNames.rowGroup}\n data-slot=\"row-group\"\n style={{\n ...gridStyle,\n height: `${isVirtualized ? rowVirtualizer.getTotalSize() : 'auto'}`,\n position: 'relative',\n }}\n role=\"rowgroup\"\n >\n {virtualRows.map((virtualRow) => {\n const row = rows[virtualRow.index]!\n const href = rowLink ? resolveRowHref(rowLink, row.original) : undefined\n const RowLink = rowLink?.component\n const rowContent = (\n <div\n className={classNames.row}\n data-slot=\"row\"\n role=\"row\"\n style={{ display: 'grid', gridTemplateColumns: 'var(--boneless-table-grid)' }}\n tabIndex={onRowClick && !href ? 0 : undefined}\n onClick={(event) => onRowClick?.(row.original, event)}\n onKeyDown={(event) => {\n if (!onRowClick || href || (event.key !== 'Enter' && event.key !== ' '))\n return\n event.preventDefault()\n onRowClick(row.original, event)\n }}\n >\n {row.getVisibleCells().map((cell) => {\n const columnSettings = getColumnSettings(cell.column)\n const title =\n columnSettings.valueDisplay != null\n ? String(cell.getValue() ?? '')\n : undefined\n const isTreeCell = Boolean(tree && cell.column.id === treeColumnId)\n const canExpand = row.getCanExpand()\n const cellContent = flexRender(cell.column.columnDef.cell, cell.getContext())\n return (\n <div\n className={classNames.cell}\n data-slot=\"cell\"\n data-align={columnSettings.align}\n data-borders={columnSettings.borders}\n role=\"cell\"\n key={cell.id}\n title={title}\n >\n {isTreeCell ? (\n <div\n data-slot=\"tree-content\"\n style={{ paddingInlineStart: `${row.depth * treeIndentPx}px` }}\n >\n {canExpand ? (\n <button\n data-slot=\"tree-row-toggle\"\n type=\"button\"\n aria-expanded={row.getIsExpanded()}\n aria-label={`${row.getIsExpanded() ? 'Collapse' : 'Expand'} row`}\n onClick={(event) => {\n event.stopPropagation()\n row.toggleExpanded()\n }}\n >\n {row.getIsExpanded()\n ? (icons?.collapse ?? '−')\n : (icons?.expand ?? '+')}\n </button>\n ) : (\n <span data-slot=\"tree-row-toggle-spacer\" aria-hidden=\"true\" />\n )}\n <span data-slot=\"tree-value\">{cellContent}</span>\n </div>\n ) : (\n cellContent\n )}\n </div>\n )\n })}\n </div>\n )\n const rowStyle = !isVirtualized\n ? undefined\n : {\n position: 'absolute' as const,\n top: 0,\n left: 0,\n width: '100%',\n transform: `translateY(${virtualRow.start}px)`,\n }\n if (!href || !rowLink || !RowLink || (tree && row.getCanExpand()))\n return (\n <div\n key={row.id}\n data-index={isVirtualized ? virtualRow.index : undefined}\n ref={isVirtualized ? rowVirtualizer.measureElement : undefined}\n style={rowStyle}\n >\n {rowContent}\n </div>\n )\n return (\n <div\n key={row.id}\n data-index={isVirtualized ? virtualRow.index : undefined}\n ref={isVirtualized ? rowVirtualizer.measureElement : undefined}\n style={rowStyle}\n >\n <RowLink\n className={classNames.rowLink ?? ''}\n href={href}\n aria-label={resolveRowLinkLabel(rowLink, row.original)}\n target={rowLink.target}\n rel={rowLink.rel}\n >\n {rowContent}\n </RowLink>\n </div>\n )\n })}\n </div>\n )}\n {isFetchingMore ? (\n <TableSkeleton\n columnCount={visibleColumns.length}\n rows={3}\n label={skeletonLabel}\n classNames={classNames}\n />\n ) : null}\n </div>\n </div>\n {renderSlot(footer, table, defaultFooter)}\n </div>\n )\n}\n","import type { Column, RowData } from '@tanstack/react-table'\nimport { useEffect, useState, type ReactNode } from 'react'\nimport type { BonelessTableColumnSettings } from './settings'\n\nexport function ColumnFilter<TData extends RowData>({\n column,\n settings,\n className,\n icon,\n debounceMs = 0,\n}: {\n column: Column<TData, unknown>\n settings: NonNullable<BonelessTableColumnSettings['filtering']>\n className?: string\n /** Optional consumer-owned icon rendered before a text input. */\n icon?: ReactNode\n debounceMs?: number\n}) {\n const value = String(column.getFilterValue() ?? '')\n const [inputValue, setInputValue] = useState(value)\n\n useEffect(() => {\n setInputValue(value)\n }, [value])\n\n useEffect(() => {\n if (settings.type !== 'text' || inputValue === value) return\n if (debounceMs <= 0) {\n column.setFilterValue(inputValue || undefined)\n return\n }\n const timer = window.setTimeout(\n () => column.setFilterValue(inputValue || undefined),\n debounceMs,\n )\n return () => window.clearTimeout(timer)\n }, [column, debounceMs, inputValue, settings.type, value])\n\n if (settings.type === 'select') {\n return (\n <select\n className={className}\n data-slot=\"filter-select\"\n aria-label={`Filter ${column.id}`}\n value={value}\n onChange={(event) => column.setFilterValue(event.target.value || undefined)}\n >\n <option value=\"\">All</option>\n {settings.options?.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </select>\n )\n }\n return (\n <label className={className} data-slot=\"filter-text\">\n {icon}\n <input\n data-slot=\"filter-input\"\n aria-label={`Filter ${column.id}`}\n value={inputValue}\n placeholder=\"Filter\"\n onChange={(event) => setInputValue(event.target.value)}\n />\n </label>\n )\n}\n","import type { Table } from '@tanstack/react-table'\nimport { useEffect, useRef, type ReactNode, type RefObject } from 'react'\n\nexport type ColumnMenuIcons = Partial<{\n close: ReactNode\n moveEarlier: ReactNode\n moveLater: ReactNode\n}>\n\nexport function ColumnMenu<TData>({\n table,\n onClose,\n onMoveColumn,\n className,\n icons,\n id = 'boneless-table-column-menu',\n triggerRef,\n}: {\n table: Table<TData>\n onClose: () => void\n onMoveColumn: (id: string, direction: -1 | 1) => void\n className?: string\n /** Optional consumer-owned icons. Text labels remain available without them. */\n icons?: ColumnMenuIcons\n id?: string\n /** The menu trigger is not an outside click; this lets it reliably toggle the dialog closed. */\n triggerRef?: RefObject<HTMLElement | null>\n}) {\n const menuRef = useRef<HTMLDivElement>(null)\n const closeButtonRef = useRef<HTMLButtonElement>(null)\n\n useEffect(() => {\n closeButtonRef.current?.focus()\n function dismissOnOutsideClick(event: MouseEvent) {\n const target = event.target as Node\n if (!menuRef.current?.contains(target) && !triggerRef?.current?.contains(target)) onClose()\n }\n document.addEventListener('mousedown', dismissOnOutsideClick)\n return () => document.removeEventListener('mousedown', dismissOnOutsideClick)\n }, [onClose])\n\n return (\n <div\n className={className}\n data-slot=\"column-menu\"\n ref={menuRef}\n id={id}\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby={`${id}-title`}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n onClose()\n }\n }}\n >\n <div data-slot=\"column-menu-header\">\n <span id={`${id}-title`}>Configure columns</span>\n <button\n data-slot=\"column-menu-close\"\n onClick={onClose}\n aria-label=\"Close column settings\"\n ref={closeButtonRef}\n >\n {icons?.close ?? 'Close'}\n </button>\n </div>\n {table.getAllLeafColumns().map((column) => (\n <div data-slot=\"column-menu-item\" key={column.id}>\n <label data-slot=\"column-menu-label\">\n <input\n type=\"checkbox\"\n checked={column.getIsVisible()}\n onChange={column.getToggleVisibilityHandler()}\n />\n {column.columnDef.meta?.columnLabel ??\n (typeof column.columnDef.header === 'string' ||\n typeof column.columnDef.header === 'number'\n ? String(column.columnDef.header)\n : column.id)}\n </label>\n <div data-slot=\"column-menu-actions\">\n <button\n data-slot=\"column-menu-move-earlier\"\n onClick={() => onMoveColumn(column.id, -1)}\n title=\"Move column earlier\"\n >\n {icons?.moveEarlier ?? 'Earlier'}\n </button>\n <button\n data-slot=\"column-menu-move-later\"\n onClick={() => onMoveColumn(column.id, 1)}\n title=\"Move column later\"\n >\n {icons?.moveLater ?? 'Later'}\n </button>\n </div>\n </div>\n ))}\n </div>\n )\n}\n","/** Joins consumer supplied class names without imposing a CSS framework. */\nexport function cn(...classNames: Array<string | false | null | undefined>) {\n return classNames.filter(Boolean).join(' ')\n}\n","import type { DeepPartial } from './types'\n\nexport type ColumnAlignment = 'left' | 'right'\nexport type ColumnBorders = 'none' | 'left' | 'right' | 'both'\nexport type FilterType = 'text' | 'select'\nexport type RevealMode = 'always' | 'hover'\n\nexport type BonelessTableColumnSizing = { widthPx: number } | { minPx: number; flex?: number }\n\nexport type BonelessTableColumnSettings = {\n sizing?: BonelessTableColumnSizing\n align?: ColumnAlignment\n borders?: ColumnBorders\n sorting?: { enabled?: boolean; reveal?: RevealMode }\n filtering?: { type: FilterType; options?: readonly string[]; reveal?: RevealMode }\n valueDisplay?: { truncateAt: number; suffix?: string }\n}\n\nexport type BonelessTableSettings = {\n columnDefaults: Required<Pick<BonelessTableColumnSettings, 'align' | 'borders'>> & {\n sizing: Required<NonNullable<BonelessTableColumnSettings['sizing']>>\n sorting: Required<NonNullable<BonelessTableColumnSettings['sorting']>>\n }\n interactions: { filterReveal: RevealMode; horizontalOverflow: 'auto' | 'scroll' }\n}\n\nexport const defaultBonelessTableSettings: BonelessTableSettings = {\n columnDefaults: {\n sizing: { minPx: 120, flex: 1 },\n align: 'left',\n borders: 'none',\n sorting: { enabled: true, reveal: 'hover' },\n },\n interactions: { filterReveal: 'hover', horizontalOverflow: 'auto' },\n}\n\nexport function mergeBonelessTableSettings(\n override?: DeepPartial<BonelessTableSettings>,\n base: BonelessTableSettings = defaultBonelessTableSettings,\n): BonelessTableSettings {\n if (!override) return base\n return {\n columnDefaults: {\n sizing: {\n ...base.columnDefaults.sizing,\n ...override.columnDefaults?.sizing,\n },\n align: override.columnDefaults?.align ?? base.columnDefaults.align,\n borders: override.columnDefaults?.borders ?? base.columnDefaults.borders,\n sorting: {\n ...base.columnDefaults.sorting,\n ...override.columnDefaults?.sorting,\n },\n },\n interactions: {\n ...base.interactions,\n ...override.interactions,\n },\n }\n}\n\nexport function resolveColumnSettings(\n settings: BonelessTableSettings,\n column: { columnDef: { meta?: { bonelessTable?: BonelessTableColumnSettings } } },\n) {\n const configured = column.columnDef.meta?.bonelessTable\n const configuredSizing = configured?.sizing\n return {\n sizing:\n configuredSizing && 'widthPx' in configuredSizing\n ? { widthPx: configuredSizing.widthPx }\n : { ...settings.columnDefaults.sizing, ...configuredSizing },\n align: configured?.align ?? settings.columnDefaults.align,\n borders: configured?.borders ?? settings.columnDefaults.borders,\n sorting: { ...settings.columnDefaults.sorting, ...configured?.sorting },\n filtering: configured?.filtering,\n valueDisplay: configured?.valueDisplay,\n }\n}\n\nexport function compactValue(value: unknown, settings?: BonelessTableColumnSettings) {\n const text = value == null ? '' : String(value)\n const display = settings?.valueDisplay\n if (!display || text.length <= display.truncateAt) return text\n return `${text.slice(0, display.truncateAt).trimEnd()}${display.suffix ?? '...'}`\n}\n","import type { RowData } from '@tanstack/react-table'\nimport { compactValue } from './settings'\nimport type { BonelessTableColumn, ResolvedBonelessTableColumn } from './types'\n\nexport function defineColumns<TData extends RowData>(\n columns: BonelessTableColumn<TData>[],\n): BonelessTableColumn<TData>[] {\n return columns\n}\n\nexport function resolveColumns<TData extends RowData>(\n columns: BonelessTableColumn<TData>[],\n): ResolvedBonelessTableColumn<TData>[] {\n return columns.map((column) => {\n if ('key' in column && column.key) {\n const { key, ...definition } = column\n return { ...definition, accessorKey: key } as ResolvedBonelessTableColumn<TData>\n }\n return column as ResolvedBonelessTableColumn<TData>\n })\n}\n\nexport function withDefaultCells<TData extends RowData>(\n columns: ResolvedBonelessTableColumn<TData>[],\n): ResolvedBonelessTableColumn<TData>[] {\n return columns.map((column) => {\n if (column.cell) return column\n return {\n ...column,\n cell: ({ getValue, column: tableColumn }) => {\n const text = compactValue(getValue(), tableColumn.columnDef.meta?.bonelessTable)\n return text\n },\n }\n })\n}\n\nexport function getColumnIds<TData extends RowData>(\n columns: BonelessTableColumn<TData>[],\n): string[] {\n return columns.map((column, index) => {\n if ('id' in column && column.id) return column.id\n if ('key' in column && column.key != null) return String(column.key)\n if ('accessorKey' in column && column.accessorKey != null) {\n return String(column.accessorKey)\n }\n return String(index)\n })\n}\n","import type { BonelessTableClassNames } from './boneless-table'\nimport { cn } from './class-names'\n\nexport function TableSkeleton({\n columnCount,\n rows,\n label = 'Loading rows',\n classNames = {},\n}: {\n columnCount: number\n rows: number\n label?: string\n classNames?: Pick<BonelessTableClassNames, 'row' | 'cell' | 'skeleton'>\n}) {\n return (\n <div data-slot=\"skeleton\" className={classNames.skeleton} aria-busy=\"true\">\n {Array.from({ length: rows }, (_, rowIndex) => (\n <div\n className={classNames.row}\n data-slot=\"skeleton-row\"\n role=\"status\"\n aria-label={label}\n key={rowIndex}\n style={{ display: 'grid', gridTemplateColumns: 'var(--boneless-table-grid)' }}\n >\n {Array.from({ length: columnCount }, (_, columnIndex) => (\n <div className={cn(classNames.cell)} data-slot=\"skeleton-cell\" key={columnIndex}>\n <span data-slot=\"skeleton-line\" />\n </div>\n ))}\n </div>\n ))}\n </div>\n )\n}\n","import type { RowData } from '@tanstack/react-table'\nimport type { AnchorHTMLAttributes, ComponentType, ReactNode } from 'react'\n\nexport type BonelessTableRowLinkComponentProps = {\n children: ReactNode\n className: string\n href: string\n 'aria-label'?: string\n target?: AnchorHTMLAttributes<HTMLAnchorElement>['target']\n rel?: string\n}\n\nexport type BonelessTableRowLink<TData extends RowData> = {\n /** A framework-specific component such as Next.js Link that wraps each resolved row. */\n component: ComponentType<BonelessTableRowLinkComponentProps>\n href: string | ((row: TData) => string | undefined)\n label?: string | ((row: TData) => string | undefined)\n target?: AnchorHTMLAttributes<HTMLAnchorElement>['target']\n rel?: string\n}\n\nfunction readPath(row: unknown, path: string): unknown {\n return path.split('.').reduce<unknown>((value, key) => {\n if (value === null || typeof value !== 'object') return undefined\n return (value as Record<string, unknown>)[key]\n }, row)\n}\n\nexport function resolveRowHref<TData extends RowData>(\n link: Pick<BonelessTableRowLink<TData>, 'href'>,\n row: TData,\n): string | undefined {\n if (typeof link.href === 'function') return link.href(row)\n\n let hasMissingValue = false\n const href = link.href.replace(/\\{(?:row\\.)?([\\w.]+)\\}/g, (token, path: string) => {\n const value = readPath(row, path)\n if (value === undefined || value === null) {\n hasMissingValue = true\n return token\n }\n return encodeURIComponent(String(value))\n })\n\n return hasMissingValue ? undefined : href\n}\n\nexport function resolveRowLinkLabel<TData extends RowData>(\n link: Pick<BonelessTableRowLink<TData>, 'label'>,\n row: TData,\n): string | undefined {\n return typeof link.label === 'function' ? link.label(row) : link.label\n}\n","'use client'\n\nimport './types'\n\nexport {\n BonelessTable,\n type BonelessTableClassNames,\n type BonelessTableIcons,\n type BonelessTableOptions,\n type BonelessTablePresentationOptions,\n type BonelessTableProps,\n type BonelessTableRowClickEvent,\n type BonelessTableSlot,\n type BonelessTableTreeOptions,\n type BonelessTableToolbarLayout,\n} from './boneless-table'\nexport {\n compactValue,\n defaultBonelessTableSettings,\n mergeBonelessTableSettings,\n resolveColumnSettings,\n type ColumnAlignment,\n type ColumnBorders,\n type BonelessTableColumnSettings,\n type BonelessTableSettings,\n type FilterType,\n type RevealMode,\n} from './settings'\nexport { defineColumns, getColumnIds, resolveColumns, withDefaultCells } from './columns'\nexport { ColumnFilter } from './column-filter'\nexport { ColumnMenu } from './column-menu'\nexport { TableSkeleton } from './table-skeleton'\nexport {\n resolveRowHref,\n resolveRowLinkLabel,\n type BonelessTableRowLink,\n type BonelessTableRowLinkComponentProps,\n} from './row-link'\nexport type { BonelessTableColumn, DeepPartial, ResolvedBonelessTableColumn } from './types'\n\nexport {\n createColumnHelper,\n flexRender,\n getCoreRowModel,\n getExpandedRowModel,\n getFilteredRowModel,\n getSortedRowModel,\n useReactTable,\n type ColumnDef,\n type ColumnFiltersState,\n type ColumnOrderState,\n type ExpandedState,\n type SortingState,\n type Table,\n type TableOptions,\n type VisibilityState,\n} from '@tanstack/react-table'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAUK;AACP,SAAS,sBAAsB;AAC/B;AAAA,EACE,aAAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OAKK;;;AC7BP,SAAS,WAAW,gBAAgC;AAuC9C,SAOE,KAPF;AApCC,SAAS,aAAoC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AACf,GAOG;AAjBH;AAkBE,QAAM,QAAQ,QAAO,YAAO,eAAe,MAAtB,YAA2B,EAAE;AAClD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAElD,YAAU,MAAM;AACd,kBAAc,KAAK;AAAA,EACrB,GAAG,CAAC,KAAK,CAAC;AAEV,YAAU,MAAM;AACd,QAAI,SAAS,SAAS,UAAU,eAAe,MAAO;AACtD,QAAI,cAAc,GAAG;AACnB,aAAO,eAAe,cAAc,MAAS;AAC7C;AAAA,IACF;AACA,UAAM,QAAQ,OAAO;AAAA,MACnB,MAAM,OAAO,eAAe,cAAc,MAAS;AAAA,MACnD;AAAA,IACF;AACA,WAAO,MAAM,OAAO,aAAa,KAAK;AAAA,EACxC,GAAG,CAAC,QAAQ,YAAY,YAAY,SAAS,MAAM,KAAK,CAAC;AAEzD,MAAI,SAAS,SAAS,UAAU;AAC9B,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,aAAU;AAAA,QACV,cAAY,UAAU,OAAO,EAAE;AAAA,QAC/B;AAAA,QACA,UAAU,CAAC,UAAU,OAAO,eAAe,MAAM,OAAO,SAAS,MAAS;AAAA,QAE1E;AAAA,8BAAC,YAAO,OAAM,IAAG,iBAAG;AAAA,WACnB,cAAS,YAAT,mBAAkB,IAAI,CAAC,WACtB,oBAAC,YAAoB,OAAO,QACzB,oBADU,MAEb;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACA,SACE,qBAAC,WAAM,WAAsB,aAAU,eACpC;AAAA;AAAA,IACD;AAAA,MAAC;AAAA;AAAA,QACC,aAAU;AAAA,QACV,cAAY,UAAU,OAAO,EAAE;AAAA,QAC/B,OAAO;AAAA,QACP,aAAY;AAAA,QACZ,UAAU,CAAC,UAAU,cAAc,MAAM,OAAO,KAAK;AAAA;AAAA,IACvD;AAAA,KACF;AAEJ;;;ACnEA,SAAS,aAAAC,YAAW,cAA8C;AAwD5D,SACE,OAAAC,MADF,QAAAC,aAAA;AAhDC,SAAS,WAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,KAAK;AAAA,EACL;AACF,GAUG;AA3BH;AA4BE,QAAM,UAAU,OAAuB,IAAI;AAC3C,QAAM,iBAAiB,OAA0B,IAAI;AAErD,EAAAF,WAAU,MAAM;AA/BlB,QAAAG;AAgCI,KAAAA,MAAA,eAAe,YAAf,gBAAAA,IAAwB;AACxB,aAAS,sBAAsB,OAAmB;AAjCtD,UAAAA,KAAA;AAkCM,YAAM,SAAS,MAAM;AACrB,UAAI,GAACA,MAAA,QAAQ,YAAR,gBAAAA,IAAiB,SAAS,YAAW,GAAC,8CAAY,YAAZ,mBAAqB,SAAS,SAAS,SAAQ;AAAA,IAC5F;AACA,aAAS,iBAAiB,aAAa,qBAAqB;AAC5D,WAAO,MAAM,SAAS,oBAAoB,aAAa,qBAAqB;AAAA,EAC9E,GAAG,CAAC,OAAO,CAAC;AAEZ,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,KAAK;AAAA,MACL;AAAA,MACA,MAAK;AAAA,MACL,cAAW;AAAA,MACX,mBAAiB,GAAG,EAAE;AAAA,MACtB,WAAW,CAAC,UAAU;AACpB,YAAI,MAAM,QAAQ,UAAU;AAC1B,gBAAM,eAAe;AACrB,kBAAQ;AAAA,QACV;AAAA,MACF;AAAA,MAEA;AAAA,wBAAAA,MAAC,SAAI,aAAU,sBACb;AAAA,0BAAAD,KAAC,UAAK,IAAI,GAAG,EAAE,UAAU,+BAAiB;AAAA,UAC1C,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,aAAU;AAAA,cACV,SAAS;AAAA,cACT,cAAW;AAAA,cACX,KAAK;AAAA,cAEJ,+CAAO,UAAP,YAAgB;AAAA;AAAA,UACnB;AAAA,WACF;AAAA,QACC,MAAM,kBAAkB,EAAE,IAAI,CAAC,WAAQ;AApE9C,cAAAE,KAAA;AAqEQ,iCAAAD,MAAC,SAAI,aAAU,oBACb;AAAA,4BAAAA,MAAC,WAAM,aAAU,qBACf;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAS,OAAO,aAAa;AAAA,kBAC7B,UAAU,OAAO,2BAA2B;AAAA;AAAA,cAC9C;AAAA,eACC,MAAAE,MAAA,OAAO,UAAU,SAAjB,gBAAAA,IAAuB,gBAAvB,YACE,OAAO,OAAO,UAAU,WAAW,YACpC,OAAO,OAAO,UAAU,WAAW,WAC/B,OAAO,OAAO,UAAU,MAAM,IAC9B,OAAO;AAAA,eACf;AAAA,YACA,gBAAAD,MAAC,SAAI,aAAU,uBACb;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,aAAU;AAAA,kBACV,SAAS,MAAM,aAAa,OAAO,IAAI,EAAE;AAAA,kBACzC,OAAM;AAAA,kBAEL,+CAAO,gBAAP,YAAsB;AAAA;AAAA,cACzB;AAAA,cACA,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,aAAU;AAAA,kBACV,SAAS,MAAM,aAAa,OAAO,IAAI,CAAC;AAAA,kBACxC,OAAM;AAAA,kBAEL,+CAAO,cAAP,YAAoB;AAAA;AAAA,cACvB;AAAA,eACF;AAAA,eA5BqC,OAAO,EA6B9C;AAAA,SACD;AAAA;AAAA;AAAA,EACH;AAEJ;;;ACrGO,SAAS,MAAM,YAAsD;AAC1E,SAAO,WAAW,OAAO,OAAO,EAAE,KAAK,GAAG;AAC5C;;;ACuBO,IAAM,+BAAsD;AAAA,EACjE,gBAAgB;AAAA,IACd,QAAQ,EAAE,OAAO,KAAK,MAAM,EAAE;AAAA,IAC9B,OAAO;AAAA,IACP,SAAS;AAAA,IACT,SAAS,EAAE,SAAS,MAAM,QAAQ,QAAQ;AAAA,EAC5C;AAAA,EACA,cAAc,EAAE,cAAc,SAAS,oBAAoB,OAAO;AACpE;AAEO,SAAS,2BACd,UACA,OAA8B,8BACP;AAvCzB;AAwCE,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO;AAAA,IACL,gBAAgB;AAAA,MACd,QAAQ,kCACH,KAAK,eAAe,UACpB,cAAS,mBAAT,mBAAyB;AAAA,MAE9B,QAAO,oBAAS,mBAAT,mBAAyB,UAAzB,YAAkC,KAAK,eAAe;AAAA,MAC7D,UAAS,oBAAS,mBAAT,mBAAyB,YAAzB,YAAoC,KAAK,eAAe;AAAA,MACjE,SAAS,kCACJ,KAAK,eAAe,WACpB,cAAS,mBAAT,mBAAyB;AAAA,IAEhC;AAAA,IACA,cAAc,kCACT,KAAK,eACL,SAAS;AAAA,EAEhB;AACF;AAEO,SAAS,sBACd,UACA,QACA;AAhEF;AAiEE,QAAM,cAAa,YAAO,UAAU,SAAjB,mBAAuB;AAC1C,QAAM,mBAAmB,yCAAY;AACrC,SAAO;AAAA,IACL,QACE,oBAAoB,aAAa,mBAC7B,EAAE,SAAS,iBAAiB,QAAQ,IACpC,kCAAK,SAAS,eAAe,SAAW;AAAA,IAC9C,QAAO,8CAAY,UAAZ,YAAqB,SAAS,eAAe;AAAA,IACpD,UAAS,8CAAY,YAAZ,YAAuB,SAAS,eAAe;AAAA,IACxD,SAAS,kCAAK,SAAS,eAAe,UAAY,yCAAY;AAAA,IAC9D,WAAW,yCAAY;AAAA,IACvB,cAAc,yCAAY;AAAA,EAC5B;AACF;AAEO,SAAS,aAAa,OAAgB,UAAwC;AAhFrF;AAiFE,QAAM,OAAO,SAAS,OAAO,KAAK,OAAO,KAAK;AAC9C,QAAM,UAAU,qCAAU;AAC1B,MAAI,CAAC,WAAW,KAAK,UAAU,QAAQ,WAAY,QAAO;AAC1D,SAAO,GAAG,KAAK,MAAM,GAAG,QAAQ,UAAU,EAAE,QAAQ,CAAC,IAAG,aAAQ,WAAR,YAAkB,KAAK;AACjF;;;ACjFO,SAAS,cACd,SAC8B;AAC9B,SAAO;AACT;AAEO,SAAS,eACd,SACsC;AACtC,SAAO,QAAQ,IAAI,CAAC,WAAW;AAC7B,QAAI,SAAS,UAAU,OAAO,KAAK;AACjC,YAA+B,aAAvB,MAfd,IAeqC,IAAf,uBAAe,IAAf,CAAR;AACR,aAAO,iCAAK,aAAL,EAAiB,aAAa,IAAI;AAAA,IAC3C;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAEO,SAAS,iBACd,SACsC;AACtC,SAAO,QAAQ,IAAI,CAAC,WAAW;AAC7B,QAAI,OAAO,KAAM,QAAO;AACxB,WAAO,iCACF,SADE;AAAA,MAEL,MAAM,CAAC,EAAE,UAAU,QAAQ,YAAY,MAAM;AA7BnD;AA8BQ,cAAM,OAAO,aAAa,SAAS,IAAG,iBAAY,UAAU,SAAtB,mBAA4B,aAAa;AAC/E,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEO,SAAS,aACd,SACU;AACV,SAAO,QAAQ,IAAI,CAAC,QAAQ,UAAU;AACpC,QAAI,QAAQ,UAAU,OAAO,GAAI,QAAO,OAAO;AAC/C,QAAI,SAAS,UAAU,OAAO,OAAO,KAAM,QAAO,OAAO,OAAO,GAAG;AACnE,QAAI,iBAAiB,UAAU,OAAO,eAAe,MAAM;AACzD,aAAO,OAAO,OAAO,WAAW;AAAA,IAClC;AACA,WAAO,OAAO,KAAK;AAAA,EACrB,CAAC;AACH;;;ACrBc,gBAAAG,YAAA;AAxBP,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,aAAa,CAAC;AAChB,GAKG;AACD,SACE,gBAAAA,KAAC,SAAI,aAAU,YAAW,WAAW,WAAW,UAAU,aAAU,QACjE,gBAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,aAChC,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,WAAW;AAAA,MACtB,aAAU;AAAA,MACV,MAAK;AAAA,MACL,cAAY;AAAA,MAEZ,OAAO,EAAE,SAAS,QAAQ,qBAAqB,6BAA6B;AAAA,MAE3E,gBAAM,KAAK,EAAE,QAAQ,YAAY,GAAG,CAACC,IAAG,gBACvC,gBAAAD,KAAC,SAAI,WAAW,GAAG,WAAW,IAAI,GAAG,aAAU,iBAC7C,0BAAAA,KAAC,UAAK,aAAU,iBAAgB,KADkC,WAEpE,CACD;AAAA;AAAA,IAPI;AAAA,EAQP,CACD,GACH;AAEJ;;;ACbA,SAAS,SAAS,KAAc,MAAuB;AACrD,SAAO,KAAK,MAAM,GAAG,EAAE,OAAgB,CAAC,OAAO,QAAQ;AACrD,QAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,WAAQ,MAAkC,GAAG;AAAA,EAC/C,GAAG,GAAG;AACR;AAEO,SAAS,eACd,MACA,KACoB;AACpB,MAAI,OAAO,KAAK,SAAS,WAAY,QAAO,KAAK,KAAK,GAAG;AAEzD,MAAI,kBAAkB;AACtB,QAAM,OAAO,KAAK,KAAK,QAAQ,2BAA2B,CAAC,OAAO,SAAiB;AACjF,UAAM,QAAQ,SAAS,KAAK,IAAI;AAChC,QAAI,UAAU,UAAa,UAAU,MAAM;AACzC,wBAAkB;AAClB,aAAO;AAAA,IACT;AACA,WAAO,mBAAmB,OAAO,KAAK,CAAC;AAAA,EACzC,CAAC;AAED,SAAO,kBAAkB,SAAY;AACvC;AAEO,SAAS,oBACd,MACA,KACoB;AACpB,SAAO,OAAO,KAAK,UAAU,aAAa,KAAK,MAAM,GAAG,IAAI,KAAK;AACnE;;;APoYI,SACE,OAAAE,MADF,QAAAC,aAAA;AA9OJ,SAAS,SAAS,OAAiB,IAAY,WAAmB;AAChE,QAAM,QAAQ,MAAM,QAAQ,EAAE;AAC9B,QAAM,SAAS,QAAQ;AACvB,MAAI,QAAQ,KAAK,SAAS,KAAK,UAAU,MAAM,OAAQ,QAAO;AAC9D,QAAM,OAAO,CAAC,GAAG,KAAK;AACrB,GAAC,KAAK,KAAK,GAAG,KAAK,MAAM,CAAC,IAAI,CAAC,KAAK,MAAM,GAAG,KAAK,KAAK,CAAC;AACzD,SAAO;AACT;AAEA,SAAS,WACP,MACA,OACA,UACA;AACA,MAAI,SAAS,MAAO,QAAO;AAC3B,MAAI,OAAO,SAAS,WAAY,QAAO,KAAK,KAAK;AACjD,MAAI,QAAQ,SAAS,KAAM,QAAO;AAClC,SAAO;AACT;AAEO,SAAS,cAAqC,IA8BvB;AA9BuB,eACnD;AAAA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,aAAa,CAAC;AAAA,IACd;AAAA,IACA,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB;AAAA,IACA,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,WAAW;AAAA,IACX,UAAU;AAAA,IACV;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,CAAC;AAAA,EA1PpB,IA8NqD,IA6BhD,yBA7BgD,IA6BhD;AAAA,IA5BH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AA1PF,MAAAC,KAAAC,KAAA;AA6PE,QAAM,WAAW,QAAQ,MAAM,2BAA2B,gBAAgB,GAAG,CAAC,gBAAgB,CAAC;AAC/F,QAAM,kBAAkB,QAAQ,MAAM,iBAAiB,eAAe,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AAC1F,QAAM,eAAe,QAAQ,MAAM,aAAa,eAAe,GAAG,CAAC,eAAe,CAAC;AACnF,QAAM,cAAcC,QAAuB,IAAI;AAC/C,QAAM,oBAAoBA,QAAuB,IAAI;AACrD,QAAM,mBAAmBA,QAA0B,IAAI;AACvD,QAAM,sBAAsBA,QAAO,KAAK;AACxC,QAAM,eAAe,MAAM;AAC3B,QAAM,CAAC,aAAa,cAAc,IAAIC,UAAS,KAAK;AACpD,QAAM,CAAC,uBAAuB,wBAAwB,IAAIA,UAAS,CAAC;AACpE,QAAM,CAAC,SAAS,UAAU,IAAIA,WAAuBF,OAAAD,MAAA,aAAa,iBAAb,gBAAAA,IAA2B,YAA3B,OAAAC,MAAsC,CAAC,CAAC;AAC7F,QAAM,CAAC,eAAe,gBAAgB,IAAIE;AAAA,KACxC,wBAAa,iBAAb,mBAA2B,kBAA3B,YAA4C,CAAC;AAAA,EAC/C;AACA,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA;AAAA,KAC9C,wBAAa,iBAAb,mBAA2B,qBAA3B,YAA+C,CAAC;AAAA,EAClD;AACA,QAAM,CAAC,aAAa,cAAc,IAAIA;AAAA,KACpC,wBAAa,iBAAb,mBAA2B,gBAA3B,YAA0C;AAAA,EAC5C;AACA,QAAM,CAAC,UAAU,WAAW,IAAIA,WAAwB,wBAAa,iBAAb,mBAA2B,aAA3B,YAAuC,CAAC,CAAC;AAEjG,QAeI,mBAdF;AAAA,WAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB;AAAA,IACjB,mBAAmB;AAAA,IACnB,qBAAqB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAhSJ,IAkSM,IADC,6BACD,IADC;AAAA,IAbH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAIF,EAAAC,WAAU,MAAM;AApSlB,QAAAJ;AAqSI,QAAI,kBAAkB,OAAW,EAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB,SAAS,EAAE,KAAK,EAAE;AAAA,EAC1E,GAAG,CAAC,aAAa,CAAC;AAElB,EAAAI,WAAU,MAAM;AACd,UAAMC,YAAW,YAAY;AAC7B,QAAI,CAACA,UAAU;AACf,UAAM,4BAA4B,MAAM;AACtC,+BAAyB,KAAK,IAAI,GAAGA,UAAS,cAAcA,UAAS,WAAW,CAAC;AAAA,IACnF;AACA,8BAA0B;AAC1B,QAAI,OAAO,mBAAmB,YAAa;AAC3C,UAAM,WAAW,IAAI,eAAe,yBAAyB;AAC7D,aAAS,QAAQA,SAAQ;AACzB,WAAO,MAAM,SAAS,WAAW;AAAA,EACnC,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ,cAAc,iCACvB,mBADuB;AAAA,IAE1B;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,OACG;AAAA,IAEL,iBAAiB,4CAAmB;AAAA,IACpC,uBAAuB,wDAAyB;AAAA,IAChD,0BAA0B,8DAA4B;AAAA,IACtD,qBAAqB,oDAAuB;AAAA,IAC5C,kBAAkB,8CAAoB;AAAA,IACtC,iBAAiB,wDAAyB,gBAAgB;AAAA,IAC1D,mBAAmB,4DAA4B,gBAAgB,SAAY,kBAAkB;AAAA,IAC7F,qBACE,gEAA8B,kBAAkB,SAAY,oBAAoB;AAAA,IAClF,qBAAqB,aAAa,oBAAoB,IAAI;AAAA,IAC1D;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAC;AAED,QAAM,iBAAiB,MAAM,sBAAsB;AACnD,QAAM,aAAa,MAAM,kBAAkB;AAC3C,QAAM,qBAAqB;AAAA,IACzB,MAAM,IAAI,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,sBAAsB,UAAU,MAAM,CAAC,CAAC,CAAC;AAAA,IAC9F,CAAC,YAAY,QAAQ;AAAA,EACvB;AACA,QAAM,oBAAoB,CAAC,WAAqC;AAvVlE,QAAAL;AAwVI,YAAAA,MAAA,mBAAmB,IAAI,OAAO,EAAE,MAAhC,OAAAA,MAAqC,sBAAsB,UAAU,MAAM;AAAA;AAC7E,QAAM,OAAO,eACV,IAAI,CAAC,WAAW;AACf,UAAM,iBAAiB,kBAAkB,MAAM;AAC/C,QAAI,aAAa,eAAe,OAAQ,QAAO,GAAG,eAAe,OAAO,OAAO;AAC/E,WAAO,UAAU,eAAe,OAAO,KAAK,OAAO,eAAe,OAAO,IAAI;AAAA,EAC/E,CAAC,EACA,KAAK,GAAG;AACX,QAAM,WAAW,eAAe,OAAO,CAAC,OAAO,WAAW;AACxD,UAAM,EAAE,OAAO,IAAI,kBAAkB,MAAM;AAC3C,WAAO,SAAS,aAAa,SAAS,OAAO,UAAU,OAAO;AAAA,EAChE,GAAG,CAAC;AACJ,QAAM,YAAY;AAAA,IAChB,yBAAyB;AAAA,IACzB,UAAU,GAAG,QAAQ;AAAA,EACvB;AACA,QAAM,OACJ,eAAe,OAAO,CAAC,IAAI,eAAe,QAAQ,SAAY;AAChE,QAAM,gBAAe,kCAAM,aAAN,aAAkB,oBAAe,CAAC,MAAhB,mBAAmB;AAC1D,QAAM,gBAAe,kCAAM,aAAN,YAAkB;AACvC,QAAM,sBAAsB,OAAO,MAAM,uBAAuB,IAAI;AACpE,QAAM,iBAAiB;AAAA,IACrB,MAAG;AA9WP,UAAAA;AA8WU,cAAAA,MAAA,2DAAqB,SAAS,OAAO,CAAC,QAAQ,IAAI,aAAa,OAA/D,OAAAA,MAAqE,CAAC;AAAA;AAAA,IAC5E,CAAC,mBAAmB;AAAA,EACtB;AACA,QAAM,sBAAsB;AAAA,IAC1B,MAAM,eAAe,SAAS,KAAK,eAAe,MAAM,CAAC,QAAQ,IAAI,cAAc,CAAC;AAAA,IACpF,CAAC,gBAAgB,QAAQ;AAAA,EAC3B;AAEA,EAAAI,WAAU,MAAM;AACd,QAAI,CAAC,kBAAkB,CAAC,YAAa,qBAAoB,UAAU;AAAA,EACrE,GAAG,CAAC,aAAa,cAAc,CAAC;AAEhC,WAAS,eAAe;AACtB,UAAM,UAAU,YAAY;AAC5B,QAAI,CAAC,QAAS;AACd,QAAI,kBAAkB,QAAS,mBAAkB,QAAQ,aAAa,QAAQ;AAC9E,UAAM,YACJ,QAAQ,eAAe,QAAQ,YAAY,QAAQ,eAAe;AACpE,QAAI,CAAC,WAAW;AACd,0BAAoB,UAAU;AAC9B;AAAA,IACF;AACA,QAAI,CAAC,aAAa,CAAC,eAAe,kBAAkB,oBAAoB,QAAS;AACjF,wBAAoB,UAAU;AAC9B,cAAU;AAAA,EACZ;AAEA,WAAS,aAAa;AACpB,QAAI,QAAS,QAAO,QAAQ;AAC5B,UAAM,aAAa;AACnB,UAAM,mBAAmB;AACzB,UAAM,sBAAsB;AAC5B,UAAM,eAAe,YAAY;AACjC,UAAM,cAAc;AAAA,EACtB;AAEA,WAAS,WAAW,IAAY,WAAmB;AACjD,UAAM,UAAU,MAAM,SAAS,EAAE;AACjC,UAAM,eAAe,SAAS,QAAQ,SAAS,UAAU,cAAc,IAAI,SAAS,CAAC;AAAA,EACvF;AAEA,QAAM,QAAQ,MAAM,YAAY,EAAE,KAAK;AACvC,QAAM,QAAQ,kCAAc;AAC5B,QAAM,OAAO,MAAM,YAAY,EAAE;AAGjC,QAAM,gBAAgB,aAAa,UAAU,mBAAmB;AAChE,QAAM,iBAAiB,eAAe;AAAA,IACpC,OAAO,KAAK;AAAA,IACZ,kBAAkB,MAAM,YAAY;AAAA,IACpC,cAAc,MAAG;AAharB,UAAAJ;AAgayB,gCAAmB,QAAQ,MAAMA,MAAA,eAAe,iBAAf,OAAAA,MAA+B;AAAA;AAAA,IACrF,UAAU,iBAAiB,oBAAe,aAAf,YAA2B,IAAK;AAAA,IAC3D,SAAS;AAAA,IACT,aAAa,EAAE,OAAO,GAAG,QAAQ,IAAI;AAAA,EACvC,CAAC;AACD,QAAM,mBAAmB,mBAAmB,QAAQ,MAAM,oBAAe,iBAAf,YAA+B;AACzF,QAAM,cAAc,CAAC,gBACjB,KAAK,IAAI,CAAC,KAAK,WAAW,EAAE,OAAO,OAAO,QAAQ,IAAI,KAAK,IAAI,GAAG,EAAE,IACpE,eAAe,gBAAgB,EAAE,SAAS,IACxC,eAAe,gBAAgB,IAC/B,KACG,MAAM,GAAG,KAAK,KAAK,MAAM,gBAAgB,MAAK,oBAAe,aAAf,YAA2B,EAAE,EAC3E,IAAI,CAAC,KAAK,WAAW;AAAA,IACpB;AAAA,IACA,OAAO,QAAQ;AAAA,IACf,KAAK,IAAI;AAAA,EACX,EAAE;AAEV,WAAS,kBAAkB;AAlb7B,QAAAA;AAmbI,mBAAe,KAAK;AACpB,KAAAA,MAAA,iBAAiB,YAAjB,gBAAAA,IAA0B;AAAA,EAC5B;AAEA,QAAM,iBACJ,gBAAAD,MAAC,SAAI,WAAW,WAAW,gBAAgB,aAAU,mBACnD;AAAA,oBAAAD,KAAC,YAAQ,gBAAM,eAAe,GAAE;AAAA,IAAS;AAAA,IAAE;AAAA,IAC1C,aACC,gBAAAA,KAAC,UAAK,WAAW,WAAW,aAAa,aAAU,gBAChD,sBACH,IACE;AAAA,KACN;AAEF,QAAM,iBACJ,gBAAAC,MAAC,SAAI,WAAW,WAAW,gBAAgB,aAAU,mBAClD;AAAA,YAAQ,eAAe,SAAS,IAC/B,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,aAAU;AAAA,QACV,SAAS,MAAM,MAAM,sBAAsB,CAAC,mBAAmB;AAAA,QAE9D;AAAA,gCAAsB,+BAAO,WAAW,+BAAO;AAAA,UAC/C,uBACI,UAAK,qBAAL,YAAyB,kBACzB,UAAK,mBAAL,YAAuB;AAAA;AAAA;AAAA,IAC9B,IACE;AAAA,IACJ,gBAAAA,MAAC,YAAO,aAAU,SAAQ,SAAS,YAAY,OAAM,wBAClD;AAAA,qCAAO;AAAA,MAAM;AAAA,OAEhB;AAAA,IACA,gBAAAA,MAAC,SAAI,aAAU,mBACb;AAAA,sBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,aAAU;AAAA,UACV,SAAS,MAAM,eAAe,CAAC,UAAU,CAAC,KAAK;AAAA,UAC/C,iBAAe;AAAA,UACf,iBAAc;AAAA,UACd,iBAAe;AAAA,UACf,KAAK;AAAA,UAEJ;AAAA,2CAAO;AAAA,YAAQ;AAAA;AAAA;AAAA,MAElB;AAAA,MACC,cACC,gBAAAD;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,SAAS;AAAA,UACT,cAAc;AAAA,UACd,WAAW,WAAW;AAAA,UACtB;AAAA,UACA,IAAI;AAAA,UACJ,YAAY;AAAA;AAAA,MACd,IACE;AAAA,OACN;AAAA,KACF;AAEF,QAAM,iBAAiB,gBACrB,cAAc,EAAE,OAAO,SAAS,gBAAgB,SAAS,eAAe,CAAC,IAEzE,gBAAAC,MAAC,SAAI,WAAW,WAAW,SAAS,aAAU,WAC3C;AAAA;AAAA,IACA;AAAA,KACH;AAGF,QAAM,gBACJ,gBAAAA,MAAC,YAAO,WAAW,WAAW,QAAQ,aAAU,UAAS;AAAA;AAAA,IAC9C,MAAM,eAAe;AAAA,IAAE;AAAA,IAAK,MAAM,eAAe;AAAA,IAAE;AAAA,IAAE;AAAA,KAChE;AAEF,QAAM,YACJ,aAAa,SACT,EAAE,SAAS,QAAQ,eAAe,UAAmB,WAAW,EAAE,IAClE;AACN,QAAM,gBAA+B;AAAA,IACnC,WAAW,SAAS,aAAa;AAAA,KAC7B,aAAa,SAAS,EAAE,MAAM,YAAY,WAAW,GAAG,WAAW,OAAO,IAAI,CAAC;AAErF,QAAM,aAA4B;AAAA,IAChC,yBAAyB;AAAA,KACrB,aAAa,SACb,EAAE,SAAS,QAAQ,eAAe,UAAU,MAAM,YAAY,WAAW,EAAE,IAC3E,CAAC;AAGP,SACE,gBAAAA,MAAC,SAAI,WAAW,GAAG,WAAW,WAAW,IAAI,GAAG,aAAU,QAAO,OAAO,WACrE;AAAA,eAAW,SAAS,OAAO,cAAc;AAAA,IAC1C,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,WAAW;AAAA,QACtB,aAAU;AAAA,QACV,OAAO;AAAA,QACP,aAAW,aAAa;AAAA,QACxB,MAAK;AAAA,QAEL;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,aAAU;AAAA,cACV,KAAK;AAAA,cACL,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,UAAU;AAAA,gBACV,UAAU;AAAA,gBACV,kBAAkB,yBAAyB;AAAA,cAC7C;AAAA,cAEA,0BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW,WAAW;AAAA,kBACtB,aAAU;AAAA,kBACV,MAAK;AAAA,kBACL,OAAO;AAAA,kBAEN,gBAAM,gBAAgB,EAAE,IAAI,CAAC,gBAC5B,gBAAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,WAAW,WAAW;AAAA,sBACtB,aAAU;AAAA,sBAEV,MAAK;AAAA,sBACL,OAAO,EAAE,SAAS,QAAQ,qBAAqB,6BAA6B;AAAA,sBAE3E,sBAAY,QAAQ,IAAI,CAAC,WAAW;AA3iBrD,4BAAAE;AA4iBkB,8BAAM,iBAAiB,kBAAkB,OAAO,MAAM;AACtD,8BAAM,YAAY,OAAO,OAAO,YAAY;AAC5C,8BAAM,aACJ,CAAC,OAAO,iBACR,OAAO,OAAO,WAAW,KACzB,eAAe,QAAQ;AACzB,+BACE,gBAAAD;AAAA,0BAAC;AAAA;AAAA,4BACC,WAAW,WAAW;AAAA,4BACtB,aAAU;AAAA,4BACV,cAAY,eAAe;AAAA,4BAC3B,gBAAc,eAAe;AAAA,4BAE7B,MAAK;AAAA,4BACL,gBAAc,OAAO,UAAU,IAAI,OAAO,UAAU;AAAA,4BACpD,aACE,cAAc,QACV,cACA,cAAc,SACZ,eACA,aACE,SACA;AAAA,4BAEV,OAAO,EAAE,YAAY,QAAQ,OAAO,OAAO,GAAG;AAAA,4BAE7C;AAAA,qCAAO,gBAAgB,OAAO,aAC7B,gBAAAA;AAAA,gCAAC;AAAA;AAAA,kCACC,WAAW,WAAW;AAAA,kCACtB,cAAY,eAAe;AAAA,kCAC3B,aAAU;AAAA,kCACV,SAAS,OAAO,OAAO,wBAAwB;AAAA,kCAE9C;AAAA,+CAAW,OAAO,OAAO,UAAU,QAAQ,OAAO,WAAW,CAAC;AAAA,qCAC9D,+BAAO,QACN,gBAAAD;AAAA,sCAAC;AAAA;AAAA,wCACC,WAAW,WAAW;AAAA,wCACtB,cAAY,eAAe;AAAA,wCAC3B,aAAU;AAAA,wCACV,eAAa,eAAe,QAAQ;AAAA,wCAEnC,gBAAM,KAAK,SAAS;AAAA;AAAA,oCACvB,IACE;AAAA;AAAA;AAAA,8BACN,IAEA,WAAW,OAAO,OAAO,UAAU,QAAQ,OAAO,WAAW,CAAC;AAAA,8BAE/D,CAAC,OAAO,iBAAiB,eAAe,YACvC,gBAAAA;AAAA,gCAAC;AAAA;AAAA,kCACC,WAAW,WAAW;AAAA,kCACtB,aAAU;AAAA,kCACV,gBACEE,MAAA,eAAe,UAAU,WAAzB,OAAAA,MAAmC,SAAS,aAAa;AAAA,kCAG3D,0BAAAF;AAAA,oCAAC;AAAA;AAAA,sCACC,QAAQ,OAAO;AAAA,sCACf,UAAU,eAAe;AAAA,sCACzB,MAAM,+BAAO;AAAA,sCACb,YAAY;AAAA;AAAA,kCACd;AAAA;AAAA,8BACF,IACE;AAAA;AAAA;AAAA,0BAnDC,OAAO;AAAA,wBAoDd;AAAA,sBAEJ,CAAC;AAAA;AAAA,oBAvEI,YAAY;AAAA,kBAwEnB,CACD;AAAA;AAAA,cACH;AAAA;AAAA,UACF;AAAA,UACA,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,WAAW;AAAA,cACtB,aAAU;AAAA,cACV,KAAK;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cAEN;AAAA,4BACC,gBAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,aAAa,eAAe;AAAA,oBAC5B,MAAM;AAAA,oBACN,OAAO;AAAA,oBACP;AAAA;AAAA,gBACF,IACE,KAAK,WAAW,IAClB,gBAAAA,KAAC,SAAI,WAAW,WAAW,YAAY,aAAU,eAAc,MAAK,UACjE,uBACG,OAAO,eAAe,aACpB,WAAW,KAAK,IAChB,aACF,MAAM,SAAS,EAAE,cAAc,SAAS,IACtC,uCACA,uBACR,IAEA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAW,WAAW;AAAA,oBACtB,aAAU;AAAA,oBACV,OAAO,iCACF,YADE;AAAA,sBAEL,QAAQ,GAAG,gBAAgB,eAAe,aAAa,IAAI,MAAM;AAAA,sBACjE,UAAU;AAAA,oBACZ;AAAA,oBACA,MAAK;AAAA,oBAEJ,sBAAY,IAAI,CAAC,eAAe;AAtpB/C,0BAAAE;AAupBgB,4BAAM,MAAM,KAAK,WAAW,KAAK;AACjC,4BAAM,OAAO,UAAU,eAAe,SAAS,IAAI,QAAQ,IAAI;AAC/D,4BAAM,UAAU,mCAAS;AACzB,4BAAM,aACJ,gBAAAF;AAAA,wBAAC;AAAA;AAAA,0BACC,WAAW,WAAW;AAAA,0BACtB,aAAU;AAAA,0BACV,MAAK;AAAA,0BACL,OAAO,EAAE,SAAS,QAAQ,qBAAqB,6BAA6B;AAAA,0BAC5E,UAAU,cAAc,CAAC,OAAO,IAAI;AAAA,0BACpC,SAAS,CAAC,UAAU,yCAAa,IAAI,UAAU;AAAA,0BAC/C,WAAW,CAAC,UAAU;AACpB,gCAAI,CAAC,cAAc,QAAS,MAAM,QAAQ,WAAW,MAAM,QAAQ;AACjE;AACF,kCAAM,eAAe;AACrB,uCAAW,IAAI,UAAU,KAAK;AAAA,0BAChC;AAAA,0BAEC,cAAI,gBAAgB,EAAE,IAAI,CAAC,SAAS;AAzqBzD,gCAAAE,KAAAC,KAAAK;AA0qBsB,kCAAM,iBAAiB,kBAAkB,KAAK,MAAM;AACpD,kCAAM,QACJ,eAAe,gBAAgB,OAC3B,QAAON,MAAA,KAAK,SAAS,MAAd,OAAAA,MAAmB,EAAE,IAC5B;AACN,kCAAM,aAAa,QAAQ,QAAQ,KAAK,OAAO,OAAO,YAAY;AAClE,kCAAM,YAAY,IAAI,aAAa;AACnC,kCAAM,cAAc,WAAW,KAAK,OAAO,UAAU,MAAM,KAAK,WAAW,CAAC;AAC5E,mCACE,gBAAAF;AAAA,8BAAC;AAAA;AAAA,gCACC,WAAW,WAAW;AAAA,gCACtB,aAAU;AAAA,gCACV,cAAY,eAAe;AAAA,gCAC3B,gBAAc,eAAe;AAAA,gCAC7B,MAAK;AAAA,gCAEL;AAAA,gCAEC,uBACC,gBAAAC;AAAA,kCAAC;AAAA;AAAA,oCACC,aAAU;AAAA,oCACV,OAAO,EAAE,oBAAoB,GAAG,IAAI,QAAQ,YAAY,KAAK;AAAA,oCAE5D;AAAA,kDACC,gBAAAD;AAAA,wCAAC;AAAA;AAAA,0CACC,aAAU;AAAA,0CACV,MAAK;AAAA,0CACL,iBAAe,IAAI,cAAc;AAAA,0CACjC,cAAY,GAAG,IAAI,cAAc,IAAI,aAAa,QAAQ;AAAA,0CAC1D,SAAS,CAAC,UAAU;AAClB,kDAAM,gBAAgB;AACtB,gDAAI,eAAe;AAAA,0CACrB;AAAA,0CAEC,cAAI,cAAc,KACdG,MAAA,+BAAO,aAAP,OAAAA,MAAmB,YACnBK,MAAA,+BAAO,WAAP,OAAAA,MAAiB;AAAA;AAAA,sCACxB,IAEA,gBAAAR,KAAC,UAAK,aAAU,0BAAyB,eAAY,QAAO;AAAA,sCAE9D,gBAAAA,KAAC,UAAK,aAAU,cAAc,uBAAY;AAAA;AAAA;AAAA,gCAC5C,IAEA;AAAA;AAAA,8BA7BG,KAAK;AAAA,4BA+BZ;AAAA,0BAEJ,CAAC;AAAA;AAAA,sBACH;AAEF,4BAAM,WAAW,CAAC,gBACd,SACA;AAAA,wBACE,UAAU;AAAA,wBACV,KAAK;AAAA,wBACL,MAAM;AAAA,wBACN,OAAO;AAAA,wBACP,WAAW,cAAc,WAAW,KAAK;AAAA,sBAC3C;AACJ,0BAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAY,QAAQ,IAAI,aAAa;AAC7D,+BACE,gBAAAA;AAAA,0BAAC;AAAA;AAAA,4BAEC,cAAY,gBAAgB,WAAW,QAAQ;AAAA,4BAC/C,KAAK,gBAAgB,eAAe,iBAAiB;AAAA,4BACrD,OAAO;AAAA,4BAEN;AAAA;AAAA,0BALI,IAAI;AAAA,wBAMX;AAEJ,6BACE,gBAAAA;AAAA,wBAAC;AAAA;AAAA,0BAEC,cAAY,gBAAgB,WAAW,QAAQ;AAAA,0BAC/C,KAAK,gBAAgB,eAAe,iBAAiB;AAAA,0BACrD,OAAO;AAAA,0BAEP,0BAAAA;AAAA,4BAAC;AAAA;AAAA,8BACC,YAAWE,MAAA,WAAW,YAAX,OAAAA,MAAsB;AAAA,8BACjC;AAAA,8BACA,cAAY,oBAAoB,SAAS,IAAI,QAAQ;AAAA,8BACrD,QAAQ,QAAQ;AAAA,8BAChB,KAAK,QAAQ;AAAA,8BAEZ;AAAA;AAAA,0BACH;AAAA;AAAA,wBAbK,IAAI;AAAA,sBAcX;AAAA,oBAEJ,CAAC;AAAA;AAAA,gBACH;AAAA,gBAED,iBACC,gBAAAF;AAAA,kBAAC;AAAA;AAAA,oBACC,aAAa,eAAe;AAAA,oBAC5B,MAAM;AAAA,oBACN,OAAO;AAAA,oBACP;AAAA;AAAA,gBACF,IACE;AAAA;AAAA;AAAA,UACN;AAAA;AAAA;AAAA,IACF;AAAA,IACC,WAAW,QAAQ,OAAO,aAAa;AAAA,KAC1C;AAEJ;;;AQ3uBA;AAAA,EACE;AAAA,EACA,cAAAS;AAAA,EACA,mBAAAC;AAAA,EACA,uBAAAC;AAAA,EACA,uBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,iBAAAC;AAAA,OASK;","names":["useEffect","useRef","useState","useEffect","jsx","jsxs","_a","jsx","_","jsx","jsxs","_a","_b","useRef","useState","useEffect","scroller","_c","flexRender","getCoreRowModel","getExpandedRowModel","getFilteredRowModel","getSortedRowModel","useReactTable"]}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "boneless-table",
3
+ "version": "0.1.0",
4
+ "description": "A typed, accessible, virtualized, unstyled data table renderer for React built on TanStack Table.",
5
+ "license": "MIT",
6
+ "sideEffects": false,
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "main": "./dist/index.js",
11
+ "module": "./dist/index.mjs",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.mjs",
17
+ "require": "./dist/index.js"
18
+ }
19
+ },
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "scripts": {
24
+ "build": "tsup",
25
+ "prepack": "npm run build",
26
+ "lint": "eslint src tests tsup.config.ts vitest.config.mts",
27
+ "test": "vitest run",
28
+ "test:watch": "vitest"
29
+ },
30
+ "peerDependencies": {
31
+ "react": "^18.2.0 || ^19.0.0",
32
+ "react-dom": "^18.2.0 || ^19.0.0"
33
+ },
34
+ "dependencies": {
35
+ "@tanstack/react-table": "^8.21.3",
36
+ "@tanstack/react-virtual": "^3.14.10"
37
+ },
38
+ "devDependencies": {
39
+ "@tanstack/react-table": "^8.21.3",
40
+ "@tanstack/react-virtual": "^3.14.10",
41
+ "@testing-library/react": "^16.3.3",
42
+ "@types/react": "^19.1.2",
43
+ "@types/react-dom": "^19.1.2",
44
+ "@typescript-eslint/parser": "^8.46.4",
45
+ "@vitejs/plugin-react": "^6.1.0",
46
+ "eslint": "^9.33.0",
47
+ "eslint-config-prettier": "^10.1.8",
48
+ "jsdom": "^29.1.1",
49
+ "react": "^19.1.0",
50
+ "react-dom": "^19.1.0",
51
+ "tsup": "^8.5.1",
52
+ "typescript": "^5.8.3",
53
+ "vitest": "^5.0.0"
54
+ }
55
+ }