@pathscale/ui 2.2.2 → 2.3.1
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/components/data-grid/DataGrid.css +247 -0
- package/dist/components/data-grid/DataGrid.generated.d.ts +41 -0
- package/dist/components/data-grid/DataGrid.generated.js +408 -0
- package/dist/components/data-grid/DataGrid.interactions.d.ts +11 -0
- package/dist/components/data-grid/DataGrid.interactions.js +25 -0
- package/dist/components/data-grid/DataGrid.recipe.d.ts +52 -0
- package/dist/components/data-grid/DataGrid.recipe.js +96 -0
- package/dist/components/data-grid/createDataGrid.d.ts +121 -0
- package/dist/components/data-grid/createDataGrid.js +252 -0
- package/dist/components/data-grid/index.d.ts +8 -0
- package/dist/components/data-grid/index.js +5 -0
- package/dist/components/spinner/Spinner.css +28 -9
- package/dist/components/spinner/Spinner.generated.d.ts +2 -2
- package/dist/components/spinner/Spinner.generated.js +1 -1
- package/dist/components/spinner/Spinner.recipe.d.ts +11 -10
- package/dist/components/spinner/Spinner.recipe.js +21 -19
- package/dist/components/table/ExpandToggle.generated.js +2 -2
- package/dist/components/table/InlineConfirm.generated.js +2 -2
- package/dist/components/table/MobileListView.generated.js +2 -2
- package/dist/components/table/SortIcon.generated.js +2 -2
- package/dist/components/table/Table.context.d.ts +23 -0
- package/dist/components/table/Table.context.js +22 -0
- package/dist/components/table/Table.d.ts +18 -0
- package/dist/components/table/Table.js +33 -0
- package/dist/components/table/Table.recipe.d.ts +130 -16
- package/dist/components/table/Table.recipe.js +420 -78
- package/dist/components/table/TableBody.generated.d.ts +6 -0
- package/dist/components/table/TableBody.generated.js +33 -0
- package/dist/components/table/TableCell.generated.d.ts +6 -0
- package/dist/components/table/TableCell.generated.js +33 -0
- package/dist/components/table/TableColumn.generated.d.ts +11 -0
- package/dist/components/table/TableColumn.generated.js +89 -0
- package/dist/components/table/TableColumnResizer.generated.d.ts +6 -0
- package/dist/components/table/TableColumnResizer.generated.js +42 -0
- package/dist/components/table/TableContent.generated.d.ts +10 -0
- package/dist/components/table/TableContent.generated.js +50 -0
- package/dist/components/table/TableExpandedRow.generated.d.ts +11 -0
- package/dist/components/table/TableExpandedRow.generated.js +50 -0
- package/dist/components/table/TableFooter.generated.d.ts +6 -0
- package/dist/components/table/TableFooter.generated.js +33 -0
- package/dist/components/table/TableHeader.generated.d.ts +6 -0
- package/dist/components/table/TableHeader.generated.js +33 -0
- package/dist/components/table/TableLoadMore.generated.d.ts +6 -0
- package/dist/components/table/TableLoadMore.generated.js +33 -0
- package/dist/components/table/TableLoadMoreContent.generated.d.ts +6 -0
- package/dist/components/table/TableLoadMoreContent.generated.js +33 -0
- package/dist/components/table/TablePageSize.generated.d.ts +13 -0
- package/dist/components/table/TablePageSize.generated.js +57 -0
- package/dist/components/table/TableResizableContainer.generated.d.ts +6 -0
- package/dist/components/table/TableResizableContainer.generated.js +33 -0
- package/dist/components/table/TableRoot.generated.d.ts +10 -0
- package/dist/components/table/TableRoot.generated.js +45 -0
- package/dist/components/table/TableRow.generated.d.ts +6 -0
- package/dist/components/table/TableRow.generated.js +33 -0
- package/dist/components/table/TableScrollContainer.generated.d.ts +6 -0
- package/dist/components/table/TableScrollContainer.generated.js +33 -0
- package/dist/components/table/VirtualSpacerRow.generated.js +2 -2
- package/dist/components/table/index.d.ts +43 -13
- package/dist/components/table/index.js +21 -5
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/layouts.manifest.json +4 -1
- package/dist/purge-manifest.json +496 -14
- package/dist/styles/themes/dark.css +3 -0
- package/dist/styles/themes/light.css +3 -0
- package/package.json +2 -2
- package/dist/components/table/Table.generated.d.ts +0 -94
- package/dist/components/table/Table.generated.js +0 -551
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { type Accessor, type JSX } from "solid-js";
|
|
2
|
+
/**
|
|
3
|
+
* The imperative grid model.
|
|
4
|
+
*
|
|
5
|
+
* Ported from vue3-ui's `DataGrid` class, keeping its verbs and their
|
|
6
|
+
* positional shapes so a call site moves across unchanged:
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* const grid = createDataGrid();
|
|
10
|
+
* grid.addColumn("id", "ID", "number");
|
|
11
|
+
* grid.addRow({ id: 1, firstName: "John" });
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* Three things are deliberately different, and all three are the same bug.
|
|
15
|
+
* In vue3 `searchColumn`, `sortByColumn` and `switchPage` each rewrite the
|
|
16
|
+
* single `rows` array from `originalRows`, so any two of them compose by
|
|
17
|
+
* destroying each other: paging after a search silently restores the rows the
|
|
18
|
+
* search removed. Here `rows` is the source and everything downstream is
|
|
19
|
+
* derived — `filteredRows` -> `sortedRows` -> `pageRows` — so the three
|
|
20
|
+
* compose, and a search is no longer lost when the reader turns the page.
|
|
21
|
+
*
|
|
22
|
+
* Consequences of that, worth knowing before porting:
|
|
23
|
+
* - `searchColumn` accumulates. Two columns can filter at once; vue3 could
|
|
24
|
+
* only ever hold the last query. `resetFilters()` clears all of them.
|
|
25
|
+
* - `sortByColumn(name)` toggles and takes a direction rather than vue3's
|
|
26
|
+
* `ascendant: boolean`, because a bare `true` meaning "ascending" is the
|
|
27
|
+
* kind of parameter 2.2 spent the release removing.
|
|
28
|
+
* - `switchPage(page)` takes the page. vue3's read a mutable field.
|
|
29
|
+
* - `deleteRow(index)` indexes the source rows, not what is on screen.
|
|
30
|
+
*/
|
|
31
|
+
export type DataGridDataType = "string" | "number" | "boolean" | "date" | "custom";
|
|
32
|
+
export type DataGridRow = Record<string, unknown>;
|
|
33
|
+
export type DataGridSortDirection = "ascending" | "descending";
|
|
34
|
+
export type DataGridSort = {
|
|
35
|
+
column: string;
|
|
36
|
+
direction: DataGridSortDirection;
|
|
37
|
+
};
|
|
38
|
+
export type DataGridSelectionMode = "none" | "single" | "multiple";
|
|
39
|
+
export type DataGridCellContext<Row extends DataGridRow = DataGridRow> = {
|
|
40
|
+
value: unknown;
|
|
41
|
+
row: Row;
|
|
42
|
+
column: DataGridColumn<Row>;
|
|
43
|
+
index: number;
|
|
44
|
+
};
|
|
45
|
+
export type DataGridColumn<Row extends DataGridRow = DataGridRow> = {
|
|
46
|
+
/** Key into the row. */
|
|
47
|
+
name: string;
|
|
48
|
+
/** Header text. vue3 called this `caption`, which collides with `<caption>`. */
|
|
49
|
+
label: string;
|
|
50
|
+
dataType: DataGridDataType;
|
|
51
|
+
visible: boolean;
|
|
52
|
+
sortable: boolean;
|
|
53
|
+
searchable: boolean;
|
|
54
|
+
sticky: boolean;
|
|
55
|
+
width?: string;
|
|
56
|
+
align?: "start" | "center" | "end";
|
|
57
|
+
/** Required in practice for `dataType: "custom"`; nothing else reads a custom cell. */
|
|
58
|
+
render?: (context: DataGridCellContext<Row>) => JSX.Element;
|
|
59
|
+
/** Overrides the dataType's ordering. Receives the raw cell values. */
|
|
60
|
+
compare?: (a: unknown, b: unknown) => number;
|
|
61
|
+
};
|
|
62
|
+
export type DataGridColumnOptions<Row extends DataGridRow = DataGridRow> = Partial<Omit<DataGridColumn<Row>, "name" | "label" | "dataType">>;
|
|
63
|
+
export type CreateDataGridOptions<Row extends DataGridRow = DataGridRow> = {
|
|
64
|
+
columns?: readonly DataGridColumn<Row>[];
|
|
65
|
+
rows?: readonly Row[];
|
|
66
|
+
/** Stable identity for selection and keyed rendering. Defaults to `row.id`, then the index. */
|
|
67
|
+
getRowId?: (row: Row, index: number) => string;
|
|
68
|
+
/** Omit for no pagination. There is no separate `pagination` flag to disagree with it. */
|
|
69
|
+
pageSize?: number;
|
|
70
|
+
/** Omit for no checkbox column. Likewise no `checkable` flag. */
|
|
71
|
+
selection?: DataGridSelectionMode;
|
|
72
|
+
sort?: DataGridSort | null;
|
|
73
|
+
groupBy?: string | null;
|
|
74
|
+
/** Defaults for columns added later. */
|
|
75
|
+
sortable?: boolean;
|
|
76
|
+
searchable?: boolean;
|
|
77
|
+
};
|
|
78
|
+
export type DataGridModel<Row extends DataGridRow = DataGridRow> = {
|
|
79
|
+
addColumn(name: string, label: string, dataType?: DataGridDataType, options?: DataGridColumnOptions<Row>): void;
|
|
80
|
+
removeColumn(name: string): void;
|
|
81
|
+
addRow(row: Row, index?: number): void;
|
|
82
|
+
deleteRow(index: number): void;
|
|
83
|
+
setRows(rows: readonly Row[]): void;
|
|
84
|
+
columns: Accessor<DataGridColumn<Row>[]>;
|
|
85
|
+
visibleColumns: Accessor<DataGridColumn<Row>[]>;
|
|
86
|
+
columnsByName: Accessor<Record<string, DataGridColumn<Row>>>;
|
|
87
|
+
toggleColumn(name: string, visible?: boolean): void;
|
|
88
|
+
rows: Accessor<Row[]>;
|
|
89
|
+
filteredRows: Accessor<Row[]>;
|
|
90
|
+
sortedRows: Accessor<Row[]>;
|
|
91
|
+
pageRows: Accessor<Row[]>;
|
|
92
|
+
rowId(row: Row, index: number): string;
|
|
93
|
+
sort: Accessor<DataGridSort | null>;
|
|
94
|
+
setSort(sort: DataGridSort | null): void;
|
|
95
|
+
sortByColumn(name: string, direction?: DataGridSortDirection): void;
|
|
96
|
+
queries: Accessor<Record<string, string>>;
|
|
97
|
+
searchColumn(name: string, query: string): void;
|
|
98
|
+
resetFilters(): void;
|
|
99
|
+
filterRows(name: string, value: unknown): Row[];
|
|
100
|
+
page: Accessor<number>;
|
|
101
|
+
pageSize: Accessor<number>;
|
|
102
|
+
pageCount: Accessor<number>;
|
|
103
|
+
total: Accessor<number>;
|
|
104
|
+
switchPage(page: number): void;
|
|
105
|
+
setPageSize(size: number): void;
|
|
106
|
+
selectionMode: Accessor<DataGridSelectionMode>;
|
|
107
|
+
selectedIds: Accessor<ReadonlySet<string>>;
|
|
108
|
+
selectedRows: Accessor<Row[]>;
|
|
109
|
+
isSelected(row: Row, index: number): boolean;
|
|
110
|
+
toggleCheck(row: Row, index: number, selected?: boolean): void;
|
|
111
|
+
toggleCheckAll(selected: boolean): void;
|
|
112
|
+
groupBy: Accessor<string | null>;
|
|
113
|
+
setGroupBy(name: string | null): void;
|
|
114
|
+
/** Distinct values in a column, in first-seen order. vue3 returned an unordered Set. */
|
|
115
|
+
groups(name: string): unknown[];
|
|
116
|
+
groupedRows: Accessor<{
|
|
117
|
+
value: unknown;
|
|
118
|
+
rows: Row[];
|
|
119
|
+
}[]>;
|
|
120
|
+
};
|
|
121
|
+
export declare function createDataGrid<Row extends DataGridRow = DataGridRow>(options?: CreateDataGridOptions<Row>): DataGridModel<Row>;
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { createMemo, createSignal, getOwner } from "solid-js";
|
|
2
|
+
import { createStore, produce } from "solid-js/store";
|
|
3
|
+
const derive = (fn)=>getOwner() ? createMemo(fn) : fn;
|
|
4
|
+
const compareValues = (a, b, dataType)=>{
|
|
5
|
+
if (a === b) return 0;
|
|
6
|
+
if (null == a) return -1;
|
|
7
|
+
if (null == b) return 1;
|
|
8
|
+
if ("number" === dataType) return Number(a) - Number(b);
|
|
9
|
+
if ("boolean" === dataType) return Number(Boolean(a)) - Number(Boolean(b));
|
|
10
|
+
if ("date" === dataType) return new Date(a).getTime() - new Date(b).getTime();
|
|
11
|
+
return String(a).localeCompare(String(b));
|
|
12
|
+
};
|
|
13
|
+
const matches = (value, query)=>{
|
|
14
|
+
if (null == value) return false;
|
|
15
|
+
return String(value).toLowerCase().includes(query.toLowerCase());
|
|
16
|
+
};
|
|
17
|
+
function createDataGrid(options = {}) {
|
|
18
|
+
const columnDefaults = {
|
|
19
|
+
sortable: options.sortable ?? true,
|
|
20
|
+
searchable: options.searchable ?? false
|
|
21
|
+
};
|
|
22
|
+
const [columnStore, setColumnStore] = createStore({
|
|
23
|
+
items: [
|
|
24
|
+
...options.columns ?? []
|
|
25
|
+
]
|
|
26
|
+
});
|
|
27
|
+
const [rowStore, setRowStore] = createStore({
|
|
28
|
+
items: [
|
|
29
|
+
...options.rows ?? []
|
|
30
|
+
]
|
|
31
|
+
});
|
|
32
|
+
const [sort, writeSort] = createSignal(options.sort ?? null);
|
|
33
|
+
const [queries, setQueries] = createSignal({});
|
|
34
|
+
const [page, setPage] = createSignal(0);
|
|
35
|
+
const [pageSize, setPageSize] = createSignal(options.pageSize ?? 0);
|
|
36
|
+
const [selectedIds, setSelectedIds] = createSignal(new Set());
|
|
37
|
+
const [groupBy, setGroupBy] = createSignal(options.groupBy ?? null);
|
|
38
|
+
const selectionMode = ()=>options.selection ?? "none";
|
|
39
|
+
const identify = (row, index)=>{
|
|
40
|
+
if (options.getRowId) return options.getRowId(row, index);
|
|
41
|
+
const own = row.id;
|
|
42
|
+
return null == own ? String(index) : String(own);
|
|
43
|
+
};
|
|
44
|
+
const idByRow = derive(()=>{
|
|
45
|
+
const map = new Map();
|
|
46
|
+
rowStore.items.forEach((row, index)=>map.set(row, identify(row, index)));
|
|
47
|
+
return map;
|
|
48
|
+
});
|
|
49
|
+
const rowId = (row, index)=>idByRow().get(row) ?? identify(row, index);
|
|
50
|
+
const columns = derive(()=>columnStore.items);
|
|
51
|
+
const visibleColumns = derive(()=>columnStore.items.filter((column)=>column.visible));
|
|
52
|
+
const columnsByName = derive(()=>Object.fromEntries(columnStore.items.map((column)=>[
|
|
53
|
+
column.name,
|
|
54
|
+
column
|
|
55
|
+
])));
|
|
56
|
+
const rows = derive(()=>rowStore.items);
|
|
57
|
+
const filteredRows = derive(()=>{
|
|
58
|
+
const active = Object.entries(queries()).filter(([, query])=>query.length > 0);
|
|
59
|
+
if (0 === active.length) return rowStore.items;
|
|
60
|
+
return rowStore.items.filter((row)=>active.every(([name, query])=>matches(row[name], query)));
|
|
61
|
+
});
|
|
62
|
+
const sortedRows = derive(()=>{
|
|
63
|
+
const descriptor = sort();
|
|
64
|
+
if (!descriptor) return filteredRows();
|
|
65
|
+
const column = columnStore.items.find((item)=>item.name === descriptor.column);
|
|
66
|
+
if (!column) return filteredRows();
|
|
67
|
+
const sign = "ascending" === descriptor.direction ? 1 : -1;
|
|
68
|
+
const compare = column.compare ?? ((a, b)=>compareValues(a, b, column.dataType));
|
|
69
|
+
return [
|
|
70
|
+
...filteredRows()
|
|
71
|
+
].sort((a, b)=>sign * compare(a[column.name], b[column.name]));
|
|
72
|
+
});
|
|
73
|
+
const total = derive(()=>filteredRows().length);
|
|
74
|
+
const pageCount = derive(()=>{
|
|
75
|
+
const size = pageSize();
|
|
76
|
+
if (size <= 0) return 1;
|
|
77
|
+
return Math.max(1, Math.ceil(total() / size));
|
|
78
|
+
});
|
|
79
|
+
const pageRows = derive(()=>{
|
|
80
|
+
const size = pageSize();
|
|
81
|
+
if (size <= 0) return sortedRows();
|
|
82
|
+
const start = page() * size;
|
|
83
|
+
return sortedRows().slice(start, start + size);
|
|
84
|
+
});
|
|
85
|
+
const selectedRows = derive(()=>{
|
|
86
|
+
const ids = selectedIds();
|
|
87
|
+
return rowStore.items.filter((row, index)=>ids.has(rowId(row, index)));
|
|
88
|
+
});
|
|
89
|
+
const groupedRows = derive(()=>{
|
|
90
|
+
const name = groupBy();
|
|
91
|
+
if (!name) return [
|
|
92
|
+
{
|
|
93
|
+
value: void 0,
|
|
94
|
+
rows: pageRows()
|
|
95
|
+
}
|
|
96
|
+
];
|
|
97
|
+
const buckets = new Map();
|
|
98
|
+
for (const row of pageRows()){
|
|
99
|
+
const value = row[name];
|
|
100
|
+
const bucket = buckets.get(value);
|
|
101
|
+
if (bucket) bucket.push(row);
|
|
102
|
+
else buckets.set(value, [
|
|
103
|
+
row
|
|
104
|
+
]);
|
|
105
|
+
}
|
|
106
|
+
return [
|
|
107
|
+
...buckets
|
|
108
|
+
].map(([value, groupRows])=>({
|
|
109
|
+
value,
|
|
110
|
+
rows: groupRows
|
|
111
|
+
}));
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
addColumn (name, label, dataType = "string", columnOptions = {}) {
|
|
115
|
+
setColumnStore("items", produce((items)=>{
|
|
116
|
+
items.push({
|
|
117
|
+
name,
|
|
118
|
+
label,
|
|
119
|
+
dataType,
|
|
120
|
+
visible: true,
|
|
121
|
+
sticky: false,
|
|
122
|
+
...columnDefaults,
|
|
123
|
+
...columnOptions
|
|
124
|
+
});
|
|
125
|
+
}));
|
|
126
|
+
},
|
|
127
|
+
removeColumn (name) {
|
|
128
|
+
setColumnStore("items", (items)=>items.filter((column)=>column.name !== name));
|
|
129
|
+
},
|
|
130
|
+
addRow (row, index) {
|
|
131
|
+
setRowStore("items", produce((items)=>{
|
|
132
|
+
if (void 0 === index) items.push(row);
|
|
133
|
+
else items.splice(index, 0, row);
|
|
134
|
+
}));
|
|
135
|
+
},
|
|
136
|
+
deleteRow (index) {
|
|
137
|
+
setRowStore("items", produce((items)=>{
|
|
138
|
+
items.splice(index, 1);
|
|
139
|
+
}));
|
|
140
|
+
},
|
|
141
|
+
setRows (next) {
|
|
142
|
+
setRowStore("items", [
|
|
143
|
+
...next
|
|
144
|
+
]);
|
|
145
|
+
},
|
|
146
|
+
columns,
|
|
147
|
+
visibleColumns,
|
|
148
|
+
columnsByName,
|
|
149
|
+
toggleColumn (name, visible) {
|
|
150
|
+
setColumnStore("items", (items)=>items.map((column)=>column.name === name ? {
|
|
151
|
+
...column,
|
|
152
|
+
visible: visible ?? !column.visible
|
|
153
|
+
} : column));
|
|
154
|
+
},
|
|
155
|
+
rows,
|
|
156
|
+
filteredRows,
|
|
157
|
+
sortedRows,
|
|
158
|
+
pageRows,
|
|
159
|
+
rowId,
|
|
160
|
+
sort,
|
|
161
|
+
setSort (next) {
|
|
162
|
+
writeSort(next);
|
|
163
|
+
setPage(0);
|
|
164
|
+
},
|
|
165
|
+
sortByColumn (name, direction) {
|
|
166
|
+
const current = sort();
|
|
167
|
+
const apply = (next)=>{
|
|
168
|
+
writeSort(next);
|
|
169
|
+
setPage(0);
|
|
170
|
+
};
|
|
171
|
+
if (direction) return void apply({
|
|
172
|
+
column: name,
|
|
173
|
+
direction
|
|
174
|
+
});
|
|
175
|
+
if (!current || current.column !== name) return void apply({
|
|
176
|
+
column: name,
|
|
177
|
+
direction: "ascending"
|
|
178
|
+
});
|
|
179
|
+
apply("ascending" === current.direction ? {
|
|
180
|
+
column: name,
|
|
181
|
+
direction: "descending"
|
|
182
|
+
} : null);
|
|
183
|
+
},
|
|
184
|
+
queries,
|
|
185
|
+
searchColumn (name, query) {
|
|
186
|
+
setQueries((previous)=>({
|
|
187
|
+
...previous,
|
|
188
|
+
[name]: query
|
|
189
|
+
}));
|
|
190
|
+
setPage(0);
|
|
191
|
+
},
|
|
192
|
+
resetFilters () {
|
|
193
|
+
setQueries({});
|
|
194
|
+
setPage(0);
|
|
195
|
+
},
|
|
196
|
+
filterRows (name, value) {
|
|
197
|
+
return rowStore.items.filter((row)=>row[name] === value);
|
|
198
|
+
},
|
|
199
|
+
page,
|
|
200
|
+
pageSize,
|
|
201
|
+
pageCount,
|
|
202
|
+
total,
|
|
203
|
+
switchPage (next) {
|
|
204
|
+
setPage(Math.min(Math.max(next, 0), pageCount() - 1));
|
|
205
|
+
},
|
|
206
|
+
setPageSize (size) {
|
|
207
|
+
setPageSize(size);
|
|
208
|
+
setPage(0);
|
|
209
|
+
},
|
|
210
|
+
selectionMode,
|
|
211
|
+
selectedIds,
|
|
212
|
+
selectedRows,
|
|
213
|
+
isSelected (row, index) {
|
|
214
|
+
return selectedIds().has(rowId(row, index));
|
|
215
|
+
},
|
|
216
|
+
toggleCheck (row, index, selected) {
|
|
217
|
+
const id = rowId(row, index);
|
|
218
|
+
setSelectedIds((previous)=>{
|
|
219
|
+
const shouldSelect = selected ?? !previous.has(id);
|
|
220
|
+
if ("single" === selectionMode()) return shouldSelect ? new Set([
|
|
221
|
+
id
|
|
222
|
+
]) : new Set();
|
|
223
|
+
const next = new Set(previous);
|
|
224
|
+
if (shouldSelect) next.add(id);
|
|
225
|
+
else next.delete(id);
|
|
226
|
+
return next;
|
|
227
|
+
});
|
|
228
|
+
},
|
|
229
|
+
toggleCheckAll (selected) {
|
|
230
|
+
if (!selected) return void setSelectedIds(new Set());
|
|
231
|
+
setSelectedIds(new Set(pageRows().map((row, index)=>rowId(row, index))));
|
|
232
|
+
},
|
|
233
|
+
groupBy,
|
|
234
|
+
setGroupBy,
|
|
235
|
+
groups (name) {
|
|
236
|
+
const seen = [];
|
|
237
|
+
const known = new Set();
|
|
238
|
+
for (const row of rowStore.items){
|
|
239
|
+
const value = row[name];
|
|
240
|
+
if (null != value) {
|
|
241
|
+
if (!known.has(value)) {
|
|
242
|
+
known.add(value);
|
|
243
|
+
seen.push(value);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return seen;
|
|
248
|
+
},
|
|
249
|
+
groupedRows
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
export { createDataGrid };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { CreateDataGridOptions, DataGridCellContext, DataGridColumn, DataGridColumnOptions, DataGridDataType, DataGridModel, DataGridRow, DataGridSelectionMode, DataGridSort, DataGridSortDirection, } from "./createDataGrid";
|
|
2
|
+
export { createDataGrid } from "./createDataGrid";
|
|
3
|
+
export type { DataGridBorders, DataGridProps, DataGridSticky, DataGridStriping, } from "./DataGrid.generated";
|
|
4
|
+
import type { JSX } from "solid-js";
|
|
5
|
+
import type { DataGridProps as Props } from "./DataGrid.generated";
|
|
6
|
+
import type { DataGridRow as Row } from "./createDataGrid";
|
|
7
|
+
declare const DataGrid: <R extends Row = Row>(props: Props<R>) => JSX.Element;
|
|
8
|
+
export default DataGrid;
|
|
@@ -52,24 +52,43 @@
|
|
|
52
52
|
/* -------------------------------------------------------------------------------------------------
|
|
53
53
|
* Color variants
|
|
54
54
|
* -----------------------------------------------------------------------------------------------*/
|
|
55
|
-
|
|
55
|
+
/* `--flavor-` to match every other component, and the full set: the recipe
|
|
56
|
+
named six classes this file never defined, so half the values a caller
|
|
57
|
+
could pass rendered unflavoured. */
|
|
58
|
+
.spinner--flavor-current {
|
|
56
59
|
color: currentColor;
|
|
57
60
|
}
|
|
58
61
|
|
|
59
|
-
.spinner--
|
|
60
|
-
color: var(--color-
|
|
62
|
+
.spinner--flavor-neutral {
|
|
63
|
+
color: var(--color-neutral, currentColor);
|
|
61
64
|
}
|
|
62
65
|
|
|
63
|
-
.spinner--
|
|
64
|
-
color: var(--color-
|
|
66
|
+
.spinner--flavor-primary {
|
|
67
|
+
color: var(--color-primary, currentColor);
|
|
65
68
|
}
|
|
66
69
|
|
|
67
|
-
.spinner--
|
|
68
|
-
color: var(--color-
|
|
70
|
+
.spinner--flavor-secondary {
|
|
71
|
+
color: var(--color-secondary, currentColor);
|
|
69
72
|
}
|
|
70
73
|
|
|
71
|
-
.spinner--
|
|
72
|
-
color: var(--color-
|
|
74
|
+
.spinner--flavor-accent {
|
|
75
|
+
color: var(--color-accent, currentColor);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.spinner--flavor-info {
|
|
79
|
+
color: var(--color-info, currentColor);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.spinner--flavor-success {
|
|
83
|
+
color: var(--color-success, currentColor);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.spinner--flavor-warning {
|
|
87
|
+
color: var(--color-warning, currentColor);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.spinner--flavor-destructive {
|
|
91
|
+
color: var(--color-error, currentColor);
|
|
73
92
|
}
|
|
74
93
|
|
|
75
94
|
/* -------------------------------------------------------------------------------------------------
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Component as __LayoutComponent } from "solid-js";
|
|
2
2
|
import "./Spinner.css";
|
|
3
3
|
import { type JSX } from "solid-js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { Flavor, Size, UIBaseProps } from "../vocabulary";
|
|
5
5
|
export type SpinnerShape = "spinner" | "dots" | "ring" | "ball" | "bars" | "infinity";
|
|
6
6
|
export type SpinnerProps = Omit<JSX.HTMLAttributes<HTMLSpanElement>, "children"> & UIBaseProps & {
|
|
7
7
|
size?: Size;
|
|
8
|
-
|
|
8
|
+
flavor?: Flavor;
|
|
9
9
|
shape?: SpinnerShape;
|
|
10
10
|
label?: string;
|
|
11
11
|
};
|
|
@@ -3,7 +3,7 @@ import { defineComponent } from "solid-layouts/application-boundary";
|
|
|
3
3
|
import "./Spinner.css";
|
|
4
4
|
import { createUniqueId } from "solid-js";
|
|
5
5
|
import { spinner } from "./Spinner.recipe.js";
|
|
6
|
-
var _tmpl$ = /*#__PURE__*/ template('<svg aria-hidden=true data-slot=spinner-icon fill=none viewBox="0 0 24 24"><defs><linearGradient x1=50% x2=50% y1=5.271% y2=91.793%><stop offset=0% stop-
|
|
6
|
+
var _tmpl$ = /*#__PURE__*/ template('<svg aria-hidden=true data-slot=spinner-icon fill=none viewBox="0 0 24 24"><defs><linearGradient x1=50% x2=50% y1=5.271% y2=91.793%><stop offset=0% stop-color=currentColor></stop><stop offset=100% stop-color=currentColor stop-opacity=0.55></stop></linearGradient><linearGradient x1=50% x2=50% y1=15.24% y2=87.15%><stop offset=0% stop-color=currentColor stop-opacity=0></stop><stop offset=100% stop-color=currentColor stop-opacity=0.55></stop></linearGradient></defs><g fill=none><path d="M8.749.021a1.5 1.5 0 0 1 .497 2.958A7.5 7.5 0 0 0 3 10.375a7.5 7.5 0 0 0 7.5 7.5v3c-5.799 0-10.5-4.7-10.5-10.5C0 5.23 3.726.865 8.749.021"transform="translate(1.5 1.625)"></path><path d="M15.392 2.673a1.5 1.5 0 0 1 2.119-.115A10.48 10.48 0 0 1 21 10.375c0 5.8-4.701 10.5-10.5 10.5v-3a7.5 7.5 0 0 0 5.007-13.084a1.5 1.5 0 0 1-.115-2.118"transform="translate(1.5 1.625)">'), _tmpl$2 = /*#__PURE__*/ template("<span>");
|
|
7
7
|
const SpinnerSVG = ()=>{
|
|
8
8
|
const id = createUniqueId();
|
|
9
9
|
return (()=>{
|
|
@@ -20,15 +20,16 @@ export declare const spinner: import("solid-layouts").Recipe<{
|
|
|
20
20
|
readonly lg: "spinner--lg";
|
|
21
21
|
readonly xl: "spinner--xl";
|
|
22
22
|
};
|
|
23
|
-
readonly
|
|
24
|
-
readonly
|
|
25
|
-
readonly
|
|
26
|
-
readonly
|
|
27
|
-
readonly
|
|
28
|
-
readonly
|
|
29
|
-
readonly
|
|
30
|
-
readonly
|
|
31
|
-
readonly
|
|
23
|
+
readonly flavor: {
|
|
24
|
+
readonly current: "spinner--flavor-current";
|
|
25
|
+
readonly neutral: "spinner--flavor-neutral";
|
|
26
|
+
readonly primary: "spinner--flavor-primary";
|
|
27
|
+
readonly secondary: "spinner--flavor-secondary";
|
|
28
|
+
readonly accent: "spinner--flavor-accent";
|
|
29
|
+
readonly success: "spinner--flavor-success";
|
|
30
|
+
readonly warning: "spinner--flavor-warning";
|
|
31
|
+
readonly destructive: "spinner--flavor-destructive";
|
|
32
|
+
readonly info: "spinner--flavor-info";
|
|
32
33
|
};
|
|
33
34
|
readonly shape: {
|
|
34
35
|
readonly spinner: "spinner--spinner";
|
|
@@ -42,7 +43,7 @@ export declare const spinner: import("solid-layouts").Recipe<{
|
|
|
42
43
|
};
|
|
43
44
|
readonly defaults: {
|
|
44
45
|
readonly size: "md";
|
|
45
|
-
readonly
|
|
46
|
+
readonly flavor: "current";
|
|
46
47
|
readonly shape: "spinner";
|
|
47
48
|
readonly label: "Loading";
|
|
48
49
|
};
|
|
@@ -15,15 +15,16 @@ const spinner = recipe({
|
|
|
15
15
|
lg: "spinner--lg",
|
|
16
16
|
xl: "spinner--xl"
|
|
17
17
|
},
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
flavor: {
|
|
19
|
+
current: "spinner--flavor-current",
|
|
20
|
+
neutral: "spinner--flavor-neutral",
|
|
21
|
+
primary: "spinner--flavor-primary",
|
|
22
|
+
secondary: "spinner--flavor-secondary",
|
|
23
|
+
accent: "spinner--flavor-accent",
|
|
24
|
+
success: "spinner--flavor-success",
|
|
25
|
+
warning: "spinner--flavor-warning",
|
|
26
|
+
destructive: "spinner--flavor-destructive",
|
|
27
|
+
info: "spinner--flavor-info"
|
|
27
28
|
},
|
|
28
29
|
shape: {
|
|
29
30
|
spinner: "spinner--spinner",
|
|
@@ -37,7 +38,7 @@ const spinner = recipe({
|
|
|
37
38
|
},
|
|
38
39
|
defaults: {
|
|
39
40
|
size: "md",
|
|
40
|
-
|
|
41
|
+
flavor: "current",
|
|
41
42
|
shape: "spinner",
|
|
42
43
|
label: "Loading"
|
|
43
44
|
},
|
|
@@ -53,15 +54,16 @@ const spinner = recipe({
|
|
|
53
54
|
lg: "spinner--lg",
|
|
54
55
|
xl: "spinner--xl"
|
|
55
56
|
},
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
flavor: {
|
|
58
|
+
current: "spinner--flavor-current",
|
|
59
|
+
neutral: "spinner--flavor-neutral",
|
|
60
|
+
primary: "spinner--flavor-primary",
|
|
61
|
+
secondary: "spinner--flavor-secondary",
|
|
62
|
+
accent: "spinner--flavor-accent",
|
|
63
|
+
success: "spinner--flavor-success",
|
|
64
|
+
warning: "spinner--flavor-warning",
|
|
65
|
+
destructive: "spinner--flavor-destructive",
|
|
66
|
+
info: "spinner--flavor-info"
|
|
65
67
|
},
|
|
66
68
|
shape: {
|
|
67
69
|
spinner: "spinner--spinner",
|
|
@@ -3,7 +3,7 @@ import { defineComponent } from "solid-layouts/application-boundary";
|
|
|
3
3
|
import { Show, splitProps } from "solid-js";
|
|
4
4
|
import { twMerge } from "tailwind-merge";
|
|
5
5
|
import icon from "../icon/index.js";
|
|
6
|
-
import {
|
|
6
|
+
import { tableExpandToggleRecipe } from "./Table.recipe.js";
|
|
7
7
|
var _tmpl$ = /*#__PURE__*/ template("<button>");
|
|
8
8
|
const __solidLayoutExpandToggle = (_stable, p)=>{
|
|
9
9
|
const [local, rest] = splitProps(p, [
|
|
@@ -86,7 +86,7 @@ const __solidLayoutExpandToggle = (_stable, p)=>{
|
|
|
86
86
|
})();
|
|
87
87
|
};
|
|
88
88
|
const ExpandToggle = defineComponent({
|
|
89
|
-
recipe:
|
|
89
|
+
recipe: tableExpandToggleRecipe,
|
|
90
90
|
layout: __solidLayoutExpandToggle,
|
|
91
91
|
embedded: true
|
|
92
92
|
});
|
|
@@ -3,7 +3,7 @@ import { defineComponent } from "solid-layouts/application-boundary";
|
|
|
3
3
|
import { splitProps } from "solid-js";
|
|
4
4
|
import { twMerge } from "tailwind-merge";
|
|
5
5
|
import button_0 from "../button/index.js";
|
|
6
|
-
import {
|
|
6
|
+
import { tableInlineConfirmRecipe } from "./Table.recipe.js";
|
|
7
7
|
var _tmpl$ = /*#__PURE__*/ template('<div><span class="text-sm text-base-content/70"data-slot=table-inline-confirm-prompt></span><div class="inline-flex items-center gap-2"data-slot=table-inline-confirm-actions>');
|
|
8
8
|
const toButtonFlavor = (variant)=>{
|
|
9
9
|
if ("danger" === variant) return "destructive";
|
|
@@ -74,7 +74,7 @@ const __solidLayoutInlineConfirm = (_stable, p)=>{
|
|
|
74
74
|
})();
|
|
75
75
|
};
|
|
76
76
|
const InlineConfirm = defineComponent({
|
|
77
|
-
recipe:
|
|
77
|
+
recipe: tableInlineConfirmRecipe,
|
|
78
78
|
layout: __solidLayoutInlineConfirm,
|
|
79
79
|
embedded: true
|
|
80
80
|
});
|
|
@@ -4,7 +4,7 @@ import { For, Show, splitProps } from "solid-js";
|
|
|
4
4
|
import { twMerge } from "tailwind-merge";
|
|
5
5
|
import { Empty } from "../empty/index.js";
|
|
6
6
|
import icon from "../icon/index.js";
|
|
7
|
-
import {
|
|
7
|
+
import { tableMobileListViewRecipe } from "./Table.recipe.js";
|
|
8
8
|
var _tmpl$ = /*#__PURE__*/ template("<div><ul>"), _tmpl$2 = /*#__PURE__*/ template("<li class=py-8 data-slot=table-mobile-list-view-empty>"), _tmpl$3 = /*#__PURE__*/ template("<li>");
|
|
9
9
|
const __solidLayoutMobileListView = (_stable, p)=>{
|
|
10
10
|
const [local, rest] = splitProps(p, [
|
|
@@ -103,7 +103,7 @@ const __solidLayoutMobileListView = (_stable, p)=>{
|
|
|
103
103
|
})();
|
|
104
104
|
};
|
|
105
105
|
const MobileListView = defineComponent({
|
|
106
|
-
recipe:
|
|
106
|
+
recipe: tableMobileListViewRecipe,
|
|
107
107
|
layout: __solidLayoutMobileListView,
|
|
108
108
|
embedded: true
|
|
109
109
|
});
|
|
@@ -3,7 +3,7 @@ import { defineComponent } from "solid-layouts/application-boundary";
|
|
|
3
3
|
import { Show, splitProps } from "solid-js";
|
|
4
4
|
import { twMerge } from "tailwind-merge";
|
|
5
5
|
import icon from "../icon/index.js";
|
|
6
|
-
import {
|
|
6
|
+
import { tableSortIconRecipe } from "./Table.recipe.js";
|
|
7
7
|
var _tmpl$ = /*#__PURE__*/ template("<span>");
|
|
8
8
|
const __solidLayoutSortIcon = (_stable, p)=>{
|
|
9
9
|
const [local, rest] = splitProps(p, [
|
|
@@ -65,7 +65,7 @@ const __solidLayoutSortIcon = (_stable, p)=>{
|
|
|
65
65
|
})();
|
|
66
66
|
};
|
|
67
67
|
const SortIcon = defineComponent({
|
|
68
|
-
recipe:
|
|
68
|
+
recipe: tableSortIconRecipe,
|
|
69
69
|
layout: __solidLayoutSortIcon,
|
|
70
70
|
embedded: true
|
|
71
71
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Accessor, type JSX } from "solid-js";
|
|
2
|
+
export type TableVariant = "primary" | "secondary";
|
|
3
|
+
export type TableSortDirection = "ascending" | "descending";
|
|
4
|
+
export type TableSortDescriptor = {
|
|
5
|
+
column: string;
|
|
6
|
+
direction: TableSortDirection;
|
|
7
|
+
};
|
|
8
|
+
export type TableColumnRenderProps = {
|
|
9
|
+
sortDirection: TableSortDirection | undefined;
|
|
10
|
+
};
|
|
11
|
+
export type TableColumnChildren = JSX.Element | ((props: TableColumnRenderProps) => JSX.Element);
|
|
12
|
+
export type TableContextValue = {
|
|
13
|
+
variant: Accessor<TableVariant>;
|
|
14
|
+
};
|
|
15
|
+
export declare const TableContext: import("solid-js").Context<TableContextValue | undefined>;
|
|
16
|
+
export type TableContentContextValue = {
|
|
17
|
+
sortDescriptor: Accessor<TableSortDescriptor | undefined>;
|
|
18
|
+
onSortChange?: (descriptor: TableSortDescriptor) => void;
|
|
19
|
+
};
|
|
20
|
+
export declare const TableContentContext: import("solid-js").Context<TableContentContextValue | undefined>;
|
|
21
|
+
export declare const useTableContext: () => TableContextValue;
|
|
22
|
+
export declare const useTableContentContext: () => TableContentContextValue;
|
|
23
|
+
export declare const invokeEventHandler: (handler: unknown, event: Event) => void;
|