@allxsmith/bestax-bulma 5.55.0 → 5.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/esm/components/DataTable.js.map +1 -1
- package/dist/esm/components/useDataTable.js +27 -0
- package/dist/esm/components/useDataTable.js.map +1 -1
- package/dist/esm/form/ColorInput.js +68 -0
- package/dist/esm/form/ColorInput.js.map +1 -0
- package/dist/esm/form/ColorInputBase.js +198 -0
- package/dist/esm/form/ColorInputBase.js.map +1 -0
- package/dist/esm/form/ColorPicker.js +4 -20
- package/dist/esm/form/ColorPicker.js.map +1 -1
- package/dist/esm/form/_colorInternals/EyeDropperButton.js +40 -0
- package/dist/esm/form/_colorInternals/EyeDropperButton.js.map +1 -0
- package/dist/esm/form/_colorInternals/pickerState.js +4 -4
- package/dist/esm/form/_colorInternals/pickerState.js.map +1 -1
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +300 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/types/components/DataTable.d.ts +1 -1
- package/dist/types/components/useDataTable.d.ts +36 -0
- package/dist/types/form/ColorInput.d.ts +76 -0
- package/dist/types/form/ColorInputBase.d.ts +108 -0
- package/dist/types/form/ColorPicker.d.ts +5 -0
- package/dist/types/form/_colorInternals/EyeDropperButton.d.ts +8 -0
- package/dist/types/form/_colorInternals/pickerState.d.ts +7 -1
- package/dist/types/index.d.ts +4 -0
- package/dist/types-cjs/components/DataTable.d.ts +1 -1
- package/dist/types-cjs/components/useDataTable.d.ts +36 -0
- package/dist/types-cjs/form/ColorInput.d.ts +76 -0
- package/dist/types-cjs/form/ColorInputBase.d.ts +108 -0
- package/dist/types-cjs/form/ColorPicker.d.ts +5 -0
- package/dist/types-cjs/form/_colorInternals/EyeDropperButton.d.ts +8 -0
- package/dist/types-cjs/form/_colorInternals/pickerState.d.ts +7 -1
- package/dist/types-cjs/index.d.ts +4 -0
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +1 -1
- package/src/scss/form/_colorinput.scss +109 -0
- package/src/scss/form/_index.scss +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataTable.js","sources":["../../../src/components/DataTable.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useId, useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { visuallyHidden } from '../helpers/statusRegion';\nimport { Table } from '../elements/Table';\nimport { Thead } from '../elements/Thead';\nimport { Tbody } from '../elements/Tbody';\nimport { Tr, TrProps } from '../elements/Tr';\nimport { Th } from '../elements/Th';\nimport { Td } from '../elements/Td';\nimport { Skeleton } from '../elements/Skeleton';\nimport { Checkbox } from '../form/Checkbox';\nimport { Input } from '../form/Input';\nimport { EmptyState } from './EmptyState';\nimport { Pagination } from './Pagination';\nimport { ScrollArea } from './ScrollArea';\nimport {\n isFiltering,\n useDataTable,\n type DataTableColumn,\n type DataTableFilters,\n type DataTableModel,\n type DataTableStateOptions,\n} from './useDataTable';\n\nexport { useDataTable } from './useDataTable';\nexport type {\n DataTableCellContext,\n DataTableCellProps,\n DataTableCheckboxProps,\n DataTableColumn,\n DataTableColumnMeta,\n DataTableFilters,\n DataTableHeaderCellProps,\n DataTableLabels,\n DataTableModel,\n DataTablePaginationProps,\n DataTableResolvedLabels,\n DataTableRowScope,\n DataTableSearchProps,\n DataTableSelectionMode,\n DataTableSort,\n DataTableSortButtonProps,\n DataTableSortDirection,\n DataTableState,\n DataTableStateOptions,\n UseDataTableOptions,\n} from './useDataTable';\n\n/**\n * Props for the DataTable component. The helper props, `className`, the\n * `ref` and the other attributes go on the wrapper `<div>`, which holds the\n * toolbar, the table and the pager. `aria-label` and `aria-labelledby` name\n * the `<table>` itself.\n *\n * @extraProp {string} [aria-label] - Names the table, in place of a `caption`. A table needs a name, so pass a `caption`, this or `aria-labelledby`, and a development build warns when it has none.\n * @extraProp {string} [aria-labelledby] - The id of a visible heading that names the table, in place of a `caption`.\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the wrapper `<div>`.\n */\nexport interface DataTableProps<TRow>\n extends\n DataTableStateOptions<TRow>,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * The columns, in the order they're shown. Required unless `table` is\n * given. Keep the array the same from one render to the next, defined\n * outside the component or in `useMemo`: a new one has every cell's text\n * worked out again.\n */\n columns?: DataTableColumn<TRow>[];\n /** The rows, as records of your own. Required unless `table` is given. */\n data?: TRow[];\n /**\n * A table made by `useDataTable`, rendered in place of one made from\n * `columns`, `data` and the state props, which are then left unread. Use\n * it to put a toolbar, a count or an export button elsewhere on the page.\n */\n table?: DataTableModel<TRow>;\n /**\n * Names the table, as a visible `<caption>`. A table needs a name: this,\n * `aria-label` or `aria-labelledby`.\n */\n caption?: React.ReactNode;\n /** Adds borders to all cells. */\n isBordered?: boolean;\n /** Adds zebra-striping to rows. */\n isStriped?: boolean;\n /** Makes the table more compact by cutting cell padding in half. */\n isNarrow?: boolean;\n /** Adds a hover effect on rows. */\n isHoverable?: boolean;\n /** Makes the table span the full width of its wrapper. */\n isFullwidth?: boolean;\n /**\n * Scrolls a table wider than its wrapper sideways, in a `ScrollArea`\n * named after the table, which can be scrolled from the keyboard while it\n * overflows.\n */\n isResponsive?: boolean;\n /** Shows a search field in the toolbar, labelled by `labels.search`. */\n hasSearch?: boolean;\n /**\n * More of the toolbar, after the search field: buttons for the selected\n * rows, a filter, a download. Given the table.\n */\n toolbar?: (table: DataTableModel<TRow>) => React.ReactNode;\n /**\n * Shows a page of skeleton rows under the header in place of the rows,\n * and marks the table busy. For data on its way, as from a server with\n * `manual`.\n */\n loading?: boolean;\n /**\n * What the table shows when it has no rows at all, in one cell across\n * every column. A small `EmptyState` saying `labels.empty` by default. A\n * title of your own sits under the heading the table does, so give it the\n * next level down with `titleAs`.\n */\n empty?: React.ReactNode;\n /**\n * What the table shows when the search and filters let no row through, in\n * one cell across every column. A small `EmptyState` saying\n * `labels.noResults` by default. A button that clears the search goes\n * away with it, so send focus back to the search field when it's pressed.\n */\n noResults?: React.ReactNode;\n /**\n * Props of your own for a row's `Tr`, such as a handler or a class. The\n * table's own (`isSelected`) win. To wrap a row in a `ContextMenu`, build\n * the table from `useDataTable`'s props instead.\n */\n rowProps?: (row: TRow) => DataTableRowProps;\n /** Additional CSS classes, on the wrapper `<div>`. */\n className?: string;\n}\n\n/** What `rowProps` gives a row's `Tr`: any of its props but the ones the table sets. */\nexport type DataTableRowProps = Omit<TrProps, 'isSelected' | 'children'>;\n\n/** The type of `DataTable`, generic in the row. */\nexport type DataTableComponent = (<TRow>(\n props: DataTableProps<TRow> & React.RefAttributes<HTMLDivElement>\n) => React.ReactElement | null) & { displayName?: string };\n\n/** How long the status region waits after a change before it speaks, in ms. */\nconst statusDelay = 500;\n\nconst noColumns: never[] = [];\nconst noRows: never[] = [];\n\n/** A text signature of the search and the filters, to tell when they change. */\nfunction filterSignature(search: string, filters: DataTableFilters): string {\n try {\n return JSON.stringify([search, Object.entries(filters).sort()]);\n } catch {\n return search;\n }\n}\n\n/** Whether a node renders something. */\nconst isShown = (node: React.ReactNode) =>\n node !== undefined && node !== null && node !== false && node !== '';\n\n/**\n * The `DataTable` component is a table of records that people can sort,\n * search, page through and select rows from, rendered with bestax's own\n * `Table` parts, `Checkbox` and `Pagination`.\n *\n * It's a native table, as in the WAI-ARIA Authoring Practices' sortable\n * table: a sortable header holds a button, the sorted one carries\n * `aria-sort`, and each row's checkbox is named for the row. It runs on\n * `useDataTable`, which custom markup can use too.\n *\n * @example\n * <DataTable\n * caption=\"Users\"\n * columns={[\n * { id: 'name', header: 'Name', sortable: true, isRowHeader: true },\n * { id: 'role', header: 'Role', sortable: true },\n * ]}\n * data={users}\n * selectionMode=\"multiple\"\n * pageSize={10}\n * hasSearch\n * />\n */\nexport const DataTable = forwardRef(function DataTableRender<TRow>(\n {\n columns,\n data,\n table: given,\n getRowId,\n sort,\n defaultSort,\n onSortChange,\n selectionMode,\n selected,\n defaultSelected,\n onSelectedChange,\n pageSize,\n page,\n defaultPage,\n onPageChange,\n search,\n defaultSearch,\n onSearchChange,\n filters,\n defaultFilters,\n onFiltersChange,\n manual,\n rowCount,\n labels,\n caption,\n isBordered,\n isStriped,\n isNarrow,\n isHoverable,\n isFullwidth,\n isResponsive,\n hasSearch,\n toolbar,\n loading,\n empty,\n noResults,\n rowProps,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n ...props\n }: DataTableProps<TRow>,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const own = useDataTable<TRow>({\n columns: columns ?? noColumns,\n data: data ?? noRows,\n getRowId,\n sort,\n defaultSort,\n onSortChange,\n selectionMode,\n selected,\n defaultSelected,\n onSelectedChange,\n pageSize,\n page,\n defaultPage,\n onPageChange,\n search,\n defaultSearch,\n onSearchChange,\n filters,\n defaultFilters,\n onFiltersChange,\n manual,\n rowCount,\n labels,\n });\n const table = given ?? own;\n const { state } = table;\n\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const rootClass = classNames(\n usePrefixedClassNames('data-table'),\n bulmaHelperClasses,\n className\n );\n const toolbarClass = usePrefixedClassNames('data-table-toolbar');\n const actionsClass = usePrefixedClassNames('data-table-actions');\n const emptyClass = usePrefixedClassNames('data-table-empty');\n\n const nameId = useId();\n const hasCaption = isShown(caption);\n const named = hasCaption || Boolean(ariaLabel || ariaLabelledby);\n useEffect(() => {\n if (!named) {\n warnOnce(\n 'DataTable:unnamed',\n '[bestax-bulma] <DataTable> has no accessible name. Pass a caption, ' +\n 'aria-label or aria-labelledby, so a screen reader can say which ' +\n 'table it is in.'\n );\n }\n }, [named]);\n const mixed = Boolean(given) && Boolean(columns || data);\n const bare = !given && (!columns || !data);\n useEffect(() => {\n if (mixed) {\n warnOnce(\n 'DataTable:table-and-columns',\n '[bestax-bulma] <DataTable> was given a `table` and `columns` or ' +\n '`data` too. It renders the `table` and leaves the rest unread, so ' +\n 'pass those to useDataTable instead.'\n );\n }\n if (bare) {\n warnOnce(\n 'DataTable:no-data',\n '[bestax-bulma] <DataTable> needs `columns` and `data`, or a `table` ' +\n 'from useDataTable.'\n );\n }\n }, [mixed, bare]);\n\n // The status region speaks only after the search, a filter or the page\n // changes, so nothing is read out as the page loads. `kind` is what last\n // changed, kept beside the values it changed from.\n const signature = filterSignature(state.search, state.filters);\n const [last, setLast] = useState({\n signature,\n page: state.page,\n kind: null as 'results' | 'page' | null,\n });\n if (last.signature !== signature) {\n setLast({ signature, page: state.page, kind: 'results' });\n } else if (last.page !== state.page) {\n setLast({ signature, page: state.page, kind: 'page' });\n }\n const { labels: words, rowCount: total, pageCount } = table;\n const size = state.pageSize;\n let message = '';\n if (last.kind && loading) {\n message = words.loading;\n } else if (last.kind === 'results' || (last.kind === 'page' && !total)) {\n message = words.results(total);\n } else if (last.kind === 'page') {\n // Without a page size, as when it's just been taken away, there's one\n // page, holding every row.\n const per = size ?? total;\n message = words.pageRange(\n (state.page - 1) * per + 1,\n Math.min(state.page * per, total),\n total\n );\n }\n // Written a moment after it changes, so typing in the search is read out\n // once it pauses rather than at every keystroke.\n const [said, setSaid] = useState('');\n useEffect(() => {\n const timer = setTimeout(() => setSaid(message), statusDelay);\n return () => clearTimeout(timer);\n }, [message]);\n\n const selectable = table.selectionMode === 'multiple';\n const sortable = table.columns.some(column => column.sortable);\n const columnCount = table.columns.length + (selectable ? 1 : 0);\n const pageRows = table.getRows('page');\n const selectAll = table.getSelectAllProps();\n\n const captionNode = hasCaption ? (\n <caption>\n <span id={nameId}>{caption}</span>\n {sortable && <span style={visuallyHidden}>{`, ${words.sortHint}.`}</span>}\n </caption>\n ) : sortable ? (\n <caption>\n <span style={visuallyHidden}>{words.sortHint}</span>\n </caption>\n ) : null;\n\n const header = (\n <Thead>\n <Tr>\n {selectable && (\n <Th scope=\"col\" isNarrow>\n <Checkbox\n {...selectAll}\n // While loading, the rows it would select aren't on screen.\n disabled={selectAll.disabled || Boolean(loading)}\n />\n </Th>\n )}\n {table.columns.map(column => (\n <Th key={column.id} {...table.getHeaderCellProps(column)}>\n {column.sortable ? (\n <button {...table.getSortButtonProps(column)}>\n {column.header}\n </button>\n ) : (\n column.header\n )}\n </Th>\n ))}\n </Tr>\n </Thead>\n );\n\n let body: React.ReactNode;\n if (loading) {\n body = Array.from({ length: size ?? 5 }, (_, index) => (\n <Tr key={index} aria-hidden=\"true\">\n {Array.from({ length: columnCount }, (__, cell) => (\n <Td key={cell}>\n <Skeleton variant=\"lines\" lines={1} />\n </Td>\n ))}\n </Tr>\n ));\n } else if (pageRows.length === 0) {\n // With `manual`, no rows under a search or a filter is no match: only\n // the server knows whether there's anything else.\n const nothing =\n table.getRows('all').length === 0 &&\n !(table.manual && isFiltering(state.search, state.filters));\n const content = nothing\n ? isShown(empty)\n ? empty\n : empty === undefined && (\n <EmptyState size=\"small\" description={words.empty} />\n )\n : isShown(noResults)\n ? noResults\n : noResults === undefined && (\n <EmptyState size=\"small\" description={words.noResults} />\n );\n body = (\n <Tr>\n <Td colSpan={columnCount} className={emptyClass}>\n {content}\n </Td>\n </Tr>\n );\n } else {\n body = pageRows.map(row => {\n const rowId = table.getRowId(row);\n return (\n <Tr key={rowId} {...rowProps?.(row)} {...table.getRowProps(row)}>\n {selectable && (\n <Td isNarrow>\n <Checkbox {...table.getSelectRowProps(row)} />\n </Td>\n )}\n {table.columns.map(column => {\n const text = table.getText(row, column.id);\n const content = column.cell\n ? column.cell(row, {\n value: table.getValue(row, column.id),\n text,\n rowId,\n })\n : text;\n const cellProps = table.getCellProps(row, column);\n return column.isRowHeader ? (\n <Th key={column.id} {...cellProps}>\n {content}\n </Th>\n ) : (\n <Td key={column.id} {...cellProps}>\n {content}\n </Td>\n );\n })}\n </Tr>\n );\n });\n }\n\n const tableElement = (\n <Table\n isBordered={isBordered}\n isStriped={isStriped}\n isNarrow={isNarrow}\n isHoverable={isHoverable}\n isFullwidth={isFullwidth}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n aria-busy={loading || undefined}\n >\n {captionNode}\n {header}\n <Tbody>{body}</Tbody>\n </Table>\n );\n\n // The name the scroll area and the pager take from the table.\n const textName =\n ariaLabel || (typeof caption === 'string' ? caption : undefined);\n const scrollName = ariaLabel\n ? { 'aria-label': ariaLabel }\n : {\n 'aria-labelledby': ariaLabelledby || (hasCaption ? nameId : undefined),\n };\n\n // Pagination names itself \"pagination\" unless given another name.\n const pagerLabel =\n words.pagination || (textName ? `${textName} pages` : undefined);\n const pagerName = pagerLabel ? { 'aria-label': pagerLabel } : {};\n\n const toolbarContent = toolbar?.(table);\n const hasToolbar = hasSearch || isShown(toolbarContent);\n\n return (\n <div ref={ref} className={rootClass} {...rest}>\n {hasToolbar && (\n <div className={toolbarClass}>\n {hasSearch && (\n <Input label={words.search} {...table.getSearchProps()} />\n )}\n {isShown(toolbarContent) && (\n <div className={actionsClass}>{toolbarContent}</div>\n )}\n </div>\n )}\n {isResponsive ? (\n <ScrollArea orientation=\"horizontal\" {...scrollName}>\n {tableElement}\n </ScrollArea>\n ) : (\n tableElement\n )}\n {/* In the page from the start, so a change to it is announced. */}\n <div role=\"status\" aria-live=\"polite\" style={visuallyHidden}>\n {said}\n </div>\n {pageCount > 1 && (\n <Pagination {...table.getPaginationProps()} {...pagerName} />\n )}\n </div>\n );\n}) as DataTableComponent;\n\nDataTable.displayName = 'DataTable';\n\nexport default DataTable;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DataTable.js","sources":["../../../src/components/DataTable.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useId, useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { visuallyHidden } from '../helpers/statusRegion';\nimport { Table } from '../elements/Table';\nimport { Thead } from '../elements/Thead';\nimport { Tbody } from '../elements/Tbody';\nimport { Tr, TrProps } from '../elements/Tr';\nimport { Th } from '../elements/Th';\nimport { Td } from '../elements/Td';\nimport { Skeleton } from '../elements/Skeleton';\nimport { Checkbox } from '../form/Checkbox';\nimport { Input } from '../form/Input';\nimport { EmptyState } from './EmptyState';\nimport { Pagination } from './Pagination';\nimport { ScrollArea } from './ScrollArea';\nimport {\n isFiltering,\n useDataTable,\n type DataTableColumn,\n type DataTableFilters,\n type DataTableModel,\n type DataTableStateOptions,\n} from './useDataTable';\n\nexport { useDataTable } from './useDataTable';\nexport type {\n DataTableCSVOptions,\n DataTableCellContext,\n DataTableCellProps,\n DataTableCheckboxProps,\n DataTableColumn,\n DataTableColumnMeta,\n DataTableFilters,\n DataTableHeaderCellProps,\n DataTableLabels,\n DataTableModel,\n DataTablePaginationProps,\n DataTableResolvedLabels,\n DataTableRowScope,\n DataTableSearchProps,\n DataTableSelectionMode,\n DataTableSort,\n DataTableSortButtonProps,\n DataTableSortDirection,\n DataTableState,\n DataTableStateOptions,\n UseDataTableOptions,\n} from './useDataTable';\n\n/**\n * Props for the DataTable component. The helper props, `className`, the\n * `ref` and the other attributes go on the wrapper `<div>`, which holds the\n * toolbar, the table and the pager. `aria-label` and `aria-labelledby` name\n * the `<table>` itself.\n *\n * @extraProp {string} [aria-label] - Names the table, in place of a `caption`. A table needs a name, so pass a `caption`, this or `aria-labelledby`, and a development build warns when it has none.\n * @extraProp {string} [aria-labelledby] - The id of a visible heading that names the table, in place of a `caption`.\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the wrapper `<div>`.\n */\nexport interface DataTableProps<TRow>\n extends\n DataTableStateOptions<TRow>,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * The columns, in the order they're shown. Required unless `table` is\n * given. Keep the array the same from one render to the next, defined\n * outside the component or in `useMemo`: a new one has every cell's text\n * worked out again.\n */\n columns?: DataTableColumn<TRow>[];\n /** The rows, as records of your own. Required unless `table` is given. */\n data?: TRow[];\n /**\n * A table made by `useDataTable`, rendered in place of one made from\n * `columns`, `data` and the state props, which are then left unread. Use\n * it to put a toolbar, a count or an export button elsewhere on the page.\n */\n table?: DataTableModel<TRow>;\n /**\n * Names the table, as a visible `<caption>`. A table needs a name: this,\n * `aria-label` or `aria-labelledby`.\n */\n caption?: React.ReactNode;\n /** Adds borders to all cells. */\n isBordered?: boolean;\n /** Adds zebra-striping to rows. */\n isStriped?: boolean;\n /** Makes the table more compact by cutting cell padding in half. */\n isNarrow?: boolean;\n /** Adds a hover effect on rows. */\n isHoverable?: boolean;\n /** Makes the table span the full width of its wrapper. */\n isFullwidth?: boolean;\n /**\n * Scrolls a table wider than its wrapper sideways, in a `ScrollArea`\n * named after the table, which can be scrolled from the keyboard while it\n * overflows.\n */\n isResponsive?: boolean;\n /** Shows a search field in the toolbar, labelled by `labels.search`. */\n hasSearch?: boolean;\n /**\n * More of the toolbar, after the search field: buttons for the selected\n * rows, a filter, a download. Given the table.\n */\n toolbar?: (table: DataTableModel<TRow>) => React.ReactNode;\n /**\n * Shows a page of skeleton rows under the header in place of the rows,\n * and marks the table busy. For data on its way, as from a server with\n * `manual`.\n */\n loading?: boolean;\n /**\n * What the table shows when it has no rows at all, in one cell across\n * every column. A small `EmptyState` saying `labels.empty` by default. A\n * title of your own sits under the heading the table does, so give it the\n * next level down with `titleAs`.\n */\n empty?: React.ReactNode;\n /**\n * What the table shows when the search and filters let no row through, in\n * one cell across every column. A small `EmptyState` saying\n * `labels.noResults` by default. A button that clears the search goes\n * away with it, so send focus back to the search field when it's pressed.\n */\n noResults?: React.ReactNode;\n /**\n * Props of your own for a row's `Tr`, such as a handler or a class. The\n * table's own (`isSelected`) win. To wrap a row in a `ContextMenu`, build\n * the table from `useDataTable`'s props instead.\n */\n rowProps?: (row: TRow) => DataTableRowProps;\n /** Additional CSS classes, on the wrapper `<div>`. */\n className?: string;\n}\n\n/** What `rowProps` gives a row's `Tr`: any of its props but the ones the table sets. */\nexport type DataTableRowProps = Omit<TrProps, 'isSelected' | 'children'>;\n\n/** The type of `DataTable`, generic in the row. */\nexport type DataTableComponent = (<TRow>(\n props: DataTableProps<TRow> & React.RefAttributes<HTMLDivElement>\n) => React.ReactElement | null) & { displayName?: string };\n\n/** How long the status region waits after a change before it speaks, in ms. */\nconst statusDelay = 500;\n\nconst noColumns: never[] = [];\nconst noRows: never[] = [];\n\n/** A text signature of the search and the filters, to tell when they change. */\nfunction filterSignature(search: string, filters: DataTableFilters): string {\n try {\n return JSON.stringify([search, Object.entries(filters).sort()]);\n } catch {\n return search;\n }\n}\n\n/** Whether a node renders something. */\nconst isShown = (node: React.ReactNode) =>\n node !== undefined && node !== null && node !== false && node !== '';\n\n/**\n * The `DataTable` component is a table of records that people can sort,\n * search, page through and select rows from, rendered with bestax's own\n * `Table` parts, `Checkbox` and `Pagination`.\n *\n * It's a native table, as in the WAI-ARIA Authoring Practices' sortable\n * table: a sortable header holds a button, the sorted one carries\n * `aria-sort`, and each row's checkbox is named for the row. It runs on\n * `useDataTable`, which custom markup can use too.\n *\n * @example\n * <DataTable\n * caption=\"Users\"\n * columns={[\n * { id: 'name', header: 'Name', sortable: true, isRowHeader: true },\n * { id: 'role', header: 'Role', sortable: true },\n * ]}\n * data={users}\n * selectionMode=\"multiple\"\n * pageSize={10}\n * hasSearch\n * />\n */\nexport const DataTable = forwardRef(function DataTableRender<TRow>(\n {\n columns,\n data,\n table: given,\n getRowId,\n sort,\n defaultSort,\n onSortChange,\n selectionMode,\n selected,\n defaultSelected,\n onSelectedChange,\n pageSize,\n page,\n defaultPage,\n onPageChange,\n search,\n defaultSearch,\n onSearchChange,\n filters,\n defaultFilters,\n onFiltersChange,\n manual,\n rowCount,\n labels,\n caption,\n isBordered,\n isStriped,\n isNarrow,\n isHoverable,\n isFullwidth,\n isResponsive,\n hasSearch,\n toolbar,\n loading,\n empty,\n noResults,\n rowProps,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n ...props\n }: DataTableProps<TRow>,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const own = useDataTable<TRow>({\n columns: columns ?? noColumns,\n data: data ?? noRows,\n getRowId,\n sort,\n defaultSort,\n onSortChange,\n selectionMode,\n selected,\n defaultSelected,\n onSelectedChange,\n pageSize,\n page,\n defaultPage,\n onPageChange,\n search,\n defaultSearch,\n onSearchChange,\n filters,\n defaultFilters,\n onFiltersChange,\n manual,\n rowCount,\n labels,\n });\n const table = given ?? own;\n const { state } = table;\n\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const rootClass = classNames(\n usePrefixedClassNames('data-table'),\n bulmaHelperClasses,\n className\n );\n const toolbarClass = usePrefixedClassNames('data-table-toolbar');\n const actionsClass = usePrefixedClassNames('data-table-actions');\n const emptyClass = usePrefixedClassNames('data-table-empty');\n\n const nameId = useId();\n const hasCaption = isShown(caption);\n const named = hasCaption || Boolean(ariaLabel || ariaLabelledby);\n useEffect(() => {\n if (!named) {\n warnOnce(\n 'DataTable:unnamed',\n '[bestax-bulma] <DataTable> has no accessible name. Pass a caption, ' +\n 'aria-label or aria-labelledby, so a screen reader can say which ' +\n 'table it is in.'\n );\n }\n }, [named]);\n const mixed = Boolean(given) && Boolean(columns || data);\n const bare = !given && (!columns || !data);\n useEffect(() => {\n if (mixed) {\n warnOnce(\n 'DataTable:table-and-columns',\n '[bestax-bulma] <DataTable> was given a `table` and `columns` or ' +\n '`data` too. It renders the `table` and leaves the rest unread, so ' +\n 'pass those to useDataTable instead.'\n );\n }\n if (bare) {\n warnOnce(\n 'DataTable:no-data',\n '[bestax-bulma] <DataTable> needs `columns` and `data`, or a `table` ' +\n 'from useDataTable.'\n );\n }\n }, [mixed, bare]);\n\n // The status region speaks only after the search, a filter or the page\n // changes, so nothing is read out as the page loads. `kind` is what last\n // changed, kept beside the values it changed from.\n const signature = filterSignature(state.search, state.filters);\n const [last, setLast] = useState({\n signature,\n page: state.page,\n kind: null as 'results' | 'page' | null,\n });\n if (last.signature !== signature) {\n setLast({ signature, page: state.page, kind: 'results' });\n } else if (last.page !== state.page) {\n setLast({ signature, page: state.page, kind: 'page' });\n }\n const { labels: words, rowCount: total, pageCount } = table;\n const size = state.pageSize;\n let message = '';\n if (last.kind && loading) {\n message = words.loading;\n } else if (last.kind === 'results' || (last.kind === 'page' && !total)) {\n message = words.results(total);\n } else if (last.kind === 'page') {\n // Without a page size, as when it's just been taken away, there's one\n // page, holding every row.\n const per = size ?? total;\n message = words.pageRange(\n (state.page - 1) * per + 1,\n Math.min(state.page * per, total),\n total\n );\n }\n // Written a moment after it changes, so typing in the search is read out\n // once it pauses rather than at every keystroke.\n const [said, setSaid] = useState('');\n useEffect(() => {\n const timer = setTimeout(() => setSaid(message), statusDelay);\n return () => clearTimeout(timer);\n }, [message]);\n\n const selectable = table.selectionMode === 'multiple';\n const sortable = table.columns.some(column => column.sortable);\n const columnCount = table.columns.length + (selectable ? 1 : 0);\n const pageRows = table.getRows('page');\n const selectAll = table.getSelectAllProps();\n\n const captionNode = hasCaption ? (\n <caption>\n <span id={nameId}>{caption}</span>\n {sortable && <span style={visuallyHidden}>{`, ${words.sortHint}.`}</span>}\n </caption>\n ) : sortable ? (\n <caption>\n <span style={visuallyHidden}>{words.sortHint}</span>\n </caption>\n ) : null;\n\n const header = (\n <Thead>\n <Tr>\n {selectable && (\n <Th scope=\"col\" isNarrow>\n <Checkbox\n {...selectAll}\n // While loading, the rows it would select aren't on screen.\n disabled={selectAll.disabled || Boolean(loading)}\n />\n </Th>\n )}\n {table.columns.map(column => (\n <Th key={column.id} {...table.getHeaderCellProps(column)}>\n {column.sortable ? (\n <button {...table.getSortButtonProps(column)}>\n {column.header}\n </button>\n ) : (\n column.header\n )}\n </Th>\n ))}\n </Tr>\n </Thead>\n );\n\n let body: React.ReactNode;\n if (loading) {\n body = Array.from({ length: size ?? 5 }, (_, index) => (\n <Tr key={index} aria-hidden=\"true\">\n {Array.from({ length: columnCount }, (__, cell) => (\n <Td key={cell}>\n <Skeleton variant=\"lines\" lines={1} />\n </Td>\n ))}\n </Tr>\n ));\n } else if (pageRows.length === 0) {\n // With `manual`, no rows under a search or a filter is no match: only\n // the server knows whether there's anything else.\n const nothing =\n table.getRows('all').length === 0 &&\n !(table.manual && isFiltering(state.search, state.filters));\n const content = nothing\n ? isShown(empty)\n ? empty\n : empty === undefined && (\n <EmptyState size=\"small\" description={words.empty} />\n )\n : isShown(noResults)\n ? noResults\n : noResults === undefined && (\n <EmptyState size=\"small\" description={words.noResults} />\n );\n body = (\n <Tr>\n <Td colSpan={columnCount} className={emptyClass}>\n {content}\n </Td>\n </Tr>\n );\n } else {\n body = pageRows.map(row => {\n const rowId = table.getRowId(row);\n return (\n <Tr key={rowId} {...rowProps?.(row)} {...table.getRowProps(row)}>\n {selectable && (\n <Td isNarrow>\n <Checkbox {...table.getSelectRowProps(row)} />\n </Td>\n )}\n {table.columns.map(column => {\n const text = table.getText(row, column.id);\n const content = column.cell\n ? column.cell(row, {\n value: table.getValue(row, column.id),\n text,\n rowId,\n })\n : text;\n const cellProps = table.getCellProps(row, column);\n return column.isRowHeader ? (\n <Th key={column.id} {...cellProps}>\n {content}\n </Th>\n ) : (\n <Td key={column.id} {...cellProps}>\n {content}\n </Td>\n );\n })}\n </Tr>\n );\n });\n }\n\n const tableElement = (\n <Table\n isBordered={isBordered}\n isStriped={isStriped}\n isNarrow={isNarrow}\n isHoverable={isHoverable}\n isFullwidth={isFullwidth}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n aria-busy={loading || undefined}\n >\n {captionNode}\n {header}\n <Tbody>{body}</Tbody>\n </Table>\n );\n\n // The name the scroll area and the pager take from the table.\n const textName =\n ariaLabel || (typeof caption === 'string' ? caption : undefined);\n const scrollName = ariaLabel\n ? { 'aria-label': ariaLabel }\n : {\n 'aria-labelledby': ariaLabelledby || (hasCaption ? nameId : undefined),\n };\n\n // Pagination names itself \"pagination\" unless given another name.\n const pagerLabel =\n words.pagination || (textName ? `${textName} pages` : undefined);\n const pagerName = pagerLabel ? { 'aria-label': pagerLabel } : {};\n\n const toolbarContent = toolbar?.(table);\n const hasToolbar = hasSearch || isShown(toolbarContent);\n\n return (\n <div ref={ref} className={rootClass} {...rest}>\n {hasToolbar && (\n <div className={toolbarClass}>\n {hasSearch && (\n <Input label={words.search} {...table.getSearchProps()} />\n )}\n {isShown(toolbarContent) && (\n <div className={actionsClass}>{toolbarContent}</div>\n )}\n </div>\n )}\n {isResponsive ? (\n <ScrollArea orientation=\"horizontal\" {...scrollName}>\n {tableElement}\n </ScrollArea>\n ) : (\n tableElement\n )}\n {/* In the page from the start, so a change to it is announced. */}\n <div role=\"status\" aria-live=\"polite\" style={visuallyHidden}>\n {said}\n </div>\n {pageCount > 1 && (\n <Pagination {...table.getPaginationProps()} {...pagerName} />\n )}\n </div>\n );\n}) as DataTableComponent;\n\nDataTable.displayName = 'DataTable';\n\nexport default DataTable;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
@@ -50,6 +50,20 @@ function isActiveFilter(value) {
|
|
|
50
50
|
value !== '' &&
|
|
51
51
|
!(Array.isArray(value) && value.length === 0));
|
|
52
52
|
}
|
|
53
|
+
/** A field a spreadsheet would read as the start of a formula. */
|
|
54
|
+
const formulaStart = /^[=+\-@\t\r]/;
|
|
55
|
+
/** A plain number, signed, with any grouping, which no spreadsheet runs. */
|
|
56
|
+
const plainNumber = /^[+-]?\d[\d.,]*$/;
|
|
57
|
+
/**
|
|
58
|
+
* One CSV field: a `'` in front of what would start a formula, then quoted
|
|
59
|
+
* when it holds the delimiter, a quote or a line break, its quotes doubled.
|
|
60
|
+
*/
|
|
61
|
+
function csvField(text, delimiter) {
|
|
62
|
+
const safe = formulaStart.test(text) && !plainNumber.test(text) ? `'${text}` : text;
|
|
63
|
+
return safe.includes(delimiter) || /["\r\n]/.test(safe)
|
|
64
|
+
? `"${safe.replace(/"/g, '""')}"`
|
|
65
|
+
: safe;
|
|
66
|
+
}
|
|
53
67
|
/**
|
|
54
68
|
* Whether a search or a filter value is narrowing the rows. Used by
|
|
55
69
|
* DataTable to tell an empty table from one with no matches.
|
|
@@ -413,6 +427,18 @@ function useDataTable(options) {
|
|
|
413
427
|
empty: labels?.empty || 'No rows to show.',
|
|
414
428
|
noResults: labels?.noResults || 'No rows match.',
|
|
415
429
|
};
|
|
430
|
+
const toCSV = useCallback(({ rows = 'filtered', columns: ids, header = true, delimiter = ',', } = {}) => {
|
|
431
|
+
const written = ids
|
|
432
|
+
? ids
|
|
433
|
+
.map(id => columnsById.get(id))
|
|
434
|
+
.filter((column) => column !== undefined)
|
|
435
|
+
: columns;
|
|
436
|
+
const line = (fields) => fields.map(field => csvField(field, delimiter)).join(delimiter);
|
|
437
|
+
const lines = getRows(rows).map(row => line(written.map(column => getText(row, column.id))));
|
|
438
|
+
if (header)
|
|
439
|
+
lines.unshift(line(written.map(column => column.header)));
|
|
440
|
+
return lines.join('\r\n');
|
|
441
|
+
}, [columnsById, columns, getRows, getText]);
|
|
416
442
|
const sortButtonClass = prefixedClassNames(prefix, 'data-table-sort');
|
|
417
443
|
return {
|
|
418
444
|
columns,
|
|
@@ -427,6 +453,7 @@ function useDataTable(options) {
|
|
|
427
453
|
getValue,
|
|
428
454
|
getText,
|
|
429
455
|
getRowLabel,
|
|
456
|
+
toCSV,
|
|
430
457
|
isSelected,
|
|
431
458
|
setSort,
|
|
432
459
|
toggleSort,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDataTable.js","sources":["../../../src/components/useDataTable.ts"],"sourcesContent":["import React, { useCallback, useMemo, useRef, useState } from 'react';\nimport { prefixedClassNames } from '../helpers/classNames';\nimport { useClassPrefix } from '../helpers/Config';\nimport { isDev, warnOnce } from '../helpers/devWarnings';\nimport { useLocale } from '../helpers/LocaleProvider';\nimport { useLocaleMatcher, useNumberFormat } from '../helpers/localeFormat';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { useLatestRef } from '../helpers/useLatestRef';\nimport type { TableAlignment } from '../elements/tableAlignment';\n\n/**\n * Carries a row type and adds nothing, so `DataTableColumnMeta` can take the\n * row type for the fields an add-on merges in while it has none of its own.\n */\ntype CarriesRow<TRow> = { [K in never]?: TRow };\n\n/**\n * Options of its own an add-on gives a column, read from the column's\n * `meta`. Empty in bestax: an add-on, such as a spreadsheet exporter, adds\n * its fields by declaration merging, and every column then takes them. Every\n * declaration of it names the row type the same way, `TRow`.\n *\n * @example\n * declare module '@allxsmith/bestax-bulma' {\n * interface DataTableColumnMeta<TRow> {\n * exportValue?: (row: TRow) => string | number;\n * }\n * }\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type -- empty so an add-on can merge into it\nexport interface DataTableColumnMeta<TRow = unknown> extends CarriesRow<TRow> {}\n\n/** What a column's `cell` is given beside the row. */\nexport interface DataTableCellContext {\n /** The column's raw value for the row, from its `accessor`. */\n value: unknown;\n /** The column's text for the row, from its `format`. */\n text: string;\n /** The row's id, from `getRowId`. */\n rowId: string;\n}\n\n/**\n * One column of a DataTable. A column keeps three things apart: its raw\n * value (`accessor`), which sorting and `filterFn` read; its text\n * (`format`), which the cell shows, the search matches and an export\n * writes; and its rich content (`cell`), which only the screen sees.\n */\nexport interface DataTableColumn<TRow> {\n /**\n * Names the column for good: the sort, the filters and an export refer to\n * it by this id. Unique within the table, and stable across renders.\n */\n id: string;\n /**\n * The column's name, as text: the header, the sort button's name, the\n * row checkboxes' names when it's the row header, and the header an\n * export writes.\n */\n header: string;\n /**\n * The raw value, for sorting and filtering: a key of the row, or a\n * function of it. Left out, it's the row's property named `id`.\n */\n accessor?: keyof TRow | ((row: TRow) => unknown);\n /**\n * The text for the value: what the cell shows when there's no `cell`, what\n * the search matches, and what an export writes. Left out, it's the value\n * as a string, and nothing for `null` or `undefined`. Give one for\n * numbers and dates you want written a certain way.\n */\n format?: (value: unknown, row: TRow) => string;\n /**\n * Rich content for the cell, such as a tag or a link. Only the screen\n * reads it: sorting, the search and an export use the value and its text.\n */\n cell?: (row: TRow, context: DataTableCellContext) => React.ReactNode;\n /**\n * Makes the header a button that sorts by this column: ascending, then\n * descending, then unsorted.\n */\n sortable?: boolean;\n /** Sorts descending on the first press, for a column read from the top, such as a score. */\n sortDescFirst?: boolean;\n /**\n * Compares two rows for an ascending sort, returning a negative number,\n * zero or a positive one. Descending reverses it. Without it, numbers,\n * dates and booleans compare by value, anything else by its text in the\n * `LocaleProvider`'s locale with numbers inside it read as numbers (\"Item\n * 9\" before \"Item 10\"), and an empty value goes last either way.\n */\n sortFn?: (a: TRow, b: TRow) => number;\n /**\n * Whether the column takes part in filtering: the search matches its\n * text, and `filters` can hold a value for it. `false` leaves it out of\n * both, as for a column of actions.\n */\n filterable?: boolean;\n /**\n * Decides whether a row passes this column's value in `filters`. Without\n * it, the column's text has to contain the value's text, compared as the\n * search compares.\n */\n filterFn?: (row: TRow, filterValue: unknown) => boolean;\n /** Aligns the header and the cells (`isAligned` on `Th` and `Td`). */\n align?: TableAlignment;\n /** The column's width, on its header cell: a number is pixels, a string any CSS length. */\n width?: string | number;\n /**\n * Renders this column's cells as row headers (`th scope=\"row\"`), which a\n * screen reader reads out with the other cells of the row. The row's\n * checkbox is named from it. Mark one column, usually the first.\n */\n isRowHeader?: boolean;\n /** Options of an add-on's own, as `DataTableColumnMeta` declares them. */\n meta?: DataTableColumnMeta<TRow>;\n}\n\n/** The direction of a sort, in `aria-sort`'s words. */\nexport type DataTableSortDirection = 'ascending' | 'descending';\n\n/** One column a DataTable sorts by. */\nexport interface DataTableSort {\n /** The column's `id`. */\n id: string;\n /** Which way it sorts. */\n direction: DataTableSortDirection;\n}\n\n/** The values per column `filters` holds, keyed by column `id`. */\nexport type DataTableFilters = Record<string, unknown>;\n\n/**\n * Which of a table's rows to read: `all` of `data`, `filtered` (the ones the\n * search and the filters let through, from every page), the `page` shown,\n * or the `selected` ones the filters let through. Each comes in the order\n * the table shows them.\n */\nexport type DataTableRowScope = 'all' | 'filtered' | 'page' | 'selected';\n\n/** Whether a DataTable has row checkboxes. */\nexport type DataTableSelectionMode = 'none' | 'multiple';\n\n/**\n * The words a DataTable writes. Each is English unless you give your own,\n * and the numbers in the default messages are written in the\n * `LocaleProvider`'s locale.\n */\nexport interface DataTableLabels {\n /**\n * The header checkbox's name. \"Select all rows\", or \"Select all rows on\n * this page\" when there's more than one page, since it then covers the\n * page shown.\n */\n selectAll?: string;\n /** A row checkbox's name, from the row's label (`label => 'Select ' + label`). */\n selectRow?: (rowLabel: string) => string;\n /**\n * Says that headers with buttons sort: hidden at the end of the caption,\n * after a comma, or as a hidden caption of its own. \"column headers with\n * buttons are sortable\".\n */\n sortHint?: string;\n /** The search field's label. \"Search\". */\n search?: string;\n /** Announced after the search or a filter changes (\"12 rows match\"). */\n results?: (count: number) => string;\n /** Announced after the page changes (\"Showing 11 to 20 of 57\"). */\n pageRange?: (first: number, last: number, total: number) => string;\n /** Announced while `loading`, once the search, a filter or the page has changed. \"Loading\". */\n loading?: string;\n /**\n * The pager's name. \"{the table's name} pages\" when the table is named by\n * `aria-label` or a text `caption`, so two tables' pagers have different\n * names, else `Pagination`'s own.\n */\n pagination?: string;\n /** What the table shows with no rows at all. \"No rows to show.\" */\n empty?: string;\n /** What the table shows when the search and filters let no row through. \"No rows match.\" */\n noResults?: string;\n}\n\n/** The words a DataTable writes, with every default filled in. */\nexport interface DataTableResolvedLabels extends Required<\n Omit<DataTableLabels, 'pagination'>\n> {\n /** The pager's name, when one was given. */\n pagination?: string;\n}\n\n/**\n * The options `useDataTable` and `DataTable` share, beside the columns and\n * the data. Each piece of state is yours when you pass its value (and its\n * `on…Change`), or the table's own, starting from its `default…`.\n */\nexport interface DataTableStateOptions<TRow> {\n /**\n * A row's id, unique and stable, which the selection is a list of. Left\n * out, it's the row's `id` property as a string. A development build\n * warns about a missing or repeated id, and a row with none falls back to\n * its index, which doesn't survive the data changing.\n */\n getRowId?: (row: TRow, index: number) => string;\n /**\n * The sort when you hold it: an array of `{ id, direction }`, the first\n * deciding and each next one breaking ties. The headers set one at a time.\n */\n sort?: DataTableSort[];\n /**\n * The sort to start with when the table holds it. Text sorts in the\n * `LocaleProvider`'s locale, or the runtime's own outside one, which can\n * differ between a server and the browser, so put a table rendered on the\n * server sorted inside a `LocaleProvider`.\n */\n defaultSort?: DataTableSort[];\n /** Called with the new sort when a header is pressed. */\n onSortChange?: (sort: DataTableSort[]) => void;\n /**\n * `multiple` adds a checkbox to each row and a \"select all\" checkbox to the header.\n *\n * @defaultValue 'none'\n */\n selectionMode?: DataTableSelectionMode;\n /**\n * The selected rows' ids when you hold them. They stay selected while the\n * search, a filter or the page hides them.\n */\n selected?: string[];\n /** The rows selected to begin with, by id, when the table holds them. */\n defaultSelected?: string[];\n /** Called with every selected id after a checkbox changes. */\n onSelectedChange?: (selected: string[]) => void;\n /** Rows per page. Set, the table pages through `Pagination`; left out, it shows every row. */\n pageSize?: number;\n /**\n * The page shown when you hold it, counting from 1. A page past the end\n * shows the last.\n */\n page?: number;\n /**\n * The page to start on when the table holds it.\n *\n * @defaultValue 1\n */\n defaultPage?: number;\n /**\n * Called with the page chosen in the pager, and with 1 when the search or\n * a filter changes through the table while the page held isn't 1, even\n * when a page past the end shows as the last.\n */\n onPageChange?: (page: number) => void;\n /**\n * The search when you hold it, matched against every filterable column's\n * text: in the `LocaleProvider`'s locale, ignoring case and the accents\n * the language ignores, or a case-insensitive substring outside one.\n */\n search?: string;\n /** The search to start with when the table holds it. */\n defaultSearch?: string;\n /** Called with the search as it changes through the table. */\n onSearchChange?: (search: string) => void;\n /**\n * A value per column, by `id`, when you hold them. A row passes when every\n * column with a value passes it: the column's `filterFn` if it has one,\n * given the value as it is, or else the column's text has to contain the\n * value's text, compared as the search compares. An array is a choice of\n * values, as a multiple-choice filter gives, and passes a row whose text\n * contains any of them. A value of `undefined`, `null`, `''` or an empty\n * array is no filter.\n */\n filters?: DataTableFilters;\n /** The filters to start with when the table holds them. */\n defaultFilters?: DataTableFilters;\n /** Called with every filter value after one changes through the table. */\n onFiltersChange?: (filters: DataTableFilters) => void;\n /**\n * Hands sorting, filtering and paging to a server: the table shows `data`\n * as given, as the current page, and only reports the state as it\n * changes.\n */\n manual?: boolean;\n /**\n * With `manual`, how many rows match in all, which sets the page count and\n * the announced count. Without it, the table counts the rows in `data`,\n * which with a `pageSize` is one page and no pager, and a development\n * build warns.\n */\n rowCount?: number;\n /** The words the table writes, in your app's language. */\n labels?: DataTableLabels;\n}\n\n/** What `useDataTable` takes. */\nexport interface UseDataTableOptions<TRow> extends DataTableStateOptions<TRow> {\n /**\n * The columns, in the order they're shown. Keep the array the same from\n * one render to the next, defined outside the component or in `useMemo`:\n * a new one has every cell's text worked out again.\n */\n columns: DataTableColumn<TRow>[];\n /** The rows, as records of your own. */\n data: TRow[];\n}\n\n/** The table's state, as it stands. */\nexport interface DataTableState {\n /** The sort, the first entry deciding. */\n sort: DataTableSort[];\n /** The selected rows' ids. */\n selected: string[];\n /** The page shown, counting from 1. */\n page: number;\n /** Rows per page, or `undefined` when it doesn't page. */\n pageSize: number | undefined;\n /** The search. */\n search: string;\n /** The filter values, by column id. */\n filters: DataTableFilters;\n}\n\n/** The props `getSortButtonProps` gives a header's `<button>`. */\nexport interface DataTableSortButtonProps {\n type: 'button';\n className: string;\n onClick: () => void;\n}\n\n/** The props `getSearchProps` gives a search `<input>` or bestax `Input`. */\nexport interface DataTableSearchProps {\n type: 'search';\n value: string;\n onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\n/** The props `getHeaderCellProps` gives a column's `Th`. */\nexport interface DataTableHeaderCellProps {\n scope: 'col';\n 'aria-sort'?: DataTableSortDirection;\n isAligned?: TableAlignment;\n width?: string | number;\n}\n\n/** The props `getCellProps` gives a row's `Td`, or its `Th` for the row header. */\nexport interface DataTableCellProps {\n scope?: 'row';\n isAligned?: TableAlignment;\n}\n\n/** The props `getSelectAllProps` and `getSelectRowProps` give a `Checkbox`. */\nexport interface DataTableCheckboxProps {\n 'aria-label': string;\n checked: boolean;\n indeterminate?: boolean;\n disabled?: boolean;\n onChange: () => void;\n}\n\n/** The props `getPaginationProps` gives `Pagination`. */\nexport interface DataTablePaginationProps {\n total: number;\n current: number;\n onPageChange: (page: number) => void;\n}\n\n/**\n * A table: what `useDataTable` returns, what `DataTable`'s `toolbar` is\n * given, and what its `table` takes. It reads the rows and the state, changes\n * the state, and hands out props for bestax's own `Th`, `Tr`, `Td`,\n * `Checkbox` and `Pagination`, so markup of your own behaves as DataTable's\n * does.\n */\nexport interface DataTableModel<TRow> {\n /** The columns, in the order they're shown. */\n columns: DataTableColumn<TRow>[];\n /** The state as it stands. */\n state: DataTableState;\n /** Whether rows have checkboxes. */\n selectionMode: DataTableSelectionMode;\n /** Whether a server sorts, filters and pages (`manual`). */\n manual: boolean;\n /** How many rows the search and filters let through, or `rowCount` with `manual`. */\n rowCount: number;\n /** How many pages there are, at least 1. */\n pageCount: number;\n /** The words the table writes, with the defaults filled in. */\n labels: DataTableResolvedLabels;\n /** The rows in `scope` (`filtered` by default), in the order the table shows them. */\n getRows: (scope?: DataTableRowScope) => TRow[];\n /** A row's id. */\n getRowId: (row: TRow) => string;\n /** A column's raw value for a row, or `undefined` for a column it doesn't have. */\n getValue: (row: TRow, columnId: string) => unknown;\n /** A column's text for a row, or `''` for a column it doesn't have. */\n getText: (row: TRow, columnId: string) => string;\n /** What names a row: its row header's text, or its first column's. */\n getRowLabel: (row: TRow) => string;\n /** Whether a row is selected. */\n isSelected: (row: TRow) => boolean;\n /** Sets the sort. */\n setSort: (sort: DataTableSort[]) => void;\n /** Moves a column through its sort, as its header button does. */\n toggleSort: (columnId: string) => void;\n /** Sets the selected ids. */\n setSelected: (selected: string[]) => void;\n /**\n * Selects a row, or clears it, or with no `selected` flips it. Called\n * twice in one handler, the second call builds on the first while the\n * table holds the selection. While you hold it, each call builds on the\n * selection as rendered, so make several changes at once with\n * `setSelected`.\n */\n toggleRowSelected: (row: TRow, selected?: boolean) => void;\n /**\n * Selects every row on the page, or clears them, or with no `selected`\n * does what the header checkbox does. It builds on earlier calls as\n * `toggleRowSelected` does.\n */\n togglePageSelected: (selected?: boolean) => void;\n /** Goes to a page, counting from 1. */\n setPage: (page: number) => void;\n /**\n * Sets the search, and goes back to page 1, calling `onPageChange` with 1\n * unless the page held is 1 already.\n */\n setSearch: (search: string) => void;\n /**\n * Sets one column's filter value, and goes back to page 1. Called twice in\n * one handler, the second call builds on the first while the table holds\n * the filters. While you hold them, each call builds on the filters as\n * rendered, so set several at once with `setFilters`.\n */\n setFilter: (columnId: string, value: unknown) => void;\n /** Sets every filter value, and goes back to page 1, as `setSearch` does. */\n setFilters: (filters: DataTableFilters) => void;\n /** Props for a column's `Th`: its scope, its `aria-sort` while sorted, its alignment and width. */\n getHeaderCellProps: (\n column: DataTableColumn<TRow>\n ) => DataTableHeaderCellProps;\n /** Props for the `<button>` in a sortable column's header. */\n getSortButtonProps: (\n column: DataTableColumn<TRow>\n ) => DataTableSortButtonProps;\n /** Props for a row's `Tr`: Bulma's selected look while it's selected. */\n getRowProps: (row: TRow) => { isSelected: boolean };\n /** Props for a row's cell in a column: its alignment, and `scope=\"row\"` for the row header. */\n getCellProps: (\n row: TRow,\n column: DataTableColumn<TRow>\n ) => DataTableCellProps;\n /** Props for the header's \"select all\" `Checkbox`, which covers the page shown. */\n getSelectAllProps: () => DataTableCheckboxProps;\n /** Props for a row's `Checkbox`, named for the row. */\n getSelectRowProps: (row: TRow) => DataTableCheckboxProps;\n /** Props for `Pagination`: the page count, the page and the handler. */\n getPaginationProps: () => DataTablePaginationProps;\n /** Props for a search field, bound to the search. */\n getSearchProps: () => DataTableSearchProps;\n}\n\n/** A column's raw value for a row. */\nfunction readValue<TRow>(column: DataTableColumn<TRow>, row: TRow): unknown {\n const { accessor } = column;\n if (typeof accessor === 'function') return accessor(row);\n if (row === null || typeof row !== 'object') return undefined;\n return (row as Record<PropertyKey, unknown>)[\n (accessor ?? column.id) as PropertyKey\n ];\n}\n\n/** A column's text for a row. */\nfunction readText<TRow>(column: DataTableColumn<TRow>, row: TRow): string {\n const value = readValue(column, row);\n if (column.format) return column.format(value, row);\n return value === null || value === undefined ? '' : String(value);\n}\n\n/** Whether a value sorts as empty: nothing, no text, or no number or date. */\nfunction isEmptyValue(value: unknown): boolean {\n return (\n value === null ||\n value === undefined ||\n value === '' ||\n (typeof value === 'number' && Number.isNaN(value)) ||\n (value instanceof Date && Number.isNaN(value.getTime()))\n );\n}\n\n/** Compares two values that aren't empty, for an ascending sort. */\nfunction compareValues(a: unknown, b: unknown, collator: Intl.Collator) {\n if (typeof a === 'number' && typeof b === 'number') return a - b;\n if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();\n if (typeof a === 'boolean' && typeof b === 'boolean') {\n return Number(a) - Number(b);\n }\n return collator.compare(String(a), String(b));\n}\n\n/** Whether a filter value filters anything. */\nfunction isActiveFilter(value: unknown): boolean {\n return (\n value !== undefined &&\n value !== null &&\n value !== '' &&\n !(Array.isArray(value) && value.length === 0)\n );\n}\n\n/**\n * Whether a search or a filter value is narrowing the rows. Used by\n * DataTable to tell an empty table from one with no matches.\n */\nexport function isFiltering(search: string, filters: DataTableFilters) {\n return search.trim() !== '' || Object.values(filters).some(isActiveFilter);\n}\n\n/** A row's id from its `id` property, or nothing when it has none. */\nfunction idOf(row: unknown): string | undefined {\n if (row === null || typeof row !== 'object') return undefined;\n const id = (row as { id?: unknown }).id;\n return id === undefined || id === null || id === '' ? undefined : String(id);\n}\n\n/**\n * A piece of state that's the caller's when they pass its value, and the\n * table's own otherwise. Setting it calls the change handler either way.\n *\n * It also returns `latest`, what a change should build on. While the table\n * holds the state, that's the value last set, even before React renders it,\n * so two changes in one handler build on each other. While the caller holds\n * it, it's the value as rendered, since only the caller knows what it made\n * of a change.\n */\nfunction useTableState<T>(\n value: T | undefined,\n initial: T,\n onChange: ((next: T) => void) | undefined\n): [T, (next: T) => void, () => T] {\n const [own, setOwn] = useState(initial);\n const held = value !== undefined;\n const current = held ? value : own;\n const rendered = useLatestRef(current);\n // A value set since the last commit, cleared once a commit shows it.\n const pendingRef = useRef<{ value: T } | null>(null);\n useClientLayoutEffect(() => {\n pendingRef.current = null;\n });\n const set = useCallback(\n (next: T) => {\n if (!held) {\n pendingRef.current = { value: next };\n setOwn(next);\n }\n onChange?.(next);\n },\n [held, onChange]\n );\n const latest = useCallback(\n () => (pendingRef.current ? pendingRef.current.value : rendered.current),\n [rendered]\n );\n return [current, set, latest];\n}\n\nconst noSort: DataTableSort[] = [];\nconst noIds: string[] = [];\nconst noFilters: DataTableFilters = {};\n\n/**\n * `useDataTable` holds a table's sort, selection, page, search and filters,\n * works out its rows, and hands out props for bestax's own table parts, so\n * custom markup behaves as `DataTable` does. Pass its result to\n * `<DataTable table={table} />` to render it with DataTable's own markup,\n * with a toolbar or an export button elsewhere on the page.\n *\n * @example\n * const table = useDataTable({ columns, data: users, pageSize: 10 });\n *\n * <DataTable table={table} caption=\"Users\" hasSearch />\n */\nexport function useDataTable<TRow>(\n options: UseDataTableOptions<TRow>\n): DataTableModel<TRow> {\n const {\n columns,\n data,\n getRowId: rowIdOf,\n sort: sortProp,\n defaultSort = noSort,\n onSortChange,\n selectionMode = 'none',\n selected: selectedProp,\n defaultSelected = noIds,\n onSelectedChange,\n pageSize: pageSizeProp,\n page: pageProp,\n defaultPage = 1,\n onPageChange,\n search: searchProp,\n defaultSearch = '',\n onSearchChange,\n filters: filtersProp,\n defaultFilters = noFilters,\n onFiltersChange,\n manual = false,\n rowCount: rowCountProp,\n labels,\n } = options;\n\n const [sort, setSort] = useTableState(sortProp, defaultSort, onSortChange);\n const [selected, setSelected, latestSelected] = useTableState(\n selectedProp,\n defaultSelected,\n onSelectedChange\n );\n const [pageState, setPageState, latestPage] = useTableState(\n pageProp,\n defaultPage,\n onPageChange\n );\n const [search, setSearchState] = useTableState(\n searchProp,\n defaultSearch,\n onSearchChange\n );\n const [filters, setFiltersState, latestFilters] = useTableState(\n filtersProp,\n defaultFilters,\n onFiltersChange\n );\n\n const prefix = useClassPrefix();\n const { locale } = useLocale();\n const matchText = useLocaleMatcher();\n const formatNumber = useNumberFormat();\n const collator = useMemo(\n () => new Intl.Collator(locale, { numeric: true }),\n [locale]\n );\n\n const pageSize =\n pageSizeProp !== undefined &&\n Number.isFinite(pageSizeProp) &&\n pageSizeProp >= 1\n ? Math.floor(pageSizeProp)\n : undefined;\n\n const columnsById = useMemo(() => {\n const byId = new Map<string, DataTableColumn<TRow>>();\n for (const column of columns) {\n if (byId.has(column.id)) {\n warnOnce(\n 'DataTable:duplicate-column',\n `[bestax-bulma] DataTable has two columns with the id \"${column.id}\". ` +\n 'Give each column its own id: the sort, the filters and an export ' +\n 'find a column by it.'\n );\n } else {\n byId.set(column.id, column);\n }\n }\n return byId;\n }, [columns]);\n\n // Each row's id, by its index in `data`.\n const ids = useMemo(() => {\n const out = data.map((row, index) => {\n const id = rowIdOf ? rowIdOf(row, index) : idOf(row);\n if (id === undefined || id === '') {\n warnOnce(\n 'DataTable:missing-row-id',\n '[bestax-bulma] A DataTable row has no id, so it falls back to its ' +\n \"index, which doesn't survive the data changing. Give each row \" +\n 'an `id`, or pass `getRowId`.'\n );\n return String(index);\n }\n return id;\n });\n if (isDev() && new Set(out).size < out.length) {\n warnOnce(\n 'DataTable:duplicate-row-id',\n '[bestax-bulma] Two DataTable rows have the same id, so selecting ' +\n 'one selects both. Make the ids unique, or pass a `getRowId` ' +\n 'that does.'\n );\n }\n return out;\n }, [data, rowIdOf]);\n\n const indexOf = useMemo(() => {\n const map = new Map<TRow, number>();\n data.forEach((row, index) => {\n if (!map.has(row)) map.set(row, index);\n });\n return map;\n }, [data]);\n\n /** A row's id, from its index when the row is one of `data`. */\n const getRowId = useCallback(\n (row: TRow) => {\n const index = indexOf.get(row);\n if (index !== undefined) return ids[index];\n const id = rowIdOf ? rowIdOf(row, -1) : idOf(row);\n return id ?? '';\n },\n [indexOf, ids, rowIdOf]\n );\n\n // Every column's text for every row, worked out once per data and\n // columns, since the search reads them on every keystroke.\n const texts = useMemo(\n () => data.map(row => columns.map(column => readText(column, row))),\n [data, columns]\n );\n\n const sortedIndexes = useMemo(() => {\n const all = data.map((_, index) => index);\n if (manual) return all;\n const keys = sort\n .map(entry => ({\n column: columnsById.get(entry.id),\n descending: entry.direction === 'descending',\n }))\n .filter(\n (key): key is { column: DataTableColumn<TRow>; descending: boolean } =>\n key.column !== undefined\n );\n if (keys.length === 0) return all;\n const values = keys.map(({ column }) =>\n column.sortFn ? null : data.map(row => readValue(column, row))\n );\n return all.sort((x, y) => {\n for (let k = 0; k < keys.length; k++) {\n const { column, descending } = keys[k];\n let result: number;\n if (column.sortFn) {\n result = column.sortFn(data[x], data[y]);\n if (descending) result = -result;\n } else {\n const a = values[k]![x];\n const b = values[k]![y];\n const aEmpty = isEmptyValue(a);\n const bEmpty = isEmptyValue(b);\n if (aEmpty || bEmpty) {\n // Empty values go last whichever way the column sorts.\n result = Number(aEmpty) - Number(bEmpty);\n } else {\n result = compareValues(a, b, collator);\n if (descending) result = -result;\n }\n }\n if (result) return result;\n }\n // Ties keep the order of `data`.\n return x - y;\n });\n }, [data, sort, columnsById, collator, manual]);\n\n const filteredIndexes = useMemo(() => {\n if (manual) return sortedIndexes;\n const query = search.trim();\n const holds = matchText\n ? (text: string, needle: string) => matchText(text, needle)\n : (text: string, needle: string) =>\n text.toLowerCase().includes(needle.toLowerCase());\n const searched = columns\n .map((column, index) => ({ column, index }))\n .filter(({ column }) => column.filterable !== false);\n const filtered = Object.entries(filters)\n .filter(([, value]) => isActiveFilter(value))\n .map(([id, value]) => ({\n column: columnsById.get(id),\n index: columns.findIndex(column => column.id === id),\n value,\n }))\n .filter(\n ({ column }) => column !== undefined && column.filterable !== false\n );\n if (query === '' && filtered.length === 0) return sortedIndexes;\n return sortedIndexes.filter(rowIndex => {\n const row = data[rowIndex];\n const rowTexts = texts[rowIndex];\n for (const { column, index, value } of filtered) {\n // An array is any of its entries, as a multiple-choice filter gives.\n const passes = column!.filterFn\n ? column!.filterFn(row, value)\n : Array.isArray(value)\n ? value.some(entry => holds(rowTexts[index], String(entry)))\n : holds(rowTexts[index], String(value));\n if (!passes) return false;\n }\n return (\n query === '' ||\n searched.some(({ index }) => holds(rowTexts[index], query))\n );\n });\n }, [\n manual,\n sortedIndexes,\n search,\n filters,\n matchText,\n columns,\n columnsById,\n data,\n texts,\n ]);\n\n const knowsCount =\n rowCountProp !== undefined && Number.isFinite(rowCountProp);\n if (manual && pageSize !== undefined && !knowsCount) {\n warnOnce(\n 'DataTable:manual-row-count',\n '[bestax-bulma] A DataTable with `manual` and a `pageSize` has no ' +\n '`rowCount`, so it counts only the rows in `data`, makes one page ' +\n 'of them and shows no pager. Pass `rowCount`, how many rows match ' +\n 'on the server.'\n );\n }\n const rowCount = manual\n ? Math.max(\n Math.floor(knowsCount ? (rowCountProp as number) : data.length),\n 0\n )\n : filteredIndexes.length;\n const pageCount = pageSize ? Math.max(Math.ceil(rowCount / pageSize), 1) : 1;\n const page = Math.min(\n Math.max(Number.isFinite(pageState) ? Math.floor(pageState) : 1, 1),\n pageCount\n );\n\n const pageIndexes = useMemo(() => {\n if (manual || !pageSize) return filteredIndexes;\n return filteredIndexes.slice((page - 1) * pageSize, page * pageSize);\n }, [manual, pageSize, filteredIndexes, page]);\n\n const selectedSet = useMemo(() => new Set(selected), [selected]);\n const selectable = selectionMode === 'multiple';\n\n const rowsOf = useCallback(\n (indexes: number[]) => indexes.map(index => data[index]),\n [data]\n );\n\n const getRows = useCallback(\n (scope: DataTableRowScope = 'filtered') => {\n switch (scope) {\n case 'all':\n return rowsOf(sortedIndexes);\n case 'page':\n return rowsOf(pageIndexes);\n case 'selected':\n return rowsOf(\n filteredIndexes.filter(index => selectedSet.has(ids[index]))\n );\n default:\n return rowsOf(filteredIndexes);\n }\n },\n [rowsOf, sortedIndexes, pageIndexes, filteredIndexes, selectedSet, ids]\n );\n\n const getValue = useCallback(\n (row: TRow, columnId: string) => {\n const column = columnsById.get(columnId);\n return column ? readValue(column, row) : undefined;\n },\n [columnsById]\n );\n\n const getText = useCallback(\n (row: TRow, columnId: string) => {\n const column = columnsById.get(columnId);\n if (!column) return '';\n const index = indexOf.get(row);\n return index !== undefined\n ? texts[index][columns.indexOf(column)]\n : readText(column, row);\n },\n [columnsById, indexOf, columns, texts]\n );\n\n const labelColumn = columns.find(column => column.isRowHeader) ?? columns[0];\n const getRowLabel = useCallback(\n (row: TRow) =>\n (labelColumn && getText(row, labelColumn.id)) || getRowId(row),\n [labelColumn, getText, getRowId]\n );\n\n const isSelected = useCallback(\n (row: TRow) => selectable && selectedSet.has(getRowId(row)),\n [selectable, selectedSet, getRowId]\n );\n\n const setPage = useCallback(\n (next: number) => {\n if (next !== page) setPageState(next);\n },\n [page, setPageState]\n );\n\n // A new search or filter starts from the first page. It's measured against\n // the page as stored, not as shown: a page past the end shows the last,\n // and left stored it would come back once the rows grew again.\n const resetPage = useCallback(() => {\n if (latestPage() !== 1) setPageState(1);\n }, [latestPage, setPageState]);\n\n const setSearch = useCallback(\n (next: string) => {\n setSearchState(next);\n resetPage();\n },\n [setSearchState, resetPage]\n );\n\n const setFilters = useCallback(\n (next: DataTableFilters) => {\n setFiltersState(next);\n resetPage();\n },\n [setFiltersState, resetPage]\n );\n\n const setFilter = useCallback(\n (columnId: string, value: unknown) => {\n const next = { ...latestFilters() };\n if (isActiveFilter(value)) next[columnId] = value;\n else delete next[columnId];\n setFilters(next);\n },\n [latestFilters, setFilters]\n );\n\n const toggleSort = useCallback(\n (columnId: string) => {\n const column = columnsById.get(columnId);\n if (!column) return;\n const first: DataTableSortDirection = column.sortDescFirst\n ? 'descending'\n : 'ascending';\n const current = sort[0]?.id === columnId ? sort[0].direction : undefined;\n if (current === undefined) {\n setSort([{ id: columnId, direction: first }]);\n } else if (current === first) {\n setSort([\n {\n id: columnId,\n direction: first === 'ascending' ? 'descending' : 'ascending',\n },\n ]);\n } else {\n setSort([]);\n }\n },\n [columnsById, sort, setSort]\n );\n\n const toggleRowSelected = useCallback(\n (row: TRow, value?: boolean) => {\n const id = getRowId(row);\n const current = latestSelected();\n const has = current.includes(id);\n const on = value ?? !has;\n if (on === has) return;\n setSelected(on ? [...current, id] : current.filter(s => s !== id));\n },\n [getRowId, latestSelected, setSelected]\n );\n\n const pageIds = useMemo(\n () => pageIndexes.map(index => ids[index]),\n [pageIndexes, ids]\n );\n const pageSelectedCount = pageIds.filter(id => selectedSet.has(id)).length;\n const allPageSelected =\n pageIds.length > 0 && pageSelectedCount === pageIds.length;\n\n const togglePageSelected = useCallback(\n (value?: boolean) => {\n const current = latestSelected();\n const has = new Set(current);\n const on =\n value ?? !(pageIds.length > 0 && pageIds.every(id => has.has(id)));\n if (on) {\n const adding = pageIds.filter(id => !has.has(id));\n if (adding.length > 0) setSelected([...current, ...adding]);\n } else {\n const onPage = new Set(pageIds);\n const kept = current.filter(id => !onPage.has(id));\n if (kept.length !== current.length) setSelected(kept);\n }\n },\n [latestSelected, pageIds, setSelected]\n );\n\n const count = useCallback(\n (value: number) => (formatNumber ? formatNumber(value) : String(value)),\n [formatNumber]\n );\n\n const resolvedLabels: DataTableResolvedLabels = {\n selectAll:\n labels?.selectAll ||\n (pageCount > 1 ? 'Select all rows on this page' : 'Select all rows'),\n selectRow: labels?.selectRow ?? (label => `Select ${label}`),\n sortHint: labels?.sortHint || 'column headers with buttons are sortable',\n search: labels?.search || 'Search',\n results:\n labels?.results ??\n (total =>\n total === 0\n ? 'No rows match'\n : `${count(total)} ${total === 1 ? 'row matches' : 'rows match'}`),\n pageRange:\n labels?.pageRange ??\n ((first, last, total) =>\n `Showing ${count(first)} to ${count(last)} of ${count(total)}`),\n loading: labels?.loading || 'Loading',\n pagination: labels?.pagination || undefined,\n empty: labels?.empty || 'No rows to show.',\n noResults: labels?.noResults || 'No rows match.',\n };\n\n const sortButtonClass = prefixedClassNames(prefix, 'data-table-sort');\n\n return {\n columns,\n state: { sort, selected, page, pageSize, search, filters },\n selectionMode,\n manual,\n rowCount,\n pageCount,\n labels: resolvedLabels,\n getRows,\n getRowId,\n getValue,\n getText,\n getRowLabel,\n isSelected,\n setSort,\n toggleSort,\n setSelected,\n toggleRowSelected,\n togglePageSelected,\n setPage,\n setSearch,\n setFilter,\n setFilters,\n getHeaderCellProps: column => ({\n scope: 'col',\n 'aria-sort': sort[0]?.id === column.id ? sort[0].direction : undefined,\n isAligned: column.align,\n width: column.width,\n }),\n getSortButtonProps: column => ({\n type: 'button',\n className: sortButtonClass,\n onClick: () => toggleSort(column.id),\n }),\n getRowProps: row => ({ isSelected: isSelected(row) }),\n getCellProps: (_row, column) => ({\n scope: column.isRowHeader ? 'row' : undefined,\n isAligned: column.align,\n }),\n getSelectAllProps: () => ({\n 'aria-label': resolvedLabels.selectAll,\n checked: allPageSelected,\n indeterminate: pageSelectedCount > 0 && !allPageSelected,\n disabled: pageIds.length === 0,\n onChange: () => togglePageSelected(),\n }),\n getSelectRowProps: row => ({\n 'aria-label': resolvedLabels.selectRow(getRowLabel(row)),\n checked: selectedSet.has(getRowId(row)),\n onChange: () => toggleRowSelected(row),\n }),\n getPaginationProps: () => ({\n total: pageCount,\n current: page,\n onPageChange: setPage,\n }),\n getSearchProps: () => ({\n type: 'search',\n value: search,\n onChange: event => setSearch(event.target.value),\n }),\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useDataTable.js","sources":["../../../src/components/useDataTable.ts"],"sourcesContent":["import React, { useCallback, useMemo, useRef, useState } from 'react';\nimport { prefixedClassNames } from '../helpers/classNames';\nimport { useClassPrefix } from '../helpers/Config';\nimport { isDev, warnOnce } from '../helpers/devWarnings';\nimport { useLocale } from '../helpers/LocaleProvider';\nimport { useLocaleMatcher, useNumberFormat } from '../helpers/localeFormat';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { useLatestRef } from '../helpers/useLatestRef';\nimport type { TableAlignment } from '../elements/tableAlignment';\n\n/**\n * Carries a row type and adds nothing, so `DataTableColumnMeta` can take the\n * row type for the fields an add-on merges in while it has none of its own.\n */\ntype CarriesRow<TRow> = { [K in never]?: TRow };\n\n/**\n * Options of its own an add-on gives a column, read from the column's\n * `meta`. Empty in bestax: an add-on, such as a spreadsheet exporter, adds\n * its fields by declaration merging, and every column then takes them. Every\n * declaration of it names the row type the same way, `TRow`.\n *\n * @example\n * declare module '@allxsmith/bestax-bulma' {\n * interface DataTableColumnMeta<TRow> {\n * exportValue?: (row: TRow) => string | number;\n * }\n * }\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type -- empty so an add-on can merge into it\nexport interface DataTableColumnMeta<TRow = unknown> extends CarriesRow<TRow> {}\n\n/** What a column's `cell` is given beside the row. */\nexport interface DataTableCellContext {\n /** The column's raw value for the row, from its `accessor`. */\n value: unknown;\n /** The column's text for the row, from its `format`. */\n text: string;\n /** The row's id, from `getRowId`. */\n rowId: string;\n}\n\n/**\n * One column of a DataTable. A column keeps three things apart: its raw\n * value (`accessor`), which sorting and `filterFn` read; its text\n * (`format`), which the cell shows, the search matches and an export\n * writes; and its rich content (`cell`), which only the screen sees.\n */\nexport interface DataTableColumn<TRow> {\n /**\n * Names the column for good: the sort, the filters and an export refer to\n * it by this id. Unique within the table, and stable across renders.\n */\n id: string;\n /**\n * The column's name, as text: the header, the sort button's name, the\n * row checkboxes' names when it's the row header, and the header an\n * export writes.\n */\n header: string;\n /**\n * The raw value, for sorting and filtering: a key of the row, or a\n * function of it. Left out, it's the row's property named `id`.\n */\n accessor?: keyof TRow | ((row: TRow) => unknown);\n /**\n * The text for the value: what the cell shows when there's no `cell`, what\n * the search matches, and what an export writes. Left out, it's the value\n * as a string, and nothing for `null` or `undefined`. Give one for\n * numbers and dates you want written a certain way.\n */\n format?: (value: unknown, row: TRow) => string;\n /**\n * Rich content for the cell, such as a tag or a link. Only the screen\n * reads it: sorting, the search and an export use the value and its text.\n */\n cell?: (row: TRow, context: DataTableCellContext) => React.ReactNode;\n /**\n * Makes the header a button that sorts by this column: ascending, then\n * descending, then unsorted.\n */\n sortable?: boolean;\n /** Sorts descending on the first press, for a column read from the top, such as a score. */\n sortDescFirst?: boolean;\n /**\n * Compares two rows for an ascending sort, returning a negative number,\n * zero or a positive one. Descending reverses it. Without it, numbers,\n * dates and booleans compare by value, anything else by its text in the\n * `LocaleProvider`'s locale with numbers inside it read as numbers (\"Item\n * 9\" before \"Item 10\"), and an empty value goes last either way.\n */\n sortFn?: (a: TRow, b: TRow) => number;\n /**\n * Whether the column takes part in filtering: the search matches its\n * text, and `filters` can hold a value for it. `false` leaves it out of\n * both, as for a column of actions.\n */\n filterable?: boolean;\n /**\n * Decides whether a row passes this column's value in `filters`. Without\n * it, the column's text has to contain the value's text, compared as the\n * search compares.\n */\n filterFn?: (row: TRow, filterValue: unknown) => boolean;\n /** Aligns the header and the cells (`isAligned` on `Th` and `Td`). */\n align?: TableAlignment;\n /** The column's width, on its header cell: a number is pixels, a string any CSS length. */\n width?: string | number;\n /**\n * Renders this column's cells as row headers (`th scope=\"row\"`), which a\n * screen reader reads out with the other cells of the row. The row's\n * checkbox is named from it. Mark one column, usually the first.\n */\n isRowHeader?: boolean;\n /** Options of an add-on's own, as `DataTableColumnMeta` declares them. */\n meta?: DataTableColumnMeta<TRow>;\n}\n\n/** The direction of a sort, in `aria-sort`'s words. */\nexport type DataTableSortDirection = 'ascending' | 'descending';\n\n/** One column a DataTable sorts by. */\nexport interface DataTableSort {\n /** The column's `id`. */\n id: string;\n /** Which way it sorts. */\n direction: DataTableSortDirection;\n}\n\n/** The values per column `filters` holds, keyed by column `id`. */\nexport type DataTableFilters = Record<string, unknown>;\n\n/**\n * Which of a table's rows to read: `all` of `data`, `filtered` (the ones the\n * search and the filters let through, from every page), the `page` shown,\n * or the `selected` ones the filters let through. Each comes in the order\n * the table shows them.\n */\nexport type DataTableRowScope = 'all' | 'filtered' | 'page' | 'selected';\n\n/** Whether a DataTable has row checkboxes. */\nexport type DataTableSelectionMode = 'none' | 'multiple';\n\n/**\n * The words a DataTable writes. Each is English unless you give your own,\n * and the numbers in the default messages are written in the\n * `LocaleProvider`'s locale.\n */\nexport interface DataTableLabels {\n /**\n * The header checkbox's name. \"Select all rows\", or \"Select all rows on\n * this page\" when there's more than one page, since it then covers the\n * page shown.\n */\n selectAll?: string;\n /** A row checkbox's name, from the row's label (`label => 'Select ' + label`). */\n selectRow?: (rowLabel: string) => string;\n /**\n * Says that headers with buttons sort: hidden at the end of the caption,\n * after a comma, or as a hidden caption of its own. \"column headers with\n * buttons are sortable\".\n */\n sortHint?: string;\n /** The search field's label. \"Search\". */\n search?: string;\n /** Announced after the search or a filter changes (\"12 rows match\"). */\n results?: (count: number) => string;\n /** Announced after the page changes (\"Showing 11 to 20 of 57\"). */\n pageRange?: (first: number, last: number, total: number) => string;\n /** Announced while `loading`, once the search, a filter or the page has changed. \"Loading\". */\n loading?: string;\n /**\n * The pager's name. \"{the table's name} pages\" when the table is named by\n * `aria-label` or a text `caption`, so two tables' pagers have different\n * names, else `Pagination`'s own.\n */\n pagination?: string;\n /** What the table shows with no rows at all. \"No rows to show.\" */\n empty?: string;\n /** What the table shows when the search and filters let no row through. \"No rows match.\" */\n noResults?: string;\n}\n\n/** The words a DataTable writes, with every default filled in. */\nexport interface DataTableResolvedLabels extends Required<\n Omit<DataTableLabels, 'pagination'>\n> {\n /** The pager's name, when one was given. */\n pagination?: string;\n}\n\n/**\n * The options `useDataTable` and `DataTable` share, beside the columns and\n * the data. Each piece of state is yours when you pass its value (and its\n * `on…Change`), or the table's own, starting from its `default…`.\n */\nexport interface DataTableStateOptions<TRow> {\n /**\n * A row's id, unique and stable, which the selection is a list of. Left\n * out, it's the row's `id` property as a string. A development build\n * warns about a missing or repeated id, and a row with none falls back to\n * its index, which doesn't survive the data changing.\n */\n getRowId?: (row: TRow, index: number) => string;\n /**\n * The sort when you hold it: an array of `{ id, direction }`, the first\n * deciding and each next one breaking ties. The headers set one at a time.\n */\n sort?: DataTableSort[];\n /**\n * The sort to start with when the table holds it. Text sorts in the\n * `LocaleProvider`'s locale, or the runtime's own outside one, which can\n * differ between a server and the browser, so put a table rendered on the\n * server sorted inside a `LocaleProvider`.\n */\n defaultSort?: DataTableSort[];\n /** Called with the new sort when a header is pressed. */\n onSortChange?: (sort: DataTableSort[]) => void;\n /**\n * `multiple` adds a checkbox to each row and a \"select all\" checkbox to the header.\n *\n * @defaultValue 'none'\n */\n selectionMode?: DataTableSelectionMode;\n /**\n * The selected rows' ids when you hold them. They stay selected while the\n * search, a filter or the page hides them.\n */\n selected?: string[];\n /** The rows selected to begin with, by id, when the table holds them. */\n defaultSelected?: string[];\n /** Called with every selected id after a checkbox changes. */\n onSelectedChange?: (selected: string[]) => void;\n /** Rows per page. Set, the table pages through `Pagination`; left out, it shows every row. */\n pageSize?: number;\n /**\n * The page shown when you hold it, counting from 1. A page past the end\n * shows the last.\n */\n page?: number;\n /**\n * The page to start on when the table holds it.\n *\n * @defaultValue 1\n */\n defaultPage?: number;\n /**\n * Called with the page chosen in the pager, and with 1 when the search or\n * a filter changes through the table while the page held isn't 1, even\n * when a page past the end shows as the last.\n */\n onPageChange?: (page: number) => void;\n /**\n * The search when you hold it, matched against every filterable column's\n * text: in the `LocaleProvider`'s locale, ignoring case and the accents\n * the language ignores, or a case-insensitive substring outside one.\n */\n search?: string;\n /** The search to start with when the table holds it. */\n defaultSearch?: string;\n /** Called with the search as it changes through the table. */\n onSearchChange?: (search: string) => void;\n /**\n * A value per column, by `id`, when you hold them. A row passes when every\n * column with a value passes it: the column's `filterFn` if it has one,\n * given the value as it is, or else the column's text has to contain the\n * value's text, compared as the search compares. An array is a choice of\n * values, as a multiple-choice filter gives, and passes a row whose text\n * contains any of them. A value of `undefined`, `null`, `''` or an empty\n * array is no filter.\n */\n filters?: DataTableFilters;\n /** The filters to start with when the table holds them. */\n defaultFilters?: DataTableFilters;\n /** Called with every filter value after one changes through the table. */\n onFiltersChange?: (filters: DataTableFilters) => void;\n /**\n * Hands sorting, filtering and paging to a server: the table shows `data`\n * as given, as the current page, and only reports the state as it\n * changes.\n */\n manual?: boolean;\n /**\n * With `manual`, how many rows match in all, which sets the page count and\n * the announced count. Without it, the table counts the rows in `data`,\n * which with a `pageSize` is one page and no pager, and a development\n * build warns.\n */\n rowCount?: number;\n /** The words the table writes, in your app's language. */\n labels?: DataTableLabels;\n}\n\n/** What `useDataTable` takes. */\nexport interface UseDataTableOptions<TRow> extends DataTableStateOptions<TRow> {\n /**\n * The columns, in the order they're shown. Keep the array the same from\n * one render to the next, defined outside the component or in `useMemo`:\n * a new one has every cell's text worked out again.\n */\n columns: DataTableColumn<TRow>[];\n /** The rows, as records of your own. */\n data: TRow[];\n}\n\n/** The table's state, as it stands. */\nexport interface DataTableState {\n /** The sort, the first entry deciding. */\n sort: DataTableSort[];\n /** The selected rows' ids. */\n selected: string[];\n /** The page shown, counting from 1. */\n page: number;\n /** Rows per page, or `undefined` when it doesn't page. */\n pageSize: number | undefined;\n /** The search. */\n search: string;\n /** The filter values, by column id. */\n filters: DataTableFilters;\n}\n\n/** The props `getSortButtonProps` gives a header's `<button>`. */\nexport interface DataTableSortButtonProps {\n type: 'button';\n className: string;\n onClick: () => void;\n}\n\n/** The props `getSearchProps` gives a search `<input>` or bestax `Input`. */\nexport interface DataTableSearchProps {\n type: 'search';\n value: string;\n onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\n/** The props `getHeaderCellProps` gives a column's `Th`. */\nexport interface DataTableHeaderCellProps {\n scope: 'col';\n 'aria-sort'?: DataTableSortDirection;\n isAligned?: TableAlignment;\n width?: string | number;\n}\n\n/** The props `getCellProps` gives a row's `Td`, or its `Th` for the row header. */\nexport interface DataTableCellProps {\n scope?: 'row';\n isAligned?: TableAlignment;\n}\n\n/** The props `getSelectAllProps` and `getSelectRowProps` give a `Checkbox`. */\nexport interface DataTableCheckboxProps {\n 'aria-label': string;\n checked: boolean;\n indeterminate?: boolean;\n disabled?: boolean;\n onChange: () => void;\n}\n\n/** The props `getPaginationProps` gives `Pagination`. */\nexport interface DataTablePaginationProps {\n total: number;\n current: number;\n onPageChange: (page: number) => void;\n}\n\n/** What `toCSV` writes. */\nexport interface DataTableCSVOptions {\n /**\n * Which rows, in the order the table shows them: the ones the search and\n * filters let through, from every page, by default, or `all`, `page` or\n * `selected`.\n *\n * @defaultValue 'filtered'\n */\n rows?: DataTableRowScope;\n /** The ids of the columns to write, in that order. Every column, in the order shown, by default. */\n columns?: string[];\n /**\n * Writes the columns' headers as the first line.\n *\n * @defaultValue true\n */\n header?: boolean;\n /**\n * What separates the fields. A semicolon suits a spreadsheet that reads\n * a comma as the decimal point, as Excel does in much of Europe.\n *\n * @defaultValue ','\n */\n delimiter?: string;\n}\n\n/**\n * A table: what `useDataTable` returns, what `DataTable`'s `toolbar` is\n * given, and what its `table` takes. It reads the rows and the state, changes\n * the state, and hands out props for bestax's own `Th`, `Tr`, `Td`,\n * `Checkbox` and `Pagination`, so markup of your own behaves as DataTable's\n * does.\n */\nexport interface DataTableModel<TRow> {\n /** The columns, in the order they're shown. */\n columns: DataTableColumn<TRow>[];\n /** The state as it stands. */\n state: DataTableState;\n /** Whether rows have checkboxes. */\n selectionMode: DataTableSelectionMode;\n /** Whether a server sorts, filters and pages (`manual`). */\n manual: boolean;\n /** How many rows the search and filters let through, or `rowCount` with `manual`. */\n rowCount: number;\n /** How many pages there are, at least 1. */\n pageCount: number;\n /** The words the table writes, with the defaults filled in. */\n labels: DataTableResolvedLabels;\n /** The rows in `scope` (`filtered` by default), in the order the table shows them. */\n getRows: (scope?: DataTableRowScope) => TRow[];\n /** A row's id. */\n getRowId: (row: TRow) => string;\n /** A column's raw value for a row, or `undefined` for a column it doesn't have. */\n getValue: (row: TRow, columnId: string) => unknown;\n /** A column's text for a row, or `''` for a column it doesn't have. */\n getText: (row: TRow, columnId: string) => string;\n /** What names a row: its row header's text, or its first column's. */\n getRowLabel: (row: TRow) => string;\n /**\n * The rows as CSV, from the columns' text (`format`, not `cell`), with a\n * line break of `\\r\\n` between rows and fields quoted as RFC 4180 asks.\n * A field that starts with `=`, `+`, `-`, `@`, a tab or a carriage return\n * gets a `'` in front, so a spreadsheet shows it as text rather than\n * running it as a formula, unless it's a plain number such as `-12.5`.\n * Excel takes a file as UTF-8 only when it starts with a byte order mark,\n * so put `\\uFEFF` in front of the text when you save it for Excel.\n */\n toCSV: (options?: DataTableCSVOptions) => string;\n /** Whether a row is selected. */\n isSelected: (row: TRow) => boolean;\n /** Sets the sort. */\n setSort: (sort: DataTableSort[]) => void;\n /** Moves a column through its sort, as its header button does. */\n toggleSort: (columnId: string) => void;\n /** Sets the selected ids. */\n setSelected: (selected: string[]) => void;\n /**\n * Selects a row, or clears it, or with no `selected` flips it. Called\n * twice in one handler, the second call builds on the first while the\n * table holds the selection. While you hold it, each call builds on the\n * selection as rendered, so make several changes at once with\n * `setSelected`.\n */\n toggleRowSelected: (row: TRow, selected?: boolean) => void;\n /**\n * Selects every row on the page, or clears them, or with no `selected`\n * does what the header checkbox does. It builds on earlier calls as\n * `toggleRowSelected` does.\n */\n togglePageSelected: (selected?: boolean) => void;\n /** Goes to a page, counting from 1. */\n setPage: (page: number) => void;\n /**\n * Sets the search, and goes back to page 1, calling `onPageChange` with 1\n * unless the page held is 1 already.\n */\n setSearch: (search: string) => void;\n /**\n * Sets one column's filter value, and goes back to page 1. Called twice in\n * one handler, the second call builds on the first while the table holds\n * the filters. While you hold them, each call builds on the filters as\n * rendered, so set several at once with `setFilters`.\n */\n setFilter: (columnId: string, value: unknown) => void;\n /** Sets every filter value, and goes back to page 1, as `setSearch` does. */\n setFilters: (filters: DataTableFilters) => void;\n /** Props for a column's `Th`: its scope, its `aria-sort` while sorted, its alignment and width. */\n getHeaderCellProps: (\n column: DataTableColumn<TRow>\n ) => DataTableHeaderCellProps;\n /** Props for the `<button>` in a sortable column's header. */\n getSortButtonProps: (\n column: DataTableColumn<TRow>\n ) => DataTableSortButtonProps;\n /** Props for a row's `Tr`: Bulma's selected look while it's selected. */\n getRowProps: (row: TRow) => { isSelected: boolean };\n /** Props for a row's cell in a column: its alignment, and `scope=\"row\"` for the row header. */\n getCellProps: (\n row: TRow,\n column: DataTableColumn<TRow>\n ) => DataTableCellProps;\n /** Props for the header's \"select all\" `Checkbox`, which covers the page shown. */\n getSelectAllProps: () => DataTableCheckboxProps;\n /** Props for a row's `Checkbox`, named for the row. */\n getSelectRowProps: (row: TRow) => DataTableCheckboxProps;\n /** Props for `Pagination`: the page count, the page and the handler. */\n getPaginationProps: () => DataTablePaginationProps;\n /** Props for a search field, bound to the search. */\n getSearchProps: () => DataTableSearchProps;\n}\n\n/** A column's raw value for a row. */\nfunction readValue<TRow>(column: DataTableColumn<TRow>, row: TRow): unknown {\n const { accessor } = column;\n if (typeof accessor === 'function') return accessor(row);\n if (row === null || typeof row !== 'object') return undefined;\n return (row as Record<PropertyKey, unknown>)[\n (accessor ?? column.id) as PropertyKey\n ];\n}\n\n/** A column's text for a row. */\nfunction readText<TRow>(column: DataTableColumn<TRow>, row: TRow): string {\n const value = readValue(column, row);\n if (column.format) return column.format(value, row);\n return value === null || value === undefined ? '' : String(value);\n}\n\n/** Whether a value sorts as empty: nothing, no text, or no number or date. */\nfunction isEmptyValue(value: unknown): boolean {\n return (\n value === null ||\n value === undefined ||\n value === '' ||\n (typeof value === 'number' && Number.isNaN(value)) ||\n (value instanceof Date && Number.isNaN(value.getTime()))\n );\n}\n\n/** Compares two values that aren't empty, for an ascending sort. */\nfunction compareValues(a: unknown, b: unknown, collator: Intl.Collator) {\n if (typeof a === 'number' && typeof b === 'number') return a - b;\n if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();\n if (typeof a === 'boolean' && typeof b === 'boolean') {\n return Number(a) - Number(b);\n }\n return collator.compare(String(a), String(b));\n}\n\n/** Whether a filter value filters anything. */\nfunction isActiveFilter(value: unknown): boolean {\n return (\n value !== undefined &&\n value !== null &&\n value !== '' &&\n !(Array.isArray(value) && value.length === 0)\n );\n}\n\n/** A field a spreadsheet would read as the start of a formula. */\nconst formulaStart = /^[=+\\-@\\t\\r]/;\n/** A plain number, signed, with any grouping, which no spreadsheet runs. */\nconst plainNumber = /^[+-]?\\d[\\d.,]*$/;\n\n/**\n * One CSV field: a `'` in front of what would start a formula, then quoted\n * when it holds the delimiter, a quote or a line break, its quotes doubled.\n */\nfunction csvField(text: string, delimiter: string): string {\n const safe =\n formulaStart.test(text) && !plainNumber.test(text) ? `'${text}` : text;\n return safe.includes(delimiter) || /[\"\\r\\n]/.test(safe)\n ? `\"${safe.replace(/\"/g, '\"\"')}\"`\n : safe;\n}\n\n/**\n * Whether a search or a filter value is narrowing the rows. Used by\n * DataTable to tell an empty table from one with no matches.\n */\nexport function isFiltering(search: string, filters: DataTableFilters) {\n return search.trim() !== '' || Object.values(filters).some(isActiveFilter);\n}\n\n/** A row's id from its `id` property, or nothing when it has none. */\nfunction idOf(row: unknown): string | undefined {\n if (row === null || typeof row !== 'object') return undefined;\n const id = (row as { id?: unknown }).id;\n return id === undefined || id === null || id === '' ? undefined : String(id);\n}\n\n/**\n * A piece of state that's the caller's when they pass its value, and the\n * table's own otherwise. Setting it calls the change handler either way.\n *\n * It also returns `latest`, what a change should build on. While the table\n * holds the state, that's the value last set, even before React renders it,\n * so two changes in one handler build on each other. While the caller holds\n * it, it's the value as rendered, since only the caller knows what it made\n * of a change.\n */\nfunction useTableState<T>(\n value: T | undefined,\n initial: T,\n onChange: ((next: T) => void) | undefined\n): [T, (next: T) => void, () => T] {\n const [own, setOwn] = useState(initial);\n const held = value !== undefined;\n const current = held ? value : own;\n const rendered = useLatestRef(current);\n // A value set since the last commit, cleared once a commit shows it.\n const pendingRef = useRef<{ value: T } | null>(null);\n useClientLayoutEffect(() => {\n pendingRef.current = null;\n });\n const set = useCallback(\n (next: T) => {\n if (!held) {\n pendingRef.current = { value: next };\n setOwn(next);\n }\n onChange?.(next);\n },\n [held, onChange]\n );\n const latest = useCallback(\n () => (pendingRef.current ? pendingRef.current.value : rendered.current),\n [rendered]\n );\n return [current, set, latest];\n}\n\nconst noSort: DataTableSort[] = [];\nconst noIds: string[] = [];\nconst noFilters: DataTableFilters = {};\n\n/**\n * `useDataTable` holds a table's sort, selection, page, search and filters,\n * works out its rows, and hands out props for bestax's own table parts, so\n * custom markup behaves as `DataTable` does. Pass its result to\n * `<DataTable table={table} />` to render it with DataTable's own markup,\n * with a toolbar or an export button elsewhere on the page.\n *\n * @example\n * const table = useDataTable({ columns, data: users, pageSize: 10 });\n *\n * <DataTable table={table} caption=\"Users\" hasSearch />\n */\nexport function useDataTable<TRow>(\n options: UseDataTableOptions<TRow>\n): DataTableModel<TRow> {\n const {\n columns,\n data,\n getRowId: rowIdOf,\n sort: sortProp,\n defaultSort = noSort,\n onSortChange,\n selectionMode = 'none',\n selected: selectedProp,\n defaultSelected = noIds,\n onSelectedChange,\n pageSize: pageSizeProp,\n page: pageProp,\n defaultPage = 1,\n onPageChange,\n search: searchProp,\n defaultSearch = '',\n onSearchChange,\n filters: filtersProp,\n defaultFilters = noFilters,\n onFiltersChange,\n manual = false,\n rowCount: rowCountProp,\n labels,\n } = options;\n\n const [sort, setSort] = useTableState(sortProp, defaultSort, onSortChange);\n const [selected, setSelected, latestSelected] = useTableState(\n selectedProp,\n defaultSelected,\n onSelectedChange\n );\n const [pageState, setPageState, latestPage] = useTableState(\n pageProp,\n defaultPage,\n onPageChange\n );\n const [search, setSearchState] = useTableState(\n searchProp,\n defaultSearch,\n onSearchChange\n );\n const [filters, setFiltersState, latestFilters] = useTableState(\n filtersProp,\n defaultFilters,\n onFiltersChange\n );\n\n const prefix = useClassPrefix();\n const { locale } = useLocale();\n const matchText = useLocaleMatcher();\n const formatNumber = useNumberFormat();\n const collator = useMemo(\n () => new Intl.Collator(locale, { numeric: true }),\n [locale]\n );\n\n const pageSize =\n pageSizeProp !== undefined &&\n Number.isFinite(pageSizeProp) &&\n pageSizeProp >= 1\n ? Math.floor(pageSizeProp)\n : undefined;\n\n const columnsById = useMemo(() => {\n const byId = new Map<string, DataTableColumn<TRow>>();\n for (const column of columns) {\n if (byId.has(column.id)) {\n warnOnce(\n 'DataTable:duplicate-column',\n `[bestax-bulma] DataTable has two columns with the id \"${column.id}\". ` +\n 'Give each column its own id: the sort, the filters and an export ' +\n 'find a column by it.'\n );\n } else {\n byId.set(column.id, column);\n }\n }\n return byId;\n }, [columns]);\n\n // Each row's id, by its index in `data`.\n const ids = useMemo(() => {\n const out = data.map((row, index) => {\n const id = rowIdOf ? rowIdOf(row, index) : idOf(row);\n if (id === undefined || id === '') {\n warnOnce(\n 'DataTable:missing-row-id',\n '[bestax-bulma] A DataTable row has no id, so it falls back to its ' +\n \"index, which doesn't survive the data changing. Give each row \" +\n 'an `id`, or pass `getRowId`.'\n );\n return String(index);\n }\n return id;\n });\n if (isDev() && new Set(out).size < out.length) {\n warnOnce(\n 'DataTable:duplicate-row-id',\n '[bestax-bulma] Two DataTable rows have the same id, so selecting ' +\n 'one selects both. Make the ids unique, or pass a `getRowId` ' +\n 'that does.'\n );\n }\n return out;\n }, [data, rowIdOf]);\n\n const indexOf = useMemo(() => {\n const map = new Map<TRow, number>();\n data.forEach((row, index) => {\n if (!map.has(row)) map.set(row, index);\n });\n return map;\n }, [data]);\n\n /** A row's id, from its index when the row is one of `data`. */\n const getRowId = useCallback(\n (row: TRow) => {\n const index = indexOf.get(row);\n if (index !== undefined) return ids[index];\n const id = rowIdOf ? rowIdOf(row, -1) : idOf(row);\n return id ?? '';\n },\n [indexOf, ids, rowIdOf]\n );\n\n // Every column's text for every row, worked out once per data and\n // columns, since the search reads them on every keystroke.\n const texts = useMemo(\n () => data.map(row => columns.map(column => readText(column, row))),\n [data, columns]\n );\n\n const sortedIndexes = useMemo(() => {\n const all = data.map((_, index) => index);\n if (manual) return all;\n const keys = sort\n .map(entry => ({\n column: columnsById.get(entry.id),\n descending: entry.direction === 'descending',\n }))\n .filter(\n (key): key is { column: DataTableColumn<TRow>; descending: boolean } =>\n key.column !== undefined\n );\n if (keys.length === 0) return all;\n const values = keys.map(({ column }) =>\n column.sortFn ? null : data.map(row => readValue(column, row))\n );\n return all.sort((x, y) => {\n for (let k = 0; k < keys.length; k++) {\n const { column, descending } = keys[k];\n let result: number;\n if (column.sortFn) {\n result = column.sortFn(data[x], data[y]);\n if (descending) result = -result;\n } else {\n const a = values[k]![x];\n const b = values[k]![y];\n const aEmpty = isEmptyValue(a);\n const bEmpty = isEmptyValue(b);\n if (aEmpty || bEmpty) {\n // Empty values go last whichever way the column sorts.\n result = Number(aEmpty) - Number(bEmpty);\n } else {\n result = compareValues(a, b, collator);\n if (descending) result = -result;\n }\n }\n if (result) return result;\n }\n // Ties keep the order of `data`.\n return x - y;\n });\n }, [data, sort, columnsById, collator, manual]);\n\n const filteredIndexes = useMemo(() => {\n if (manual) return sortedIndexes;\n const query = search.trim();\n const holds = matchText\n ? (text: string, needle: string) => matchText(text, needle)\n : (text: string, needle: string) =>\n text.toLowerCase().includes(needle.toLowerCase());\n const searched = columns\n .map((column, index) => ({ column, index }))\n .filter(({ column }) => column.filterable !== false);\n const filtered = Object.entries(filters)\n .filter(([, value]) => isActiveFilter(value))\n .map(([id, value]) => ({\n column: columnsById.get(id),\n index: columns.findIndex(column => column.id === id),\n value,\n }))\n .filter(\n ({ column }) => column !== undefined && column.filterable !== false\n );\n if (query === '' && filtered.length === 0) return sortedIndexes;\n return sortedIndexes.filter(rowIndex => {\n const row = data[rowIndex];\n const rowTexts = texts[rowIndex];\n for (const { column, index, value } of filtered) {\n // An array is any of its entries, as a multiple-choice filter gives.\n const passes = column!.filterFn\n ? column!.filterFn(row, value)\n : Array.isArray(value)\n ? value.some(entry => holds(rowTexts[index], String(entry)))\n : holds(rowTexts[index], String(value));\n if (!passes) return false;\n }\n return (\n query === '' ||\n searched.some(({ index }) => holds(rowTexts[index], query))\n );\n });\n }, [\n manual,\n sortedIndexes,\n search,\n filters,\n matchText,\n columns,\n columnsById,\n data,\n texts,\n ]);\n\n const knowsCount =\n rowCountProp !== undefined && Number.isFinite(rowCountProp);\n if (manual && pageSize !== undefined && !knowsCount) {\n warnOnce(\n 'DataTable:manual-row-count',\n '[bestax-bulma] A DataTable with `manual` and a `pageSize` has no ' +\n '`rowCount`, so it counts only the rows in `data`, makes one page ' +\n 'of them and shows no pager. Pass `rowCount`, how many rows match ' +\n 'on the server.'\n );\n }\n const rowCount = manual\n ? Math.max(\n Math.floor(knowsCount ? (rowCountProp as number) : data.length),\n 0\n )\n : filteredIndexes.length;\n const pageCount = pageSize ? Math.max(Math.ceil(rowCount / pageSize), 1) : 1;\n const page = Math.min(\n Math.max(Number.isFinite(pageState) ? Math.floor(pageState) : 1, 1),\n pageCount\n );\n\n const pageIndexes = useMemo(() => {\n if (manual || !pageSize) return filteredIndexes;\n return filteredIndexes.slice((page - 1) * pageSize, page * pageSize);\n }, [manual, pageSize, filteredIndexes, page]);\n\n const selectedSet = useMemo(() => new Set(selected), [selected]);\n const selectable = selectionMode === 'multiple';\n\n const rowsOf = useCallback(\n (indexes: number[]) => indexes.map(index => data[index]),\n [data]\n );\n\n const getRows = useCallback(\n (scope: DataTableRowScope = 'filtered') => {\n switch (scope) {\n case 'all':\n return rowsOf(sortedIndexes);\n case 'page':\n return rowsOf(pageIndexes);\n case 'selected':\n return rowsOf(\n filteredIndexes.filter(index => selectedSet.has(ids[index]))\n );\n default:\n return rowsOf(filteredIndexes);\n }\n },\n [rowsOf, sortedIndexes, pageIndexes, filteredIndexes, selectedSet, ids]\n );\n\n const getValue = useCallback(\n (row: TRow, columnId: string) => {\n const column = columnsById.get(columnId);\n return column ? readValue(column, row) : undefined;\n },\n [columnsById]\n );\n\n const getText = useCallback(\n (row: TRow, columnId: string) => {\n const column = columnsById.get(columnId);\n if (!column) return '';\n const index = indexOf.get(row);\n return index !== undefined\n ? texts[index][columns.indexOf(column)]\n : readText(column, row);\n },\n [columnsById, indexOf, columns, texts]\n );\n\n const labelColumn = columns.find(column => column.isRowHeader) ?? columns[0];\n const getRowLabel = useCallback(\n (row: TRow) =>\n (labelColumn && getText(row, labelColumn.id)) || getRowId(row),\n [labelColumn, getText, getRowId]\n );\n\n const isSelected = useCallback(\n (row: TRow) => selectable && selectedSet.has(getRowId(row)),\n [selectable, selectedSet, getRowId]\n );\n\n const setPage = useCallback(\n (next: number) => {\n if (next !== page) setPageState(next);\n },\n [page, setPageState]\n );\n\n // A new search or filter starts from the first page. It's measured against\n // the page as stored, not as shown: a page past the end shows the last,\n // and left stored it would come back once the rows grew again.\n const resetPage = useCallback(() => {\n if (latestPage() !== 1) setPageState(1);\n }, [latestPage, setPageState]);\n\n const setSearch = useCallback(\n (next: string) => {\n setSearchState(next);\n resetPage();\n },\n [setSearchState, resetPage]\n );\n\n const setFilters = useCallback(\n (next: DataTableFilters) => {\n setFiltersState(next);\n resetPage();\n },\n [setFiltersState, resetPage]\n );\n\n const setFilter = useCallback(\n (columnId: string, value: unknown) => {\n const next = { ...latestFilters() };\n if (isActiveFilter(value)) next[columnId] = value;\n else delete next[columnId];\n setFilters(next);\n },\n [latestFilters, setFilters]\n );\n\n const toggleSort = useCallback(\n (columnId: string) => {\n const column = columnsById.get(columnId);\n if (!column) return;\n const first: DataTableSortDirection = column.sortDescFirst\n ? 'descending'\n : 'ascending';\n const current = sort[0]?.id === columnId ? sort[0].direction : undefined;\n if (current === undefined) {\n setSort([{ id: columnId, direction: first }]);\n } else if (current === first) {\n setSort([\n {\n id: columnId,\n direction: first === 'ascending' ? 'descending' : 'ascending',\n },\n ]);\n } else {\n setSort([]);\n }\n },\n [columnsById, sort, setSort]\n );\n\n const toggleRowSelected = useCallback(\n (row: TRow, value?: boolean) => {\n const id = getRowId(row);\n const current = latestSelected();\n const has = current.includes(id);\n const on = value ?? !has;\n if (on === has) return;\n setSelected(on ? [...current, id] : current.filter(s => s !== id));\n },\n [getRowId, latestSelected, setSelected]\n );\n\n const pageIds = useMemo(\n () => pageIndexes.map(index => ids[index]),\n [pageIndexes, ids]\n );\n const pageSelectedCount = pageIds.filter(id => selectedSet.has(id)).length;\n const allPageSelected =\n pageIds.length > 0 && pageSelectedCount === pageIds.length;\n\n const togglePageSelected = useCallback(\n (value?: boolean) => {\n const current = latestSelected();\n const has = new Set(current);\n const on =\n value ?? !(pageIds.length > 0 && pageIds.every(id => has.has(id)));\n if (on) {\n const adding = pageIds.filter(id => !has.has(id));\n if (adding.length > 0) setSelected([...current, ...adding]);\n } else {\n const onPage = new Set(pageIds);\n const kept = current.filter(id => !onPage.has(id));\n if (kept.length !== current.length) setSelected(kept);\n }\n },\n [latestSelected, pageIds, setSelected]\n );\n\n const count = useCallback(\n (value: number) => (formatNumber ? formatNumber(value) : String(value)),\n [formatNumber]\n );\n\n const resolvedLabels: DataTableResolvedLabels = {\n selectAll:\n labels?.selectAll ||\n (pageCount > 1 ? 'Select all rows on this page' : 'Select all rows'),\n selectRow: labels?.selectRow ?? (label => `Select ${label}`),\n sortHint: labels?.sortHint || 'column headers with buttons are sortable',\n search: labels?.search || 'Search',\n results:\n labels?.results ??\n (total =>\n total === 0\n ? 'No rows match'\n : `${count(total)} ${total === 1 ? 'row matches' : 'rows match'}`),\n pageRange:\n labels?.pageRange ??\n ((first, last, total) =>\n `Showing ${count(first)} to ${count(last)} of ${count(total)}`),\n loading: labels?.loading || 'Loading',\n pagination: labels?.pagination || undefined,\n empty: labels?.empty || 'No rows to show.',\n noResults: labels?.noResults || 'No rows match.',\n };\n\n const toCSV = useCallback(\n ({\n rows = 'filtered',\n columns: ids,\n header = true,\n delimiter = ',',\n }: DataTableCSVOptions = {}) => {\n const written = ids\n ? ids\n .map(id => columnsById.get(id))\n .filter(\n (column): column is DataTableColumn<TRow> => column !== undefined\n )\n : columns;\n const line = (fields: string[]) =>\n fields.map(field => csvField(field, delimiter)).join(delimiter);\n const lines = getRows(rows).map(row =>\n line(written.map(column => getText(row, column.id)))\n );\n if (header) lines.unshift(line(written.map(column => column.header)));\n return lines.join('\\r\\n');\n },\n [columnsById, columns, getRows, getText]\n );\n\n const sortButtonClass = prefixedClassNames(prefix, 'data-table-sort');\n\n return {\n columns,\n state: { sort, selected, page, pageSize, search, filters },\n selectionMode,\n manual,\n rowCount,\n pageCount,\n labels: resolvedLabels,\n getRows,\n getRowId,\n getValue,\n getText,\n getRowLabel,\n toCSV,\n isSelected,\n setSort,\n toggleSort,\n setSelected,\n toggleRowSelected,\n togglePageSelected,\n setPage,\n setSearch,\n setFilter,\n setFilters,\n getHeaderCellProps: column => ({\n scope: 'col',\n 'aria-sort': sort[0]?.id === column.id ? sort[0].direction : undefined,\n isAligned: column.align,\n width: column.width,\n }),\n getSortButtonProps: column => ({\n type: 'button',\n className: sortButtonClass,\n onClick: () => toggleSort(column.id),\n }),\n getRowProps: row => ({ isSelected: isSelected(row) }),\n getCellProps: (_row, column) => ({\n scope: column.isRowHeader ? 'row' : undefined,\n isAligned: column.align,\n }),\n getSelectAllProps: () => ({\n 'aria-label': resolvedLabels.selectAll,\n checked: allPageSelected,\n indeterminate: pageSelectedCount > 0 && !allPageSelected,\n disabled: pageIds.length === 0,\n onChange: () => togglePageSelected(),\n }),\n getSelectRowProps: row => ({\n 'aria-label': resolvedLabels.selectRow(getRowLabel(row)),\n checked: selectedSet.has(getRowId(row)),\n onChange: () => toggleRowSelected(row),\n }),\n getPaginationProps: () => ({\n total: pageCount,\n current: page,\n onPageChange: setPage,\n }),\n getSearchProps: () => ({\n type: 'search',\n value: search,\n onChange: event => setSearch(event.target.value),\n }),\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { forwardRef } from 'react';
|
|
4
|
+
import { usePrefixedClassNames } from '../helpers/classNames.js';
|
|
5
|
+
import { Field } from './Field.js';
|
|
6
|
+
import { Control } from './Control.js';
|
|
7
|
+
import { ColorInputBase } from './ColorInputBase.js';
|
|
8
|
+
import { useInsideField, useInsideControl, rendersOwnField, rendersOwnControl } from './FormContext.js';
|
|
9
|
+
import { useAutoLabelId } from './useAutoLabelId.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The `ColorInput` component is a form field for a color: type it, or open a color picker from its launcher or its swatch.
|
|
13
|
+
*
|
|
14
|
+
* The value is a CSS color string, HSL by default, or empty. The panel is
|
|
15
|
+
* the `ColorPicker`'s square, hue slider and, when asked for, alpha slider,
|
|
16
|
+
* swatches and eye dropper, in the same popover the date pickers use.
|
|
17
|
+
*
|
|
18
|
+
* @function
|
|
19
|
+
* @param {ColorInputProps} props - Props for the ColorInput.
|
|
20
|
+
* @returns {JSX.Element}
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* <ColorInput label="Brand color" defaultValue="hsl(202, 67%, 36%)" swatches="bulma" />
|
|
24
|
+
*/
|
|
25
|
+
const ColorInput = forwardRef((props, ref) => {
|
|
26
|
+
const { label, labelSize, labelProps, horizontal, isLoading, isExpanded, controlSize, message, messageColor, fieldClassName, controlClassName, ...baseProps } = props;
|
|
27
|
+
const insideField = useInsideField();
|
|
28
|
+
const insideControl = useInsideControl();
|
|
29
|
+
const ownField = rendersOwnField('ColorInput', {
|
|
30
|
+
insideField,
|
|
31
|
+
insideControl,
|
|
32
|
+
label,
|
|
33
|
+
message,
|
|
34
|
+
horizontal,
|
|
35
|
+
fieldClassName,
|
|
36
|
+
});
|
|
37
|
+
const ownControl = rendersOwnControl('ColorInput', {
|
|
38
|
+
insideControl,
|
|
39
|
+
isLoading,
|
|
40
|
+
isExpanded,
|
|
41
|
+
controlSize,
|
|
42
|
+
controlClassName,
|
|
43
|
+
});
|
|
44
|
+
const { controlId, fieldLabelProps } = useAutoLabelId({
|
|
45
|
+
label,
|
|
46
|
+
id: baseProps.id,
|
|
47
|
+
labelProps,
|
|
48
|
+
rendersLabel: ownField,
|
|
49
|
+
});
|
|
50
|
+
const helpClass = usePrefixedClassNames('help', {
|
|
51
|
+
[`is-${messageColor}`]: !!messageColor,
|
|
52
|
+
});
|
|
53
|
+
// The base hides its launcher while the Control it sits in is loading,
|
|
54
|
+
// whether that is the one rendered below or an enclosing one.
|
|
55
|
+
let content = (jsx(ColorInputBase, { ref: ref, ...baseProps, id: controlId }));
|
|
56
|
+
if (ownControl) {
|
|
57
|
+
content = (jsx(Control, { isLoading: isLoading, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
|
|
58
|
+
}
|
|
59
|
+
const messageEl = message ? jsx("p", { className: helpClass, children: message }) : null;
|
|
60
|
+
if (ownField) {
|
|
61
|
+
return (jsxs(Field, { label: label, labelSize: labelSize, labelProps: fieldLabelProps, horizontal: horizontal, className: fieldClassName, children: [content, messageEl] }));
|
|
62
|
+
}
|
|
63
|
+
return (jsxs(Fragment, { children: [content, messageEl] }));
|
|
64
|
+
});
|
|
65
|
+
ColorInput.displayName = 'ColorInput';
|
|
66
|
+
|
|
67
|
+
export { ColorInput };
|
|
68
|
+
//# sourceMappingURL=ColorInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColorInput.js","sources":["../../../src/form/ColorInput.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { usePrefixedClassNames } from '../helpers/classNames';\nimport { Field, FieldProps } from './Field';\nimport { Control, ControlBaseProps } from './Control';\nimport { ColorInputBase, ColorInputBaseProps } from './ColorInputBase';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n} from './FormContext';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/**\n * Props for the ColorInput convenience wrapper. Extends\n * `ColorInputBaseProps` with Field-level (label, horizontal, message) and\n * Control-level (loading, expanded) props. Inside an existing `Control` it\n * renders no `Control` of its own, so its Control-level props do nothing\n * there and warn in development; set them on that `Control` instead. Inside\n * an outer `Field`, or a `Control` with no `Field` around it, it renders no\n * `Field` of its own either. The exception is `label`, `message`,\n * `horizontal` or `fieldClassName` in that bare `Control`: it keeps a `Field`\n * for them, nested in the `.control`, and warns in development. Wrap the\n * `Control` in a `Field` instead, and set the `label`, `horizontal` and class\n * name on that `Field`.\n *\n * @helperProps Helper props go on the `.colorinput` `<div>`, with\n * `className`. The other attributes go on the text `<input>`.\n * @extraProp {string} [name] - Form field name. The field submits the text it shows, the value in `format`, or nothing when it's empty.\n * @extraProp {boolean} [required=false] - Marks the field required, so an empty one fails the form's constraint validation.\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Forwarded to the text `<input>`.\n */\nexport interface ColorInputProps extends ColorInputBaseProps {\n /** Field label (component auto-wraps in a `Field` if not already inside). Automatically associated with the text field via `htmlFor`, using your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. */\n label?: React.ReactNode;\n /** Size for the label. */\n labelSize?: FieldProps['labelSize'];\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). */\n labelProps?: FieldProps['labelProps'];\n /** Render the field with horizontal layout. */\n horizontal?: boolean;\n /**\n * Shows a loading spinner on the `Control` it renders, and hides the\n * launcher (`triggerIcon`) while it does. Inside your own `Control` it\n * renders none, so this draws nothing and warns in development; set\n * `isLoading` on that `Control`.\n */\n isLoading?: boolean;\n /**\n * Shows the launcher on the field's end that toggles the panel. Hidden by\n * default while a spinner shows at the same edge: this component's\n * `isLoading` when it renders its own `Control`, or the enclosing\n * `Control`'s `isLoading` inside one.\n * @defaultValue true\n */\n triggerIcon?: boolean;\n /** Expand the control to fill its container. */\n isExpanded?: boolean;\n /** Size of the wrapping Control. */\n controlSize?: ControlBaseProps['size'];\n /** Help/validation text below the field. */\n message?: React.ReactNode;\n /** Color modifier for the help message. */\n messageColor?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Additional CSS classes for the Field wrapper. */\n fieldClassName?: string;\n /** Additional CSS classes for the Control wrapper. */\n controlClassName?: string;\n}\n\n/**\n * The `ColorInput` component is a form field for a color: type it, or open a color picker from its launcher or its swatch.\n *\n * The value is a CSS color string, HSL by default, or empty. The panel is\n * the `ColorPicker`'s square, hue slider and, when asked for, alpha slider,\n * swatches and eye dropper, in the same popover the date pickers use.\n *\n * @function\n * @param {ColorInputProps} props - Props for the ColorInput.\n * @returns {JSX.Element}\n *\n * @example\n * <ColorInput label=\"Brand color\" defaultValue=\"hsl(202, 67%, 36%)\" swatches=\"bulma\" />\n */\nexport const ColorInput = forwardRef<HTMLInputElement, ColorInputProps>(\n (props, ref) => {\n const {\n label,\n labelSize,\n labelProps,\n horizontal,\n isLoading,\n isExpanded,\n controlSize,\n message,\n messageColor,\n fieldClassName,\n controlClassName,\n ...baseProps\n } = props;\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('ColorInput', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const ownControl = rendersOwnControl('ColorInput', {\n insideControl,\n isLoading,\n isExpanded,\n controlSize,\n controlClassName,\n });\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: baseProps.id,\n labelProps,\n rendersLabel: ownField,\n });\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n\n // The base hides its launcher while the Control it sits in is loading,\n // whether that is the one rendered below or an enclosing one.\n let content: React.ReactNode = (\n <ColorInputBase ref={ref} {...baseProps} id={controlId} />\n );\n\n if (ownControl) {\n content = (\n <Control\n isLoading={isLoading}\n isExpanded={isExpanded}\n size={controlSize}\n className={controlClassName}\n >\n {content}\n </Control>\n );\n }\n\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {content}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n }\n);\n\nColorInput.displayName = 'ColorInput';\n\nexport default ColorInput;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":";;;;;;;;;;AAsEA;;;;;;;;;;;;;AAaG;AACI,MAAM,UAAU,GAAG,UAAU,CAClC,CAAC,KAAK,EAAE,GAAG,KAAI;AACb,IAAA,MAAM,EACJ,KAAK,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,WAAW,EACX,OAAO,EACP,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,GAAG,SAAS,EACb,GAAG,KAAK;AACT,IAAA,MAAM,WAAW,GAAG,cAAc,EAAE;AACpC,IAAA,MAAM,aAAa,GAAG,gBAAgB,EAAE;AACxC,IAAA,MAAM,QAAQ,GAAG,eAAe,CAAC,YAAY,EAAE;QAC7C,WAAW;QACX,aAAa;QACb,KAAK;QACL,OAAO;QACP,UAAU;QACV,cAAc;AACf,KAAA,CAAC;AACF,IAAA,MAAM,UAAU,GAAG,iBAAiB,CAAC,YAAY,EAAE;QACjD,aAAa;QACb,SAAS;QACT,UAAU;QACV,WAAW;QACX,gBAAgB;AACjB,KAAA,CAAC;AACF,IAAA,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,cAAc,CAAC;QACpD,KAAK;QACL,EAAE,EAAE,SAAS,CAAC,EAAE;QAChB,UAAU;AACV,QAAA,YAAY,EAAE,QAAQ;AACvB,KAAA,CAAC;AACF,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,EAAE;AAC9C,QAAA,CAAC,MAAM,YAAY,CAAA,CAAE,GAAG,CAAC,CAAC,YAAY;AACvC,KAAA,CAAC;;;AAIF,IAAA,IAAI,OAAO,IACTA,GAAA,CAAC,cAAc,IAAC,GAAG,EAAE,GAAG,EAAA,GAAM,SAAS,EAAE,EAAE,EAAE,SAAS,EAAA,CAAI,CAC3D;IAED,IAAI,UAAU,EAAE;QACd,OAAO,IACLA,GAAA,CAAC,OAAO,EAAA,EACN,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,gBAAgB,EAAA,QAAA,EAE1B,OAAO,EAAA,CACA,CACX;IACH;AAEA,IAAA,MAAM,SAAS,GAAG,OAAO,GAAGA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAE,SAAS,YAAG,OAAO,EAAA,CAAK,GAAG,IAAI;IAEzE,IAAI,QAAQ,EAAE;AACZ,QAAA,QACEC,IAAA,CAAC,KAAK,EAAA,EACJ,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,cAAc,EAAA,QAAA,EAAA,CAExB,OAAO,EACP,SAAS,CAAA,EAAA,CACJ;IAEZ;AAEA,IAAA,QACEA,IAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAA,CACG,OAAO,EACP,SAAS,CAAA,EAAA,CACT;AAEP,CAAC;AAGH,UAAU,CAAC,WAAW,GAAG,YAAY;;"}
|