@tint-ui/data-table 0.3.11 → 0.3.13

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.
@@ -65,7 +65,9 @@ const FilterOptionType = ({
65
65
  lexicon,
66
66
  icon,
67
67
  groupBy = null,
68
- disableSearch = false
68
+ disableSearch = false,
69
+ multiple,
70
+ toggleMode
69
71
  } = ctx;
70
72
  const selectedOptions = getSelectedOptions();
71
73
  const optionGroups = React.useMemo(() => groupBy ? createOptionGroups(options, groupBy) : [{
@@ -111,12 +113,16 @@ const FilterOptionType = ({
111
113
  } = option.config || {};
112
114
  return /*#__PURE__*/React.createElement(_command.CommandItem, {
113
115
  key: option.value,
116
+ "data-multiple": multiple,
114
117
  onSelect: () => {
115
118
  const selectedValues = new Set(value);
116
119
  if (isSelected) {
120
+ if (!toggleMode) {
121
+ return;
122
+ }
117
123
  selectedValues.delete(optionValue);
118
124
  } else {
119
- if (!filter.multiple) {
125
+ if (!multiple) {
120
126
  selectedValues.clear();
121
127
  }
122
128
  selectedValues.add(optionValue);
@@ -126,7 +132,7 @@ const FilterOptionType = ({
126
132
  }, /*#__PURE__*/React.createElement("div", {
127
133
  className: (0, _clsx.default)(classes.checkbox, isSelected && classes.selected)
128
134
  }, /*#__PURE__*/React.createElement(_svgIcon.SvgThemeIcon, {
129
- icon: "check",
135
+ icon: multiple ? "filter-option-checkbox" : "filter-option-radio",
130
136
  "aria-hidden": "true"
131
137
  })), !(0, _isEmpty.isEmptyString)(icon) && /*#__PURE__*/React.createElement(_svgIcon.SvgThemeIcon, {
132
138
  icon: icon,
@@ -10,7 +10,7 @@ var React = _interopRequireWildcard(require("react"));
10
10
  var _context = require("../context");
11
11
  var _errorMessage = require("@tint-ui/tools/error-message");
12
12
  var _makeOption = require("@tint-ui/tools/make-option");
13
- const _excluded = ["options", "initialOptions"];
13
+ const _excluded = ["options", "initialOptions", "toggleMode"];
14
14
  const getOptions = (result, dump) => {
15
15
  const options = [];
16
16
  if (result.length) {
@@ -26,9 +26,11 @@ const getOptions = (result, dump) => {
26
26
  const useOptionFilter = function (filter) {
27
27
  const {
28
28
  name,
29
+ multiple = false,
29
30
  config: {
30
31
  options: filterOptions,
31
- initialOptions
32
+ initialOptions,
33
+ toggleMode = multiple
32
34
  } = {}
33
35
  } = filter,
34
36
  rest = (0, _objectWithoutPropertiesLoose2.default)(filter.config, _excluded);
@@ -181,6 +183,8 @@ const useOptionFilter = function (filter) {
181
183
  name,
182
184
  column,
183
185
  inputProps,
186
+ multiple,
187
+ toggleMode,
184
188
  getSelectedOptions,
185
189
  lexicon: ctx.lexicon,
186
190
  size: ctx.toolbar.size,
@@ -20,7 +20,8 @@ var _utils = require("./utils");
20
20
  const _excluded = ["globalFilter"],
21
21
  _excluded2 = ["columnFilters"],
22
22
  _excluded3 = ["sorting"],
23
- _excluded4 = ["pagination"];
23
+ _excluded4 = ["pagination"],
24
+ _excluded5 = ["onFilterReset", "state"];
24
25
  const createHash = function (name, keyName, manual, cells) {
25
26
  let hash = `${name}[${keyName},${manual ? "1" : "0"}]://`;
26
27
  for (const cell of cells) {
@@ -388,10 +389,14 @@ const useDataTable = function (props) {
388
389
  if (!mount) {
389
390
  return;
390
391
  }
392
+ const cb = refOptions.current?.onFilterReset;
391
393
  setState(prev => {
392
394
  if (prev.loading) {
393
395
  return prev;
394
396
  }
397
+ if (cb) {
398
+ cb();
399
+ }
395
400
  const state = Object.assign({}, prev, {
396
401
  pagination: {
397
402
  pageSize: prev.pagination.pageSize,
@@ -408,15 +413,20 @@ const useDataTable = function (props) {
408
413
  });
409
414
  },
410
415
  onPageSizeChange(pageSize) {
416
+ const cb = refOptions.current?.onPaginationChange;
411
417
  setState(prev => {
412
418
  if (prev.loading || prev.pagination.pageSize === pageSize) {
413
419
  return prev;
414
420
  }
421
+ const paginationState = {
422
+ pageSize,
423
+ pageIndex: 0
424
+ };
425
+ if (cb) {
426
+ cb(paginationState);
427
+ }
415
428
  const state = Object.assign({}, prev, {
416
- pagination: {
417
- pageSize,
418
- pageIndex: 0
419
- }
429
+ pagination: paginationState
420
430
  });
421
431
  if (force(state)) {
422
432
  state.loading = true;
@@ -723,10 +733,22 @@ const useDataTable = function (props) {
723
733
  }
724
734
  };
725
735
  }, [onRowClick, loading]);
736
+ let optProp = {};
737
+ let optState = {};
738
+ if (options != null) {
739
+ const {
740
+ state
741
+ } = options,
742
+ prop = (0, _objectWithoutPropertiesLoose2.default)(options, _excluded5);
743
+ optProp = prop;
744
+ if (state) {
745
+ optState = state;
746
+ }
747
+ }
726
748
  const {
727
749
  pagination
728
750
  } = state;
729
- const tableCtx = (0, _reactTable.useReactTable)(Object.assign({}, options, {
751
+ const tableCtx = (0, _reactTable.useReactTable)(Object.assign({}, optProp, {
730
752
  pageCount: manual ? state.pageCount : undefined,
731
753
  getCoreRowModel: (0, _reactTable.getCoreRowModel)(),
732
754
  getPaginationRowModel: (0, _reactTable.getPaginationRowModel)(),
@@ -741,7 +763,7 @@ const useDataTable = function (props) {
741
763
  manualFiltering: manual,
742
764
  manualSorting: manual,
743
765
  manualPagination: manual,
744
- state: Object.assign({}, options?.state || null, {
766
+ state: Object.assign({}, optState, {
745
767
  columnVisibility,
746
768
  sorting: state.sorting,
747
769
  globalFilter: state.globalFilter,
@@ -60,7 +60,9 @@ const FilterOptionType = ({
60
60
  lexicon,
61
61
  icon,
62
62
  groupBy = null,
63
- disableSearch = false
63
+ disableSearch = false,
64
+ multiple,
65
+ toggleMode
64
66
  } = ctx;
65
67
  const selectedOptions = getSelectedOptions();
66
68
  const optionGroups = React.useMemo(() => groupBy ? createOptionGroups(options, groupBy) : [{
@@ -106,12 +108,16 @@ const FilterOptionType = ({
106
108
  } = option.config || {};
107
109
  return /*#__PURE__*/React.createElement(CommandItem, {
108
110
  key: option.value,
111
+ "data-multiple": multiple,
109
112
  onSelect: () => {
110
113
  const selectedValues = new Set(value);
111
114
  if (isSelected) {
115
+ if (!toggleMode) {
116
+ return;
117
+ }
112
118
  selectedValues.delete(optionValue);
113
119
  } else {
114
- if (!filter.multiple) {
120
+ if (!multiple) {
115
121
  selectedValues.clear();
116
122
  }
117
123
  selectedValues.add(optionValue);
@@ -121,7 +127,7 @@ const FilterOptionType = ({
121
127
  }, /*#__PURE__*/React.createElement("div", {
122
128
  className: clsx(classes.checkbox, isSelected && classes.selected)
123
129
  }, /*#__PURE__*/React.createElement(SvgThemeIcon, {
124
- icon: "check",
130
+ icon: multiple ? "filter-option-checkbox" : "filter-option-radio",
125
131
  "aria-hidden": "true"
126
132
  })), !isEmptyString(icon) && /*#__PURE__*/React.createElement(SvgThemeIcon, {
127
133
  icon: icon,
@@ -9,6 +9,8 @@ declare const useOptionFilter: <TData>(filter: DataTableDisplayFilter<keyof TDat
9
9
  onValueChange(inputText: string): void;
10
10
  onFocus(): void;
11
11
  };
12
+ multiple: boolean;
13
+ toggleMode: boolean;
12
14
  getSelectedOptions: () => InputSelectOption<object>[];
13
15
  lexicon: import("../types").LexiconType;
14
16
  size: import("../types").DataTableToolbarSize;
@@ -19,9 +19,11 @@ const getOptions = (result, dump) => {
19
19
  const useOptionFilter = function (filter) {
20
20
  const {
21
21
  name,
22
+ multiple = false,
22
23
  config: {
23
24
  options: filterOptions,
24
25
  initialOptions,
26
+ toggleMode = multiple,
25
27
  ...rest
26
28
  } = {}
27
29
  } = filter;
@@ -178,6 +180,8 @@ const useOptionFilter = function (filter) {
178
180
  name,
179
181
  column,
180
182
  inputProps,
183
+ multiple,
184
+ toggleMode,
181
185
  getSelectedOptions,
182
186
  lexicon: ctx.lexicon,
183
187
  size: ctx.toolbar.size,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tint-ui/data-table",
3
- "version": "0.3.11",
3
+ "version": "0.3.13",
4
4
  "author": "phragon@websoftlab.com",
5
5
  "license": "MIT",
6
6
  "dependencies": {
package/styles-filter.css CHANGED
@@ -1 +1 @@
1
- .tui-data-table-filter_badges{align-items:center;gap:.5rem}.tui-data-table-filter_badges [data-size=sm]{gap:.25rem}.tui-data-table-filter_badge{border-radius:calc(var(--radius) - 4px);display:inline-block;font-weight:400;max-width:120px;overflow:hidden;padding-left:.25rem;padding-right:.25rem;text-overflow:ellipsis;white-space:nowrap}.tui-data-table-filter_popover{max-width:200px;padding:0}.tui-data-table-filter{border-style:dashed}.tui-data-table-filter>.tui-data-table-filter_badge,.tui-data-table-filter>.tui-data-table-filter_badges{margin-left:.25rem;margin-right:-.5rem}.tui-data-table-filter:hover .tui-data-table-filter_badge{background-color:hsl(var(--background))}.tui-data-table-filter_mobile{display:inline-flex}@media (min-width:1024px){.tui-data-table-filter_mobile{display:none}}.tui-data-table-filter_mobile.tui-data-table-filter_badge{display:flow-root}@media (min-width:1024px){.tui-data-table-filter_mobile.tui-data-table-filter_badge{display:none}}.tui-data-table-filter_desktop{display:none}@media (min-width:1024px){.tui-data-table-filter_desktop{display:inline-flex}}.tui-data-table-filter_checkbox{align-items:center;border:1px dashed #64748b80;border-radius:calc(var(--radius) - 4px);display:inline-flex;height:1rem;justify-content:center;opacity:.5;width:1rem}.tui-data-table-filter_checkbox svg{height:1rem;visibility:hidden;width:1rem}.tui-data-table-filter_checkbox.tui-data-table-filter_selected{border-color:#0000;opacity:1}.tui-data-table-filter_checkbox.tui-data-table-filter_selected svg{visibility:visible}.tui-data-table-filter_text{width:180px}@media (min-width:1024px){.tui-data-table-filter_text{width:220px}}.tui-data-table-filter_text.tui-data-table-filter_text--mobile{width:100%}.tui-data-table-filter_icon{color:hsl(var(--muted-foreground));height:1rem;margin-right:.5rem;width:1rem}.tui-data-table-filter_label{margin-right:auto}
1
+ .tui-data-table-filter_badges{align-items:center;gap:.5rem}.tui-data-table-filter_badges [data-size=sm]{gap:.25rem}.tui-data-table-filter_badge{border-radius:calc(var(--radius) - 4px);display:inline-block;font-weight:400;max-width:120px;overflow:hidden;padding-left:.25rem;padding-right:.25rem;text-overflow:ellipsis;white-space:nowrap}.tui-data-table-filter_popover{max-width:200px;padding:0}.tui-data-table-filter{border-style:dashed}.tui-data-table-filter>.tui-data-table-filter_badge,.tui-data-table-filter>.tui-data-table-filter_badges{margin-left:.25rem;margin-right:-.5rem}.tui-data-table-filter:hover .tui-data-table-filter_badge{background-color:hsl(var(--background))}.tui-data-table-filter_mobile{display:inline-flex}@media (min-width:1024px){.tui-data-table-filter_mobile{display:none}}.tui-data-table-filter_mobile.tui-data-table-filter_badge{display:flow-root}@media (min-width:1024px){.tui-data-table-filter_mobile.tui-data-table-filter_badge{display:none}}.tui-data-table-filter_desktop{display:none}@media (min-width:1024px){.tui-data-table-filter_desktop{display:inline-flex}}.tui-data-table-filter_checkbox{align-items:center;border:1px dashed #64748b80;border-radius:calc(var(--radius) - 4px);display:inline-flex;height:1rem;justify-content:center;opacity:.5;width:1rem}.tui-data-table-filter_checkbox svg{height:1rem;visibility:hidden;width:1rem}.tui-data-table-filter_checkbox.tui-data-table-filter_selected{border-color:#0000;opacity:1}.tui-data-table-filter_checkbox.tui-data-table-filter_selected svg{visibility:visible}[data-multiple=false]>.tui-data-table-filter_checkbox{border-radius:9999px}[data-multiple=false]>.tui-data-table-filter_checkbox.tui-data-table-filter_selected{background-color:hsl(var(--foreground));color:hsl(var(--background))}.tui-data-table-filter_text{width:180px}@media (min-width:1024px){.tui-data-table-filter_text{width:220px}}.tui-data-table-filter_text.tui-data-table-filter_text--mobile{width:100%}.tui-data-table-filter_icon{color:hsl(var(--muted-foreground));height:1rem;margin-right:.5rem;width:1rem}.tui-data-table-filter_label{margin-right:auto}
@@ -47,6 +47,12 @@
47
47
  .checkbox.selected svg {
48
48
  @apply visible;
49
49
  }
50
+ [data-multiple=false] > .checkbox {
51
+ @apply rounded-full;
52
+ }
53
+ [data-multiple=false] > .checkbox.selected {
54
+ @apply bg-foreground text-background;
55
+ }
50
56
 
51
57
  .text {
52
58
  @apply w-[180px] lg:w-[220px];
@@ -47,6 +47,12 @@
47
47
  @apply visible;
48
48
  }
49
49
  }
50
+ [data-multiple="false"] > & {
51
+ @apply rounded-full;
52
+ &.selected {
53
+ @apply bg-foreground text-background;
54
+ }
55
+ }
50
56
  }
51
57
 
52
58
  .text {
package/types.d.ts CHANGED
@@ -34,6 +34,7 @@ export type DataTableToolbarSize = "sm" | "md" | "lg";
34
34
  export type DataTableNavbarSize = "sm" | "md" | "lg";
35
35
  export interface DataTableOptions<TData> extends Partial<Omit<TableOptions<TData>, "pageCount" | "getCoreRowModel" | "getPaginationRowModel" | "getFilteredRowModel" | "getSortedRowModel" | "globalFilterFn" | "manualFiltering" | "manualSorting" | "manualPagination" | "data" | "columns" | "state">> {
36
36
  state?: Partial<Omit<TableState, "columnVisibility" | "sorting" | "globalFilter" | "columnFilters" | "pagination">>;
37
+ onFilterReset?: () => void;
37
38
  }
38
39
  export interface DataTableCoreProps<TData> extends FilterType<TData> {
39
40
  table: DataTableType<TData>;
@@ -145,6 +146,7 @@ export interface DataTableFilterOptionConfig {
145
146
  disableSearch?: boolean;
146
147
  autoSelect?: boolean;
147
148
  groupBy?: string;
149
+ toggleMode?: boolean;
148
150
  }
149
151
  export type DataTableDisplayCell<TValue = string, TConfig extends object = any> = Required<Omit<DataTableCellType<TValue, TConfig>, "filter">> & {
150
152
  filter: boolean;
@@ -1,3 +1,3 @@
1
- import { DataTableCoreProps, DataTableContextType } from "./types";
1
+ import type { DataTableCoreProps, DataTableContextType } from "./types";
2
2
  declare const useDataTable: <TData extends object>(props: DataTableCoreProps<TData>) => DataTableContextType<TData>;
3
3
  export { useDataTable };
package/use-data-table.js CHANGED
@@ -380,10 +380,14 @@ const useDataTable = function (props) {
380
380
  if (!mount) {
381
381
  return;
382
382
  }
383
+ const cb = refOptions.current?.onFilterReset;
383
384
  setState(prev => {
384
385
  if (prev.loading) {
385
386
  return prev;
386
387
  }
388
+ if (cb) {
389
+ cb();
390
+ }
387
391
  const state = {
388
392
  ...prev,
389
393
  pagination: {
@@ -401,16 +405,21 @@ const useDataTable = function (props) {
401
405
  });
402
406
  },
403
407
  onPageSizeChange(pageSize) {
408
+ const cb = refOptions.current?.onPaginationChange;
404
409
  setState(prev => {
405
410
  if (prev.loading || prev.pagination.pageSize === pageSize) {
406
411
  return prev;
407
412
  }
413
+ const paginationState = {
414
+ pageSize,
415
+ pageIndex: 0
416
+ };
417
+ if (cb) {
418
+ cb(paginationState);
419
+ }
408
420
  const state = {
409
421
  ...prev,
410
- pagination: {
411
- pageSize,
412
- pageIndex: 0
413
- }
422
+ pagination: paginationState
414
423
  };
415
424
  if (force(state)) {
416
425
  state.loading = true;
@@ -721,11 +730,24 @@ const useDataTable = function (props) {
721
730
  }
722
731
  };
723
732
  }, [onRowClick, loading]);
733
+ let optProp = {};
734
+ let optState = {};
735
+ if (options != null) {
736
+ const {
737
+ onFilterReset,
738
+ state,
739
+ ...prop
740
+ } = options;
741
+ optProp = prop;
742
+ if (state) {
743
+ optState = state;
744
+ }
745
+ }
724
746
  const {
725
747
  pagination
726
748
  } = state;
727
749
  const tableCtx = useReactTable({
728
- ...options,
750
+ ...optProp,
729
751
  pageCount: manual ? state.pageCount : undefined,
730
752
  getCoreRowModel: getCoreRowModel(),
731
753
  getPaginationRowModel: getPaginationRowModel(),
@@ -741,7 +763,7 @@ const useDataTable = function (props) {
741
763
  manualSorting: manual,
742
764
  manualPagination: manual,
743
765
  state: {
744
- ...(options?.state || null),
766
+ ...optState,
745
767
  columnVisibility,
746
768
  sorting: state.sorting,
747
769
  globalFilter: state.globalFilter,