@eyesee/ui-components 0.15.1 → 0.17.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/components/Button/Button.js +19 -19
- package/dist/components/ImagePlaceholder/ImageHoverPreview/ImageHoverPreview.js +29 -36
- package/dist/components/ImagePlaceholder/ImageHoverPreview/ImageHoverPreview.module.scss.js +4 -6
- package/dist/components/Table/Table.d.ts +225 -0
- package/dist/components/Table/Table.js +135 -0
- package/dist/components/Table/Table.module.scss.js +33 -0
- package/dist/components/Table/TableColumnHeader/TableColumnHeader.d.ts +33 -0
- package/dist/components/Table/TableColumnHeader/TableColumnHeader.js +60 -0
- package/dist/components/Table/TableColumnHeader/TableColumnHeader.module.scss.js +11 -0
- package/dist/components/Table/tableSort/tableSortUtils.d.ts +28 -0
- package/dist/components/Table/tableSort/tableSortUtils.js +20 -0
- package/dist/components/Table/tableSort/useTableClientSort.d.ts +75 -0
- package/dist/components/Table/tableSort/useTableClientSort.js +16 -0
- package/dist/components/Tooltip/Tooltip.module.scss.js +26 -26
- package/dist/components/icons-v2/EditSquareIcon.d.ts +123 -0
- package/dist/components/icons-v2/EditSquareIcon.js +15 -0
- package/dist/components/icons-v2/index.d.ts +1 -0
- package/dist/components/icons-v2/index.js +52 -50
- package/dist/components/index.d.ts +2 -0
- package/dist/index.js +52 -45
- package/dist/style.css +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs as m, jsx as r } from "react/jsx-runtime";
|
|
2
|
-
import { useState as
|
|
2
|
+
import { useState as L, useRef as R, useEffect as S } from "react";
|
|
3
3
|
import p from "clsx";
|
|
4
|
-
import { ChevronDownIcon as
|
|
4
|
+
import { ChevronDownIcon as W } from "../icons-v2/ChevronDownIcon.js";
|
|
5
5
|
import { ChevronUpIcon as A } from "../icons-v2/ChevronUpIcon.js";
|
|
6
6
|
import U from "../../hooks/useClickOutside.js";
|
|
7
7
|
import { ListItem as q } from "../ListItem/ListItem.js";
|
|
@@ -13,36 +13,36 @@ function Z({
|
|
|
13
13
|
options: f = [],
|
|
14
14
|
onClick: u = () => {
|
|
15
15
|
},
|
|
16
|
-
className:
|
|
16
|
+
className: N,
|
|
17
17
|
iconSize: h = "m",
|
|
18
|
-
size:
|
|
19
|
-
variant:
|
|
20
|
-
type:
|
|
18
|
+
size: O = "md",
|
|
19
|
+
variant: g = "primary",
|
|
20
|
+
type: y = "fill",
|
|
21
21
|
pressed: d = !1,
|
|
22
22
|
icon: s = null,
|
|
23
23
|
tooltipContent: b = null,
|
|
24
|
-
tooltipTitle:
|
|
24
|
+
tooltipTitle: D,
|
|
25
25
|
disabled: i = !1,
|
|
26
|
-
fullWidth:
|
|
26
|
+
fullWidth: I = !1,
|
|
27
27
|
dropdownAlign: x = "start",
|
|
28
28
|
tooltipProps: k = { position: "bottom", variant: "light" },
|
|
29
29
|
dropdownCustomContent: c = null,
|
|
30
30
|
...B
|
|
31
31
|
}) {
|
|
32
|
-
const [l, o] =
|
|
33
|
-
U(
|
|
32
|
+
const [l, o] = L(!1), w = R(null);
|
|
33
|
+
U(w, () => o(!1));
|
|
34
34
|
const T = (n) => {
|
|
35
35
|
u(n), o(!1);
|
|
36
36
|
};
|
|
37
|
-
|
|
37
|
+
S(() => {
|
|
38
38
|
i && l && o(!1);
|
|
39
39
|
}, [i, l]);
|
|
40
|
-
const t = f.length > 0 || !!c,
|
|
40
|
+
const t = f.length > 0 || !!c, j = s && !a && !t, C = s && !a, E = !!b, v = /* @__PURE__ */ m(
|
|
41
41
|
"div",
|
|
42
42
|
{
|
|
43
|
-
ref:
|
|
43
|
+
ref: w,
|
|
44
44
|
"data-button-wrapper": !0,
|
|
45
|
-
className: p(e.wrapper,
|
|
45
|
+
className: p(e.wrapper, N, I && e.fullWidth),
|
|
46
46
|
...B,
|
|
47
47
|
children: [
|
|
48
48
|
/* @__PURE__ */ m(
|
|
@@ -51,12 +51,12 @@ function Z({
|
|
|
51
51
|
type: "button",
|
|
52
52
|
className: p(
|
|
53
53
|
e.button,
|
|
54
|
-
e[N],
|
|
55
54
|
e[O],
|
|
56
55
|
e[g],
|
|
56
|
+
e[y],
|
|
57
57
|
t && e.hasDropdown,
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
j && e.iconOnly,
|
|
59
|
+
C && e.isIcon,
|
|
60
60
|
d && e.pressed
|
|
61
61
|
),
|
|
62
62
|
onClick: () => t ? o((n) => !n) : u(),
|
|
@@ -78,7 +78,7 @@ function Z({
|
|
|
78
78
|
]
|
|
79
79
|
}
|
|
80
80
|
),
|
|
81
|
-
t && /* @__PURE__ */ r("span", { className: e.buttonArrow, children: l ? /* @__PURE__ */ r(A, { iconSize: h }) : /* @__PURE__ */ r(
|
|
81
|
+
t && /* @__PURE__ */ r("span", { className: e.buttonArrow, children: l ? /* @__PURE__ */ r(A, { iconSize: h }) : /* @__PURE__ */ r(W, { iconSize: h }) })
|
|
82
82
|
]
|
|
83
83
|
}
|
|
84
84
|
),
|
|
@@ -98,7 +98,7 @@ function Z({
|
|
|
98
98
|
]
|
|
99
99
|
}
|
|
100
100
|
);
|
|
101
|
-
return
|
|
101
|
+
return E ? /* @__PURE__ */ r(F, { title: D, content: b, ...k, fullWidth: I, children: v }) : v;
|
|
102
102
|
}
|
|
103
103
|
export {
|
|
104
104
|
Z as Button
|
|
@@ -1,65 +1,58 @@
|
|
|
1
|
-
import { jsxs as f, Fragment as p, jsx as
|
|
2
|
-
import { useRef as
|
|
3
|
-
import { createPortal as
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
const w = 200,
|
|
7
|
-
function
|
|
8
|
-
const a =
|
|
1
|
+
import { jsxs as f, Fragment as p, jsx as i } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as P, useState as I } from "react";
|
|
3
|
+
import { createPortal as E } from "react-dom";
|
|
4
|
+
import u from "../ImagePlaceholder.js";
|
|
5
|
+
import M from "./ImageHoverPreview.module.scss.js";
|
|
6
|
+
const w = 200, n = 8, d = 8, A = () => document.getElementById("modal") ?? document.body, h = (t, r, a) => Math.min(Math.max(t, r), a);
|
|
7
|
+
function B({ previewSize: t = w, ...r }) {
|
|
8
|
+
const a = P(null), [s, m] = I(null);
|
|
9
9
|
return /* @__PURE__ */ f(p, { children: [
|
|
10
|
-
/* @__PURE__ */
|
|
11
|
-
|
|
10
|
+
/* @__PURE__ */ i(
|
|
11
|
+
u,
|
|
12
12
|
{
|
|
13
|
-
...
|
|
13
|
+
...r,
|
|
14
14
|
imageAreaRef: a,
|
|
15
15
|
onImageAreaMouseEnter: (l) => {
|
|
16
16
|
var c;
|
|
17
17
|
l.stopPropagation();
|
|
18
|
-
const
|
|
19
|
-
if (!
|
|
20
|
-
let
|
|
21
|
-
|
|
18
|
+
const e = (c = a.current) == null ? void 0 : c.getBoundingClientRect();
|
|
19
|
+
if (!e) return;
|
|
20
|
+
let o = e.right + d;
|
|
21
|
+
o + t > window.innerWidth - n && (o = e.left - t - d), o = h(
|
|
22
|
+
o,
|
|
22
23
|
n,
|
|
23
|
-
|
|
24
|
-
window.innerWidth - t - r
|
|
24
|
+
window.innerWidth - t - n
|
|
25
25
|
);
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
window.innerHeight - t -
|
|
26
|
+
const g = h(
|
|
27
|
+
e.top + e.height / 2 - t / 2,
|
|
28
|
+
n,
|
|
29
|
+
window.innerHeight - t - n
|
|
30
30
|
);
|
|
31
|
-
|
|
31
|
+
m({ top: g, left: o });
|
|
32
32
|
},
|
|
33
33
|
onImageAreaMouseLeave: (l) => {
|
|
34
|
-
l.stopPropagation(),
|
|
34
|
+
l.stopPropagation(), m(null);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
),
|
|
38
|
-
s &&
|
|
39
|
-
/* @__PURE__ */
|
|
38
|
+
s && E(
|
|
39
|
+
/* @__PURE__ */ i(
|
|
40
40
|
"div",
|
|
41
41
|
{
|
|
42
|
-
className:
|
|
42
|
+
className: M.preview,
|
|
43
43
|
style: {
|
|
44
44
|
top: s.top,
|
|
45
45
|
left: s.left,
|
|
46
46
|
width: t,
|
|
47
47
|
height: t
|
|
48
48
|
},
|
|
49
|
-
children: /* @__PURE__ */
|
|
50
|
-
"img",
|
|
51
|
-
{
|
|
52
|
-
src: e.url,
|
|
53
|
-
alt: e.text ?? "",
|
|
54
|
-
className: u.previewImage
|
|
55
|
-
}
|
|
56
|
-
)
|
|
49
|
+
children: /* @__PURE__ */ i(u, { url: r.url })
|
|
57
50
|
}
|
|
58
51
|
),
|
|
59
|
-
|
|
52
|
+
A()
|
|
60
53
|
)
|
|
61
54
|
] });
|
|
62
55
|
}
|
|
63
56
|
export {
|
|
64
|
-
|
|
57
|
+
B as ImageHoverPreview
|
|
65
58
|
};
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flexible table with per-column custom headers and cells, plus optional infinite scroll.
|
|
3
|
+
*
|
|
4
|
+
* @param {TableProps} props
|
|
5
|
+
* @returns {import('react').ReactElement}
|
|
6
|
+
*
|
|
7
|
+
* @example <caption>Columns, rows, infinite scroll</caption>
|
|
8
|
+
* import { Button, Checkbox, Table } from '@eyesee/ui-components';
|
|
9
|
+
*
|
|
10
|
+
* const columns = [
|
|
11
|
+
* {
|
|
12
|
+
* id: 'select',
|
|
13
|
+
* width: 'max-content',
|
|
14
|
+
* align: 'center',
|
|
15
|
+
* renderHeader: () => <Checkbox aria-label="Select all" />,
|
|
16
|
+
* renderCell: (row, rowIndex) => (
|
|
17
|
+
* <Checkbox checked={row.selected} aria-label={`Select row ${rowIndex + 1}`} />
|
|
18
|
+
* ),
|
|
19
|
+
* },
|
|
20
|
+
* {
|
|
21
|
+
* id: 'name',
|
|
22
|
+
* headerTitle: 'Product',
|
|
23
|
+
* renderCell: (row, rowIndex, column) => row.name,
|
|
24
|
+
* },
|
|
25
|
+
* {
|
|
26
|
+
* id: 'qty',
|
|
27
|
+
* width: 96,
|
|
28
|
+
* align: 'end',
|
|
29
|
+
* renderHeader: (column) => <strong>{column.headerTitle ?? 'Qty'}</strong>,
|
|
30
|
+
* headerTitle: 'Qty',
|
|
31
|
+
* renderCell: (row) => row.qty,
|
|
32
|
+
* },
|
|
33
|
+
* {
|
|
34
|
+
* id: 'actions',
|
|
35
|
+
* width: '10rem',
|
|
36
|
+
* align: 'center',
|
|
37
|
+
* renderHeader: () => null,
|
|
38
|
+
* renderCell: (row) => <Button text="Edit" onClick={() => editRow(row.id)} />,
|
|
39
|
+
* },
|
|
40
|
+
* ];
|
|
41
|
+
*
|
|
42
|
+
* // Shape is yours — fields below match only what `columns` / callbacks read.
|
|
43
|
+
* const rows = [
|
|
44
|
+
* { id: 1, name: 'Granola pack', qty: 12, selected: true },
|
|
45
|
+
* { id: 2, name: 'Shelf display', qty: 3, selected: false },
|
|
46
|
+
* ];
|
|
47
|
+
*
|
|
48
|
+
* <Table
|
|
49
|
+
* aria-label="Orders"
|
|
50
|
+
* rowHeight={80}
|
|
51
|
+
* headerHeight={56}
|
|
52
|
+
* columns={columns}
|
|
53
|
+
* rows={rows}
|
|
54
|
+
* getRowKey={(row) => row.id}
|
|
55
|
+
* isRowSubtle={(row) => row.selected}
|
|
56
|
+
* hasMore={hasNextPage}
|
|
57
|
+
* isLoadingMore={isFetchingNextPage}
|
|
58
|
+
* onLoadMore={fetchNextPage}
|
|
59
|
+
* loadMoreThreshold={50}
|
|
60
|
+
* loadingMoreContent="Loading more…"
|
|
61
|
+
* />
|
|
62
|
+
*
|
|
63
|
+
* @example <caption>Client-side sort</caption>
|
|
64
|
+
* import { Table, useTableClientSort } from '@eyesee/ui-components';
|
|
65
|
+
*
|
|
66
|
+
* const sortableColumns = [
|
|
67
|
+
* {
|
|
68
|
+
* id: 'name',
|
|
69
|
+
* headerTitle: 'Product',
|
|
70
|
+
* sortable: true,
|
|
71
|
+
* sortValue: (row) => row.name,
|
|
72
|
+
* renderCell: (row) => row.name,
|
|
73
|
+
* },
|
|
74
|
+
* ];
|
|
75
|
+
*
|
|
76
|
+
* const { sort, onSortChange, sortedRows } = useTableClientSort({
|
|
77
|
+
* rows,
|
|
78
|
+
* columns: sortableColumns,
|
|
79
|
+
* });
|
|
80
|
+
*
|
|
81
|
+
* <Table
|
|
82
|
+
* aria-label="Orders"
|
|
83
|
+
* columns={sortableColumns}
|
|
84
|
+
* rows={sortedRows}
|
|
85
|
+
* sort={sort}
|
|
86
|
+
* onSortChange={onSortChange}
|
|
87
|
+
* />
|
|
88
|
+
*
|
|
89
|
+
* @example <caption>Server-side sort (fetch in parent)</caption>
|
|
90
|
+
* <Table
|
|
91
|
+
* aria-label="Orders"
|
|
92
|
+
* columns={sortableColumns}
|
|
93
|
+
* rows={rowsFromApi}
|
|
94
|
+
* sort={sort}
|
|
95
|
+
* onSortChange={handleSortChange}
|
|
96
|
+
* isSortLoading={isFetchingSort}
|
|
97
|
+
* sortError={sortFetchError}
|
|
98
|
+
* />
|
|
99
|
+
*/
|
|
100
|
+
export function Table({ columns, rows, getRowKey, "aria-label": ariaLabel, hasMore, isLoadingMore, onLoadMore, loadMoreThreshold, loadingMoreContent, isRowSubtle, rowHeight, headerHeight, sort, onSortChange, isSortLoading, sortError, }: TableProps): import("react").ReactElement;
|
|
101
|
+
export type TableColumn = {
|
|
102
|
+
/**
|
|
103
|
+
* Unique column key.
|
|
104
|
+
*/
|
|
105
|
+
id: string;
|
|
106
|
+
/**
|
|
107
|
+
* Default header label when `renderHeader` is omitted.
|
|
108
|
+
*/
|
|
109
|
+
headerTitle?: string;
|
|
110
|
+
/**
|
|
111
|
+
* Custom header cell content. Receives the column definition.
|
|
112
|
+
*/
|
|
113
|
+
renderHeader?: (column: TableColumn) => import("react").ReactNode;
|
|
114
|
+
/**
|
|
115
|
+
* Custom body cell content.
|
|
116
|
+
*/
|
|
117
|
+
renderCell: (row: any, rowIndex: number, column: TableColumn) => import("react").ReactNode;
|
|
118
|
+
/**
|
|
119
|
+
* Column width (e.g. `128`, `'128px'`, `'max-content'`). Omit `width` for a fluid column that
|
|
120
|
+
* shares remaining space.
|
|
121
|
+
*/
|
|
122
|
+
width?: string | number;
|
|
123
|
+
/**
|
|
124
|
+
* Horizontal alignment inside the cell. Default `'start'`.
|
|
125
|
+
*/
|
|
126
|
+
align?: "start" | "center" | "end";
|
|
127
|
+
/**
|
|
128
|
+
* When true and `onSortChange` is set on {@link Table}, the default header (`headerTitle`) is
|
|
129
|
+
* sort arrows (up applies/clears asc, down applies/clears desc). Custom `renderHeader` must wire
|
|
130
|
+
* sort UI yourself; `aria-sort` is still applied on the column header.
|
|
131
|
+
*/
|
|
132
|
+
sortable?: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Used with {@link useTableClientSort} / {@link sortTableRows} for client-side sort (not read by
|
|
135
|
+
* {@link Table} itself).
|
|
136
|
+
*/
|
|
137
|
+
sortValue?: (row: any) => string | number | null | undefined;
|
|
138
|
+
};
|
|
139
|
+
export type TableSort = {
|
|
140
|
+
/**
|
|
141
|
+
* Active sort column id.
|
|
142
|
+
*/
|
|
143
|
+
columnId: string;
|
|
144
|
+
/**
|
|
145
|
+
* Sort direction.
|
|
146
|
+
*/
|
|
147
|
+
direction: "asc" | "desc";
|
|
148
|
+
};
|
|
149
|
+
export type TableSortChangeHandler = (sort: TableSort | null) => void;
|
|
150
|
+
export type TableLoadMoreHandler = () => void;
|
|
151
|
+
export type TableRowKeyGetter = (row: any, index: number) => string | number;
|
|
152
|
+
export type TableRowSubtlePredicate = (row: any, index: number) => boolean;
|
|
153
|
+
export type TableProps = {
|
|
154
|
+
/**
|
|
155
|
+
* Column definitions (order defines layout).
|
|
156
|
+
*/
|
|
157
|
+
columns: TableColumn[];
|
|
158
|
+
/**
|
|
159
|
+
* Arbitrary row objects from your app. `Table` does not read fixed keys — only what you use in
|
|
160
|
+
* `renderCell`, `getRowKey`, and `isRowSubtle`.
|
|
161
|
+
*/
|
|
162
|
+
rows: any[];
|
|
163
|
+
/**
|
|
164
|
+
* Stable React key per row. Default uses `row.id` or the row index.
|
|
165
|
+
*/
|
|
166
|
+
getRowKey?: TableRowKeyGetter;
|
|
167
|
+
/**
|
|
168
|
+
* Accessible name for the table region. Parent must define height (`height: 100%` or flex
|
|
169
|
+
* child with `flex: 1` and `min-height: 0`) so the table can fill it and scroll internally.
|
|
170
|
+
*/
|
|
171
|
+
"aria-label"?: string;
|
|
172
|
+
/**
|
|
173
|
+
* When true, scrolling near the bottom can trigger `onLoadMore`. Default `false`.
|
|
174
|
+
*/
|
|
175
|
+
hasMore?: boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Suppresses duplicate `onLoadMore` calls while a page is loading. Default `false`.
|
|
178
|
+
*/
|
|
179
|
+
isLoadingMore?: boolean;
|
|
180
|
+
/**
|
|
181
|
+
* Called when the user scrolls within `loadMoreThreshold` px of the bottom.
|
|
182
|
+
*/
|
|
183
|
+
onLoadMore?: TableLoadMoreHandler;
|
|
184
|
+
/**
|
|
185
|
+
* Distance from the bottom (px) that triggers `onLoadMore`. Default `50`.
|
|
186
|
+
*/
|
|
187
|
+
loadMoreThreshold?: number;
|
|
188
|
+
/**
|
|
189
|
+
* Shown at the bottom while `isLoadingMore` is true.
|
|
190
|
+
*/
|
|
191
|
+
loadingMoreContent?: import("react").ReactNode;
|
|
192
|
+
/**
|
|
193
|
+
* When true for a row, applies the subtle background (selected/highlight row).
|
|
194
|
+
*/
|
|
195
|
+
isRowSubtle?: TableRowSubtlePredicate;
|
|
196
|
+
/**
|
|
197
|
+
* Fixed body row height (e.g. `80`). Default `80`.
|
|
198
|
+
*/
|
|
199
|
+
rowHeight?: string | number;
|
|
200
|
+
/**
|
|
201
|
+
* Fixed header row height (e.g. `56`). Default `56`.
|
|
202
|
+
*/
|
|
203
|
+
headerHeight?: string | number;
|
|
204
|
+
/**
|
|
205
|
+
* Active sort (controlled). Default `null`.
|
|
206
|
+
*/
|
|
207
|
+
sort?: TableSort | null;
|
|
208
|
+
/**
|
|
209
|
+
* Fired when sort arrows are used. Update `sort` and supply `rows` (e.g. fetch sorted data from
|
|
210
|
+
* the server, or use {@link useTableClientSort} and pass `sortedRows`).
|
|
211
|
+
*/
|
|
212
|
+
onSortChange?: TableSortChangeHandler;
|
|
213
|
+
/**
|
|
214
|
+
* When true (e.g. while fetching server-sorted `rows`), body rows are hidden and a loader is
|
|
215
|
+
* shown until new data arrives. Default `false`.
|
|
216
|
+
*/
|
|
217
|
+
isSortLoading?: boolean;
|
|
218
|
+
/**
|
|
219
|
+
* When set (and not `isSortLoading`), body rows are hidden and an error message is shown instead
|
|
220
|
+
* (same slot as the sort loader). Clear on retry or the next successful fetch. Default
|
|
221
|
+
* `undefined`.
|
|
222
|
+
*/
|
|
223
|
+
sortError?: import("react").ReactNode;
|
|
224
|
+
};
|
|
225
|
+
export { getTableSortFromArrowClick, sortTableRows } from "./tableSort/tableSortUtils";
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { jsx as t, jsxs as C } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as I, useCallback as K, useEffect as R } from "react";
|
|
3
|
+
import d from "clsx";
|
|
4
|
+
import { LoaderIcon as W } from "../icons-v2/LoaderIcon.js";
|
|
5
|
+
import { renderTableColumnHeader as $ } from "./TableColumnHeader/TableColumnHeader.js";
|
|
6
|
+
import r from "./Table.module.scss.js";
|
|
7
|
+
import { Infobox as q } from "../Infobox/Infobox.js";
|
|
8
|
+
function v(e) {
|
|
9
|
+
if (e != null)
|
|
10
|
+
return typeof e == "number" ? `${e}px` : e;
|
|
11
|
+
}
|
|
12
|
+
function D(e) {
|
|
13
|
+
return e.map((a) => a.width == null ? "minmax(0, 1fr)" : v(a.width)).join(" ");
|
|
14
|
+
}
|
|
15
|
+
function x(e) {
|
|
16
|
+
if (e === "start") return r.alignStart;
|
|
17
|
+
if (e === "center") return r.alignCenter;
|
|
18
|
+
if (e === "end") return r.alignEnd;
|
|
19
|
+
}
|
|
20
|
+
function J(e, a) {
|
|
21
|
+
if (e.sortable)
|
|
22
|
+
return !a || a.columnId !== e.id ? "none" : a.direction === "asc" ? "ascending" : "descending";
|
|
23
|
+
}
|
|
24
|
+
function Y({
|
|
25
|
+
columns: e,
|
|
26
|
+
rows: a,
|
|
27
|
+
getRowKey: T = (n, h) => (n == null ? void 0 : n.id) ?? h,
|
|
28
|
+
"aria-label": j,
|
|
29
|
+
hasMore: b = !1,
|
|
30
|
+
isLoadingMore: c = !1,
|
|
31
|
+
onLoadMore: f,
|
|
32
|
+
loadMoreThreshold: g = 50,
|
|
33
|
+
loadingMoreContent: k = "Loading…",
|
|
34
|
+
isRowSubtle: u,
|
|
35
|
+
rowHeight: w = 80,
|
|
36
|
+
headerHeight: B = 56,
|
|
37
|
+
sort: N = null,
|
|
38
|
+
onSortChange: H,
|
|
39
|
+
isSortLoading: i = !1,
|
|
40
|
+
sortError: m
|
|
41
|
+
}) {
|
|
42
|
+
const n = I(!1), h = K(
|
|
43
|
+
(l) => {
|
|
44
|
+
if (!b || c || i || !f)
|
|
45
|
+
return;
|
|
46
|
+
const s = l.currentTarget;
|
|
47
|
+
if (s.scrollHeight - s.scrollTop - s.clientHeight > g) {
|
|
48
|
+
n.current = !1;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
n.current || (n.current = !0, f());
|
|
52
|
+
},
|
|
53
|
+
[b, c, i, g, f]
|
|
54
|
+
);
|
|
55
|
+
R(() => {
|
|
56
|
+
c || (n.current = !1);
|
|
57
|
+
}, [c]);
|
|
58
|
+
const A = D(e), F = { height: v(B) }, z = { height: v(w) }, E = i || !!m;
|
|
59
|
+
let p = null;
|
|
60
|
+
return i ? p = /* @__PURE__ */ t(
|
|
61
|
+
W,
|
|
62
|
+
{
|
|
63
|
+
iconSize: "xl",
|
|
64
|
+
strokeColor: "var(--color--text--default--body-lighter)",
|
|
65
|
+
animated: !0
|
|
66
|
+
}
|
|
67
|
+
) : m && (p = /* @__PURE__ */ t(q, { title: "Error sorting table", text: m, status: "error", fullWidth: !0 })), /* @__PURE__ */ t("div", { className: r.table, children: /* @__PURE__ */ C(
|
|
68
|
+
"div",
|
|
69
|
+
{
|
|
70
|
+
className: r.scrollArea,
|
|
71
|
+
onScroll: h,
|
|
72
|
+
role: "table",
|
|
73
|
+
"aria-label": j,
|
|
74
|
+
"aria-busy": i || void 0,
|
|
75
|
+
children: [
|
|
76
|
+
/* @__PURE__ */ C("div", { className: r.gridTable, style: { gridTemplateColumns: A }, children: [
|
|
77
|
+
/* @__PURE__ */ t("div", { role: "rowgroup", className: r.rowgroup, children: /* @__PURE__ */ t("div", { className: r.header, role: "row", style: F, children: e.map((l) => /* @__PURE__ */ t(
|
|
78
|
+
"div",
|
|
79
|
+
{
|
|
80
|
+
role: "columnheader",
|
|
81
|
+
"aria-sort": J(l, N),
|
|
82
|
+
className: d(
|
|
83
|
+
r.cell,
|
|
84
|
+
x(l.align ?? "start")
|
|
85
|
+
),
|
|
86
|
+
children: $(
|
|
87
|
+
l,
|
|
88
|
+
N,
|
|
89
|
+
H,
|
|
90
|
+
i
|
|
91
|
+
)
|
|
92
|
+
},
|
|
93
|
+
l.id
|
|
94
|
+
)) }) }),
|
|
95
|
+
/* @__PURE__ */ t("div", { className: r.body, role: "rowgroup", children: E ? /* @__PURE__ */ t("div", { role: "row", className: d(r.row, r.statusRow), children: /* @__PURE__ */ t(
|
|
96
|
+
"div",
|
|
97
|
+
{
|
|
98
|
+
role: "cell",
|
|
99
|
+
className: r.infoContent,
|
|
100
|
+
"aria-live": i ? "polite" : "assertive",
|
|
101
|
+
children: p
|
|
102
|
+
}
|
|
103
|
+
) }) : a.map((l, s) => {
|
|
104
|
+
const y = T(l, s), G = (u == null ? void 0 : u(l, s)) ?? !1;
|
|
105
|
+
return /* @__PURE__ */ t(
|
|
106
|
+
"div",
|
|
107
|
+
{
|
|
108
|
+
role: "row",
|
|
109
|
+
className: d(r.row, G && r.subtle),
|
|
110
|
+
style: z,
|
|
111
|
+
children: e.map((o) => /* @__PURE__ */ t(
|
|
112
|
+
"div",
|
|
113
|
+
{
|
|
114
|
+
role: "cell",
|
|
115
|
+
className: d(
|
|
116
|
+
r.cell,
|
|
117
|
+
x(o.align ?? "start")
|
|
118
|
+
),
|
|
119
|
+
children: o.renderCell(l, s, o)
|
|
120
|
+
},
|
|
121
|
+
o.id
|
|
122
|
+
))
|
|
123
|
+
},
|
|
124
|
+
y
|
|
125
|
+
);
|
|
126
|
+
}) })
|
|
127
|
+
] }),
|
|
128
|
+
c ? /* @__PURE__ */ t("div", { className: r.loadMore, "aria-live": "polite", children: k }) : null
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
) });
|
|
132
|
+
}
|
|
133
|
+
export {
|
|
134
|
+
Y as Table
|
|
135
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const o = "_table_181fo_3", _ = "_scrollArea_181fo_16", n = "_gridTable_181fo_23", t = "_rowgroup_181fo_28", e = "_header_181fo_32", l = "_row_181fo_28", r = "_body_181fo_50", a = "_subtle_181fo_60", s = "_cell_181fo_64", c = "_alignStart_181fo_74", f = "_alignCenter_181fo_77", d = "_alignEnd_181fo_80", g = "_infoContent_181fo_84", i = "_loadMore_181fo_95", b = {
|
|
2
|
+
table: o,
|
|
3
|
+
scrollArea: _,
|
|
4
|
+
gridTable: n,
|
|
5
|
+
rowgroup: t,
|
|
6
|
+
header: e,
|
|
7
|
+
row: l,
|
|
8
|
+
body: r,
|
|
9
|
+
subtle: a,
|
|
10
|
+
cell: s,
|
|
11
|
+
alignStart: c,
|
|
12
|
+
alignCenter: f,
|
|
13
|
+
alignEnd: d,
|
|
14
|
+
infoContent: g,
|
|
15
|
+
loadMore: i
|
|
16
|
+
};
|
|
17
|
+
export {
|
|
18
|
+
f as alignCenter,
|
|
19
|
+
d as alignEnd,
|
|
20
|
+
c as alignStart,
|
|
21
|
+
r as body,
|
|
22
|
+
s as cell,
|
|
23
|
+
b as default,
|
|
24
|
+
n as gridTable,
|
|
25
|
+
e as header,
|
|
26
|
+
g as infoContent,
|
|
27
|
+
i as loadMore,
|
|
28
|
+
l as row,
|
|
29
|
+
t as rowgroup,
|
|
30
|
+
_ as scrollArea,
|
|
31
|
+
a as subtle,
|
|
32
|
+
o as table
|
|
33
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {object} props
|
|
3
|
+
* @param {TableColumnHeaderColumn} props.column
|
|
4
|
+
* @param {TableSort|null} props.sort
|
|
5
|
+
* @param {TableSortChangeHandler} props.onSortChange
|
|
6
|
+
* @param {boolean} [props.isSortLoading]
|
|
7
|
+
* @returns {import('react').ReactElement}
|
|
8
|
+
*/
|
|
9
|
+
export function TableSortableHeader({ column, sort, onSortChange, isSortLoading }: {
|
|
10
|
+
column: TableColumnHeaderColumn;
|
|
11
|
+
sort: TableSort | null;
|
|
12
|
+
onSortChange: TableSortChangeHandler;
|
|
13
|
+
isSortLoading?: boolean;
|
|
14
|
+
}): import("react").ReactElement;
|
|
15
|
+
/**
|
|
16
|
+
* @param {TableColumnHeaderColumn} column
|
|
17
|
+
* @param {TableSort|null} sort
|
|
18
|
+
* @param {TableSortChangeHandler} [onSortChange]
|
|
19
|
+
* @param {boolean} [isSortLoading]
|
|
20
|
+
* @returns {import('react').ReactNode}
|
|
21
|
+
*/
|
|
22
|
+
export function renderTableColumnHeader(column: TableColumnHeaderColumn, sort: TableSort | null, onSortChange?: TableSortChangeHandler, isSortLoading?: boolean): import("react").ReactNode;
|
|
23
|
+
export type TableColumnHeaderColumn = {
|
|
24
|
+
id: string;
|
|
25
|
+
headerTitle?: string;
|
|
26
|
+
renderHeader?: (column: TableColumnHeaderColumn) => import("react").ReactNode;
|
|
27
|
+
sortable?: boolean;
|
|
28
|
+
};
|
|
29
|
+
export type TableSort = {
|
|
30
|
+
columnId: string;
|
|
31
|
+
direction: "asc" | "desc";
|
|
32
|
+
};
|
|
33
|
+
export type TableSortChangeHandler = (sort: TableSort | null) => void;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx as i, jsxs as l } from "react/jsx-runtime";
|
|
2
|
+
import { ArrowDownIcon as f } from "../../icons-v2/ArrowDownIcon.js";
|
|
3
|
+
import { ArrowUpIcon as p } from "../../icons-v2/ArrowUpIcon.js";
|
|
4
|
+
import { Button as c } from "../../Button/Button.js";
|
|
5
|
+
import { getTableSortFromArrowClick as h } from "../tableSort/tableSortUtils.js";
|
|
6
|
+
import n from "./TableColumnHeader.module.scss.js";
|
|
7
|
+
function b(e) {
|
|
8
|
+
return e.headerTitle ? /* @__PURE__ */ i("span", { className: n.headerTitle, children: e.headerTitle }) : null;
|
|
9
|
+
}
|
|
10
|
+
function x({ column: e, sort: r, onSortChange: t, isSortLoading: a = !1 }) {
|
|
11
|
+
const d = (r == null ? void 0 : r.columnId) === e.id ? r.direction : null, s = (o) => {
|
|
12
|
+
a || t(h(r, e.id, o));
|
|
13
|
+
};
|
|
14
|
+
return /* @__PURE__ */ l("div", { className: n.sortHeader, children: [
|
|
15
|
+
/* @__PURE__ */ i("span", { className: n.headerTitle, children: e.headerTitle }),
|
|
16
|
+
/* @__PURE__ */ l("span", { className: n.sortIcons, children: [
|
|
17
|
+
/* @__PURE__ */ i(
|
|
18
|
+
c,
|
|
19
|
+
{
|
|
20
|
+
type: "blank",
|
|
21
|
+
variant: "neutral",
|
|
22
|
+
size: "xxxxs",
|
|
23
|
+
onClick: () => s("asc"),
|
|
24
|
+
disabled: a,
|
|
25
|
+
pressed: d === "asc",
|
|
26
|
+
"aria-label": `Sort ${e.headerTitle} ascending`,
|
|
27
|
+
icon: /* @__PURE__ */ i(p, { iconSize: "s" })
|
|
28
|
+
}
|
|
29
|
+
),
|
|
30
|
+
/* @__PURE__ */ i(
|
|
31
|
+
c,
|
|
32
|
+
{
|
|
33
|
+
type: "blank",
|
|
34
|
+
variant: "neutral",
|
|
35
|
+
size: "xxxxs",
|
|
36
|
+
pressed: d === "desc",
|
|
37
|
+
icon: /* @__PURE__ */ i(f, { iconSize: "s" }),
|
|
38
|
+
onClick: () => s("desc"),
|
|
39
|
+
disabled: a,
|
|
40
|
+
"aria-label": `Sort ${e.headerTitle} descending`
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
] })
|
|
44
|
+
] });
|
|
45
|
+
}
|
|
46
|
+
function w(e, r, t, a) {
|
|
47
|
+
return e.renderHeader ? e.renderHeader(e) : e.sortable && t && e.headerTitle ? /* @__PURE__ */ i(
|
|
48
|
+
x,
|
|
49
|
+
{
|
|
50
|
+
column: e,
|
|
51
|
+
sort: r,
|
|
52
|
+
onSortChange: t,
|
|
53
|
+
isSortLoading: a
|
|
54
|
+
}
|
|
55
|
+
) : b(e);
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
x as TableSortableHeader,
|
|
59
|
+
w as renderTableColumnHeader
|
|
60
|
+
};
|