schummar-table 0.5.4 → 0.7.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/cjs/index.js CHANGED
@@ -33,461 +33,193 @@ var __objRest = (source, exclude) => {
33
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
34
  exports[Symbol.toStringTag] = "Module";
35
35
  var react = require("react");
36
+ var react$1 = require("schummar-state/react");
36
37
  var tableTheme = require("./tableTheme.js");
37
38
  var jsxRuntime = require("@emotion/react/jsx-runtime");
38
39
  var dayzed = require("dayzed");
39
40
  var immer = require("immer");
40
- var react$1 = require("schummar-state/react");
41
- require("@emotion/react");
41
+ var react$2 = require("@emotion/react");
42
42
  require("react-dom");
43
- function useTheme() {
44
- const table = useTableContext();
45
- return table.useState("theme");
43
+ const TableMemoContext = react.createContext(/* @__PURE__ */ new Map());
44
+ function TableMemoContextProvider({
45
+ children
46
+ }) {
47
+ return jsxRuntime.jsx(TableMemoContext.Provider, {
48
+ value: react.useMemo(() => /* @__PURE__ */ new Map(), []),
49
+ children
50
+ });
46
51
  }
47
- function AutoFocusTextField(props) {
48
- const {
49
- components: {
50
- TextField
52
+ function useTableMemo() {
53
+ const memoCache = react.useContext(TableMemoContext);
54
+ return (key, fn) => {
55
+ let deps;
56
+ if (Array.isArray(fn)) {
57
+ deps = fn.slice(1);
58
+ fn = fn[0];
59
+ } else {
60
+ deps = [fn.toString()];
51
61
  }
52
- } = useTheme();
53
- const ref = react.useRef(null);
54
- const {
55
- visible
56
- } = react.useContext(tableTheme.PopoverContext);
57
- react.useLayoutEffect(() => {
58
- if (visible && ref.current) {
59
- ref.current.focus();
62
+ let cachedValue = memoCache.get(key);
63
+ const hit = cachedValue && cachedValue[1].length === deps.length && cachedValue[1].every((x, i) => x === deps[i]);
64
+ if (!cachedValue || !hit) {
65
+ cachedValue = [fn, deps];
66
+ memoCache.set(key, cachedValue);
60
67
  }
61
- }, [visible]);
62
- return jsxRuntime.jsx(TextField, __spreadProps(__spreadValues({}, props), {
63
- inputRef: ref
64
- }));
65
- }
66
- function useCssVariables() {
67
- const table = useTableContext();
68
- return table.useState((state) => ({
69
- "--spacing": state.theme.spacing,
70
- "--primaryMain": state.theme.colors.primary.main,
71
- "--primaryLight": state.theme.colors.primary.light,
72
- "--primaryContrastText": state.theme.colors.primary.contrastText,
73
- "--secondaryMain": state.theme.colors.secondary.main,
74
- "--secondaryLight": state.theme.colors.secondary.light,
75
- "--secondaryContrastText": state.theme.colors.secondary.contrastText
76
- }));
68
+ return cachedValue[0];
69
+ };
77
70
  }
78
- const weekDays = [0, 1, 2, 3, 4, 5, 6];
79
- const months = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
80
- const startOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
81
- const endOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + 1, 0, 0, 0, -1);
82
- function dateIntersect(a, b) {
83
- if (a instanceof Date) {
84
- a = {
85
- min: a,
86
- max: a
87
- };
71
+ class Queue {
72
+ constructor() {
73
+ this.q = new Array();
74
+ this.isRunning = false;
88
75
  }
89
- if (b instanceof Date) {
90
- b = {
91
- min: b,
92
- max: b
93
- };
76
+ run(job, replace) {
77
+ return new Promise((resolve, reject) => {
78
+ if (replace) {
79
+ this.q = [];
80
+ }
81
+ this.q.push({ job, resolve, reject });
82
+ if (!this.isRunning)
83
+ this.start();
84
+ });
94
85
  }
95
- if (!(a == null ? void 0 : a.min) || !a.max || !(b == null ? void 0 : b.min) || !b.max) {
96
- return false;
86
+ async start() {
87
+ this.isRunning = true;
88
+ let next;
89
+ while (next = this.q.shift()) {
90
+ try {
91
+ const result = await next.job();
92
+ next.resolve(result);
93
+ } catch (e) {
94
+ next.reject(e);
95
+ }
96
+ }
97
+ this.isRunning = false;
97
98
  }
98
- return !(endOfDay(a.max) < startOfDay(b.min) || startOfDay(a.min) > endOfDay(b.max));
99
99
  }
100
- function DatePicker({
101
- value,
102
- onChange,
103
- rangeSelect,
104
- locale,
105
- firstDayOfWeek = 0
106
- }) {
107
- const {
108
- components: {
109
- IconButton
110
- },
111
- icons: {
112
- ChevronRight
100
+ const KEYS = ["sort", "selection", "expanded", "hiddenColumns", "filterValues", "columnWidths", "columnOrder"];
101
+ const storageName = (id) => `schummar-table_state-v1_${id}`;
102
+ function stringify(value) {
103
+ function prepare(value2) {
104
+ if (value2 instanceof Date) {
105
+ return { __date: value2.toJSON() };
113
106
  }
114
- } = useTheme();
115
- const [baseDate] = react.useState(new Date());
116
- const [dateInView, setDateInView] = react.useState(baseDate);
117
- const [currentMin, setCurrentMin] = react.useState();
118
- const [hovered, setHovered] = react.useState();
119
- const min = currentMin != null ? currentMin : value instanceof Date ? value : value == null ? void 0 : value.min;
120
- const max = currentMin ? void 0 : value instanceof Date ? value : value == null ? void 0 : value.max;
121
- const {
122
- calendars,
123
- getBackProps,
124
- getForwardProps,
125
- getDateProps
126
- } = dayzed.useDayzed({
127
- onDateSelected: () => void 0,
128
- firstDayOfWeek,
129
- showOutsideDays: true,
130
- date: dateInView,
131
- onOffsetChanged: (offset) => setDateInView(new Date(dateInView.getFullYear(), dateInView.getMonth() + offset)),
132
- offset: 0
133
- });
134
- const formatWeekday = react.useMemo(() => {
135
- const {
136
- format
137
- } = new Intl.DateTimeFormat(locale, {
138
- weekday: "short"
139
- });
140
- return (weekDay) => format(new Date(Date.UTC(2021, 5, weekDay)));
141
- }, [locale]);
142
- react.useEffect(() => setDateInView(value === null ? new Date() : value instanceof Date ? value : value.max), [value]);
143
- return jsxRuntime.jsx("div", {
144
- children: calendars.map(({
145
- month,
146
- year,
147
- weeks
148
- }) => jsxRuntime.jsxs("div", {
149
- children: [jsxRuntime.jsxs("div", {
150
- css: {
151
- margin: "calc(var(--spacing) * 4) 0",
152
- display: "grid",
153
- gridAutoFlow: "column",
154
- justifyContent: "space-between",
155
- alignItems: "center"
156
- },
157
- children: [jsxRuntime.jsx(IconButton, __spreadProps(__spreadValues({}, getBackProps({
158
- calendars
159
- })), {
160
- children: jsxRuntime.jsx(ChevronRight, {
161
- css: {
162
- transform: "rotate3d(0, 0, 1, 180deg)"
163
- }
164
- })
165
- })), jsxRuntime.jsxs("div", {
166
- css: {
167
- display: "flex"
168
- },
169
- children: [jsxRuntime.jsx(MonthSelector, {
170
- value: month,
171
- onChange: (month2) => setDateInView(new Date(year, month2)),
172
- locale
173
- }), jsxRuntime.jsx(YearSelector, {
174
- value: year,
175
- onChange: (year2) => setDateInView(new Date(year2, month))
176
- })]
177
- }), jsxRuntime.jsx(IconButton, __spreadProps(__spreadValues({}, getForwardProps({
178
- calendars
179
- })), {
180
- children: jsxRuntime.jsx(ChevronRight, {})
181
- }))]
182
- }), jsxRuntime.jsxs("div", {
183
- css: {
184
- display: "grid",
185
- gridTemplateColumns: "repeat(7, max-content)",
186
- fontWeight: "bold"
187
- },
188
- children: [weekDays.map((_v, weekDay) => jsxRuntime.jsx("div", {
189
- css: {
190
- justifySelf: "center",
191
- marginBottom: "var(--spacing)"
192
- },
193
- children: formatWeekday(weekDay)
194
- }, weekDay)), weeks.map((week, index) => week.map((dateObj, dayIndex) => {
195
- if (!dateObj) {
196
- return jsxRuntime.jsx("div", {});
197
- }
198
- const {
199
- prevMonth,
200
- nextMonth,
201
- date,
202
- today: today2
203
- } = dateObj;
204
- const selected = date.getTime() === (min == null ? void 0 : min.getTime()) || min && max && dateIntersect(date, {
205
- min,
206
- max
207
- });
208
- const preSelected = !selected && (date.getTime() === (hovered == null ? void 0 : hovered.getTime()) || min && !max && hovered && dateIntersect(date, min <= hovered ? {
209
- min,
210
- max: hovered
211
- } : {
212
- min: hovered,
213
- max: min
214
- }));
215
- return jsxRuntime.jsx("button", __spreadProps(__spreadValues({
216
- css: [{
217
- padding: 10,
218
- border: "1px solid transparent",
219
- background: "transparent",
220
- cursor: "pointer"
221
- }, (prevMonth || nextMonth) && {
222
- color: tableTheme.gray
223
- }, today2 && {
224
- border: "1px solid var(--secondaryMain)"
225
- }, selected && {
226
- background: "var(--primaryMain)",
227
- color: "var(--primaryContrastText)"
228
- }, preSelected && {
229
- background: "var(--primaryLight)",
230
- color: "var(--primaryContrastText)"
231
- }]
232
- }, getDateProps({
233
- dateObj
234
- })), {
235
- onClick: () => {
236
- if (!rangeSelect) {
237
- setCurrentMin(void 0);
238
- onChange(date);
239
- } else if (min && !max) {
240
- setCurrentMin(void 0);
241
- if (date > min) {
242
- onChange({
243
- min,
244
- max: date
245
- });
246
- } else {
247
- onChange({
248
- min: date,
249
- max: min
250
- });
251
- }
252
- } else {
253
- setCurrentMin(date);
254
- }
255
- },
256
- onPointerOver: () => setHovered(date),
257
- onPointerOut: () => setHovered(void 0),
258
- children: date.getDate()
259
- }), `${index}-${dayIndex}`);
260
- }))]
261
- })]
262
- }, `${month}${year}`))
263
- });
107
+ if (value2 instanceof Set) {
108
+ return { __set: Array.from(value2).map(prepare) };
109
+ }
110
+ if (value2 instanceof Map) {
111
+ return { __map: Array.from(value2.entries()).map((entry) => entry.map(prepare)) };
112
+ }
113
+ if (value2 instanceof Array) {
114
+ return value2.map(prepare);
115
+ }
116
+ if (value2 instanceof Object) {
117
+ return Object.fromEntries(Object.entries(value2).map(([k, v]) => [k, prepare(v)]));
118
+ }
119
+ return value2;
120
+ }
121
+ return JSON.stringify(prepare(value));
264
122
  }
265
- function MonthSelector({
266
- value,
267
- onChange,
268
- locale
269
- }) {
270
- const {
271
- components: {
272
- Popover
123
+ function parse(value) {
124
+ return JSON.parse(value, (_key, value2) => {
125
+ if (value2 instanceof Object && "__date" in value2) {
126
+ return new Date(value2.__date);
273
127
  }
274
- } = useTheme();
275
- const cssVariables = useCssVariables();
276
- const [anchor, setAnchor] = react.useState();
277
- const formatMonth = react.useMemo(() => {
278
- const {
279
- format
280
- } = new Intl.DateTimeFormat(locale, {
281
- month: "long"
282
- });
283
- return (month) => format(new Date(2021, month));
284
- }, [locale]);
285
- return jsxRuntime.jsxs(jsxRuntime.Fragment, {
286
- children: [jsxRuntime.jsx("button", {
287
- css: {
288
- border: "none",
289
- background: "transparent",
290
- fontSize: "inherit",
291
- cursor: "pointer"
292
- },
293
- onClick: (e) => setAnchor(e.currentTarget),
294
- children: formatMonth(value)
295
- }), jsxRuntime.jsx(Popover, {
296
- open: !!anchor,
297
- anchorEl: anchor != null ? anchor : null,
298
- onClose: () => setAnchor(void 0),
299
- align: "center",
300
- css: cssVariables,
301
- children: jsxRuntime.jsx("div", {
302
- css: {
303
- display: "grid"
304
- },
305
- children: months.map((month) => jsxRuntime.jsx("button", {
306
- css: [{
307
- padding: "var(--spacing)",
308
- border: "none",
309
- background: "transparent",
310
- "&:hover": {
311
- background: "var(--primaryLight)"
312
- }
313
- }, month === value && {
314
- background: "var(--primaryMain)"
315
- }],
316
- onClick: () => onChange(month),
317
- children: formatMonth(month)
318
- }, month))
319
- })
320
- })]
128
+ if (value2 instanceof Object && "__set" in value2) {
129
+ return new Set(value2.__set);
130
+ }
131
+ if (value2 instanceof Object && "__map" in value2) {
132
+ return new Map(value2.__map);
133
+ }
134
+ return value2;
321
135
  });
322
136
  }
323
- function YearSelector({
324
- value,
325
- onChange,
326
- locale
327
- }) {
328
- const [input, setInput] = react.useState();
329
- const ref = react.useRef(null);
330
- function apply() {
331
- onChange(Number(input));
332
- setInput(void 0);
333
- }
334
- const formatYear = react.useMemo(() => {
335
- const {
336
- format
337
- } = new Intl.DateTimeFormat(locale, {
338
- year: "numeric"
339
- });
340
- return (year) => format(new Date(year, 0, 1));
341
- }, [locale]);
342
- react.useLayoutEffect(() => {
343
- var _a;
344
- return (_a = ref.current) == null ? void 0 : _a.focus();
345
- }, [ref.current]);
346
- if (input === void 0) {
347
- return jsxRuntime.jsx("div", {
348
- onClick: () => setInput(String(value)),
349
- children: formatYear(value)
350
- });
351
- }
352
- return jsxRuntime.jsx("input", {
353
- ref,
354
- css: {
355
- width: "4ch"
356
- },
357
- value: input,
358
- onChange: (e) => {
359
- if (e.target.value.match(/^\d{0,4}$/)) {
360
- setInput(e.target.value);
137
+ function useTableStateStorage() {
138
+ const table = useTableContext();
139
+ const [isHydrated, setIsHydrated] = react.useState(false);
140
+ react.useEffect(() => {
141
+ const { persist } = table.getState().props;
142
+ if (!persist) {
143
+ setIsHydrated(true);
144
+ return;
145
+ }
146
+ let isCanceled = false;
147
+ (async () => {
148
+ var _a, _b;
149
+ try {
150
+ const { storage, id, include, exclude } = persist;
151
+ const json = await storage.getItem(storageName(id));
152
+ if (isCanceled || !json)
153
+ return;
154
+ const data = parse(json);
155
+ (_b = (_a = table.getState().props).debug) == null ? void 0 : _b.call(_a, "load", json, data);
156
+ table.update((state) => {
157
+ var _a2, _b2, _c, _d;
158
+ for (const key of KEYS) {
159
+ if ((!include || include.includes(key)) && !(exclude == null ? void 0 : exclude.includes(key)) && key in data) {
160
+ if (key === "filterValues") {
161
+ for (const [id2, value] of data[key]) {
162
+ if ((_b2 = (_a2 = state.filters.get(id2)) == null ? void 0 : _a2.persist) != null ? _b2 : true) {
163
+ state.filterValues.set(id2, value);
164
+ }
165
+ }
166
+ } else {
167
+ state[key] = data[key];
168
+ if (key === "expanded" || key === "hiddenColumns" || key === "selection" || key === "sort") {
169
+ (_d = (_c = state.props)[`on${key.slice(0, 1).toUpperCase() + key.slice(1)}Change`]) == null ? void 0 : _d.call(_c, data[key]);
170
+ }
171
+ }
172
+ }
173
+ }
174
+ });
175
+ } catch (e) {
176
+ console.error("Failed to load table state:", e);
177
+ } finally {
178
+ setIsHydrated(true);
361
179
  }
362
- },
363
- onBlur: apply,
364
- onKeyPress: (e) => e.key === "Enter" && apply()
365
- });
366
- }
367
- function convertDate(x) {
368
- if (x instanceof Date)
369
- return x;
370
- if (typeof x === "number" || typeof x === "string")
371
- return new Date(x);
372
- return null;
373
- }
374
- function convertDateOrRange(x) {
375
- if (x instanceof Object && "min" in x && "max" in x) {
376
- const range = {
377
- min: convertDate(x.min),
378
- max: convertDate(x.max)
180
+ })();
181
+ return () => {
182
+ isCanceled = true;
379
183
  };
380
- return range.min && range.max ? range : null;
381
- }
382
- return convertDate(x);
383
- }
384
- function convertDateOrArray(x) {
385
- if (x instanceof Array)
386
- return x.map(convertDateOrRange).filter(Boolean);
387
- return convertDateOrRange(x);
388
- }
389
- function DateFilter(_a) {
390
- var _b = _a, {
391
- locale,
392
- firstDayOfWeek,
393
- singleSelect,
394
- filterBy = convertDateOrArray
395
- } = _b, props = __objRest(_b, [
396
- "locale",
397
- "firstDayOfWeek",
398
- "singleSelect",
399
- "filterBy"
400
- ]);
401
- const {
402
- components: {
403
- Button
404
- },
405
- text
406
- } = useTheme();
407
- const {
408
- value = null,
409
- onChange
410
- } = useFilter(__spreadProps(__spreadValues({}, props), {
411
- filterBy,
412
- id: "dateFilter",
413
- isActive(filterValue) {
414
- return !!filterValue;
415
- },
416
- test(filterValue, value2) {
417
- return dateIntersect(filterValue, value2);
418
- }
419
- }));
420
- const formatDate = react.useMemo(() => {
421
- const {
422
- format
423
- } = new Intl.DateTimeFormat(locale, {
424
- dateStyle: "medium"
425
- });
426
- return format;
427
- }, [locale]);
428
- return jsxRuntime.jsxs("div", {
429
- css: {
430
- padding: "calc(var(--spacing) * 2)",
431
- display: "grid"
432
- },
433
- children: [!singleSelect && jsxRuntime.jsxs("div", {
434
- css: {
435
- marginBottom: "var(--spacing)",
436
- display: "flex",
437
- justifyContent: "center"
438
- },
439
- children: [value ? formatDate(value instanceof Date ? value : value.min) : "", " -", " ", value ? formatDate(value instanceof Date ? value : value.max) : ""]
440
- }), jsxRuntime.jsx(DatePicker, {
441
- rangeSelect: !singleSelect,
442
- value,
443
- onChange,
444
- locale,
445
- firstDayOfWeek
446
- }), jsxRuntime.jsxs("div", {
447
- css: {
448
- marginTop: "var(--spacing)",
449
- display: "grid",
450
- gridAutoFlow: "column",
451
- justifyContent: "center"
452
- },
453
- children: [jsxRuntime.jsx(Button, {
454
- variant: "text",
455
- onClick: () => onChange(today()),
456
- children: text.today
457
- }), jsxRuntime.jsx(Button, {
458
- variant: "text",
459
- onClick: () => onChange(thisWeek(firstDayOfWeek)),
460
- children: text.thisWeek
461
- }), jsxRuntime.jsx(Button, {
462
- variant: "text",
463
- onClick: () => onChange(null),
464
- children: text.reset
465
- })]
466
- })]
467
- });
184
+ }, []);
185
+ react.useEffect(() => {
186
+ if (!isHydrated)
187
+ return;
188
+ const q = new Queue();
189
+ return table.subscribe((state) => {
190
+ var _a, _b;
191
+ if (!state.props.persist)
192
+ return;
193
+ const { storage, id, include, exclude } = state.props.persist;
194
+ const data = {};
195
+ for (const key of KEYS) {
196
+ if ((!include || include.includes(key)) && !(exclude == null ? void 0 : exclude.includes(key))) {
197
+ if (key === "filterValues") {
198
+ data[key] = /* @__PURE__ */ new Map();
199
+ for (const [id2, value] of state.filterValues) {
200
+ if ((_b = (_a = state.filters.get(id2)) == null ? void 0 : _a.persist) != null ? _b : true) {
201
+ data.filterValues.set(id2, value);
202
+ }
203
+ }
204
+ } else {
205
+ data[key] = state[key];
206
+ }
207
+ }
208
+ }
209
+ return { storage, id, data };
210
+ }, (props) => {
211
+ var _a, _b;
212
+ if (!props)
213
+ return;
214
+ const { storage, id, data } = props;
215
+ (_b = (_a = table.getState().props).debug) == null ? void 0 : _b.call(_a, "save", data, stringify(data));
216
+ q.run(async () => {
217
+ await storage.setItem(storageName(id), stringify(data));
218
+ }, true);
219
+ }, { throttle: 1e3 });
220
+ }, [isHydrated]);
221
+ return isHydrated;
468
222
  }
469
- const today = () => {
470
- const today2 = startOfDay(new Date());
471
- return {
472
- min: today2,
473
- max: today2
474
- };
475
- };
476
- const thisWeek = (firstDayOfWeek = 0) => {
477
- const now = new Date();
478
- const min = new Date(now);
479
- let diff = min.getDay() - firstDayOfWeek;
480
- if (diff < 0) {
481
- diff += 7;
482
- }
483
- min.setDate(min.getDate() - diff);
484
- const max = new Date(min);
485
- max.setDate(max.getDate() + 6);
486
- return {
487
- min: startOfDay(min),
488
- max: endOfDay(max)
489
- };
490
- };
491
223
  const flatMap = (arr, flatMap2) => {
492
224
  return [...arr].reduce((out, cur) => out.concat(flatMap2(cur)), []);
493
225
  };
@@ -564,185 +296,8 @@ const cx = (...classNames) => classNames.flatMap((entry) => {
564
296
  return [];
565
297
  if (typeof entry === "string")
566
298
  return [entry];
567
- return Object.entries(entry).filter(([, predicate]) => predicate).map(([className]) => className);
299
+ return Object.entries(entry).filter(([, predicate]) => predicate).map(([className2]) => className2);
568
300
  }).join(" ");
569
- function FormControlLabel({
570
- control,
571
- label,
572
- disabled
573
- }) {
574
- return jsxRuntime.jsxs("label", {
575
- css: [{
576
- display: "flex",
577
- alignItems: "center",
578
- cursor: "pointer",
579
- userSelect: "none",
580
- "& > *": {
581
- cursor: "pointer"
582
- }
583
- }, disabled && {
584
- color: "rgba(0, 0, 0, 0.26)"
585
- }],
586
- children: [control, jsxRuntime.jsx("span", {
587
- css: {
588
- marginLeft: "var(--spacing)"
589
- },
590
- children: label
591
- })]
592
- });
593
- }
594
- class Queue {
595
- constructor() {
596
- this.q = new Array();
597
- this.isRunning = false;
598
- }
599
- run(job, replace) {
600
- return new Promise((resolve, reject) => {
601
- if (replace) {
602
- this.q = [];
603
- }
604
- this.q.push({ job, resolve, reject });
605
- if (!this.isRunning)
606
- this.start();
607
- });
608
- }
609
- async start() {
610
- this.isRunning = true;
611
- let next;
612
- while (next = this.q.shift()) {
613
- try {
614
- const result = await next.job();
615
- next.resolve(result);
616
- } catch (e) {
617
- next.reject(e);
618
- }
619
- }
620
- this.isRunning = false;
621
- }
622
- }
623
- const KEYS = ["sort", "selection", "expanded", "hiddenColumns", "filterValues", "columnWidths", "columnOrder"];
624
- const storageName = (id) => `schummar-table_state-v1_${id}`;
625
- function stringify(value) {
626
- function prepare(value2) {
627
- if (value2 instanceof Date) {
628
- return { __date: value2.toJSON() };
629
- }
630
- if (value2 instanceof Set) {
631
- return { __set: Array.from(value2).map(prepare) };
632
- }
633
- if (value2 instanceof Map) {
634
- return { __map: Array.from(value2.entries()).map((entry) => entry.map(prepare)) };
635
- }
636
- if (value2 instanceof Array) {
637
- return value2.map(prepare);
638
- }
639
- if (value2 instanceof Object) {
640
- return Object.fromEntries(Object.entries(value2).map(([k, v]) => [k, prepare(v)]));
641
- }
642
- return value2;
643
- }
644
- return JSON.stringify(prepare(value));
645
- }
646
- function parse(value) {
647
- return JSON.parse(value, (_key, value2) => {
648
- if (value2 instanceof Object && "__date" in value2) {
649
- return new Date(value2.__date);
650
- }
651
- if (value2 instanceof Object && "__set" in value2) {
652
- return new Set(value2.__set);
653
- }
654
- if (value2 instanceof Object && "__map" in value2) {
655
- return new Map(value2.__map);
656
- }
657
- return value2;
658
- });
659
- }
660
- function useTableStateStorage() {
661
- const table = useTableContext();
662
- const [isHydrated, setIsHydrated] = react.useState(false);
663
- react.useEffect(() => {
664
- const { persist } = table.getState().props;
665
- if (!persist) {
666
- setIsHydrated(true);
667
- return;
668
- }
669
- let isCanceled = false;
670
- (async () => {
671
- var _a, _b;
672
- try {
673
- const { storage, id, include, exclude } = persist;
674
- const json = await storage.getItem(storageName(id));
675
- if (isCanceled || !json)
676
- return;
677
- const data = parse(json);
678
- (_b = (_a = table.getState().props).debug) == null ? void 0 : _b.call(_a, "load", json, data);
679
- table.update((state) => {
680
- var _a2, _b2, _c, _d;
681
- for (const key of KEYS) {
682
- if ((!include || include.includes(key)) && !(exclude == null ? void 0 : exclude.includes(key)) && key in data) {
683
- if (key === "filterValues") {
684
- for (const [id2, value] of data[key]) {
685
- if ((_b2 = (_a2 = state.filters.get(id2)) == null ? void 0 : _a2.persist) != null ? _b2 : true) {
686
- state.filterValues.set(id2, value);
687
- }
688
- }
689
- } else {
690
- state[key] = data[key];
691
- if (key === "expanded" || key === "hiddenColumns" || key === "selection" || key === "sort") {
692
- (_d = (_c = state.props)[`on${key.slice(0, 1).toUpperCase() + key.slice(1)}Change`]) == null ? void 0 : _d.call(_c, data[key]);
693
- }
694
- }
695
- }
696
- }
697
- });
698
- } catch (e) {
699
- console.error("Failed to load table state:", e);
700
- } finally {
701
- setIsHydrated(true);
702
- }
703
- })();
704
- return () => {
705
- isCanceled = true;
706
- };
707
- }, []);
708
- react.useEffect(() => {
709
- if (!isHydrated)
710
- return;
711
- const q = new Queue();
712
- return table.subscribe((state) => {
713
- var _a, _b;
714
- if (!state.props.persist)
715
- return;
716
- const { storage, id, include, exclude } = state.props.persist;
717
- const data = {};
718
- for (const key of KEYS) {
719
- if ((!include || include.includes(key)) && !(exclude == null ? void 0 : exclude.includes(key))) {
720
- if (key === "filterValues") {
721
- data[key] = /* @__PURE__ */ new Map();
722
- for (const [id2, value] of state.filterValues) {
723
- if ((_b = (_a = state.filters.get(id2)) == null ? void 0 : _a.persist) != null ? _b : true) {
724
- data.filterValues.set(id2, value);
725
- }
726
- }
727
- } else {
728
- data[key] = state[key];
729
- }
730
- }
731
- }
732
- return { storage, id, data };
733
- }, (props) => {
734
- var _a, _b;
735
- if (!props)
736
- return;
737
- const { storage, id, data } = props;
738
- (_b = (_a = table.getState().props).debug) == null ? void 0 : _b.call(_a, "save", data, stringify(data));
739
- q.run(async () => {
740
- await storage.setItem(storageName(id), stringify(data));
741
- }, true);
742
- }, { throttle: 1e3 });
743
- }, [isHydrated]);
744
- return isHydrated;
745
- }
746
301
  function calcItems(state) {
747
302
  react.useEffect(() => state.addReaction((state2) => [
748
303
  state2.props.items,
@@ -768,8 +323,10 @@ function calcItems(state) {
768
323
  const column = activeColumns.find((column2) => column2.id === sort2.columnId);
769
324
  if (!column)
770
325
  return [];
771
- const sortBy = column.sortBy instanceof Array ? column.sortBy : [column.sortBy];
772
- return sortBy.map((sortBy2) => ({ selector: (item) => sortBy2(column.value(item), item), direction: sort2.direction }));
326
+ return column.sortBy.map((sortBy) => ({
327
+ selector: (item) => sortBy(column.value(item), item),
328
+ direction: sort2.direction
329
+ }));
773
330
  }).filter(Boolean);
774
331
  sorted = orderBy(tableItems, selectors.map((x) => x.selector), selectors.map((x) => x.direction));
775
332
  }
@@ -841,20 +398,20 @@ function calcItems(state) {
841
398
  }
842
399
  const noopParentId = () => void 0;
843
400
  function calcProps(props) {
844
- const columnCache = react.useRef(/* @__PURE__ */ new Map());
401
+ const cache = useTableMemo();
845
402
  return react.useMemo(() => {
846
- var _c, _d, _e, _f, _g, _h;
403
+ var _e, _f, _g, _h, _i, _j;
847
404
  let id;
848
- if (props.id instanceof Function) {
849
- id = props.id;
405
+ if (props.id instanceof Function || Array.isArray(props.id)) {
406
+ id = cache("id", props.id);
850
407
  } else {
851
- id = (item) => item[props.id];
408
+ id = cache("id", [(item) => item[props.id], props.id]);
852
409
  }
853
410
  let parentId;
854
- if (props.parentId instanceof Function) {
855
- parentId = props.parentId;
856
- } else if (typeof props.parentId === "string") {
857
- parentId = (item) => item[props.parentId];
411
+ if (props.parentId instanceof Function || Array.isArray(props.parentId)) {
412
+ parentId = cache("parentId", props.parentId);
413
+ } else if (props.parentId !== void 0) {
414
+ parentId = cache("parentId", [(item) => item[props.parentId], props.parentId]);
858
415
  } else {
859
416
  parentId = noopParentId;
860
417
  }
@@ -864,42 +421,37 @@ function calcProps(props) {
864
421
  } else {
865
422
  inputColumns = props.columns.map((column) => __spreadProps(__spreadValues({}, column), { dependecies: void 0 }));
866
423
  }
867
- const newColumnCache = /* @__PURE__ */ new Map();
868
- const columns = inputColumns.map(function(_a, index) {
869
- var _b = _a, {
424
+ const defCol = props.defaultColumnProps;
425
+ const mapColumn = ({
426
+ id: _id,
427
+ header = ((_a) => (_a = defCol == null ? void 0 : defCol.header) != null ? _a : null)(),
428
+ value,
429
+ renderCell = ((_b) => (_b = defCol == null ? void 0 : defCol.renderCell) != null ? _b : asString)(),
430
+ exportCell = ((_c) => (_c = defCol == null ? void 0 : defCol.exportCell) != null ? _c : asString)(),
431
+ sortBy = ((_d) => (_d = defCol == null ? void 0 : defCol.sortBy) != null ? _d : [(v) => typeof v === "number" || v instanceof Date ? v : String(v)])(),
432
+ cannotHide = defCol == null ? void 0 : defCol.cannotHide,
433
+ classes = defCol == null ? void 0 : defCol.classes,
434
+ filter = defCol == null ? void 0 : defCol.filter,
435
+ width = defCol == null ? void 0 : defCol.width
436
+ }, index) => {
437
+ const id2 = _id != null ? _id : index;
438
+ const cacheKey = typeof id2 === "string" ? `s${id2}` : `n${id2}`;
439
+ return {
870
440
  id: id2,
871
- header = null,
872
- renderCell = asString,
873
- exportCell = asString,
874
- sortBy = (v) => typeof v === "number" || v instanceof Date ? v : String(v),
875
- dependencies = []
876
- } = _b, props2 = __objRest(_b, [
877
- "id",
878
- "header",
879
- "renderCell",
880
- "exportCell",
881
- "sortBy",
882
- "dependencies"
883
- ]);
884
- var _a2;
885
- const [depsInCache, columnInCache] = (_a2 = columnCache.current.get(id2 != null ? id2 : index)) != null ? _a2 : [];
886
- let column;
887
- if (depsInCache && columnInCache && depsInCache.length === dependencies.length && depsInCache.every((x, i) => dependencies[i] === x)) {
888
- column = columnInCache;
889
- } else {
890
- column = __spreadValues({
891
- id: id2 != null ? id2 : index,
892
- header,
893
- renderCell,
894
- exportCell,
895
- sortBy,
896
- dependencies
897
- }, props2);
898
- }
899
- newColumnCache.set(id2 != null ? id2 : index, [dependencies, column]);
900
- return column;
901
- });
902
- columnCache.current = newColumnCache;
441
+ header,
442
+ value: cache(`columns.${cacheKey}.value`, value),
443
+ renderCell: cache(`columns.${cacheKey}.renderCell`, renderCell),
444
+ exportCell,
445
+ sortBy: sortBy.map((fn, i) => cache(`columns.${cacheKey}.sortBy.${i}`, fn)),
446
+ cannotHide,
447
+ classes,
448
+ filter,
449
+ width
450
+ };
451
+ };
452
+ const columns = inputColumns.map(mapColumn);
453
+ const wrapCell = props.wrapCell && cache("wrapCell", props.wrapCell);
454
+ const rowAction = props.rowAction instanceof Function || Array.isArray(props.rowAction) ? cache("rowAction", props.rowAction) : props.rowAction;
903
455
  let copy;
904
456
  if (props.enableExport === true || props.enableExport instanceof Object && props.enableExport.copy === true) {
905
457
  copy = { separator: " " };
@@ -917,13 +469,15 @@ function calcProps(props) {
917
469
  id,
918
470
  parentId,
919
471
  columns,
920
- enableSelection: (_c = props.enableSelection) != null ? _c : true,
921
- selectSyncChildren: (_d = props.selectSyncChildren) != null ? _d : true,
922
- stickyHeader: (_e = props.stickyHeader) != null ? _e : true,
472
+ wrapCell,
473
+ rowAction,
474
+ enableSelection: (_e = props.enableSelection) != null ? _e : true,
475
+ selectSyncChildren: (_f = props.selectSyncChildren) != null ? _f : true,
476
+ stickyHeader: (_g = props.stickyHeader) != null ? _g : true,
923
477
  enableExport,
924
- enableColumnSelection: (_f = props.enableColumnSelection) != null ? _f : true,
925
- enableColumnResize: (_g = props.enableColumnResize) != null ? _g : true,
926
- enableColumnReorder: (_h = props.enableColumnReorder) != null ? _h : true
478
+ enableColumnSelection: (_h = props.enableColumnSelection) != null ? _h : true,
479
+ enableColumnResize: (_i = props.enableColumnResize) != null ? _i : true,
480
+ enableColumnReorder: (_j = props.enableColumnReorder) != null ? _j : true
927
481
  });
928
482
  }, [props]);
929
483
  }
@@ -1005,12 +559,10 @@ function syncSelections(table) {
1005
559
  }
1006
560
  function useTableState(_props) {
1007
561
  const props = calcProps(_props);
1008
- const theme = tableTheme.useTableTheme(props);
1009
562
  const state = react.useMemo(() => {
1010
563
  var _a, _b, _c, _d;
1011
564
  return new react$1.Store({
1012
565
  props,
1013
- theme,
1014
566
  sort: (_a = props.defaultSort) != null ? _a : [],
1015
567
  selection: (_b = props.defaultSelection) != null ? _b : /* @__PURE__ */ new Set(),
1016
568
  expanded: (_c = props.defaultExpanded) != null ? _c : /* @__PURE__ */ new Set(),
@@ -1050,11 +602,21 @@ function useTableState(_props) {
1050
602
  state2.columnOrder.splice(index, 0, column.id);
1051
603
  }
1052
604
  }
1053
- state2.theme = theme;
1054
605
  });
1055
606
  }, [state, props]);
1056
607
  return state;
1057
608
  }
609
+ function useCssVariables() {
610
+ return useTheme(({ spacing, colors }) => ({
611
+ "--spacing": spacing,
612
+ "--primaryMain": colors.primary.main,
613
+ "--primaryLight": colors.primary.light,
614
+ "--primaryContrastText": colors.primary.contrastText,
615
+ "--secondaryMain": colors.secondary.main,
616
+ "--secondaryLight": colors.secondary.light,
617
+ "--secondaryContrastText": colors.secondary.contrastText
618
+ }));
619
+ }
1058
620
  const ColumnHeaderContext = new react$1.StoreScope({
1059
621
  items: /* @__PURE__ */ new Map()
1060
622
  });
@@ -1193,18 +755,37 @@ function ColumnHeader(props) {
1193
755
  children: props.children
1194
756
  }));
1195
757
  }
758
+ function FormControlLabel({
759
+ control,
760
+ label,
761
+ disabled
762
+ }) {
763
+ return jsxRuntime.jsxs("label", {
764
+ css: [{
765
+ display: "flex",
766
+ alignItems: "center",
767
+ cursor: "pointer",
768
+ userSelect: "none",
769
+ "& > *": {
770
+ cursor: "pointer"
771
+ }
772
+ }, disabled && {
773
+ color: "rgba(0, 0, 0, 0.26)"
774
+ }],
775
+ children: [control, jsxRuntime.jsx("span", {
776
+ css: {
777
+ marginLeft: "var(--spacing)"
778
+ },
779
+ children: label
780
+ })]
781
+ });
782
+ }
1196
783
  function ColumnSelection() {
1197
- const {
1198
- components: {
1199
- IconButton,
1200
- Popover,
1201
- Checkbox
1202
- },
1203
- icons: {
1204
- Settings
1205
- },
1206
- text
1207
- } = useTheme();
784
+ const IconButton2 = useTheme((t) => t.components.IconButton);
785
+ const Popover = useTheme((t) => t.components.Popover);
786
+ const Checkbox2 = useTheme((t) => t.components.Checkbox);
787
+ const Settings2 = useTheme((t) => t.icons.Settings);
788
+ const selectColumns = useTheme((t) => t.text.selectColumns);
1208
789
  const cssVariables = useCssVariables();
1209
790
  const table = useTableContext();
1210
791
  const columns = table.useState("props.columns");
@@ -1230,9 +811,9 @@ function ColumnSelection() {
1230
811
  onHiddenColumnsChange == null ? void 0 : onHiddenColumnsChange(newValue);
1231
812
  };
1232
813
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
1233
- children: [jsxRuntime.jsx(IconButton, {
814
+ children: [jsxRuntime.jsx(IconButton2, {
1234
815
  onClick: (e) => setAnchorEl(anchorEl ? null : e.currentTarget),
1235
- children: jsxRuntime.jsx(Settings, {})
816
+ children: jsxRuntime.jsx(Settings2, {})
1236
817
  }), jsxRuntime.jsx(Popover, {
1237
818
  anchorEl,
1238
819
  open: !!anchorEl,
@@ -1247,9 +828,9 @@ function ColumnSelection() {
1247
828
  css: {
1248
829
  marginBottom: "var(--spacing)"
1249
830
  },
1250
- children: text.selectColumns
831
+ children: selectColumns
1251
832
  }), columns.map((column) => jsxRuntime.jsx(FormControlLabel, {
1252
- control: jsxRuntime.jsx(Checkbox, {
833
+ control: jsxRuntime.jsx(Checkbox2, {
1253
834
  checked: !hiddenColumns.has(column.id),
1254
835
  onChange: () => toggle2(column),
1255
836
  disabled: column.cannotHide
@@ -1272,20 +853,16 @@ function csvExport(data, { sepPrefix, separator = ",", quote = '"', eol = "\n" }
1272
853
  return (sepPrefix ? `SEP=${separator}
1273
854
  ` : "") + cells.map((line) => line.join(separator)).join(eol);
1274
855
  }
1275
- function Export() {
856
+ function Export$1() {
1276
857
  const table = useTableContext();
1277
- const {
1278
- components: {
1279
- Button,
1280
- IconButton,
1281
- Popover
1282
- },
1283
- icons: {
1284
- Export: Export2,
1285
- Clipboard
1286
- },
1287
- text
1288
- } = useTheme();
858
+ const Button2 = useTheme((t) => t.components.Button);
859
+ const IconButton2 = useTheme((t) => t.components.IconButton);
860
+ const Popover = useTheme((t) => t.components.Popover);
861
+ const Export2 = useTheme((t) => t.icons.Export);
862
+ const Clipboard2 = useTheme((t) => t.icons.Clipboard);
863
+ const exportTitle = useTheme((t) => t.text.exportTitle);
864
+ const exportCopy = useTheme((t) => t.text.exportCopy);
865
+ const exportDownload = useTheme((t) => t.text.exportDownload);
1289
866
  const cssVariables = useCssVariables();
1290
867
  const [anchor, setAnchor] = react.useState(null);
1291
868
  const generate = (options) => {
@@ -1308,7 +885,7 @@ function Export() {
1308
885
  document.body.removeChild(a);
1309
886
  };
1310
887
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
1311
- children: [jsxRuntime.jsx(IconButton, {
888
+ children: [jsxRuntime.jsx(IconButton2, {
1312
889
  onClick: (e) => setAnchor(anchor ? null : e.currentTarget),
1313
890
  children: jsxRuntime.jsx(Export2, {
1314
891
  css: !!anchor && {
@@ -1334,15 +911,15 @@ function Export() {
1334
911
  css: {
1335
912
  marginBottom: "var(--spacing)"
1336
913
  },
1337
- children: text.exportTitle
1338
- }), jsxRuntime.jsx(Button, {
1339
- startIcon: jsxRuntime.jsx(Clipboard, {}),
914
+ children: exportTitle
915
+ }), jsxRuntime.jsx(Button2, {
916
+ startIcon: jsxRuntime.jsx(Clipboard2, {}),
1340
917
  onClick: copy,
1341
- children: text.exportCopy
1342
- }), jsxRuntime.jsx(Button, {
918
+ children: exportCopy
919
+ }), jsxRuntime.jsx(Button2, {
1343
920
  startIcon: jsxRuntime.jsx(Export2, {}),
1344
921
  onClick: download,
1345
- children: text.exportDownload
922
+ children: exportDownload
1346
923
  })]
1347
924
  })
1348
925
  })]
@@ -1352,16 +929,10 @@ const FilterControlContext = react.createContext(() => void 0);
1352
929
  function FilterControl() {
1353
930
  const table = useTableContext();
1354
931
  const columnId = useColumnContext();
1355
- const {
1356
- components: {
1357
- IconButton,
1358
- Popover
1359
- },
1360
- icons: {
1361
- FilterList,
1362
- ArrowDropDown
1363
- }
1364
- } = useTheme();
932
+ const IconButton2 = useTheme((t) => t.components.IconButton);
933
+ const Popover = useTheme((t) => t.components.Popover);
934
+ const FilterList2 = useTheme((t) => t.icons.FilterList);
935
+ const ArrowDropDown2 = useTheme((t) => t.icons.ArrowDropDown);
1365
936
  const cssVariables = useCssVariables();
1366
937
  const [anchor, setAnchor] = react.useState(null);
1367
938
  const isActive = table.useState((state) => {
@@ -1392,13 +963,13 @@ function FilterControl() {
1392
963
  e.preventDefault();
1393
964
  return false;
1394
965
  },
1395
- children: jsxRuntime.jsx(IconButton, {
966
+ children: jsxRuntime.jsx(IconButton2, {
1396
967
  css: [{
1397
968
  color: "#b0bac9"
1398
969
  }, isActive && {
1399
970
  color: "var(--primaryMain) !important"
1400
971
  }],
1401
- children: isActive ? jsxRuntime.jsx(FilterList, {}) : jsxRuntime.jsx(ArrowDropDown, {})
972
+ children: isActive ? jsxRuntime.jsx(FilterList2, {}) : jsxRuntime.jsx(ArrowDropDown2, {})
1402
973
  })
1403
974
  }), jsxRuntime.jsx("div", {
1404
975
  onPointerDown: (e) => {
@@ -1460,10 +1031,10 @@ function ResizeHandle() {
1460
1031
  onDoubleClick: enabled ? onDoubleClick : void 0
1461
1032
  });
1462
1033
  }
1463
- function ResizeHandleView(_c) {
1464
- var _d = _c, {
1034
+ function ResizeHandleView(_a) {
1035
+ var _b = _a, {
1465
1036
  enabled
1466
- } = _d, props = __objRest(_d, [
1037
+ } = _b, props = __objRest(_b, [
1467
1038
  "enabled"
1468
1039
  ]);
1469
1040
  return jsxRuntime.jsx("div", __spreadValues({
@@ -1483,49 +1054,56 @@ function ResizeHandleView(_c) {
1483
1054
  }
1484
1055
  }, props));
1485
1056
  }
1057
+ const defaultWrapCell = (content) => {
1058
+ if (typeof content === "string") {
1059
+ return jsxRuntime.jsx("span", {
1060
+ css: tableTheme.defaultClasses.text,
1061
+ title: content,
1062
+ children: content
1063
+ });
1064
+ }
1065
+ return content;
1066
+ };
1486
1067
  const Cell = react.memo(function Cell2({
1487
1068
  itemId,
1488
1069
  rowIndex
1489
1070
  }) {
1490
- var _a, _b;
1071
+ var _a;
1491
1072
  const table = useTableContext();
1492
1073
  const columnId = useColumnContext();
1493
- const {
1494
- classes
1495
- } = useTheme();
1496
- const column = table.useState((state) => state.activeColumns.find((column2) => column2.id === columnId));
1074
+ const column = table.useState((state) => {
1075
+ const col = state.activeColumns.find((column2) => column2.id === columnId);
1076
+ return col && {
1077
+ value: col.value,
1078
+ renderCell: col.renderCell
1079
+ };
1080
+ });
1081
+ const wrapCell = (_a = table.useState((state) => state.props.wrapCell)) != null ? _a : defaultWrapCell;
1497
1082
  const item = table.useState((state) => state.activeItemsById.get(itemId));
1498
1083
  const columnStyleOverride = table.useState((state) => state.columnStyleOverride.get(columnId), {
1499
1084
  throttle: 16
1500
1085
  });
1086
+ react.useLayoutEffect(() => {
1087
+ var _a2, _b;
1088
+ return (_b = (_a2 = table.getState().props).debugRender) == null ? void 0 : _b.call(_a2, "render cell", itemId, columnId);
1089
+ });
1090
+ const className2 = useTheme((t) => cx(...calcClassNames(t.classes, item, rowIndex)));
1501
1091
  if (!column || !item)
1502
1092
  return null;
1503
- (_b = (_a = table.getState().props).debugRender) == null ? void 0 : _b.call(_a, "render cell", itemId, columnId);
1504
- const classNames = [...calcClassNames(classes, item, rowIndex), ...calcClassNames(column == null ? void 0 : column.classes, item, rowIndex)];
1505
1093
  const content = column.renderCell(column.value(item), item);
1506
1094
  return jsxRuntime.jsx("div", {
1507
- className: cx(...classNames),
1508
- css: [tableTheme.defaultClasses.cell, classNames, columnStyleOverride],
1509
- children: typeof content === "string" ? jsxRuntime.jsx("span", {
1510
- css: tableTheme.defaultClasses.text,
1511
- title: content,
1512
- children: content
1513
- }) : content
1095
+ className: className2,
1096
+ css: [tableTheme.defaultClasses.cell, columnStyleOverride],
1097
+ children: wrapCell(content, column.value(item), item, rowIndex)
1514
1098
  });
1515
1099
  });
1516
1100
  function ExpandControl({
1517
1101
  itemId,
1518
1102
  hasDeferredChildren
1519
1103
  }) {
1520
- const {
1521
- components: {
1522
- IconButton,
1523
- Spinner
1524
- },
1525
- icons: {
1526
- ChevronRight
1527
- }
1528
- } = useTheme();
1104
+ const IconButton2 = useTheme((t) => t.components.IconButton);
1105
+ const Spinner2 = useTheme((t) => t.components.Spinner);
1106
+ const ChevronRight2 = useTheme((t) => t.icons.ChevronRight);
1529
1107
  const table = useTableContext();
1530
1108
  const isExpanded = table.useState((state) => state.expanded.has(itemId));
1531
1109
  const hasChildren = table.useState((state) => {
@@ -1562,13 +1140,13 @@ function ExpandControl({
1562
1140
  }
1563
1141
  }
1564
1142
  if (isExpanded && hasDeferredChildren && !hasChildren) {
1565
- return jsxRuntime.jsx(Spinner, {
1143
+ return jsxRuntime.jsx(Spinner2, {
1566
1144
  css: {
1567
1145
  margin: "0 var(--spacing)"
1568
1146
  }
1569
1147
  });
1570
1148
  }
1571
- return jsxRuntime.jsx(IconButton, {
1149
+ return jsxRuntime.jsx(IconButton2, {
1572
1150
  onClick: toggle2,
1573
1151
  children: jsxRuntime.jsx("span", {
1574
1152
  css: {
@@ -1576,7 +1154,7 @@ function ExpandControl({
1576
1154
  transition: "all 300ms",
1577
1155
  transform: isExpanded ? "rotate3d(0, 0, 1, 90deg)" : "rotate3d(0, 0, 1, 0deg)"
1578
1156
  },
1579
- children: jsxRuntime.jsx(ChevronRight, {})
1157
+ children: jsxRuntime.jsx(ChevronRight2, {})
1580
1158
  })
1581
1159
  });
1582
1160
  }
@@ -1584,11 +1162,7 @@ function SelectComponent({
1584
1162
  itemId
1585
1163
  }) {
1586
1164
  const table = useTableContext();
1587
- const {
1588
- components: {
1589
- Checkbox
1590
- }
1591
- } = useTheme();
1165
+ const Checkbox2 = useTheme((t) => t.components.Checkbox);
1592
1166
  const isSelected = table.useState((state) => {
1593
1167
  const itemIds = itemId ? [itemId] : Array.from(state.activeItemsById.keys());
1594
1168
  return state.activeItemsById.size > 0 && itemIds.every((itemId2) => state.selection.has(itemId2));
@@ -1640,7 +1214,7 @@ function SelectComponent({
1640
1214
  state.lastSelectedId = itemId;
1641
1215
  });
1642
1216
  }
1643
- return jsxRuntime.jsx(Checkbox, {
1217
+ return jsxRuntime.jsx(Checkbox2, {
1644
1218
  css: {
1645
1219
  justifySelf: "start",
1646
1220
  color: "#c9cfda"
@@ -1656,11 +1230,11 @@ const Row = react.memo(function Row2({
1656
1230
  itemId,
1657
1231
  rowIndex
1658
1232
  }) {
1659
- var _a, _b;
1660
1233
  const table = useTableContext();
1661
1234
  const divRef = react.useRef(null);
1235
+ const classes = useTheme((t) => t.classes);
1662
1236
  const {
1663
- className,
1237
+ className: className2,
1664
1238
  indent,
1665
1239
  hasChildren,
1666
1240
  hasDeferredChildren,
@@ -1668,17 +1242,16 @@ const Row = react.memo(function Row2({
1668
1242
  enableSelection,
1669
1243
  rowAction
1670
1244
  } = table.useState((state) => {
1671
- var _a2, _b2;
1245
+ var _a, _b;
1672
1246
  const item = state.activeItemsById.get(itemId);
1673
- const index = !item ? -1 : state.activeItems.indexOf(item);
1674
1247
  return {
1675
- className: cx(...calcClassNames(state.props.classes, item, index)),
1248
+ className: cx(...calcClassNames(classes, item, rowIndex)),
1676
1249
  indent: item ? getAncestors(state.activeItemsById, item).size : 0,
1677
1250
  hasChildren: !!(item == null ? void 0 : item.children.length),
1678
- hasDeferredChildren: item && ((_b2 = (_a2 = state.props).hasDeferredChildren) == null ? void 0 : _b2.call(_a2, item)),
1251
+ hasDeferredChildren: item && ((_b = (_a = state.props).hasDeferredChildren) == null ? void 0 : _b.call(_a, item)),
1679
1252
  columnIds: state.activeColumns.map((column) => column.id),
1680
1253
  enableSelection: state.props.enableSelection,
1681
- rowAction: state.props.rowAction instanceof Function ? item ? state.props.rowAction(item, index) : null : state.props.rowAction
1254
+ rowAction: state.props.rowAction instanceof Function ? item ? state.props.rowAction(item, rowIndex) : null : state.props.rowAction
1682
1255
  };
1683
1256
  });
1684
1257
  react.useEffect(() => {
@@ -1695,14 +1268,17 @@ const Row = react.memo(function Row2({
1695
1268
  o.observe(div);
1696
1269
  return () => o.disconnect();
1697
1270
  }, [divRef.current]);
1698
- (_b = (_a = table.getState().props).debugRender) == null ? void 0 : _b.call(_a, "render row", itemId);
1271
+ react.useLayoutEffect(() => {
1272
+ var _a, _b;
1273
+ return (_b = (_a = table.getState().props).debugRender) == null ? void 0 : _b.call(_a, "render row", itemId);
1274
+ });
1699
1275
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
1700
1276
  children: [jsxRuntime.jsx("div", {
1701
- className,
1277
+ className: className2,
1702
1278
  css: [tableTheme.defaultClasses.cellFill],
1703
1279
  ref: divRef
1704
1280
  }), jsxRuntime.jsxs("div", {
1705
- className,
1281
+ className: className2,
1706
1282
  css: [tableTheme.defaultClasses.cell, tableTheme.defaultClasses.firstCell],
1707
1283
  children: [jsxRuntime.jsx("div", {
1708
1284
  css: {
@@ -1721,7 +1297,7 @@ const Row = react.memo(function Row2({
1721
1297
  rowIndex
1722
1298
  })
1723
1299
  }, columnId)), jsxRuntime.jsx("div", {
1724
- className,
1300
+ className: className2,
1725
1301
  css: [tableTheme.defaultClasses.cellFill]
1726
1302
  })]
1727
1303
  });
@@ -1731,14 +1307,8 @@ function SortComponent({
1731
1307
  }) {
1732
1308
  const table = useTableContext();
1733
1309
  const columnId = useColumnContext();
1734
- const {
1735
- components: {
1736
- Badge
1737
- },
1738
- icons: {
1739
- ArrowUpward
1740
- }
1741
- } = useTheme();
1310
+ const Badge2 = useTheme((t) => t.components.Badge);
1311
+ const ArrowUpward2 = useTheme((t) => t.icons.ArrowUpward);
1742
1312
  const {
1743
1313
  direction,
1744
1314
  index
@@ -1790,7 +1360,7 @@ function SortComponent({
1790
1360
  onContextMenu: (e) => toggle2(e, true),
1791
1361
  children: [jsxRuntime.jsx("div", {
1792
1362
  children
1793
- }), jsxRuntime.jsx(Badge, {
1363
+ }), jsxRuntime.jsx(Badge2, {
1794
1364
  badgeContent: index,
1795
1365
  children: jsxRuntime.jsx("span", {
1796
1366
  css: [{
@@ -1801,7 +1371,7 @@ function SortComponent({
1801
1371
  }, direction === "desc" && {
1802
1372
  transform: "rotate3d(0, 0, 1, 180deg)"
1803
1373
  }],
1804
- children: jsxRuntime.jsx(ArrowUpward, {})
1374
+ children: jsxRuntime.jsx(ArrowUpward2, {})
1805
1375
  })
1806
1376
  })]
1807
1377
  });
@@ -1832,6 +1402,11 @@ function throttle(fn, ms) {
1832
1402
  if (lastArgs) {
1833
1403
  run();
1834
1404
  }
1405
+ },
1406
+ cancel() {
1407
+ if (timeout) {
1408
+ clearTimeout(timeout);
1409
+ }
1835
1410
  }
1836
1411
  });
1837
1412
  }
@@ -1850,15 +1425,15 @@ const relativeOffset = (x, y) => {
1850
1425
  return relativeOffset(x.offsetParent, y) + x.offsetTop;
1851
1426
  return 0;
1852
1427
  };
1853
- function Virtualized(_e) {
1854
- var _f = _e, {
1428
+ function Virtualized(_c) {
1429
+ var _d = _c, {
1855
1430
  header,
1856
1431
  children
1857
- } = _f, props = __objRest(_f, [
1432
+ } = _d, props = __objRest(_d, [
1858
1433
  "header",
1859
1434
  "children"
1860
1435
  ]);
1861
- var _a, _b, _c, _d;
1436
+ var _a, _b;
1862
1437
  const table = useTableContext();
1863
1438
  const virtual = table.useState("props.virtual");
1864
1439
  const probeRef = react.useRef(null);
@@ -1926,145 +1501,1086 @@ function Virtualized(_e) {
1926
1501
  if (!virtual || !probeRef.current)
1927
1502
  return;
1928
1503
  window.addEventListener("scroll", incCounter, true);
1504
+ window.addEventListener("resize", incCounter, true);
1929
1505
  return () => {
1930
1506
  window.removeEventListener("scroll", incCounter, true);
1507
+ window.removeEventListener("resize", incCounter, true);
1931
1508
  };
1932
1509
  }, [probeRef.current, incCounter]);
1933
- (_d = (_c = table.getState().props).debugRender) == null ? void 0 : _d.call(_c, `Virtualalized render ${from} to ${to}`);
1510
+ react.useEffect(() => incCounter.cancel, [incCounter]);
1511
+ react.useLayoutEffect(() => {
1512
+ var _a2, _b2;
1513
+ return (_b2 = (_a2 = table.getState().props).debugRender) == null ? void 0 : _b2.call(_a2, `Virtualalized render ${from} to ${to}`);
1514
+ });
1934
1515
  return jsxRuntime.jsxs("div", __spreadProps(__spreadValues({}, props), {
1935
1516
  children: [header, virtual && jsxRuntime.jsx("div", {
1936
1517
  style: {
1937
1518
  gridColumn: "1 / -1",
1938
1519
  height: before
1939
1520
  },
1940
- ref: probeRef
1941
- }), children(itemIds, from), virtual && jsxRuntime.jsx("div", {
1942
- style: {
1943
- gridColumn: "1 / -1",
1944
- height: after
1945
- }
1521
+ ref: probeRef
1522
+ }), children(itemIds, from), virtual && jsxRuntime.jsx("div", {
1523
+ style: {
1524
+ gridColumn: "1 / -1",
1525
+ height: after
1526
+ }
1527
+ })]
1528
+ }));
1529
+ }
1530
+ const TableContext = react.createContext(null);
1531
+ const ColumnContext = react.createContext(null);
1532
+ function useTableContext() {
1533
+ const value = react.useContext(TableContext);
1534
+ if (!value)
1535
+ throw Error("No table context available");
1536
+ return value;
1537
+ }
1538
+ function useColumnContext() {
1539
+ const value = react.useContext(ColumnContext);
1540
+ if (value === null)
1541
+ throw Error("No column context available");
1542
+ return value;
1543
+ }
1544
+ function Table(props) {
1545
+ const table = useTableState(props);
1546
+ react.useLayoutEffect(() => {
1547
+ var _a, _b;
1548
+ return (_b = (_a = table.getState().props).debugRender) == null ? void 0 : _b.call(_a, "render table");
1549
+ });
1550
+ return jsxRuntime.jsx(TableContext.Provider, {
1551
+ value: table,
1552
+ children: jsxRuntime.jsx(TableMemoContextProvider, {
1553
+ children: jsxRuntime.jsx(TableLoadingState, {})
1554
+ })
1555
+ });
1556
+ }
1557
+ function TableLoadingState() {
1558
+ const loadingText = useTheme((t) => t.text.loading);
1559
+ const isHydrated = useTableStateStorage();
1560
+ const [showLoading, setShowLoading] = react.useState(false);
1561
+ react.useEffect(() => {
1562
+ const handle = setTimeout(() => setShowLoading(true), 500);
1563
+ return () => clearTimeout(handle);
1564
+ });
1565
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, {
1566
+ children: [!isHydrated && showLoading && jsxRuntime.jsx("div", {
1567
+ children: loadingText
1568
+ }), jsxRuntime.jsx(TableInner, {
1569
+ hidden: !isHydrated
1570
+ })]
1571
+ });
1572
+ }
1573
+ const TableInner = react.memo(function TableInner2({
1574
+ hidden
1575
+ }) {
1576
+ const table = useTableContext();
1577
+ const fullWidth = table.useState("props.fullWidth");
1578
+ const activeColumns = table.useState((state) => state.activeColumns.map((column) => ({
1579
+ id: column.id,
1580
+ width: column.width,
1581
+ classes: column.classes,
1582
+ header: column.header
1583
+ })));
1584
+ const columnWidths = table.useState("columnWidths", {
1585
+ throttle: 16
1586
+ });
1587
+ const columnStyleOverride = table.useState("columnStyleOverride", {
1588
+ throttle: 16
1589
+ });
1590
+ const classes = table.useState("props.classes");
1591
+ const stickyHeader = table.useState("props.stickyHeader");
1592
+ const enableSelection = table.useState("props.enableSelection");
1593
+ const enableColumnSelection = table.useState("props.enableColumnSelection");
1594
+ const enableExport = table.useState((state) => !!state.props.enableExport.copy || !!state.props.enableExport.download);
1595
+ const cssVariables = useCssVariables();
1596
+ react.useLayoutEffect(() => {
1597
+ var _a, _b;
1598
+ return (_b = (_a = table.getState().props).debugRender) == null ? void 0 : _b.call(_a, "render table inner");
1599
+ });
1600
+ return jsxRuntime.jsx(Virtualized, {
1601
+ className: classes == null ? void 0 : classes.table,
1602
+ css: [cssVariables, tableTheme.defaultClasses.table, {
1603
+ gridTemplateColumns: [
1604
+ fullWidth === "right" || fullWidth === true ? "auto" : "0",
1605
+ "max-content",
1606
+ ...activeColumns.map((column) => {
1607
+ var _a, _b;
1608
+ return (_b = (_a = columnWidths.get(column.id)) != null ? _a : column.width) != null ? _b : "max-content";
1609
+ }),
1610
+ fullWidth === "left" || fullWidth === true ? "auto" : "0"
1611
+ ].join(" ")
1612
+ }, hidden && {
1613
+ visibility: "hidden"
1614
+ }],
1615
+ header: jsxRuntime.jsxs(jsxRuntime.Fragment, {
1616
+ children: [jsxRuntime.jsx("div", {
1617
+ className: classes == null ? void 0 : classes.headerCell,
1618
+ css: [tableTheme.defaultClasses.headerFill, stickyHeader && tableTheme.defaultClasses.sticky, stickyHeader instanceof Object && stickyHeader]
1619
+ }), jsxRuntime.jsxs("div", {
1620
+ className: classes == null ? void 0 : classes.headerCell,
1621
+ css: [tableTheme.defaultClasses.headerCell, stickyHeader && tableTheme.defaultClasses.sticky, stickyHeader instanceof Object && stickyHeader],
1622
+ children: [enableSelection && jsxRuntime.jsx(SelectComponent, {}), enableColumnSelection && jsxRuntime.jsx(ColumnSelection, {}), enableExport && jsxRuntime.jsx(Export$1, {}), jsxRuntime.jsx(ResizeHandleView, {})]
1623
+ }), jsxRuntime.jsx(ColumnHeaderContext.Provider, {
1624
+ children: activeColumns.map((column) => {
1625
+ var _a;
1626
+ return jsxRuntime.jsx(ColumnContext.Provider, {
1627
+ value: column.id,
1628
+ children: jsxRuntime.jsxs(ColumnHeader, {
1629
+ className: cx(classes == null ? void 0 : classes.headerCell, (_a = column.classes) == null ? void 0 : _a.headerCell),
1630
+ css: [tableTheme.defaultClasses.headerCell, columnStyleOverride.get(column.id), stickyHeader && tableTheme.defaultClasses.sticky, stickyHeader instanceof Object && stickyHeader],
1631
+ children: [jsxRuntime.jsx(SortComponent, {
1632
+ children: column.header
1633
+ }), jsxRuntime.jsx("div", {
1634
+ css: {
1635
+ flex: 1
1636
+ }
1637
+ }), jsxRuntime.jsx(FilterControl, {}), jsxRuntime.jsx(ResizeHandle, {})]
1638
+ }, column.id)
1639
+ }, column.id);
1640
+ })
1641
+ }), jsxRuntime.jsx("div", {
1642
+ className: classes == null ? void 0 : classes.headerCell,
1643
+ css: [tableTheme.defaultClasses.headerFill, stickyHeader && tableTheme.defaultClasses.sticky, stickyHeader instanceof Object && stickyHeader]
1644
+ })]
1645
+ }),
1646
+ children: (itemIds, startIndex) => itemIds.map((itemId, index) => jsxRuntime.jsx(Row, {
1647
+ itemId,
1648
+ rowIndex: startIndex + index
1649
+ }, itemId))
1650
+ });
1651
+ });
1652
+ const defaultColors = {
1653
+ primary: { main: "#1976d2", light: "#42a5f5", contrastText: "#fff" },
1654
+ secondary: { main: "#9c27b0", light: "#ba68c8", contrastText: "#fff" }
1655
+ };
1656
+ function Spinner({
1657
+ className: className2
1658
+ }) {
1659
+ return jsxRuntime.jsxs("div", {
1660
+ className: className2,
1661
+ css: react$2.css`
1662
+ display: inline-block;
1663
+ position: relative;
1664
+ width: 1em;
1665
+ height: 1em;
1666
+
1667
+ div {
1668
+ box-sizing: border-box;
1669
+ display: block;
1670
+ position: absolute;
1671
+ width: 0.8em;
1672
+ height: 0.8em;
1673
+ margin: 0.1em;
1674
+ border: 0.1em solid #fff;
1675
+ border-radius: 50%;
1676
+ animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
1677
+ border-color: currentColor transparent transparent transparent;
1678
+ }
1679
+ div:nth-of-type(1) {
1680
+ animation-delay: -0.45s;
1681
+ }
1682
+ div:nth-of-type(2) {
1683
+ animation-delay: -0.3s;
1684
+ }
1685
+ div:nth-of-type(3) {
1686
+ animation-delay: -0.15s;
1687
+ }
1688
+ @keyframes lds-ring {
1689
+ 0% {
1690
+ transform: rotate(0deg);
1691
+ }
1692
+ 100% {
1693
+ transform: rotate(360deg);
1694
+ }
1695
+ }
1696
+ `,
1697
+ children: [jsxRuntime.jsx("div", {}), jsxRuntime.jsx("div", {}), jsxRuntime.jsx("div", {})]
1698
+ });
1699
+ }
1700
+ const Badge = ({
1701
+ badgeContent,
1702
+ children
1703
+ }) => {
1704
+ if (!open)
1705
+ return null;
1706
+ return jsxRuntime.jsxs("span", {
1707
+ css: {
1708
+ display: "inline-flex",
1709
+ position: "relative",
1710
+ flexShrink: 0,
1711
+ verticalAlign: "middle"
1712
+ },
1713
+ children: [children, jsxRuntime.jsx("span", {
1714
+ css: [{
1715
+ top: 0,
1716
+ right: 0,
1717
+ transform: "scale(1) translate(50%, -50%)",
1718
+ transformOrigin: "100% 0%",
1719
+ height: 20,
1720
+ display: "flex",
1721
+ padding: "0 6px",
1722
+ zIndex: 1,
1723
+ position: "absolute",
1724
+ flexWrap: "wrap",
1725
+ minWidth: 20,
1726
+ transition: "transform 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms",
1727
+ alignItems: "center",
1728
+ lineHeight: 1,
1729
+ alignContent: "center",
1730
+ borderRadius: 10,
1731
+ justifyContent: "center",
1732
+ fontSize: "0.8em"
1733
+ }, !badgeContent && {
1734
+ transform: "scale(0) translate(50%, -50%)",
1735
+ transition: "transform 195ms cubic-bezier(0.4, 0, 0.2, 1) 0ms"
1736
+ }],
1737
+ children: badgeContent
1738
+ })]
1739
+ });
1740
+ };
1741
+ const Button = (_e) => {
1742
+ var _f = _e, {
1743
+ startIcon,
1744
+ children,
1745
+ variant = "text"
1746
+ } = _f, props = __objRest(_f, [
1747
+ "startIcon",
1748
+ "children",
1749
+ "variant"
1750
+ ]);
1751
+ return jsxRuntime.jsxs("button", __spreadProps(__spreadValues({
1752
+ css: [{
1753
+ padding: `var(--spacing) calc(var(--spacing) * 2)`,
1754
+ display: "inline-flex",
1755
+ alignItems: "center",
1756
+ transition: "background-color 150ms",
1757
+ border: "none",
1758
+ cursor: "pointer",
1759
+ background: "transparent",
1760
+ borderRadius: 4,
1761
+ "&:active:not(:disabled)": {
1762
+ transform: "scale3d(0.95, 0.95, 1)"
1763
+ }
1764
+ }, variant === "text" && {
1765
+ "&:hover": {
1766
+ background: "rgba(0, 0, 0, 0.1)"
1767
+ }
1768
+ }, variant === "outlined" && {
1769
+ border: `1px solid ${tableTheme.darkGray}`,
1770
+ "&:disabled": {
1771
+ borderColor: tableTheme.lightGray
1772
+ }
1773
+ }, variant === "contained" && {
1774
+ color: "var(--primaryContrastText)",
1775
+ backgroundColor: "var(--primaryMain)",
1776
+ boxShadow: "0px 3px 1px -2px rgb(0 0 0 / 20%), 0px 2px 2px 0px rgb(0 0 0 / 14%), 0px 1px 5px 0px rgb(0 0 0 / 12%)",
1777
+ "&:hover": {
1778
+ filter: "brightness(0.9)"
1779
+ },
1780
+ "&:disabled": {
1781
+ filter: "grayscale()",
1782
+ opacity: 0.5
1783
+ }
1784
+ }]
1785
+ }, props), {
1786
+ children: [startIcon && jsxRuntime.jsx("span", {
1787
+ css: {
1788
+ marginRight: `calc(var(--spacing) * 2)`
1789
+ },
1790
+ children: startIcon
1791
+ }), jsxRuntime.jsx("span", {
1792
+ children
1793
+ })]
1794
+ }));
1795
+ };
1796
+ const Checkbox = (_g) => {
1797
+ var _h = _g, {
1798
+ className: className2
1799
+ } = _h, props = __objRest(_h, [
1800
+ "className"
1801
+ ]);
1802
+ return jsxRuntime.jsxs("label", {
1803
+ css: [{
1804
+ padding: "calc(var(--spacing) * 1.8)",
1805
+ display: "flex",
1806
+ color: "currentcolor",
1807
+ userSelect: "none",
1808
+ "& input": {
1809
+ appearance: "none",
1810
+ margin: 0
1811
+ }
1812
+ }, props.disabled && {
1813
+ color: "rgba(0, 0, 0, 0.26)"
1814
+ }],
1815
+ className: className2,
1816
+ children: [jsxRuntime.jsx("input", __spreadValues({
1817
+ type: "checkbox"
1818
+ }, props)), props.checked ? jsxRuntime.jsx("svg", {
1819
+ css: {
1820
+ fontSize: "1.25rem",
1821
+ width: "1em",
1822
+ height: "1em",
1823
+ fill: "var(--primaryMain)"
1824
+ },
1825
+ focusable: "false",
1826
+ viewBox: "0 0 24 24",
1827
+ "aria-hidden": "true",
1828
+ children: jsxRuntime.jsx("path", {
1829
+ d: "M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
1830
+ })
1831
+ }) : jsxRuntime.jsx("svg", {
1832
+ css: {
1833
+ fontSize: "1.25rem",
1834
+ width: "1em",
1835
+ height: "1em",
1836
+ fill: "currentColor"
1837
+ },
1838
+ focusable: "false",
1839
+ viewBox: "0 0 24 24",
1840
+ "aria-hidden": "true",
1841
+ children: jsxRuntime.jsx("path", {
1842
+ d: "M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"
1843
+ })
1844
+ })]
1845
+ });
1846
+ };
1847
+ const IconButton = (props) => {
1848
+ return jsxRuntime.jsx("button", __spreadValues({
1849
+ css: {
1850
+ padding: "var(--spacing)",
1851
+ borderRadius: "50%",
1852
+ display: "inline-flex",
1853
+ justifyContent: "center",
1854
+ alignItems: "center",
1855
+ transition: "background-color 150ms",
1856
+ border: "none",
1857
+ cursor: "pointer",
1858
+ color: "inherit",
1859
+ background: "transparent",
1860
+ "&:hover": {
1861
+ backgroundColor: "rgba(0, 0, 0, 0.04)"
1862
+ },
1863
+ "&:active": {
1864
+ transformColor: "scale3d(0.95, 0.95, 1)"
1865
+ }
1866
+ }
1867
+ }, props));
1868
+ };
1869
+ const TextField = (_i) => {
1870
+ var _j = _i, {
1871
+ endIcon,
1872
+ className: className2,
1873
+ inputRef
1874
+ } = _j, props = __objRest(_j, [
1875
+ "endIcon",
1876
+ "className",
1877
+ "inputRef"
1878
+ ]);
1879
+ var _a;
1880
+ const [focus, setFocus] = react.useState(false);
1881
+ return jsxRuntime.jsx("div", {
1882
+ className: className2,
1883
+ css: {
1884
+ display: "flex"
1885
+ },
1886
+ children: jsxRuntime.jsxs("span", {
1887
+ css: [{
1888
+ flex: 1,
1889
+ display: "flex",
1890
+ alignItems: "center",
1891
+ border: `1px solid ${tableTheme.darkGray}`,
1892
+ borderRadius: 4
1893
+ }, focus && {
1894
+ border: "2px solid var(--primaryMain)",
1895
+ margin: -1
1896
+ }],
1897
+ children: [jsxRuntime.jsx("input", __spreadProps(__spreadValues({
1898
+ ref: inputRef
1899
+ }, props), {
1900
+ value: (_a = props.value) != null ? _a : "",
1901
+ onFocus: () => setFocus(true),
1902
+ onBlur: () => setFocus(false),
1903
+ css: {
1904
+ flex: 1,
1905
+ border: "none",
1906
+ outline: "none",
1907
+ borderRadius: 4,
1908
+ padding: "calc(var(--spacing) * 2)",
1909
+ paddingRight: 0,
1910
+ transition: "outline 500ms"
1911
+ }
1912
+ })), endIcon]
1913
+ })
1914
+ });
1915
+ };
1916
+ const defaultComponents = {
1917
+ IconButton,
1918
+ Checkbox,
1919
+ Popover: tableTheme.Popover,
1920
+ Button,
1921
+ Badge,
1922
+ TextField,
1923
+ Spinner
1924
+ };
1925
+ const IconDefaultStyle = react$2.css({
1926
+ width: "1.5em",
1927
+ height: "1.5em",
1928
+ color: "inherit"
1929
+ });
1930
+ function Icon(svg) {
1931
+ return (props) => jsxRuntime.jsx(react$2.ClassNames, {
1932
+ children: ({
1933
+ css: css2
1934
+ }) => react.cloneElement(svg, __spreadProps(__spreadValues({}, props), {
1935
+ className: css2(IconDefaultStyle, props.className)
1936
+ }))
1937
+ });
1938
+ }
1939
+ const Settings = Icon(jsxRuntime.jsxs("svg", {
1940
+ xmlns: "http://www.w3.org/2000/svg",
1941
+ height: "24px",
1942
+ viewBox: "0 0 24 24",
1943
+ width: "24px",
1944
+ fill: "currentColor",
1945
+ children: [jsxRuntime.jsx("path", {
1946
+ d: "M0 0h24v24H0V0z",
1947
+ fill: "none"
1948
+ }), jsxRuntime.jsx("path", {
1949
+ d: "M3 17v2h6v-2H3zM3 5v2h10V5H3zm10 16v-2h8v-2h-8v-2h-2v6h2zM7 9v2H3v2h4v2h2V9H7zm14 4v-2H11v2h10zm-6-4h2V7h4V5h-4V3h-2v6z"
1950
+ })]
1951
+ }));
1952
+ const Export = Icon(jsxRuntime.jsxs("svg", {
1953
+ xmlns: "http://www.w3.org/2000/svg",
1954
+ enableBackground: "new 0 0 24 24",
1955
+ height: "24px",
1956
+ viewBox: "0 0 24 24",
1957
+ width: "24px",
1958
+ fill: "currentColor",
1959
+ children: [jsxRuntime.jsx("g", {
1960
+ children: jsxRuntime.jsx("rect", {
1961
+ fill: "none",
1962
+ height: "24",
1963
+ width: "24"
1964
+ })
1965
+ }), jsxRuntime.jsx("g", {
1966
+ children: jsxRuntime.jsx("path", {
1967
+ d: "M18,15v3H6v-3H4v3c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-3H18z M17,11l-1.41-1.41L13,12.17V4h-2v8.17L8.41,9.59L7,11l5,5 L17,11z"
1968
+ })
1969
+ })]
1970
+ }));
1971
+ const Clipboard = Icon(jsxRuntime.jsxs("svg", {
1972
+ xmlns: "http://www.w3.org/2000/svg",
1973
+ height: "24px",
1974
+ viewBox: "0 0 24 24",
1975
+ width: "24px",
1976
+ fill: "currentColor",
1977
+ children: [jsxRuntime.jsx("path", {
1978
+ d: "M0 0h24v24H0V0z",
1979
+ fill: "none"
1980
+ }), jsxRuntime.jsx("path", {
1981
+ d: "M19 2h-4.18C14.4.84 13.3 0 12 0S9.6.84 9.18 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"
1982
+ })]
1983
+ }));
1984
+ const ChevronRight = Icon(jsxRuntime.jsxs("svg", {
1985
+ xmlns: "http://www.w3.org/2000/svg",
1986
+ height: "24px",
1987
+ viewBox: "0 0 24 24",
1988
+ width: "24px",
1989
+ fill: "currentColor",
1990
+ children: [jsxRuntime.jsx("path", {
1991
+ d: "M0 0h24v24H0V0z",
1992
+ fill: "none"
1993
+ }), jsxRuntime.jsx("path", {
1994
+ d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6-6-6z"
1995
+ })]
1996
+ }));
1997
+ const Search = Icon(jsxRuntime.jsxs("svg", {
1998
+ xmlns: "http://www.w3.org/2000/svg",
1999
+ height: "24px",
2000
+ viewBox: "0 0 24 24",
2001
+ width: "24px",
2002
+ fill: "currentColor",
2003
+ children: [jsxRuntime.jsx("path", {
2004
+ d: "M0 0h24v24H0V0z",
2005
+ fill: "none"
2006
+ }), jsxRuntime.jsx("path", {
2007
+ d: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
2008
+ })]
2009
+ }));
2010
+ const Clear = Icon(jsxRuntime.jsxs("svg", {
2011
+ xmlns: "http://www.w3.org/2000/svg",
2012
+ height: "24px",
2013
+ viewBox: "0 0 24 24",
2014
+ width: "24px",
2015
+ fill: "currentColor",
2016
+ children: [jsxRuntime.jsx("path", {
2017
+ d: "M0 0h24v24H0V0z",
2018
+ fill: "none"
2019
+ }), jsxRuntime.jsx("path", {
2020
+ d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"
2021
+ })]
2022
+ }));
2023
+ const ArrowDropDown = Icon(jsxRuntime.jsxs("svg", {
2024
+ xmlns: "http://www.w3.org/2000/svg",
2025
+ height: "24px",
2026
+ viewBox: "0 0 24 24",
2027
+ width: "24px",
2028
+ fill: "currentColor",
2029
+ children: [jsxRuntime.jsx("path", {
2030
+ d: "M0 0h24v24H0V0z",
2031
+ fill: "none"
2032
+ }), jsxRuntime.jsx("path", {
2033
+ d: "M7 10l5 5 5-5H7z"
2034
+ })]
2035
+ }));
2036
+ const FilterList = Icon(jsxRuntime.jsx("svg", {
2037
+ viewBox: "0 0 24 24",
2038
+ children: jsxRuntime.jsx("path", {
2039
+ fill: "currentColor",
2040
+ d: "M14,12V19.88C14.04,20.18 13.94,20.5 13.71,20.71C13.32,21.1 12.69,21.1 12.3,20.71L10.29,18.7C10.06,18.47 9.96,18.16 10,17.87V12H9.97L4.21,4.62C3.87,4.19 3.95,3.56 4.38,3.22C4.57,3.08 4.78,3 5,3V3H19V3C19.22,3 19.43,3.08 19.62,3.22C20.05,3.56 20.13,4.19 19.79,4.62L14.03,12H14Z"
2041
+ })
2042
+ }));
2043
+ const ArrowUpward = Icon(jsxRuntime.jsxs("svg", {
2044
+ xmlns: "http://www.w3.org/2000/svg",
2045
+ height: "24px",
2046
+ viewBox: "0 0 24 24",
2047
+ width: "24px",
2048
+ fill: "currentColor",
2049
+ children: [jsxRuntime.jsx("path", {
2050
+ d: "M0 0h24v24H0V0z",
2051
+ fill: "none"
2052
+ }), jsxRuntime.jsx("path", {
2053
+ d: "M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"
2054
+ })]
2055
+ }));
2056
+ const defaultIcons = {
2057
+ Settings,
2058
+ Export,
2059
+ Clipboard,
2060
+ ChevronRight,
2061
+ Search,
2062
+ Clear,
2063
+ ArrowDropDown,
2064
+ FilterList,
2065
+ ArrowUpward
2066
+ };
2067
+ const defaultTexts = {
2068
+ selectColumns: "Select visible columns",
2069
+ noResults: "No results",
2070
+ exportTitle: "Export",
2071
+ exportCopy: "To clipboard",
2072
+ exportDownload: "Download",
2073
+ today: "Today",
2074
+ thisWeek: "This week",
2075
+ reset: "Reset",
2076
+ loading: "Loading",
2077
+ selected: (count) => `${count} selected`
2078
+ };
2079
+ const defaultTableTheme = {
2080
+ text: defaultTexts,
2081
+ components: defaultComponents,
2082
+ icons: defaultIcons,
2083
+ colors: defaultColors,
2084
+ spacing: "5px"
2085
+ };
2086
+ const emptyStore = new react$1.Store(void 0);
2087
+ function useTheme(selector) {
2088
+ var _a, _b;
2089
+ const contextTableTheme = react.useContext(tableTheme.TableThemeContext);
2090
+ const table = react.useContext(TableContext);
2091
+ const columnId = react.useContext(ColumnContext);
2092
+ const memo = useTableMemo();
2093
+ const process = (t) => {
2094
+ var _a2;
2095
+ const cell = (_a2 = t.classes) == null ? void 0 : _a2.cell;
2096
+ const selected = t.text.selected;
2097
+ return __spreadProps(__spreadValues({}, t), {
2098
+ classes: __spreadProps(__spreadValues({}, t.classes), {
2099
+ cell: cell instanceof Function || Array.isArray(cell) ? memo("theme.classes.cell", cell) : cell
2100
+ }),
2101
+ text: __spreadProps(__spreadValues({}, t.text), {
2102
+ selected: selected instanceof Function || Array.isArray(selected) ? memo("theme.text.selected", selected) : selected
2103
+ })
2104
+ });
2105
+ };
2106
+ const theme = (_b = (_a = table == null ? void 0 : table.useState((state) => {
2107
+ const localTheme = {
2108
+ text: state.props.text,
2109
+ classes: state.props.classes,
2110
+ components: state.props.components,
2111
+ icons: state.props.icons,
2112
+ colors: state.props.colors,
2113
+ spacing: state.props.spacing
2114
+ };
2115
+ const column = state.activeColumns.find((column2) => column2.id === columnId);
2116
+ const columnsTheme = {
2117
+ classes: column == null ? void 0 : column.classes
2118
+ };
2119
+ const theme2 = tableTheme.mergeThemes(defaultTableTheme, tableTheme.globalTableTheme, contextTableTheme, localTheme, columnsTheme);
2120
+ return selector(process(theme2));
2121
+ })) != null ? _a : emptyStore.useState()) != null ? _b : selector(process(tableTheme.mergeThemes(defaultTableTheme, tableTheme.globalTableTheme, contextTableTheme)));
2122
+ return theme;
2123
+ }
2124
+ function AutoFocusTextField(props) {
2125
+ const TextField2 = useTheme((t) => t.components.TextField);
2126
+ const ref = react.useRef(null);
2127
+ const {
2128
+ visible
2129
+ } = react.useContext(tableTheme.PopoverContext);
2130
+ react.useLayoutEffect(() => {
2131
+ if (visible && ref.current) {
2132
+ ref.current.focus();
2133
+ }
2134
+ }, [visible]);
2135
+ return jsxRuntime.jsx(TextField2, __spreadProps(__spreadValues({}, props), {
2136
+ inputRef: ref
2137
+ }));
2138
+ }
2139
+ const className = "schummar-table-date-input";
2140
+ const defaultDate = new Date(1970, 0, 1);
2141
+ const isIncludedType = (type) => type === "day" || type === "month" || type === "year";
2142
+ const defaultLengths = {
2143
+ day: 2,
2144
+ month: 2,
2145
+ year: 4
2146
+ };
2147
+ const maxLengths = {
2148
+ day: 2,
2149
+ month: 2,
2150
+ year: Infinity
2151
+ };
2152
+ const length = (type, value) => Math.max(value.length, defaultLengths[type]);
2153
+ const tabNext = (e) => {
2154
+ const all = Array.from(document.querySelectorAll(`.${className}`));
2155
+ const index = all.indexOf(e);
2156
+ const next = all[(index + 1) % all.length];
2157
+ if (next instanceof HTMLElement) {
2158
+ next.focus();
2159
+ }
2160
+ };
2161
+ function DateInput({
2162
+ value,
2163
+ onChange,
2164
+ locale
2165
+ }) {
2166
+ const [override, setOverride] = react.useState();
2167
+ const commit = () => {
2168
+ if (!override) {
2169
+ return;
2170
+ }
2171
+ setOverride(void 0);
2172
+ if (!override.value) {
2173
+ onChange(null);
2174
+ return;
2175
+ }
2176
+ const newValue = value ? new Date(value) : new Date();
2177
+ if (override.type === "day") {
2178
+ newValue.setDate(Number(override.value));
2179
+ } else if (override.type === "month") {
2180
+ newValue.setMonth(Number(override.value) - 1);
2181
+ } else if (override.type === "year") {
2182
+ newValue.setFullYear(Number(override.value));
2183
+ }
2184
+ onChange(newValue);
2185
+ };
2186
+ const format = react.useMemo(() => new Intl.DateTimeFormat(locale, {
2187
+ day: "2-digit",
2188
+ month: "2-digit",
2189
+ year: "numeric"
2190
+ }), [locale]);
2191
+ const parts = format.formatToParts(value != null ? value : defaultDate);
2192
+ const isEmpty = !value;
2193
+ return jsxRuntime.jsx("div", {
2194
+ css: {
2195
+ display: "flex",
2196
+ alignItems: "baseline"
2197
+ },
2198
+ children: parts.map(({
2199
+ type,
2200
+ value: value2
2201
+ }, index) => jsxRuntime.jsx(react.Fragment, {
2202
+ children: isIncludedType(type) ? jsxRuntime.jsx("input", {
2203
+ className,
2204
+ css: {
2205
+ width: `${length(type, value2)}ch`,
2206
+ boxSizing: "content-box",
2207
+ overflow: "visible",
2208
+ border: "none",
2209
+ borderBottom: "2px solid transparent",
2210
+ outline: "none",
2211
+ fontSize: "inherit",
2212
+ "&:focus": {
2213
+ borderBottom: "2px solid var(--primaryMain)"
2214
+ }
2215
+ },
2216
+ placeholder: "".padEnd(length(type, value2), "0"),
2217
+ value: (override == null ? void 0 : override.type) === type ? override.value : !isEmpty ? value2 : "",
2218
+ onChange: (e) => {
2219
+ setOverride({
2220
+ type,
2221
+ value: e.target.value
2222
+ });
2223
+ if (e.target.value.length >= maxLengths[type]) {
2224
+ setTimeout(() => tabNext(e.target));
2225
+ }
2226
+ },
2227
+ onFocus: (e) => e.target.select(),
2228
+ onBlur: commit
2229
+ }) : type === "literal" ? jsxRuntime.jsx("span", {
2230
+ children: value2
2231
+ }) : null
2232
+ }, index))
2233
+ });
2234
+ }
2235
+ const weekDays = [0, 1, 2, 3, 4, 5, 6];
2236
+ const startOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
2237
+ const endOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + 1, 0, 0, 0, -1);
2238
+ const today = () => {
2239
+ const today2 = startOfDay(new Date());
2240
+ return {
2241
+ min: today2,
2242
+ max: today2
2243
+ };
2244
+ };
2245
+ const thisWeek = (firstDayOfWeek = 0) => {
2246
+ const now = new Date();
2247
+ const min = new Date(now);
2248
+ let diff = min.getDay() - firstDayOfWeek;
2249
+ if (diff < 0) {
2250
+ diff += 7;
2251
+ }
2252
+ min.setDate(min.getDate() - diff);
2253
+ const max = new Date(min);
2254
+ max.setDate(max.getDate() + 6);
2255
+ return {
2256
+ min: startOfDay(min),
2257
+ max: endOfDay(max)
2258
+ };
2259
+ };
2260
+ function dateIntersect(a, b) {
2261
+ if (a instanceof Date) {
2262
+ a = {
2263
+ min: a,
2264
+ max: a
2265
+ };
2266
+ }
2267
+ if (b instanceof Date) {
2268
+ b = {
2269
+ min: b,
2270
+ max: b
2271
+ };
2272
+ }
2273
+ if (!(a == null ? void 0 : a.min) || !a.max || !(b == null ? void 0 : b.min) || !b.max) {
2274
+ return false;
2275
+ }
2276
+ return !(endOfDay(a.max) < startOfDay(b.min) || startOfDay(a.min) > endOfDay(b.max));
2277
+ }
2278
+ function DatePicker({
2279
+ value,
2280
+ onChange,
2281
+ rangeSelect,
2282
+ locale,
2283
+ firstDayOfWeek = 0
2284
+ }) {
2285
+ const Button2 = useTheme((t) => t.components.Button);
2286
+ const IconButton2 = useTheme((t) => t.components.IconButton);
2287
+ const ChevronRight2 = useTheme((t) => t.icons.ChevronRight);
2288
+ const textToday = useTheme((t) => t.text.today);
2289
+ const textThisWeek = useTheme((t) => t.text.thisWeek);
2290
+ const textReset = useTheme((t) => t.text.reset);
2291
+ const [baseDate] = react.useState(new Date());
2292
+ const [dateInView, setDateInView] = react.useState(baseDate);
2293
+ const [dirty, setDirty] = react.useState();
2294
+ const [hovered, setHovered] = react.useState();
2295
+ const min = dirty ? dirty.min : value instanceof Date ? value : value == null ? void 0 : value.min;
2296
+ const max = dirty ? dirty.max : value instanceof Date ? value : value == null ? void 0 : value.max;
2297
+ const {
2298
+ calendars,
2299
+ getBackProps,
2300
+ getForwardProps,
2301
+ getDateProps
2302
+ } = dayzed.useDayzed({
2303
+ onDateSelected: () => void 0,
2304
+ firstDayOfWeek,
2305
+ showOutsideDays: true,
2306
+ date: dateInView,
2307
+ onOffsetChanged: (offset) => setDateInView(new Date(dateInView.getFullYear(), dateInView.getMonth() + offset)),
2308
+ offset: 0
2309
+ });
2310
+ const formatWeekday = react.useMemo(() => {
2311
+ const {
2312
+ format
2313
+ } = new Intl.DateTimeFormat(locale, {
2314
+ weekday: "short"
2315
+ });
2316
+ return (weekDay) => format(new Date(Date.UTC(2021, 5, weekDay)));
2317
+ }, [locale]);
2318
+ react.useEffect(() => setDateInView(value === null ? new Date() : value instanceof Date ? value : value.max), [value]);
2319
+ react.useEffect(() => {
2320
+ if (!rangeSelect) {
2321
+ setDirty(void 0);
2322
+ }
2323
+ }, [rangeSelect]);
2324
+ function set(min2, max2, edit) {
2325
+ if (!rangeSelect) {
2326
+ onChange(min2 != null ? min2 : null);
2327
+ return;
2328
+ }
2329
+ if (min2 && max2 && min2 > max2) {
2330
+ if (edit === "min") {
2331
+ max2 = min2;
2332
+ } else if (edit === "max") {
2333
+ min2 = max2;
2334
+ } else {
2335
+ [min2, max2] = [max2, min2];
2336
+ }
2337
+ }
2338
+ if (!min2 === !max2) {
2339
+ setDirty(void 0);
2340
+ onChange(min2 && max2 ? {
2341
+ min: min2,
2342
+ max: max2
2343
+ } : null);
2344
+ } else {
2345
+ setDirty({
2346
+ min: min2,
2347
+ max: max2
2348
+ });
2349
+ }
2350
+ }
2351
+ const formatMonth = react.useMemo(() => {
2352
+ const {
2353
+ format
2354
+ } = new Intl.DateTimeFormat(locale, {
2355
+ month: "long"
2356
+ });
2357
+ return (month) => format(new Date(2021, month));
2358
+ }, [locale]);
2359
+ const formatYear = react.useMemo(() => {
2360
+ const {
2361
+ format
2362
+ } = new Intl.DateTimeFormat(locale, {
2363
+ year: "numeric"
2364
+ });
2365
+ return (year) => format(new Date(year, 0, 1));
2366
+ }, [locale]);
2367
+ return jsxRuntime.jsxs("div", {
2368
+ children: [jsxRuntime.jsxs("div", {
2369
+ css: {
2370
+ display: "grid",
2371
+ gridAutoFlow: "column",
2372
+ justifyContent: "center",
2373
+ alignItems: "baseline",
2374
+ gap: "var(--spacing)"
2375
+ },
2376
+ children: [jsxRuntime.jsx(DateInput, {
2377
+ value: min != null ? min : null,
2378
+ onChange: (date) => set(date != null ? date : void 0, max, "min"),
2379
+ locale
2380
+ }), rangeSelect && jsxRuntime.jsxs(jsxRuntime.Fragment, {
2381
+ children: [" - ", jsxRuntime.jsx(DateInput, {
2382
+ value: max != null ? max : null,
2383
+ onChange: (date) => set(min, date != null ? date : void 0, "max"),
2384
+ locale
2385
+ })]
2386
+ })]
2387
+ }), calendars.map(({
2388
+ month,
2389
+ year,
2390
+ weeks
2391
+ }) => jsxRuntime.jsxs("div", {
2392
+ css: {
2393
+ display: "grid"
2394
+ },
2395
+ children: [jsxRuntime.jsxs("div", {
2396
+ css: {
2397
+ margin: "calc(var(--spacing) * 4) 0",
2398
+ display: "grid",
2399
+ gridAutoFlow: "column",
2400
+ justifyContent: "space-between",
2401
+ alignItems: "center"
2402
+ },
2403
+ children: [jsxRuntime.jsx(IconButton2, __spreadProps(__spreadValues({}, getBackProps({
2404
+ calendars
2405
+ })), {
2406
+ children: jsxRuntime.jsx(ChevronRight2, {
2407
+ css: {
2408
+ transform: "rotate3d(0, 0, 1, 180deg)"
2409
+ }
2410
+ })
2411
+ })), jsxRuntime.jsxs("div", {
2412
+ css: {
2413
+ display: "flex"
2414
+ },
2415
+ children: [formatMonth(month), " ", formatYear(year)]
2416
+ }), jsxRuntime.jsx(IconButton2, __spreadProps(__spreadValues({}, getForwardProps({
2417
+ calendars
2418
+ })), {
2419
+ children: jsxRuntime.jsx(ChevronRight2, {})
2420
+ }))]
2421
+ }), jsxRuntime.jsxs("div", {
2422
+ css: {
2423
+ justifySelf: "center",
2424
+ display: "grid",
2425
+ gridTemplateColumns: "repeat(7, max-content)",
2426
+ fontWeight: "bold"
2427
+ },
2428
+ children: [weekDays.map((_v, weekDay) => jsxRuntime.jsx("div", {
2429
+ css: {
2430
+ justifySelf: "center",
2431
+ marginBottom: "var(--spacing)"
2432
+ },
2433
+ children: formatWeekday(weekDay)
2434
+ }, weekDay)), weeks.map((week, index) => week.map((dateObj, dayIndex) => {
2435
+ if (!dateObj) {
2436
+ return jsxRuntime.jsx("div", {});
2437
+ }
2438
+ const {
2439
+ prevMonth,
2440
+ nextMonth,
2441
+ date,
2442
+ today: today2
2443
+ } = dateObj;
2444
+ const selected = date.getTime() === (min == null ? void 0 : min.getTime()) || min && max && dateIntersect(date, {
2445
+ min,
2446
+ max
2447
+ });
2448
+ const preSelected = !selected && (date.getTime() === (hovered == null ? void 0 : hovered.getTime()) || min && !max && hovered && dateIntersect(date, min <= hovered ? {
2449
+ min,
2450
+ max: hovered
2451
+ } : {
2452
+ min: hovered,
2453
+ max: min
2454
+ }));
2455
+ return jsxRuntime.jsx("button", __spreadProps(__spreadValues({
2456
+ css: [{
2457
+ padding: 10,
2458
+ border: "1px solid transparent",
2459
+ background: "transparent",
2460
+ cursor: "pointer"
2461
+ }, (prevMonth || nextMonth) && {
2462
+ color: tableTheme.gray
2463
+ }, today2 && {
2464
+ border: "1px solid var(--secondaryMain)"
2465
+ }, selected && {
2466
+ background: "var(--primaryMain)",
2467
+ color: "var(--primaryContrastText)"
2468
+ }, preSelected && {
2469
+ background: "var(--primaryLight)",
2470
+ color: "var(--primaryContrastText)"
2471
+ }]
2472
+ }, getDateProps({
2473
+ dateObj
2474
+ })), {
2475
+ onClick: () => {
2476
+ if (dirty) {
2477
+ if (min)
2478
+ set(min, date);
2479
+ else
2480
+ set(date, max);
2481
+ } else {
2482
+ set(date);
2483
+ }
2484
+ },
2485
+ onPointerOver: () => setHovered(date),
2486
+ onPointerOut: () => setHovered(void 0),
2487
+ children: date.getDate()
2488
+ }), `${index}-${dayIndex}`);
2489
+ }))]
2490
+ })]
2491
+ }, `${month}${year}`)), jsxRuntime.jsxs("div", {
2492
+ css: {
2493
+ marginTop: "var(--spacing)",
2494
+ display: "grid",
2495
+ gridAutoFlow: "column",
2496
+ justifyContent: "center"
2497
+ },
2498
+ children: [jsxRuntime.jsx(Button2, {
2499
+ variant: "text",
2500
+ onClick: () => {
2501
+ setDirty(void 0);
2502
+ onChange(today());
2503
+ },
2504
+ children: textToday
2505
+ }), jsxRuntime.jsx(Button2, {
2506
+ variant: "text",
2507
+ onClick: () => {
2508
+ setDirty(void 0);
2509
+ onChange(thisWeek(firstDayOfWeek));
2510
+ },
2511
+ children: textThisWeek
2512
+ }), jsxRuntime.jsx(Button2, {
2513
+ variant: "text",
2514
+ onClick: () => {
2515
+ setDirty(void 0);
2516
+ onChange(null);
2517
+ },
2518
+ children: textReset
2519
+ })]
1946
2520
  })]
1947
- }));
2521
+ });
1948
2522
  }
1949
- const TableContext = react.createContext(null);
1950
- const ColumnContext = react.createContext(null);
1951
- function useTableContext() {
1952
- const value = react.useContext(TableContext);
1953
- if (!value)
1954
- throw Error("No table context available");
1955
- return value;
2523
+ function convertDate(x) {
2524
+ if (x instanceof Date)
2525
+ return x;
2526
+ if (typeof x === "number" || typeof x === "string")
2527
+ return new Date(x);
2528
+ return null;
1956
2529
  }
1957
- function useColumnContext() {
1958
- const value = react.useContext(ColumnContext);
1959
- if (value === null)
1960
- throw Error("No column context available");
1961
- return value;
2530
+ function convertDateOrRange(x) {
2531
+ if (x instanceof Object && "min" in x && "max" in x) {
2532
+ const range = {
2533
+ min: convertDate(x.min),
2534
+ max: convertDate(x.max)
2535
+ };
2536
+ return range.min && range.max ? range : null;
2537
+ }
2538
+ return convertDate(x);
1962
2539
  }
1963
- function Table(props) {
1964
- var _a, _b;
1965
- const table = useTableState(props);
1966
- (_b = (_a = table.getState().props).debugRender) == null ? void 0 : _b.call(_a, "render table");
1967
- return jsxRuntime.jsx(TableContext.Provider, {
1968
- value: table,
1969
- children: jsxRuntime.jsx(TableLoadingState, {})
1970
- });
2540
+ function convertDateOrArray(x) {
2541
+ if (x instanceof Array)
2542
+ return x.map(convertDateOrRange).filter(Boolean);
2543
+ return convertDateOrRange(x);
1971
2544
  }
1972
- function TableLoadingState() {
2545
+ function DateFilter(_k) {
2546
+ var _l = _k, {
2547
+ locale,
2548
+ firstDayOfWeek,
2549
+ singleSelect,
2550
+ filterBy = convertDateOrArray
2551
+ } = _l, props = __objRest(_l, [
2552
+ "locale",
2553
+ "firstDayOfWeek",
2554
+ "singleSelect",
2555
+ "filterBy"
2556
+ ]);
1973
2557
  const {
1974
- text
1975
- } = useTheme();
1976
- const isHydrated = useTableStateStorage();
1977
- const [showLoading, setShowLoading] = react.useState(false);
1978
- react.useEffect(() => {
1979
- const handle = setTimeout(() => setShowLoading(true), 500);
1980
- return () => clearTimeout(handle);
1981
- });
1982
- return jsxRuntime.jsxs(jsxRuntime.Fragment, {
1983
- children: [!isHydrated && showLoading && jsxRuntime.jsx("div", {
1984
- children: text.loading
1985
- }), jsxRuntime.jsx(TableInner, {
1986
- hidden: !isHydrated
1987
- })]
2558
+ value = null,
2559
+ onChange
2560
+ } = useFilter(__spreadProps(__spreadValues({}, props), {
2561
+ filterBy,
2562
+ id: "dateFilter",
2563
+ isActive(filterValue) {
2564
+ return !!filterValue;
2565
+ },
2566
+ test(filterValue, value2) {
2567
+ return dateIntersect(filterValue, value2);
2568
+ }
2569
+ }));
2570
+ return jsxRuntime.jsx("div", {
2571
+ css: {
2572
+ padding: "calc(var(--spacing) * 2)",
2573
+ display: "grid"
2574
+ },
2575
+ children: jsxRuntime.jsx(DatePicker, {
2576
+ rangeSelect: !singleSelect,
2577
+ value,
2578
+ onChange,
2579
+ locale,
2580
+ firstDayOfWeek
2581
+ })
1988
2582
  });
1989
2583
  }
1990
- const TableInner = react.memo(function TableInner2({
1991
- hidden
1992
- }) {
1993
- var _a, _b;
1994
- const table = useTableContext();
1995
- const fullWidth = table.useState("props.fullWidth");
1996
- const activeColumns = table.useState((state) => state.activeColumns.map((column) => ({
1997
- id: column.id,
1998
- width: column.width,
1999
- classes: column.classes,
2000
- header: column.header
2001
- })));
2002
- const columnWidths = table.useState("columnWidths", {
2003
- throttle: 16
2004
- });
2005
- const columnStyleOverride = table.useState("columnStyleOverride", {
2006
- throttle: 16
2007
- });
2008
- const defaultWidth = table.useState("props.defaultWidth");
2009
- const classes = table.useState("props.classes");
2010
- const stickyHeader = table.useState("props.stickyHeader");
2011
- const enableSelection = table.useState("props.enableSelection");
2012
- const enableColumnSelection = table.useState("props.enableColumnSelection");
2013
- const enableExport = table.useState((state) => !!state.props.enableExport.copy || !!state.props.enableExport.download);
2014
- const cssVariables = useCssVariables();
2015
- (_b = (_a = table.getState().props).debugRender) == null ? void 0 : _b.call(_a, "render table inner");
2016
- return jsxRuntime.jsx(Virtualized, {
2017
- className: classes == null ? void 0 : classes.table,
2018
- css: [cssVariables, tableTheme.defaultClasses.table, {
2019
- gridTemplateColumns: [
2020
- fullWidth === "right" || fullWidth === true ? "auto" : "0",
2021
- "max-content",
2022
- ...activeColumns.map((column) => {
2023
- var _a2, _b2, _c;
2024
- return (_c = (_b2 = (_a2 = columnWidths.get(column.id)) != null ? _a2 : column.width) != null ? _b2 : defaultWidth) != null ? _c : "max-content";
2025
- }),
2026
- fullWidth === "left" || fullWidth === true ? "auto" : "0"
2027
- ].join(" ")
2028
- }, hidden && {
2029
- visibility: "hidden"
2030
- }],
2031
- header: jsxRuntime.jsxs(jsxRuntime.Fragment, {
2032
- children: [jsxRuntime.jsx("div", {
2033
- className: classes == null ? void 0 : classes.headerCell,
2034
- css: [tableTheme.defaultClasses.headerFill, stickyHeader && tableTheme.defaultClasses.sticky, stickyHeader instanceof Object && stickyHeader]
2035
- }), jsxRuntime.jsxs("div", {
2036
- className: classes == null ? void 0 : classes.headerCell,
2037
- css: [tableTheme.defaultClasses.headerCell, stickyHeader && tableTheme.defaultClasses.sticky, stickyHeader instanceof Object && stickyHeader],
2038
- children: [enableSelection && jsxRuntime.jsx(SelectComponent, {}), enableColumnSelection && jsxRuntime.jsx(ColumnSelection, {}), enableExport && jsxRuntime.jsx(Export, {}), jsxRuntime.jsx(ResizeHandleView, {})]
2039
- }), jsxRuntime.jsx(ColumnHeaderContext.Provider, {
2040
- children: activeColumns.map((column) => {
2041
- var _a2;
2042
- return jsxRuntime.jsx(ColumnContext.Provider, {
2043
- value: column.id,
2044
- children: jsxRuntime.jsxs(ColumnHeader, {
2045
- className: cx(classes == null ? void 0 : classes.headerCell, (_a2 = column.classes) == null ? void 0 : _a2.headerCell),
2046
- css: [tableTheme.defaultClasses.headerCell, columnStyleOverride.get(column.id), stickyHeader && tableTheme.defaultClasses.sticky, stickyHeader instanceof Object && stickyHeader],
2047
- children: [jsxRuntime.jsx(SortComponent, {
2048
- children: column.header
2049
- }), jsxRuntime.jsx("div", {
2050
- css: {
2051
- flex: 1
2052
- }
2053
- }), jsxRuntime.jsx(FilterControl, {}), jsxRuntime.jsx(ResizeHandle, {})]
2054
- }, column.id)
2055
- }, column.id);
2056
- })
2057
- }), jsxRuntime.jsx("div", {
2058
- className: classes == null ? void 0 : classes.headerCell,
2059
- css: [tableTheme.defaultClasses.headerFill, stickyHeader && tableTheme.defaultClasses.sticky, stickyHeader instanceof Object && stickyHeader]
2060
- })]
2061
- }),
2062
- children: (itemIds, startIndex) => itemIds.map((itemId, index) => jsxRuntime.jsx(Row, {
2063
- itemId,
2064
- rowIndex: startIndex + index
2065
- }, itemId))
2066
- });
2067
- });
2068
2584
  function toggle(set, value, singleSelect) {
2069
2585
  const newSet = new Set(singleSelect ? [] : set);
2070
2586
  if (set.has(value)) {
@@ -2074,46 +2590,30 @@ function toggle(set, value, singleSelect) {
2074
2590
  }
2075
2591
  return newSet;
2076
2592
  }
2077
- function SelectFilter(_g) {
2078
- var _h = _g, {
2593
+ function SelectFilter(_m) {
2594
+ var _n = _m, {
2079
2595
  options: providedOptions,
2080
2596
  stringValue = asString,
2081
2597
  render = stringValue,
2082
2598
  singleSelect
2083
- } = _h, props = __objRest(_h, [
2599
+ } = _n, props = __objRest(_n, [
2084
2600
  "options",
2085
2601
  "stringValue",
2086
2602
  "render",
2087
2603
  "singleSelect"
2088
2604
  ]);
2089
- const {
2090
- components: {
2091
- IconButton,
2092
- Checkbox
2093
- },
2094
- icons: {
2095
- Search,
2096
- Clear
2097
- },
2098
- text
2099
- } = useTheme();
2605
+ const IconButton2 = useTheme((t) => t.components.IconButton);
2606
+ const Checkbox2 = useTheme((t) => t.components.Checkbox);
2607
+ const Search2 = useTheme((t) => t.icons.Search);
2608
+ const Clear2 = useTheme((t) => t.icons.Clear);
2609
+ const selected = useTheme((t) => t.text.selected);
2610
+ const noResults = useTheme((t) => t.text.noResults);
2100
2611
  const table = useTableContext();
2101
2612
  const columnId = useColumnContext();
2102
- const options = table.useState((state) => {
2103
- var _a;
2104
- if (providedOptions)
2105
- return uniq(providedOptions);
2106
- const column = state.activeColumns.find((column2) => column2.id === columnId);
2107
- if (!column)
2108
- return [];
2109
- const filterBy = (_a = props.filterBy) != null ? _a : (x) => x;
2110
- return uniq(flatMap(state.items, (item) => castArray(filterBy(column.value(item), item))));
2111
- });
2112
- const [query, setQuery] = react.useState("");
2113
- const filtered = options.filter((option) => !query || stringValue(option).toLowerCase().includes(query.toLowerCase()));
2114
2613
  const {
2115
2614
  value = /* @__PURE__ */ new Set(),
2116
- onChange
2615
+ onChange,
2616
+ filterBy
2117
2617
  } = useFilter(__spreadProps(__spreadValues({}, props), {
2118
2618
  id: "selectFilter",
2119
2619
  isActive(filterValue) {
@@ -2123,6 +2623,16 @@ function SelectFilter(_g) {
2123
2623
  return filterValue.has(value2);
2124
2624
  }
2125
2625
  }));
2626
+ const options = table.useState((state) => {
2627
+ if (providedOptions)
2628
+ return uniq(providedOptions);
2629
+ const column = state.activeColumns.find((column2) => column2.id === columnId);
2630
+ if (!column)
2631
+ return [];
2632
+ return uniq(flatMap(state.items, (item) => castArray(filterBy(column.value(item), item))));
2633
+ });
2634
+ const [query, setQuery] = react.useState("");
2635
+ const filtered = options.filter((option) => !query || stringValue(option).toLowerCase().includes(query.toLowerCase()));
2126
2636
  return jsxRuntime.jsxs("div", {
2127
2637
  css: {
2128
2638
  padding: "calc(var(--spacing) * 2)",
@@ -2132,9 +2642,9 @@ function SelectFilter(_g) {
2132
2642
  children: [jsxRuntime.jsx(AutoFocusTextField, {
2133
2643
  value: query,
2134
2644
  onChange: (e) => setQuery(e.target.value),
2135
- endIcon: jsxRuntime.jsx(IconButton, {
2645
+ endIcon: jsxRuntime.jsx(IconButton2, {
2136
2646
  onClick: () => setQuery(""),
2137
- children: !query ? jsxRuntime.jsx(Search, {}) : jsxRuntime.jsx(Clear, {})
2647
+ children: !query ? jsxRuntime.jsx(Search2, {}) : jsxRuntime.jsx(Clear2, {})
2138
2648
  }),
2139
2649
  css: {
2140
2650
  marginBottom: "var(--spacing)"
@@ -2146,16 +2656,16 @@ function SelectFilter(_g) {
2146
2656
  },
2147
2657
  children: [jsxRuntime.jsx(FormControlLabel, {
2148
2658
  disabled: value.size === 0,
2149
- control: jsxRuntime.jsx(Checkbox, {
2659
+ control: jsxRuntime.jsx(Checkbox2, {
2150
2660
  disabled: value.size === 0,
2151
2661
  checked: value.size > 0,
2152
2662
  onChange: () => onChange(/* @__PURE__ */ new Set())
2153
2663
  }),
2154
2664
  label: jsxRuntime.jsxs(jsxRuntime.Fragment, {
2155
- children: ["<", text.selected(value.size), ">"]
2665
+ children: ["<", selected(value.size), ">"]
2156
2666
  })
2157
2667
  }), filtered.map((option, index) => jsxRuntime.jsx(FormControlLabel, {
2158
- control: jsxRuntime.jsx(Checkbox, {
2668
+ control: jsxRuntime.jsx(Checkbox2, {
2159
2669
  checked: value.has(option),
2160
2670
  onChange: () => onChange(toggle(value, option, singleSelect))
2161
2671
  }),
@@ -2165,7 +2675,7 @@ function SelectFilter(_g) {
2165
2675
  css: {
2166
2676
  textAlign: "center"
2167
2677
  },
2168
- children: text.noResults
2678
+ children: noResults
2169
2679
  })]
2170
2680
  });
2171
2681
  }
@@ -2194,9 +2704,10 @@ function debounce(fn, ms) {
2194
2704
  });
2195
2705
  }
2196
2706
  function useFilter(impl) {
2197
- var _a;
2198
2707
  const table = useTableContext();
2199
2708
  const columnId = useColumnContext();
2709
+ const cache = useTableMemo();
2710
+ const filterBy = impl.filterBy && cache("", impl.filterBy);
2200
2711
  react.useEffect(() => {
2201
2712
  table.update((state) => {
2202
2713
  if (impl.defaultValue !== void 0) {
@@ -2206,7 +2717,7 @@ function useFilter(impl) {
2206
2717
  }, []);
2207
2718
  react.useEffect(() => {
2208
2719
  table.update((state) => {
2209
- state.filters.set(columnId, immer.castDraft(impl));
2720
+ state.filters.set(columnId, immer.castDraft(__spreadProps(__spreadValues({}, impl), { filterBy })));
2210
2721
  if (impl.value !== void 0) {
2211
2722
  state.filterValues.set(columnId, impl.value);
2212
2723
  }
@@ -2216,7 +2727,7 @@ function useFilter(impl) {
2216
2727
  state.filters.delete(columnId);
2217
2728
  });
2218
2729
  };
2219
- }, [table, columnId, ...(_a = impl.dependencies) != null ? _a : [impl]]);
2730
+ }, [table, columnId, impl]);
2220
2731
  const value = table.useState((state) => state.filterValues.get(columnId));
2221
2732
  const [dirtyValue, setDirtyValue] = react.useState();
2222
2733
  const implRef = react.useRef(impl);
@@ -2241,7 +2752,8 @@ function useFilter(impl) {
2241
2752
  return {
2242
2753
  value: dirtyValue != null ? dirtyValue : value,
2243
2754
  onChange,
2244
- close: react.useContext(FilterControlContext)
2755
+ close: react.useContext(FilterControlContext),
2756
+ filterBy: filterBy != null ? filterBy : (x) => x
2245
2757
  };
2246
2758
  }
2247
2759
  const textMatch = (text, query) => {
@@ -2263,23 +2775,17 @@ const termMatch = (text, query) => {
2263
2775
  }
2264
2776
  return true;
2265
2777
  };
2266
- function TextFilter(_i) {
2267
- var _j = _i, {
2778
+ function TextFilter(_o) {
2779
+ var _p = _o, {
2268
2780
  compare = textMatch,
2269
2781
  filterBy = asStringOrArray
2270
- } = _j, props = __objRest(_j, [
2782
+ } = _p, props = __objRest(_p, [
2271
2783
  "compare",
2272
2784
  "filterBy"
2273
2785
  ]);
2274
- const {
2275
- components: {
2276
- IconButton
2277
- },
2278
- icons: {
2279
- Search,
2280
- Clear
2281
- }
2282
- } = useTheme();
2786
+ const IconButton2 = useTheme((t) => t.components.IconButton);
2787
+ const Search2 = useTheme((t) => t.icons.Search);
2788
+ const Clear2 = useTheme((t) => t.icons.Clear);
2283
2789
  const {
2284
2790
  value = "",
2285
2791
  onChange
@@ -2301,9 +2807,9 @@ function TextFilter(_i) {
2301
2807
  children: jsxRuntime.jsx(AutoFocusTextField, {
2302
2808
  value,
2303
2809
  onChange: (e) => onChange(e.target.value),
2304
- endIcon: jsxRuntime.jsx(IconButton, {
2810
+ endIcon: jsxRuntime.jsx(IconButton2, {
2305
2811
  onClick: () => onChange(""),
2306
- children: !value ? jsxRuntime.jsx(Search, {}) : jsxRuntime.jsx(Clear, {})
2812
+ children: !value ? jsxRuntime.jsx(Search2, {}) : jsxRuntime.jsx(Clear2, {})
2307
2813
  })
2308
2814
  })
2309
2815
  });
@@ -2315,10 +2821,14 @@ exports.mergeThemes = tableTheme.mergeThemes;
2315
2821
  exports.AutoFocusTextField = AutoFocusTextField;
2316
2822
  exports.ColumnContext = ColumnContext;
2317
2823
  exports.DateFilter = DateFilter;
2824
+ exports.DatePicker = DatePicker;
2318
2825
  exports.SelectFilter = SelectFilter;
2319
2826
  exports.Table = Table;
2320
2827
  exports.TableContext = TableContext;
2321
2828
  exports.TextFilter = TextFilter;
2829
+ exports.dateIntersect = dateIntersect;
2830
+ exports.endOfDay = endOfDay;
2831
+ exports.startOfDay = startOfDay;
2322
2832
  exports.termMatch = termMatch;
2323
2833
  exports.textMatch = textMatch;
2324
2834
  exports.useColumnContext = useColumnContext;