@allxsmith/bestax-bulma 5.54.0 → 5.55.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/Command.js +22 -22
- package/dist/esm/components/Command.js.map +1 -1
- package/dist/esm/components/DataTable.js +215 -0
- package/dist/esm/components/DataTable.js.map +1 -0
- package/dist/esm/components/useDataTable.js +482 -0
- package/dist/esm/components/useDataTable.js.map +1 -0
- package/dist/esm/elements/ColorSwatch.js +49 -0
- package/dist/esm/elements/ColorSwatch.js.map +1 -0
- package/dist/esm/elements/RingProgress.js +3 -3
- package/dist/esm/elements/Td.js +4 -2
- package/dist/esm/elements/Td.js.map +1 -1
- package/dist/esm/elements/Th.js +13 -5
- package/dist/esm/elements/Th.js.map +1 -1
- package/dist/esm/elements/Tr.js.map +1 -1
- package/dist/esm/form/ColorPicker.js +540 -0
- package/dist/esm/form/ColorPicker.js.map +1 -0
- package/dist/esm/form/Combobox.js +18 -18
- package/dist/esm/form/Combobox.js.map +1 -1
- package/dist/esm/form/Dropzone.js +524 -0
- package/dist/esm/form/Dropzone.js.map +1 -0
- package/dist/esm/form/File.js.map +1 -1
- package/dist/esm/form/_colorInternals/colorMath.js +292 -0
- package/dist/esm/form/_colorInternals/colorMath.js.map +1 -0
- package/dist/esm/form/_colorInternals/pickerState.js +160 -0
- package/dist/esm/form/_colorInternals/pickerState.js.map +1 -0
- package/dist/esm/helpers/statusRegion.js +3 -3
- package/dist/esm/helpers/statusRegion.js.map +1 -1
- package/dist/esm/helpers/useFocusTrap.js +2 -2
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +2986 -796
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +5 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/types/components/DataTable.d.ts +120 -0
- package/dist/types/components/useDataTable.d.ts +445 -0
- package/dist/types/elements/ColorSwatch.d.ts +54 -0
- package/dist/types/elements/Td.d.ts +9 -1
- package/dist/types/elements/Th.d.ts +14 -2
- package/dist/types/elements/Tr.d.ts +10 -1
- package/dist/types/form/ColorPicker.d.ts +266 -0
- package/dist/types/form/Dropzone.d.ts +138 -0
- package/dist/types/form/File.d.ts +2 -0
- package/dist/types/form/_colorInternals/colorMath.d.ts +63 -0
- package/dist/types/form/_colorInternals/pickerState.d.ts +62 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types-cjs/components/DataTable.d.ts +120 -0
- package/dist/types-cjs/components/useDataTable.d.ts +445 -0
- package/dist/types-cjs/elements/ColorSwatch.d.ts +54 -0
- package/dist/types-cjs/elements/Td.d.ts +9 -1
- package/dist/types-cjs/elements/Th.d.ts +14 -2
- package/dist/types-cjs/elements/Tr.d.ts +10 -1
- package/dist/types-cjs/form/ColorPicker.d.ts +266 -0
- package/dist/types-cjs/form/Dropzone.d.ts +138 -0
- package/dist/types-cjs/form/File.d.ts +2 -0
- package/dist/types-cjs/form/_colorInternals/colorMath.d.ts +63 -0
- package/dist/types-cjs/form/_colorInternals/pickerState.d.ts +62 -0
- 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/components/_datatable.scss +152 -0
- package/src/scss/components/_index.scss +1 -0
- package/src/scss/elements/_colorswatch.scss +100 -0
- package/src/scss/elements/_index.scss +1 -0
- package/src/scss/form/_checkbox.scss +53 -0
- package/src/scss/form/_colorpicker.scss +354 -0
- package/src/scss/form/_dropzone.scss +233 -0
- package/src/scss/form/_file.scss +29 -1
- package/src/scss/form/_index.scss +2 -0
package/dist/index.esm.js
CHANGED
|
@@ -33,6 +33,7 @@ export { Reveal } from './esm/components/Reveal.js';
|
|
|
33
33
|
export { TreeView, TreeViewItem } from './esm/components/TreeView.js';
|
|
34
34
|
export { ScrollArea } from './esm/components/ScrollArea.js';
|
|
35
35
|
export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from './esm/components/Command.js';
|
|
36
|
+
export { DataTable } from './esm/components/DataTable.js';
|
|
36
37
|
export { Block } from './esm/elements/Block.js';
|
|
37
38
|
export { Box } from './esm/elements/Box.js';
|
|
38
39
|
export { Button } from './esm/elements/Button.js';
|
|
@@ -40,6 +41,7 @@ export { Buttons } from './esm/elements/Buttons.js';
|
|
|
40
41
|
export { LinkButton } from './esm/elements/LinkButton.js';
|
|
41
42
|
export { ToggleButton } from './esm/elements/ToggleButton.js';
|
|
42
43
|
export { Code } from './esm/elements/Code.js';
|
|
44
|
+
export { ColorSwatch } from './esm/elements/ColorSwatch.js';
|
|
43
45
|
export { Content } from './esm/elements/Content.js';
|
|
44
46
|
export { Delete } from './esm/elements/Delete.js';
|
|
45
47
|
export { DescriptionList, DescriptionListItem, DescriptionListLabel, DescriptionListValue } from './esm/elements/DescriptionList.js';
|
|
@@ -78,6 +80,7 @@ export { Checkbox, checkboxColors, checkboxSizes } from './esm/form/Checkbox.js'
|
|
|
78
80
|
export { CheckboxCard } from './esm/form/CheckboxCard.js';
|
|
79
81
|
export { Checkboxes } from './esm/form/Checkboxes.js';
|
|
80
82
|
export { Control } from './esm/form/Control.js';
|
|
83
|
+
export { Dropzone } from './esm/form/Dropzone.js';
|
|
81
84
|
export { Field, FieldBody, FieldLabel } from './esm/form/Field.js';
|
|
82
85
|
export { Fieldset } from './esm/form/Fieldset.js';
|
|
83
86
|
export { File } from './esm/form/File.js';
|
|
@@ -92,6 +95,7 @@ export { Rate } from './esm/form/Rate.js';
|
|
|
92
95
|
export { Autocomplete } from './esm/form/Autocomplete.js';
|
|
93
96
|
export { Combobox, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxList, ComboboxMenu } from './esm/form/Combobox.js';
|
|
94
97
|
export { TagInput, Taginput } from './esm/form/Taginput.js';
|
|
98
|
+
export { ColorPicker, ColorPickerAlphaSlider, ColorPickerArea, ColorPickerHueSlider, ColorPickerInput, ColorPickerSwatches } from './esm/form/ColorPicker.js';
|
|
95
99
|
export { InputBase } from './esm/form/InputBase.js';
|
|
96
100
|
export { SelectBase } from './esm/form/SelectBase.js';
|
|
97
101
|
export { TextAreaBase } from './esm/form/TextAreaBase.js';
|
|
@@ -127,6 +131,7 @@ export { Media, MediaContent, MediaLeft, MediaRight } from './esm/layout/Media.j
|
|
|
127
131
|
export { Section } from './esm/layout/Section.js';
|
|
128
132
|
export { Splitter, SplitterPane } from './esm/layout/Splitter.js';
|
|
129
133
|
export { useColorClasses, useColorStyles } from './esm/helpers/useColorClasses.js';
|
|
134
|
+
export { useDataTable } from './esm/components/useDataTable.js';
|
|
130
135
|
export { useFlexboxClasses } from './esm/helpers/useFlexboxClasses.js';
|
|
131
136
|
export { useOtherClasses } from './esm/helpers/useOtherClasses.js';
|
|
132
137
|
export { useSpacingClasses } from './esm/helpers/useSpacingClasses.js';
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { BulmaClassesProps } from '../helpers/useBulmaClasses.js';
|
|
3
|
+
import { TrProps } from '../elements/Tr.js';
|
|
4
|
+
import { type DataTableColumn, type DataTableModel, type DataTableStateOptions } from './useDataTable.js';
|
|
5
|
+
export { useDataTable } from './useDataTable.js';
|
|
6
|
+
export type { DataTableCellContext, DataTableCellProps, DataTableCheckboxProps, DataTableColumn, DataTableColumnMeta, DataTableFilters, DataTableHeaderCellProps, DataTableLabels, DataTableModel, DataTablePaginationProps, DataTableResolvedLabels, DataTableRowScope, DataTableSearchProps, DataTableSelectionMode, DataTableSort, DataTableSortButtonProps, DataTableSortDirection, DataTableState, DataTableStateOptions, UseDataTableOptions, } from './useDataTable.js';
|
|
7
|
+
/**
|
|
8
|
+
* Props for the DataTable component. The helper props, `className`, the
|
|
9
|
+
* `ref` and the other attributes go on the wrapper `<div>`, which holds the
|
|
10
|
+
* toolbar, the table and the pager. `aria-label` and `aria-labelledby` name
|
|
11
|
+
* the `<table>` itself.
|
|
12
|
+
*
|
|
13
|
+
* @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.
|
|
14
|
+
* @extraProp {string} [aria-labelledby] - The id of a visible heading that names the table, in place of a `caption`.
|
|
15
|
+
* @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the wrapper `<div>`.
|
|
16
|
+
*/
|
|
17
|
+
export interface DataTableProps<TRow> extends DataTableStateOptions<TRow>, Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
|
|
18
|
+
/**
|
|
19
|
+
* The columns, in the order they're shown. Required unless `table` is
|
|
20
|
+
* given. Keep the array the same from one render to the next, defined
|
|
21
|
+
* outside the component or in `useMemo`: a new one has every cell's text
|
|
22
|
+
* worked out again.
|
|
23
|
+
*/
|
|
24
|
+
columns?: DataTableColumn<TRow>[];
|
|
25
|
+
/** The rows, as records of your own. Required unless `table` is given. */
|
|
26
|
+
data?: TRow[];
|
|
27
|
+
/**
|
|
28
|
+
* A table made by `useDataTable`, rendered in place of one made from
|
|
29
|
+
* `columns`, `data` and the state props, which are then left unread. Use
|
|
30
|
+
* it to put a toolbar, a count or an export button elsewhere on the page.
|
|
31
|
+
*/
|
|
32
|
+
table?: DataTableModel<TRow>;
|
|
33
|
+
/**
|
|
34
|
+
* Names the table, as a visible `<caption>`. A table needs a name: this,
|
|
35
|
+
* `aria-label` or `aria-labelledby`.
|
|
36
|
+
*/
|
|
37
|
+
caption?: React.ReactNode;
|
|
38
|
+
/** Adds borders to all cells. */
|
|
39
|
+
isBordered?: boolean;
|
|
40
|
+
/** Adds zebra-striping to rows. */
|
|
41
|
+
isStriped?: boolean;
|
|
42
|
+
/** Makes the table more compact by cutting cell padding in half. */
|
|
43
|
+
isNarrow?: boolean;
|
|
44
|
+
/** Adds a hover effect on rows. */
|
|
45
|
+
isHoverable?: boolean;
|
|
46
|
+
/** Makes the table span the full width of its wrapper. */
|
|
47
|
+
isFullwidth?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Scrolls a table wider than its wrapper sideways, in a `ScrollArea`
|
|
50
|
+
* named after the table, which can be scrolled from the keyboard while it
|
|
51
|
+
* overflows.
|
|
52
|
+
*/
|
|
53
|
+
isResponsive?: boolean;
|
|
54
|
+
/** Shows a search field in the toolbar, labelled by `labels.search`. */
|
|
55
|
+
hasSearch?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* More of the toolbar, after the search field: buttons for the selected
|
|
58
|
+
* rows, a filter, a download. Given the table.
|
|
59
|
+
*/
|
|
60
|
+
toolbar?: (table: DataTableModel<TRow>) => React.ReactNode;
|
|
61
|
+
/**
|
|
62
|
+
* Shows a page of skeleton rows under the header in place of the rows,
|
|
63
|
+
* and marks the table busy. For data on its way, as from a server with
|
|
64
|
+
* `manual`.
|
|
65
|
+
*/
|
|
66
|
+
loading?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* What the table shows when it has no rows at all, in one cell across
|
|
69
|
+
* every column. A small `EmptyState` saying `labels.empty` by default. A
|
|
70
|
+
* title of your own sits under the heading the table does, so give it the
|
|
71
|
+
* next level down with `titleAs`.
|
|
72
|
+
*/
|
|
73
|
+
empty?: React.ReactNode;
|
|
74
|
+
/**
|
|
75
|
+
* What the table shows when the search and filters let no row through, in
|
|
76
|
+
* one cell across every column. A small `EmptyState` saying
|
|
77
|
+
* `labels.noResults` by default. A button that clears the search goes
|
|
78
|
+
* away with it, so send focus back to the search field when it's pressed.
|
|
79
|
+
*/
|
|
80
|
+
noResults?: React.ReactNode;
|
|
81
|
+
/**
|
|
82
|
+
* Props of your own for a row's `Tr`, such as a handler or a class. The
|
|
83
|
+
* table's own (`isSelected`) win. To wrap a row in a `ContextMenu`, build
|
|
84
|
+
* the table from `useDataTable`'s props instead.
|
|
85
|
+
*/
|
|
86
|
+
rowProps?: (row: TRow) => DataTableRowProps;
|
|
87
|
+
/** Additional CSS classes, on the wrapper `<div>`. */
|
|
88
|
+
className?: string;
|
|
89
|
+
}
|
|
90
|
+
/** What `rowProps` gives a row's `Tr`: any of its props but the ones the table sets. */
|
|
91
|
+
export type DataTableRowProps = Omit<TrProps, 'isSelected' | 'children'>;
|
|
92
|
+
/** The type of `DataTable`, generic in the row. */
|
|
93
|
+
export type DataTableComponent = (<TRow>(props: DataTableProps<TRow> & React.RefAttributes<HTMLDivElement>) => React.ReactElement | null) & {
|
|
94
|
+
displayName?: string;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* The `DataTable` component is a table of records that people can sort,
|
|
98
|
+
* search, page through and select rows from, rendered with bestax's own
|
|
99
|
+
* `Table` parts, `Checkbox` and `Pagination`.
|
|
100
|
+
*
|
|
101
|
+
* It's a native table, as in the WAI-ARIA Authoring Practices' sortable
|
|
102
|
+
* table: a sortable header holds a button, the sorted one carries
|
|
103
|
+
* `aria-sort`, and each row's checkbox is named for the row. It runs on
|
|
104
|
+
* `useDataTable`, which custom markup can use too.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* <DataTable
|
|
108
|
+
* caption="Users"
|
|
109
|
+
* columns={[
|
|
110
|
+
* { id: 'name', header: 'Name', sortable: true, isRowHeader: true },
|
|
111
|
+
* { id: 'role', header: 'Role', sortable: true },
|
|
112
|
+
* ]}
|
|
113
|
+
* data={users}
|
|
114
|
+
* selectionMode="multiple"
|
|
115
|
+
* pageSize={10}
|
|
116
|
+
* hasSearch
|
|
117
|
+
* />
|
|
118
|
+
*/
|
|
119
|
+
export declare const DataTable: DataTableComponent;
|
|
120
|
+
export default DataTable;
|
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { TableAlignment } from '../elements/tableAlignment.js';
|
|
3
|
+
/**
|
|
4
|
+
* Carries a row type and adds nothing, so `DataTableColumnMeta` can take the
|
|
5
|
+
* row type for the fields an add-on merges in while it has none of its own.
|
|
6
|
+
*/
|
|
7
|
+
type CarriesRow<TRow> = {
|
|
8
|
+
[K in never]?: TRow;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Options of its own an add-on gives a column, read from the column's
|
|
12
|
+
* `meta`. Empty in bestax: an add-on, such as a spreadsheet exporter, adds
|
|
13
|
+
* its fields by declaration merging, and every column then takes them. Every
|
|
14
|
+
* declaration of it names the row type the same way, `TRow`.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* declare module '@allxsmith/bestax-bulma' {
|
|
18
|
+
* interface DataTableColumnMeta<TRow> {
|
|
19
|
+
* exportValue?: (row: TRow) => string | number;
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
*/
|
|
23
|
+
export interface DataTableColumnMeta<TRow = unknown> extends CarriesRow<TRow> {
|
|
24
|
+
}
|
|
25
|
+
/** What a column's `cell` is given beside the row. */
|
|
26
|
+
export interface DataTableCellContext {
|
|
27
|
+
/** The column's raw value for the row, from its `accessor`. */
|
|
28
|
+
value: unknown;
|
|
29
|
+
/** The column's text for the row, from its `format`. */
|
|
30
|
+
text: string;
|
|
31
|
+
/** The row's id, from `getRowId`. */
|
|
32
|
+
rowId: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* One column of a DataTable. A column keeps three things apart: its raw
|
|
36
|
+
* value (`accessor`), which sorting and `filterFn` read; its text
|
|
37
|
+
* (`format`), which the cell shows, the search matches and an export
|
|
38
|
+
* writes; and its rich content (`cell`), which only the screen sees.
|
|
39
|
+
*/
|
|
40
|
+
export interface DataTableColumn<TRow> {
|
|
41
|
+
/**
|
|
42
|
+
* Names the column for good: the sort, the filters and an export refer to
|
|
43
|
+
* it by this id. Unique within the table, and stable across renders.
|
|
44
|
+
*/
|
|
45
|
+
id: string;
|
|
46
|
+
/**
|
|
47
|
+
* The column's name, as text: the header, the sort button's name, the
|
|
48
|
+
* row checkboxes' names when it's the row header, and the header an
|
|
49
|
+
* export writes.
|
|
50
|
+
*/
|
|
51
|
+
header: string;
|
|
52
|
+
/**
|
|
53
|
+
* The raw value, for sorting and filtering: a key of the row, or a
|
|
54
|
+
* function of it. Left out, it's the row's property named `id`.
|
|
55
|
+
*/
|
|
56
|
+
accessor?: keyof TRow | ((row: TRow) => unknown);
|
|
57
|
+
/**
|
|
58
|
+
* The text for the value: what the cell shows when there's no `cell`, what
|
|
59
|
+
* the search matches, and what an export writes. Left out, it's the value
|
|
60
|
+
* as a string, and nothing for `null` or `undefined`. Give one for
|
|
61
|
+
* numbers and dates you want written a certain way.
|
|
62
|
+
*/
|
|
63
|
+
format?: (value: unknown, row: TRow) => string;
|
|
64
|
+
/**
|
|
65
|
+
* Rich content for the cell, such as a tag or a link. Only the screen
|
|
66
|
+
* reads it: sorting, the search and an export use the value and its text.
|
|
67
|
+
*/
|
|
68
|
+
cell?: (row: TRow, context: DataTableCellContext) => React.ReactNode;
|
|
69
|
+
/**
|
|
70
|
+
* Makes the header a button that sorts by this column: ascending, then
|
|
71
|
+
* descending, then unsorted.
|
|
72
|
+
*/
|
|
73
|
+
sortable?: boolean;
|
|
74
|
+
/** Sorts descending on the first press, for a column read from the top, such as a score. */
|
|
75
|
+
sortDescFirst?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Compares two rows for an ascending sort, returning a negative number,
|
|
78
|
+
* zero or a positive one. Descending reverses it. Without it, numbers,
|
|
79
|
+
* dates and booleans compare by value, anything else by its text in the
|
|
80
|
+
* `LocaleProvider`'s locale with numbers inside it read as numbers ("Item
|
|
81
|
+
* 9" before "Item 10"), and an empty value goes last either way.
|
|
82
|
+
*/
|
|
83
|
+
sortFn?: (a: TRow, b: TRow) => number;
|
|
84
|
+
/**
|
|
85
|
+
* Whether the column takes part in filtering: the search matches its
|
|
86
|
+
* text, and `filters` can hold a value for it. `false` leaves it out of
|
|
87
|
+
* both, as for a column of actions.
|
|
88
|
+
*/
|
|
89
|
+
filterable?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Decides whether a row passes this column's value in `filters`. Without
|
|
92
|
+
* it, the column's text has to contain the value's text, compared as the
|
|
93
|
+
* search compares.
|
|
94
|
+
*/
|
|
95
|
+
filterFn?: (row: TRow, filterValue: unknown) => boolean;
|
|
96
|
+
/** Aligns the header and the cells (`isAligned` on `Th` and `Td`). */
|
|
97
|
+
align?: TableAlignment;
|
|
98
|
+
/** The column's width, on its header cell: a number is pixels, a string any CSS length. */
|
|
99
|
+
width?: string | number;
|
|
100
|
+
/**
|
|
101
|
+
* Renders this column's cells as row headers (`th scope="row"`), which a
|
|
102
|
+
* screen reader reads out with the other cells of the row. The row's
|
|
103
|
+
* checkbox is named from it. Mark one column, usually the first.
|
|
104
|
+
*/
|
|
105
|
+
isRowHeader?: boolean;
|
|
106
|
+
/** Options of an add-on's own, as `DataTableColumnMeta` declares them. */
|
|
107
|
+
meta?: DataTableColumnMeta<TRow>;
|
|
108
|
+
}
|
|
109
|
+
/** The direction of a sort, in `aria-sort`'s words. */
|
|
110
|
+
export type DataTableSortDirection = 'ascending' | 'descending';
|
|
111
|
+
/** One column a DataTable sorts by. */
|
|
112
|
+
export interface DataTableSort {
|
|
113
|
+
/** The column's `id`. */
|
|
114
|
+
id: string;
|
|
115
|
+
/** Which way it sorts. */
|
|
116
|
+
direction: DataTableSortDirection;
|
|
117
|
+
}
|
|
118
|
+
/** The values per column `filters` holds, keyed by column `id`. */
|
|
119
|
+
export type DataTableFilters = Record<string, unknown>;
|
|
120
|
+
/**
|
|
121
|
+
* Which of a table's rows to read: `all` of `data`, `filtered` (the ones the
|
|
122
|
+
* search and the filters let through, from every page), the `page` shown,
|
|
123
|
+
* or the `selected` ones the filters let through. Each comes in the order
|
|
124
|
+
* the table shows them.
|
|
125
|
+
*/
|
|
126
|
+
export type DataTableRowScope = 'all' | 'filtered' | 'page' | 'selected';
|
|
127
|
+
/** Whether a DataTable has row checkboxes. */
|
|
128
|
+
export type DataTableSelectionMode = 'none' | 'multiple';
|
|
129
|
+
/**
|
|
130
|
+
* The words a DataTable writes. Each is English unless you give your own,
|
|
131
|
+
* and the numbers in the default messages are written in the
|
|
132
|
+
* `LocaleProvider`'s locale.
|
|
133
|
+
*/
|
|
134
|
+
export interface DataTableLabels {
|
|
135
|
+
/**
|
|
136
|
+
* The header checkbox's name. "Select all rows", or "Select all rows on
|
|
137
|
+
* this page" when there's more than one page, since it then covers the
|
|
138
|
+
* page shown.
|
|
139
|
+
*/
|
|
140
|
+
selectAll?: string;
|
|
141
|
+
/** A row checkbox's name, from the row's label (`label => 'Select ' + label`). */
|
|
142
|
+
selectRow?: (rowLabel: string) => string;
|
|
143
|
+
/**
|
|
144
|
+
* Says that headers with buttons sort: hidden at the end of the caption,
|
|
145
|
+
* after a comma, or as a hidden caption of its own. "column headers with
|
|
146
|
+
* buttons are sortable".
|
|
147
|
+
*/
|
|
148
|
+
sortHint?: string;
|
|
149
|
+
/** The search field's label. "Search". */
|
|
150
|
+
search?: string;
|
|
151
|
+
/** Announced after the search or a filter changes ("12 rows match"). */
|
|
152
|
+
results?: (count: number) => string;
|
|
153
|
+
/** Announced after the page changes ("Showing 11 to 20 of 57"). */
|
|
154
|
+
pageRange?: (first: number, last: number, total: number) => string;
|
|
155
|
+
/** Announced while `loading`, once the search, a filter or the page has changed. "Loading". */
|
|
156
|
+
loading?: string;
|
|
157
|
+
/**
|
|
158
|
+
* The pager's name. "{the table's name} pages" when the table is named by
|
|
159
|
+
* `aria-label` or a text `caption`, so two tables' pagers have different
|
|
160
|
+
* names, else `Pagination`'s own.
|
|
161
|
+
*/
|
|
162
|
+
pagination?: string;
|
|
163
|
+
/** What the table shows with no rows at all. "No rows to show." */
|
|
164
|
+
empty?: string;
|
|
165
|
+
/** What the table shows when the search and filters let no row through. "No rows match." */
|
|
166
|
+
noResults?: string;
|
|
167
|
+
}
|
|
168
|
+
/** The words a DataTable writes, with every default filled in. */
|
|
169
|
+
export interface DataTableResolvedLabels extends Required<Omit<DataTableLabels, 'pagination'>> {
|
|
170
|
+
/** The pager's name, when one was given. */
|
|
171
|
+
pagination?: string;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* The options `useDataTable` and `DataTable` share, beside the columns and
|
|
175
|
+
* the data. Each piece of state is yours when you pass its value (and its
|
|
176
|
+
* `on…Change`), or the table's own, starting from its `default…`.
|
|
177
|
+
*/
|
|
178
|
+
export interface DataTableStateOptions<TRow> {
|
|
179
|
+
/**
|
|
180
|
+
* A row's id, unique and stable, which the selection is a list of. Left
|
|
181
|
+
* out, it's the row's `id` property as a string. A development build
|
|
182
|
+
* warns about a missing or repeated id, and a row with none falls back to
|
|
183
|
+
* its index, which doesn't survive the data changing.
|
|
184
|
+
*/
|
|
185
|
+
getRowId?: (row: TRow, index: number) => string;
|
|
186
|
+
/**
|
|
187
|
+
* The sort when you hold it: an array of `{ id, direction }`, the first
|
|
188
|
+
* deciding and each next one breaking ties. The headers set one at a time.
|
|
189
|
+
*/
|
|
190
|
+
sort?: DataTableSort[];
|
|
191
|
+
/**
|
|
192
|
+
* The sort to start with when the table holds it. Text sorts in the
|
|
193
|
+
* `LocaleProvider`'s locale, or the runtime's own outside one, which can
|
|
194
|
+
* differ between a server and the browser, so put a table rendered on the
|
|
195
|
+
* server sorted inside a `LocaleProvider`.
|
|
196
|
+
*/
|
|
197
|
+
defaultSort?: DataTableSort[];
|
|
198
|
+
/** Called with the new sort when a header is pressed. */
|
|
199
|
+
onSortChange?: (sort: DataTableSort[]) => void;
|
|
200
|
+
/**
|
|
201
|
+
* `multiple` adds a checkbox to each row and a "select all" checkbox to the header.
|
|
202
|
+
*
|
|
203
|
+
* @defaultValue 'none'
|
|
204
|
+
*/
|
|
205
|
+
selectionMode?: DataTableSelectionMode;
|
|
206
|
+
/**
|
|
207
|
+
* The selected rows' ids when you hold them. They stay selected while the
|
|
208
|
+
* search, a filter or the page hides them.
|
|
209
|
+
*/
|
|
210
|
+
selected?: string[];
|
|
211
|
+
/** The rows selected to begin with, by id, when the table holds them. */
|
|
212
|
+
defaultSelected?: string[];
|
|
213
|
+
/** Called with every selected id after a checkbox changes. */
|
|
214
|
+
onSelectedChange?: (selected: string[]) => void;
|
|
215
|
+
/** Rows per page. Set, the table pages through `Pagination`; left out, it shows every row. */
|
|
216
|
+
pageSize?: number;
|
|
217
|
+
/**
|
|
218
|
+
* The page shown when you hold it, counting from 1. A page past the end
|
|
219
|
+
* shows the last.
|
|
220
|
+
*/
|
|
221
|
+
page?: number;
|
|
222
|
+
/**
|
|
223
|
+
* The page to start on when the table holds it.
|
|
224
|
+
*
|
|
225
|
+
* @defaultValue 1
|
|
226
|
+
*/
|
|
227
|
+
defaultPage?: number;
|
|
228
|
+
/**
|
|
229
|
+
* Called with the page chosen in the pager, and with 1 when the search or
|
|
230
|
+
* a filter changes through the table while the page held isn't 1, even
|
|
231
|
+
* when a page past the end shows as the last.
|
|
232
|
+
*/
|
|
233
|
+
onPageChange?: (page: number) => void;
|
|
234
|
+
/**
|
|
235
|
+
* The search when you hold it, matched against every filterable column's
|
|
236
|
+
* text: in the `LocaleProvider`'s locale, ignoring case and the accents
|
|
237
|
+
* the language ignores, or a case-insensitive substring outside one.
|
|
238
|
+
*/
|
|
239
|
+
search?: string;
|
|
240
|
+
/** The search to start with when the table holds it. */
|
|
241
|
+
defaultSearch?: string;
|
|
242
|
+
/** Called with the search as it changes through the table. */
|
|
243
|
+
onSearchChange?: (search: string) => void;
|
|
244
|
+
/**
|
|
245
|
+
* A value per column, by `id`, when you hold them. A row passes when every
|
|
246
|
+
* column with a value passes it: the column's `filterFn` if it has one,
|
|
247
|
+
* given the value as it is, or else the column's text has to contain the
|
|
248
|
+
* value's text, compared as the search compares. An array is a choice of
|
|
249
|
+
* values, as a multiple-choice filter gives, and passes a row whose text
|
|
250
|
+
* contains any of them. A value of `undefined`, `null`, `''` or an empty
|
|
251
|
+
* array is no filter.
|
|
252
|
+
*/
|
|
253
|
+
filters?: DataTableFilters;
|
|
254
|
+
/** The filters to start with when the table holds them. */
|
|
255
|
+
defaultFilters?: DataTableFilters;
|
|
256
|
+
/** Called with every filter value after one changes through the table. */
|
|
257
|
+
onFiltersChange?: (filters: DataTableFilters) => void;
|
|
258
|
+
/**
|
|
259
|
+
* Hands sorting, filtering and paging to a server: the table shows `data`
|
|
260
|
+
* as given, as the current page, and only reports the state as it
|
|
261
|
+
* changes.
|
|
262
|
+
*/
|
|
263
|
+
manual?: boolean;
|
|
264
|
+
/**
|
|
265
|
+
* With `manual`, how many rows match in all, which sets the page count and
|
|
266
|
+
* the announced count. Without it, the table counts the rows in `data`,
|
|
267
|
+
* which with a `pageSize` is one page and no pager, and a development
|
|
268
|
+
* build warns.
|
|
269
|
+
*/
|
|
270
|
+
rowCount?: number;
|
|
271
|
+
/** The words the table writes, in your app's language. */
|
|
272
|
+
labels?: DataTableLabels;
|
|
273
|
+
}
|
|
274
|
+
/** What `useDataTable` takes. */
|
|
275
|
+
export interface UseDataTableOptions<TRow> extends DataTableStateOptions<TRow> {
|
|
276
|
+
/**
|
|
277
|
+
* The columns, in the order they're shown. Keep the array the same from
|
|
278
|
+
* one render to the next, defined outside the component or in `useMemo`:
|
|
279
|
+
* a new one has every cell's text worked out again.
|
|
280
|
+
*/
|
|
281
|
+
columns: DataTableColumn<TRow>[];
|
|
282
|
+
/** The rows, as records of your own. */
|
|
283
|
+
data: TRow[];
|
|
284
|
+
}
|
|
285
|
+
/** The table's state, as it stands. */
|
|
286
|
+
export interface DataTableState {
|
|
287
|
+
/** The sort, the first entry deciding. */
|
|
288
|
+
sort: DataTableSort[];
|
|
289
|
+
/** The selected rows' ids. */
|
|
290
|
+
selected: string[];
|
|
291
|
+
/** The page shown, counting from 1. */
|
|
292
|
+
page: number;
|
|
293
|
+
/** Rows per page, or `undefined` when it doesn't page. */
|
|
294
|
+
pageSize: number | undefined;
|
|
295
|
+
/** The search. */
|
|
296
|
+
search: string;
|
|
297
|
+
/** The filter values, by column id. */
|
|
298
|
+
filters: DataTableFilters;
|
|
299
|
+
}
|
|
300
|
+
/** The props `getSortButtonProps` gives a header's `<button>`. */
|
|
301
|
+
export interface DataTableSortButtonProps {
|
|
302
|
+
type: 'button';
|
|
303
|
+
className: string;
|
|
304
|
+
onClick: () => void;
|
|
305
|
+
}
|
|
306
|
+
/** The props `getSearchProps` gives a search `<input>` or bestax `Input`. */
|
|
307
|
+
export interface DataTableSearchProps {
|
|
308
|
+
type: 'search';
|
|
309
|
+
value: string;
|
|
310
|
+
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
311
|
+
}
|
|
312
|
+
/** The props `getHeaderCellProps` gives a column's `Th`. */
|
|
313
|
+
export interface DataTableHeaderCellProps {
|
|
314
|
+
scope: 'col';
|
|
315
|
+
'aria-sort'?: DataTableSortDirection;
|
|
316
|
+
isAligned?: TableAlignment;
|
|
317
|
+
width?: string | number;
|
|
318
|
+
}
|
|
319
|
+
/** The props `getCellProps` gives a row's `Td`, or its `Th` for the row header. */
|
|
320
|
+
export interface DataTableCellProps {
|
|
321
|
+
scope?: 'row';
|
|
322
|
+
isAligned?: TableAlignment;
|
|
323
|
+
}
|
|
324
|
+
/** The props `getSelectAllProps` and `getSelectRowProps` give a `Checkbox`. */
|
|
325
|
+
export interface DataTableCheckboxProps {
|
|
326
|
+
'aria-label': string;
|
|
327
|
+
checked: boolean;
|
|
328
|
+
indeterminate?: boolean;
|
|
329
|
+
disabled?: boolean;
|
|
330
|
+
onChange: () => void;
|
|
331
|
+
}
|
|
332
|
+
/** The props `getPaginationProps` gives `Pagination`. */
|
|
333
|
+
export interface DataTablePaginationProps {
|
|
334
|
+
total: number;
|
|
335
|
+
current: number;
|
|
336
|
+
onPageChange: (page: number) => void;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* A table: what `useDataTable` returns, what `DataTable`'s `toolbar` is
|
|
340
|
+
* given, and what its `table` takes. It reads the rows and the state, changes
|
|
341
|
+
* the state, and hands out props for bestax's own `Th`, `Tr`, `Td`,
|
|
342
|
+
* `Checkbox` and `Pagination`, so markup of your own behaves as DataTable's
|
|
343
|
+
* does.
|
|
344
|
+
*/
|
|
345
|
+
export interface DataTableModel<TRow> {
|
|
346
|
+
/** The columns, in the order they're shown. */
|
|
347
|
+
columns: DataTableColumn<TRow>[];
|
|
348
|
+
/** The state as it stands. */
|
|
349
|
+
state: DataTableState;
|
|
350
|
+
/** Whether rows have checkboxes. */
|
|
351
|
+
selectionMode: DataTableSelectionMode;
|
|
352
|
+
/** Whether a server sorts, filters and pages (`manual`). */
|
|
353
|
+
manual: boolean;
|
|
354
|
+
/** How many rows the search and filters let through, or `rowCount` with `manual`. */
|
|
355
|
+
rowCount: number;
|
|
356
|
+
/** How many pages there are, at least 1. */
|
|
357
|
+
pageCount: number;
|
|
358
|
+
/** The words the table writes, with the defaults filled in. */
|
|
359
|
+
labels: DataTableResolvedLabels;
|
|
360
|
+
/** The rows in `scope` (`filtered` by default), in the order the table shows them. */
|
|
361
|
+
getRows: (scope?: DataTableRowScope) => TRow[];
|
|
362
|
+
/** A row's id. */
|
|
363
|
+
getRowId: (row: TRow) => string;
|
|
364
|
+
/** A column's raw value for a row, or `undefined` for a column it doesn't have. */
|
|
365
|
+
getValue: (row: TRow, columnId: string) => unknown;
|
|
366
|
+
/** A column's text for a row, or `''` for a column it doesn't have. */
|
|
367
|
+
getText: (row: TRow, columnId: string) => string;
|
|
368
|
+
/** What names a row: its row header's text, or its first column's. */
|
|
369
|
+
getRowLabel: (row: TRow) => string;
|
|
370
|
+
/** Whether a row is selected. */
|
|
371
|
+
isSelected: (row: TRow) => boolean;
|
|
372
|
+
/** Sets the sort. */
|
|
373
|
+
setSort: (sort: DataTableSort[]) => void;
|
|
374
|
+
/** Moves a column through its sort, as its header button does. */
|
|
375
|
+
toggleSort: (columnId: string) => void;
|
|
376
|
+
/** Sets the selected ids. */
|
|
377
|
+
setSelected: (selected: string[]) => void;
|
|
378
|
+
/**
|
|
379
|
+
* Selects a row, or clears it, or with no `selected` flips it. Called
|
|
380
|
+
* twice in one handler, the second call builds on the first while the
|
|
381
|
+
* table holds the selection. While you hold it, each call builds on the
|
|
382
|
+
* selection as rendered, so make several changes at once with
|
|
383
|
+
* `setSelected`.
|
|
384
|
+
*/
|
|
385
|
+
toggleRowSelected: (row: TRow, selected?: boolean) => void;
|
|
386
|
+
/**
|
|
387
|
+
* Selects every row on the page, or clears them, or with no `selected`
|
|
388
|
+
* does what the header checkbox does. It builds on earlier calls as
|
|
389
|
+
* `toggleRowSelected` does.
|
|
390
|
+
*/
|
|
391
|
+
togglePageSelected: (selected?: boolean) => void;
|
|
392
|
+
/** Goes to a page, counting from 1. */
|
|
393
|
+
setPage: (page: number) => void;
|
|
394
|
+
/**
|
|
395
|
+
* Sets the search, and goes back to page 1, calling `onPageChange` with 1
|
|
396
|
+
* unless the page held is 1 already.
|
|
397
|
+
*/
|
|
398
|
+
setSearch: (search: string) => void;
|
|
399
|
+
/**
|
|
400
|
+
* Sets one column's filter value, and goes back to page 1. Called twice in
|
|
401
|
+
* one handler, the second call builds on the first while the table holds
|
|
402
|
+
* the filters. While you hold them, each call builds on the filters as
|
|
403
|
+
* rendered, so set several at once with `setFilters`.
|
|
404
|
+
*/
|
|
405
|
+
setFilter: (columnId: string, value: unknown) => void;
|
|
406
|
+
/** Sets every filter value, and goes back to page 1, as `setSearch` does. */
|
|
407
|
+
setFilters: (filters: DataTableFilters) => void;
|
|
408
|
+
/** Props for a column's `Th`: its scope, its `aria-sort` while sorted, its alignment and width. */
|
|
409
|
+
getHeaderCellProps: (column: DataTableColumn<TRow>) => DataTableHeaderCellProps;
|
|
410
|
+
/** Props for the `<button>` in a sortable column's header. */
|
|
411
|
+
getSortButtonProps: (column: DataTableColumn<TRow>) => DataTableSortButtonProps;
|
|
412
|
+
/** Props for a row's `Tr`: Bulma's selected look while it's selected. */
|
|
413
|
+
getRowProps: (row: TRow) => {
|
|
414
|
+
isSelected: boolean;
|
|
415
|
+
};
|
|
416
|
+
/** Props for a row's cell in a column: its alignment, and `scope="row"` for the row header. */
|
|
417
|
+
getCellProps: (row: TRow, column: DataTableColumn<TRow>) => DataTableCellProps;
|
|
418
|
+
/** Props for the header's "select all" `Checkbox`, which covers the page shown. */
|
|
419
|
+
getSelectAllProps: () => DataTableCheckboxProps;
|
|
420
|
+
/** Props for a row's `Checkbox`, named for the row. */
|
|
421
|
+
getSelectRowProps: (row: TRow) => DataTableCheckboxProps;
|
|
422
|
+
/** Props for `Pagination`: the page count, the page and the handler. */
|
|
423
|
+
getPaginationProps: () => DataTablePaginationProps;
|
|
424
|
+
/** Props for a search field, bound to the search. */
|
|
425
|
+
getSearchProps: () => DataTableSearchProps;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Whether a search or a filter value is narrowing the rows. Used by
|
|
429
|
+
* DataTable to tell an empty table from one with no matches.
|
|
430
|
+
*/
|
|
431
|
+
export declare function isFiltering(search: string, filters: DataTableFilters): boolean;
|
|
432
|
+
/**
|
|
433
|
+
* `useDataTable` holds a table's sort, selection, page, search and filters,
|
|
434
|
+
* works out its rows, and hands out props for bestax's own table parts, so
|
|
435
|
+
* custom markup behaves as `DataTable` does. Pass its result to
|
|
436
|
+
* `<DataTable table={table} />` to render it with DataTable's own markup,
|
|
437
|
+
* with a toolbar or an export button elsewhere on the page.
|
|
438
|
+
*
|
|
439
|
+
* @example
|
|
440
|
+
* const table = useDataTable({ columns, data: users, pageSize: 10 });
|
|
441
|
+
*
|
|
442
|
+
* <DataTable table={table} caption="Users" hasSearch />
|
|
443
|
+
*/
|
|
444
|
+
export declare function useDataTable<TRow>(options: UseDataTableOptions<TRow>): DataTableModel<TRow>;
|
|
445
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { BulmaClassesProps, validColors } from '../helpers/useBulmaClasses.js';
|
|
3
|
+
declare const validColorSwatchSizes: readonly ["small", "medium", "large"];
|
|
4
|
+
/**
|
|
5
|
+
* Props for the ColorSwatch component. The helper props, the other
|
|
6
|
+
* attributes and the `ref` land on its `<span>`.
|
|
7
|
+
*
|
|
8
|
+
* @extraProp {React.Ref<HTMLSpanElement>} [ref] - Ref forwarded to the `<span>`.
|
|
9
|
+
* @extraProp {string} [aria-label] - Names the swatch in place of `label`.
|
|
10
|
+
* @extraProp {boolean} [aria-hidden] - Hides the swatch from assistive tech, for one beside text that already names the color.
|
|
11
|
+
*/
|
|
12
|
+
export interface ColorSwatchProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'color' | 'role'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
|
|
13
|
+
/** Additional CSS classes to apply. */
|
|
14
|
+
className?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The color it shows: any CSS color, such as `#1e6b99`,
|
|
17
|
+
* `hsl(202, 67%, 36%)` or `var(--bulma-primary)`. A see-through color
|
|
18
|
+
* shows a checkerboard behind it.
|
|
19
|
+
*/
|
|
20
|
+
color: string;
|
|
21
|
+
/**
|
|
22
|
+
* What the color is called, such as "Brand blue", read as the swatch's
|
|
23
|
+
* name in place of `color` as written. A `var()` reads as nothing useful,
|
|
24
|
+
* so a development build warns when one has no name.
|
|
25
|
+
*/
|
|
26
|
+
label?: string;
|
|
27
|
+
/** The swatch's size. */
|
|
28
|
+
size?: (typeof validColorSwatchSizes)[number];
|
|
29
|
+
/** Draws a circle in place of a rounded square. */
|
|
30
|
+
isRounded?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Drawn on the swatch, such as an icon. It's hidden from assistive tech,
|
|
33
|
+
* since the swatch is an image named by its label.
|
|
34
|
+
*/
|
|
35
|
+
children?: React.ReactNode;
|
|
36
|
+
/** Text color helper, the color of anything drawn on the swatch. */
|
|
37
|
+
textColor?: (typeof validColors)[number] | 'inherit' | 'current';
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The `ColorSwatch` component shows a color as a small chip, named by its label or by the color itself.
|
|
41
|
+
*
|
|
42
|
+
* It's an image to assistive tech, so the color is always there in words.
|
|
43
|
+
* In forced colors it keeps its color, edged in the system's text color.
|
|
44
|
+
*
|
|
45
|
+
* @function
|
|
46
|
+
* @param {ColorSwatchProps} props - Props for the ColorSwatch component.
|
|
47
|
+
* @param {React.Ref<HTMLSpanElement>} ref - Forwarded ref to the `<span>`.
|
|
48
|
+
* @returns {JSX.Element} The rendered swatch.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* <ColorSwatch color="#1e6b99" label="Brand blue" />
|
|
52
|
+
*/
|
|
53
|
+
export declare const ColorSwatch: React.ForwardRefExoticComponent<ColorSwatchProps & React.RefAttributes<HTMLSpanElement>>;
|
|
54
|
+
export default ColorSwatch;
|