@tint-ui/data-table 0.3.5

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.
Files changed (122) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +9 -0
  3. package/adapters/boolean.d.ts +10 -0
  4. package/adapters/boolean.js +38 -0
  5. package/adapters/index.d.ts +6 -0
  6. package/adapters/index.js +18 -0
  7. package/adapters/number-format.d.ts +1 -0
  8. package/adapters/number-format.js +42 -0
  9. package/adapters/number.d.ts +12 -0
  10. package/adapters/number.js +51 -0
  11. package/adapters/text.d.ts +4 -0
  12. package/adapters/text.js +9 -0
  13. package/cell-adapter-type.d.ts +43 -0
  14. package/cell-adapter-type.js +306 -0
  15. package/cjs/adapters/boolean.js +43 -0
  16. package/cjs/adapters/index.js +21 -0
  17. package/cjs/adapters/number-format.js +46 -0
  18. package/cjs/adapters/number.js +56 -0
  19. package/cjs/adapters/text.js +13 -0
  20. package/cjs/cell-adapter-type.js +312 -0
  21. package/cjs/classes.js +27 -0
  22. package/cjs/context.js +14 -0
  23. package/cjs/data-table-content.js +105 -0
  24. package/cjs/data-table-pagination.js +38 -0
  25. package/cjs/data-table-text-filter.js +83 -0
  26. package/cjs/data-table-toolbar.js +103 -0
  27. package/cjs/data-table-views-options.js +137 -0
  28. package/cjs/data-table.js +63 -0
  29. package/cjs/filter-adapter-type.js +162 -0
  30. package/cjs/filter-adapters/index.js +10 -0
  31. package/cjs/filter-adapters/option.js +152 -0
  32. package/cjs/filter-adapters/use-option-filter.js +195 -0
  33. package/cjs/filter-classes.js +26 -0
  34. package/cjs/filter-fn.js +84 -0
  35. package/cjs/index.js +99 -0
  36. package/cjs/package.json +3 -0
  37. package/cjs/pagination-arrow.js +93 -0
  38. package/cjs/pagination-classes.js +20 -0
  39. package/cjs/pagination-number.js +66 -0
  40. package/cjs/pagination-size-options.js +48 -0
  41. package/cjs/row-button-menu.js +49 -0
  42. package/cjs/row-popover-menu.js +52 -0
  43. package/cjs/toolbar-classes.js +24 -0
  44. package/cjs/types.js +3 -0
  45. package/cjs/use-data-table.js +768 -0
  46. package/cjs/use-lexicon.js +155 -0
  47. package/cjs/use-row-menu.js +60 -0
  48. package/cjs/use-visibility-column.js +105 -0
  49. package/cjs/use-visibility-filter.js +149 -0
  50. package/cjs/utils.js +136 -0
  51. package/classes.d.ts +34 -0
  52. package/classes.js +23 -0
  53. package/context.d.ts +5 -0
  54. package/context.js +9 -0
  55. package/data-table-content.d.ts +9 -0
  56. package/data-table-content.js +98 -0
  57. package/data-table-pagination.d.ts +5 -0
  58. package/data-table-pagination.js +31 -0
  59. package/data-table-text-filter.d.ts +7 -0
  60. package/data-table-text-filter.js +76 -0
  61. package/data-table-toolbar.d.ts +5 -0
  62. package/data-table-toolbar.js +95 -0
  63. package/data-table-views-options.d.ts +2 -0
  64. package/data-table-views-options.js +133 -0
  65. package/data-table.d.ts +18 -0
  66. package/data-table.js +56 -0
  67. package/filter-adapter-type.d.ts +9 -0
  68. package/filter-adapter-type.js +155 -0
  69. package/filter-adapters/index.d.ts +5 -0
  70. package/filter-adapters/index.js +7 -0
  71. package/filter-adapters/option.d.ts +3 -0
  72. package/filter-adapters/option.js +147 -0
  73. package/filter-adapters/use-option-filter.d.ts +27 -0
  74. package/filter-adapters/use-option-filter.js +192 -0
  75. package/filter-classes.d.ts +32 -0
  76. package/filter-classes.js +22 -0
  77. package/filter-fn.d.ts +7 -0
  78. package/filter-fn.js +76 -0
  79. package/index.d.ts +16 -0
  80. package/index.js +16 -0
  81. package/package.json +97 -0
  82. package/pagination-arrow.d.ts +5 -0
  83. package/pagination-arrow.js +86 -0
  84. package/pagination-classes.d.ts +20 -0
  85. package/pagination-classes.js +16 -0
  86. package/pagination-number.d.ts +5 -0
  87. package/pagination-number.js +59 -0
  88. package/pagination-size-options.d.ts +3 -0
  89. package/pagination-size-options.js +44 -0
  90. package/row-button-menu.d.ts +5 -0
  91. package/row-button-menu.js +45 -0
  92. package/row-popover-menu.d.ts +5 -0
  93. package/row-popover-menu.js +48 -0
  94. package/styles-filter.css +1 -0
  95. package/styles-filter.module.css +64 -0
  96. package/styles-filter.module.scss +65 -0
  97. package/styles-pagination.css +1 -0
  98. package/styles-pagination.module.css +28 -0
  99. package/styles-pagination.module.scss +31 -0
  100. package/styles-toolbar.css +1 -0
  101. package/styles-toolbar.module.css +70 -0
  102. package/styles-toolbar.module.scss +67 -0
  103. package/styles.css +1 -0
  104. package/styles.json +8 -0
  105. package/styles.module.css +39 -0
  106. package/styles.module.scss +38 -0
  107. package/toolbar-classes.d.ts +26 -0
  108. package/toolbar-classes.js +20 -0
  109. package/types.d.ts +226 -0
  110. package/types.js +2 -0
  111. package/use-data-table.d.ts +3 -0
  112. package/use-data-table.js +768 -0
  113. package/use-lexicon.d.ts +12 -0
  114. package/use-lexicon.js +151 -0
  115. package/use-row-menu.d.ts +7 -0
  116. package/use-row-menu.js +58 -0
  117. package/use-visibility-column.d.ts +7 -0
  118. package/use-visibility-column.js +101 -0
  119. package/use-visibility-filter.d.ts +7 -0
  120. package/use-visibility-filter.js +145 -0
  121. package/utils.d.ts +14 -0
  122. package/utils.js +128 -0
@@ -0,0 +1,155 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { invariant, warningOnce } from "@tint-ui/tools/proof";
5
+ import { errorMessage } from "@tint-ui/tools/error-message";
6
+ import { adapters as coreAdapters } from "./filter-adapters/index.js";
7
+ import { useDataTableClasses } from "./classes.js";
8
+ const adapters = new Map();
9
+ const defaultAdapters = new Map();
10
+ Object.entries(coreAdapters).forEach(([name, {
11
+ adapter
12
+ }]) => {
13
+ defaultAdapters.set(name, {
14
+ adapter
15
+ });
16
+ });
17
+ const getAdapt = type => {
18
+ const adapter = adapters.get(type) || defaultAdapters.get(type);
19
+ if (!adapter) {
20
+ return null;
21
+ }
22
+ return adapter;
23
+ };
24
+ const privateTypes = [];
25
+ const checkAdapt = type => {
26
+ if (!type) {
27
+ throw new Error(`Adapter type is empty`);
28
+ }
29
+ if (privateTypes.includes(type)) {
30
+ throw new Error(`The ${type} type is private`);
31
+ }
32
+ if (adapters.has(type)) {
33
+ throw new Error(`The ${type} form adapter already exists`);
34
+ }
35
+ };
36
+ const hasFilterAdapter = type => adapters.has(type);
37
+ const addFilterAdapter = function (name, adapter) {
38
+ checkAdapt(name);
39
+ adapters.set(name, {
40
+ adapter
41
+ });
42
+ };
43
+ const addFilterAdapterAsync = function (name, handler) {
44
+ checkAdapt(name);
45
+ adapters.set(name, {
46
+ adapter: createAsyncAdapterCallback(name, handler)
47
+ });
48
+ };
49
+ const getAsyncAdapter = function (type, result) {
50
+ const adapter = result?.default;
51
+ invariant(typeof adapter === "function", `Async ${type} adapter failure: default is not function`);
52
+ return adapter;
53
+ };
54
+ const createAsyncAdapterCallback = function (type, handler) {
55
+ const adapt = {
56
+ waiters: new Set(),
57
+ handler,
58
+ error: null
59
+ };
60
+ const adapter = filter => {
61
+ return /*#__PURE__*/React.createElement(DataTableFilterAdapterAsync, {
62
+ adapt: adapt,
63
+ type: type,
64
+ filter: filter
65
+ });
66
+ };
67
+ adapt.adapter = adapter;
68
+ return adapter;
69
+ };
70
+ const createAsyncPromise = async (type, adapt) => {
71
+ try {
72
+ const result = await adapt.handler();
73
+ const adapter = getAsyncAdapter(type, result);
74
+ adapt.error = null;
75
+ adapt.adapter = adapter;
76
+ adapters.set(type, {
77
+ adapter
78
+ });
79
+ } catch (err) {
80
+ adapt.error = errorMessage(err).message;
81
+ }
82
+ let event;
83
+ if (adapt.error != null) {
84
+ event = {
85
+ error: adapt.error
86
+ };
87
+ } else if (adapt.adapter) {
88
+ event = {
89
+ adapter: adapt.adapter
90
+ };
91
+ } else {
92
+ return;
93
+ }
94
+ const handlers = Array.from(adapt.waiters.values());
95
+ adapt.waiters.clear();
96
+ handlers.forEach(handler => {
97
+ handler(event);
98
+ });
99
+ };
100
+ const DataTableFilterAdapterAsync = props => {
101
+ const classes = useDataTableClasses();
102
+ const {
103
+ adapt,
104
+ filter,
105
+ type
106
+ } = props;
107
+ const [state, setState] = React.useState(() => {
108
+ return adapt.adapter ? {
109
+ adapter: adapt.adapter
110
+ } : adapt.error != null ? {
111
+ error: adapt.error
112
+ } : null;
113
+ });
114
+ React.useEffect(() => {
115
+ const {
116
+ adapter,
117
+ error,
118
+ promise
119
+ } = adapt;
120
+ if (error != null || adapter != null) {
121
+ return;
122
+ }
123
+ if (promise == null) {
124
+ adapt.promise = createAsyncPromise(type, adapt);
125
+ }
126
+ adapt.waiters.add(setState);
127
+ return () => {
128
+ adapt.waiters.delete(setState);
129
+ };
130
+ }, [type, adapt]);
131
+ if (state == null) {
132
+ return /*#__PURE__*/React.createElement("div", {
133
+ className: classes.loader
134
+ });
135
+ }
136
+ if ("error" in state) {
137
+ return /*#__PURE__*/React.createElement("div", {
138
+ className: classes.error
139
+ }, state.error);
140
+ }
141
+ return /*#__PURE__*/React.createElement(React.Fragment, null, state.adapter(filter));
142
+ };
143
+ DataTableFilterAdapterAsync.displayName = "DataTableFilterAdapterAsync";
144
+ const renderDataTableFilter = function (filter) {
145
+ const {
146
+ type = "option"
147
+ } = filter;
148
+ const adapt = getAdapt(type);
149
+ if (!adapt) {
150
+ warningOnce(`table-filter:${type}`, false, `The ${type} filter type not found`);
151
+ return null;
152
+ }
153
+ return adapt.adapter(filter);
154
+ };
155
+ export { hasFilterAdapter, addFilterAdapter, addFilterAdapterAsync, renderDataTableFilter };
@@ -0,0 +1,5 @@
1
+ import type { DataTableFilterAdapter } from "../types";
2
+ declare const adapters: Record<string, {
3
+ adapter: DataTableFilterAdapter<any>;
4
+ }>;
5
+ export { adapters };
@@ -0,0 +1,7 @@
1
+ import { optionFilterAdapter } from "./option.js";
2
+ const adapters = {
3
+ option: {
4
+ adapter: optionFilterAdapter
5
+ }
6
+ };
7
+ export { adapters };
@@ -0,0 +1,3 @@
1
+ import type { DataTableFilterAdapter, DataTableFilterOptionConfig } from "../types";
2
+ declare const optionFilterAdapter: DataTableFilterAdapter<string, DataTableFilterOptionConfig>;
3
+ export { optionFilterAdapter };
@@ -0,0 +1,147 @@
1
+ "use client";
2
+
3
+ import _extends from "@babel/runtime/helpers/esm/extends";
4
+ import * as React from "react";
5
+ import { SvgThemeIcon } from "@tint-ui/svg-icon";
6
+ import clsx from "clsx";
7
+ import { isEmptyString } from "@tint-ui/tools/is-empty";
8
+ import { Badge } from "@tint-ui/badge";
9
+ import { Button } from "@tint-ui/button";
10
+ import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from "@tint-ui/command";
11
+ import { Popover, PopoverContent, PopoverTrigger } from "@tint-ui/popover";
12
+ import { useOptionFilter } from "./use-option-filter.js";
13
+ import { useDataTableFilterClasses } from "../filter-classes.js";
14
+ const createOptionGroups = (options, groupBy) => {
15
+ const root = [];
16
+ const optionGroup = [];
17
+ const cache = new Map();
18
+ for (const option of options) {
19
+ const {
20
+ config
21
+ } = option;
22
+ if (config && groupBy in config && config[groupBy]) {
23
+ const heading = String(config[groupBy]).trim();
24
+ let options = cache.get(heading);
25
+ if (!options) {
26
+ options = [];
27
+ cache.set(heading, options);
28
+ optionGroup.push({
29
+ heading,
30
+ options
31
+ });
32
+ }
33
+ options.push(option);
34
+ } else {
35
+ root.push(option);
36
+ }
37
+ }
38
+ if (root.length) {
39
+ optionGroup.push({
40
+ options: root
41
+ });
42
+ }
43
+ return optionGroup;
44
+ };
45
+ const FilterOptionType = ({
46
+ filter
47
+ }) => {
48
+ const classes = useDataTableFilterClasses();
49
+ const ctx = useOptionFilter(filter);
50
+ const column = ctx.column;
51
+ if (!column) {
52
+ return null;
53
+ }
54
+ const {
55
+ value,
56
+ options,
57
+ getSelectedOptions,
58
+ manual,
59
+ inputProps,
60
+ lexicon,
61
+ icon,
62
+ groupBy = null,
63
+ disableSearch = false
64
+ } = ctx;
65
+ const selectedOptions = getSelectedOptions();
66
+ const optionGroups = React.useMemo(() => groupBy ? createOptionGroups(options, groupBy) : [{
67
+ options
68
+ }], [options, groupBy]);
69
+ return /*#__PURE__*/React.createElement(Popover, null, /*#__PURE__*/React.createElement(PopoverTrigger, {
70
+ asChild: true
71
+ }, /*#__PURE__*/React.createElement(Button, {
72
+ variant: "outline",
73
+ size: ctx.size,
74
+ className: classes.button,
75
+ iconLeft: /*#__PURE__*/React.createElement(SvgThemeIcon, {
76
+ icon: icon || "data-table-add-filter"
77
+ })
78
+ }, /*#__PURE__*/React.createElement("span", null, filter.label), selectedOptions.length > 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Badge, {
79
+ variant: "secondary",
80
+ className: clsx(classes.badge, classes.mobile)
81
+ }, selectedOptions.length), /*#__PURE__*/React.createElement("div", {
82
+ className: clsx(classes.badges, classes.desktop)
83
+ }, selectedOptions.length > 2 ? /*#__PURE__*/React.createElement(Badge, {
84
+ variant: "secondary",
85
+ className: classes.badge
86
+ }, lexicon.filterSelected(selectedOptions.length)) : selectedOptions.map(option => /*#__PURE__*/React.createElement(Badge, {
87
+ variant: "secondary",
88
+ key: option.value,
89
+ className: classes.badge
90
+ }, option.label)))))), /*#__PURE__*/React.createElement(PopoverContent, {
91
+ className: classes.popover,
92
+ align: "start"
93
+ }, /*#__PURE__*/React.createElement(Command, null, (manual || options.length > 5 && !disableSearch) && /*#__PURE__*/React.createElement(CommandInput, _extends({
94
+ placeholder: lexicon.filterSearch(filter.label)
95
+ }, manual ? inputProps : null)), /*#__PURE__*/React.createElement(CommandList, null, /*#__PURE__*/React.createElement(CommandEmpty, null, lexicon.filterNotFound), optionGroups.map(({
96
+ heading,
97
+ options
98
+ }, index) => /*#__PURE__*/React.createElement(CommandGroup, {
99
+ key: index,
100
+ heading: heading
101
+ }, options.map(option => {
102
+ const optionValue = option.value;
103
+ const isSelected = value.includes(optionValue);
104
+ const {
105
+ icon
106
+ } = option.config || {};
107
+ return /*#__PURE__*/React.createElement(CommandItem, {
108
+ key: option.value,
109
+ onSelect: () => {
110
+ const selectedValues = new Set(value);
111
+ if (isSelected) {
112
+ selectedValues.delete(optionValue);
113
+ } else {
114
+ if (!filter.multiple) {
115
+ selectedValues.clear();
116
+ }
117
+ selectedValues.add(optionValue);
118
+ }
119
+ column.setFilterValue(Array.from(selectedValues));
120
+ }
121
+ }, /*#__PURE__*/React.createElement("div", {
122
+ className: clsx(classes.checkbox, isSelected && classes.selected)
123
+ }, /*#__PURE__*/React.createElement(SvgThemeIcon, {
124
+ icon: "check",
125
+ "aria-hidden": "true"
126
+ })), !isEmptyString(icon) && /*#__PURE__*/React.createElement(SvgThemeIcon, {
127
+ icon: icon,
128
+ className: classes.icon,
129
+ "aria-hidden": "true"
130
+ }), /*#__PURE__*/React.createElement("span", {
131
+ className: classes.label
132
+ }, option.label));
133
+ }))), value.length > 0 && /*#__PURE__*/React.createElement(CommandGroup, {
134
+ forceMount: true
135
+ }, /*#__PURE__*/React.createElement(CommandSeparator, null), /*#__PURE__*/React.createElement(CommandItem, {
136
+ onSelect: () => {
137
+ column.setFilterValue(undefined);
138
+ }
139
+ }, lexicon.filterClear))))));
140
+ };
141
+ FilterOptionType.displayName = "FilterOptionType";
142
+ const optionFilterAdapter = filter => {
143
+ return /*#__PURE__*/React.createElement(FilterOptionType, {
144
+ filter: filter
145
+ });
146
+ };
147
+ export { optionFilterAdapter };
@@ -0,0 +1,27 @@
1
+ import type { Column } from "@tanstack/react-table";
2
+ import type { InputSelectOption } from "@tint-ui/tools";
3
+ import type { DataTableDisplayFilter, DataTableFilterOptionConfig } from "../types";
4
+ declare const useOptionFilter: <TData>(filter: DataTableDisplayFilter<keyof TData, DataTableFilterOptionConfig>) => {
5
+ name: keyof TData extends infer T ? T extends keyof TData ? T extends string ? T : string : never : never;
6
+ column: Column<TData, unknown> | undefined;
7
+ inputProps: {
8
+ readonly value: string;
9
+ onValueChange(inputText: string): void;
10
+ onFocus(): void;
11
+ };
12
+ getSelectedOptions: () => InputSelectOption<object>[];
13
+ lexicon: import("../types").LexiconType;
14
+ size: import("../types").DataTableToolbarSize;
15
+ manual: boolean;
16
+ value: string[];
17
+ options: InputSelectOption<object>[];
18
+ inputText: string;
19
+ error: string | null;
20
+ loading: boolean;
21
+ type?: "string" | "number" | "boolean" | undefined;
22
+ icon?: string | undefined;
23
+ disableSearch?: boolean | undefined;
24
+ autoSelect?: boolean | undefined;
25
+ groupBy?: string | undefined;
26
+ };
27
+ export { useOptionFilter };
@@ -0,0 +1,192 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { useDataTableContext } from "../context.js";
5
+ import { errorMessage } from "@tint-ui/tools/error-message";
6
+ import { makeOption } from "@tint-ui/tools/make-option";
7
+ const getOptions = (result, dump) => {
8
+ const options = [];
9
+ if (result.length) {
10
+ result.forEach(option => {
11
+ const item = makeOption(option, dump);
12
+ if (item) {
13
+ options.push(item);
14
+ }
15
+ });
16
+ }
17
+ return options;
18
+ };
19
+ const useOptionFilter = function (filter) {
20
+ const {
21
+ name,
22
+ config: {
23
+ options: filterOptions,
24
+ initialOptions,
25
+ ...rest
26
+ } = {}
27
+ } = filter;
28
+ const ctx = useDataTableContext();
29
+ const column = ctx.table.getColumn(name);
30
+ const refFn = React.useRef(null);
31
+ refFn.current = typeof filterOptions === "function" ? filterOptions : null;
32
+ const refDump = React.useRef({});
33
+ const filterValue = column ? column.getFilterValue() : null;
34
+ const value = filterValue == null ? [] : Array.isArray(filterValue) ? filterValue : [filterValue];
35
+ const refValue = React.useRef(value);
36
+ refValue.current = value;
37
+ const [state, setState] = React.useState(() => ({
38
+ options: Array.isArray(filterOptions) ? getOptions(filterOptions, refDump.current) : Array.isArray(initialOptions) ? getOptions(initialOptions, refDump.current) : [],
39
+ inputText: "",
40
+ text: "",
41
+ loading: false,
42
+ error: null
43
+ }));
44
+ const refState = React.useRef(state);
45
+ refState.current = state;
46
+ const {
47
+ onMount,
48
+ inputProps,
49
+ getSelectedOptions
50
+ } = React.useMemo(() => {
51
+ let localState = state;
52
+ let lazyId = null;
53
+ let mount = false;
54
+ let abortController = null;
55
+ const update = newState => {
56
+ if (!mount) {
57
+ return;
58
+ }
59
+ localState = {
60
+ ...localState,
61
+ ...newState
62
+ };
63
+ setState(localState);
64
+ };
65
+ const lazyClear = () => {
66
+ if (lazyId != null) {
67
+ window.clearTimeout(lazyId);
68
+ lazyId = null;
69
+ }
70
+ };
71
+ const abort = () => {
72
+ if (abortController != null) {
73
+ abortController.abort();
74
+ abortController = null;
75
+ }
76
+ };
77
+ const query = (force = false, mode = "search") => {
78
+ if (!mount) {
79
+ return;
80
+ }
81
+ const callback = refFn.current;
82
+ const text = localState.inputText.trim();
83
+ if (callback == null) {
84
+ return update({
85
+ loading: false,
86
+ error: null,
87
+ text
88
+ });
89
+ }
90
+ if (!force && localState.text === text) {
91
+ return;
92
+ }
93
+ abort();
94
+ update({
95
+ loading: true,
96
+ error: null,
97
+ text
98
+ });
99
+ abortController = new AbortController();
100
+ const signal = abortController.signal;
101
+ (async (...args) => callback(...args))(localState.text, refValue.current, mode, abortController).then(result => {
102
+ const options = [];
103
+ const resultDump = {};
104
+ result.forEach(option => {
105
+ const item = makeOption(option, resultDump);
106
+ if (item) {
107
+ options.push(item);
108
+ }
109
+ });
110
+ Object.assign(refDump.current, resultDump);
111
+ update({
112
+ options,
113
+ loading: false
114
+ });
115
+ }).catch(error => {
116
+ if (signal.aborted) {
117
+ return;
118
+ }
119
+ update({
120
+ loading: false,
121
+ error: errorMessage(error).message
122
+ });
123
+ }).finally(() => {
124
+ abortController = null;
125
+ });
126
+ };
127
+ const lazyLoad = () => {
128
+ if (refFn.current) {
129
+ return;
130
+ }
131
+ lazyClear();
132
+ lazyId = window.setTimeout(() => {
133
+ lazyId = null;
134
+ query();
135
+ }, 250);
136
+ };
137
+ return {
138
+ onMount() {
139
+ mount = true;
140
+ if (refValue.current.length) {
141
+ query(true, "initial");
142
+ }
143
+ return () => {
144
+ mount = false;
145
+ lazyClear();
146
+ abort();
147
+ };
148
+ },
149
+ getSelectedOptions() {
150
+ const options = [];
151
+ refValue.current.forEach(name => {
152
+ const option = refDump.current[name];
153
+ if (option) {
154
+ options.push(option);
155
+ }
156
+ });
157
+ return options;
158
+ },
159
+ inputProps: {
160
+ get value() {
161
+ return localState.inputText;
162
+ },
163
+ onValueChange(inputText) {
164
+ update({
165
+ inputText
166
+ });
167
+ lazyLoad();
168
+ },
169
+ onFocus() {
170
+ query(true);
171
+ }
172
+ }
173
+ };
174
+ }, []);
175
+ React.useEffect(onMount, [onMount]);
176
+ return {
177
+ ...rest,
178
+ name,
179
+ column,
180
+ inputProps,
181
+ getSelectedOptions,
182
+ lexicon: ctx.lexicon,
183
+ size: ctx.toolbar.size,
184
+ manual: refFn.current != null,
185
+ value: refValue.current,
186
+ options: state.options,
187
+ inputText: state.inputText,
188
+ error: state.error,
189
+ loading: state.loading
190
+ };
191
+ };
192
+ export { useOptionFilter };
@@ -0,0 +1,32 @@
1
+ declare const filterClasses: {
2
+ button: string;
3
+ popover: string;
4
+ badges: string;
5
+ badge: string;
6
+ mobile: string;
7
+ desktop: string;
8
+ checkbox: string;
9
+ icon: string;
10
+ label: string;
11
+ selected: string;
12
+ text: string;
13
+ textMobile: string;
14
+ };
15
+ declare const useDataTableFilterClasses: () => {
16
+ button: string;
17
+ popover: string;
18
+ badges: string;
19
+ badge: string;
20
+ mobile: string;
21
+ desktop: string;
22
+ checkbox: string;
23
+ icon: string;
24
+ label: string;
25
+ selected: string;
26
+ text: string;
27
+ textMobile: string;
28
+ };
29
+ type DataTableFilterClassesType = keyof typeof filterClasses;
30
+ type DataTableFilterClasses = Record<DataTableFilterClassesType, string>;
31
+ export { filterClasses, useDataTableFilterClasses };
32
+ export type { DataTableFilterClassesType, DataTableFilterClasses };
@@ -0,0 +1,22 @@
1
+ import { classGroup } from "@tint-ui/tools/class-group";
2
+ import { useClasses } from "@tint-ui/theme";
3
+ const {
4
+ base,
5
+ b
6
+ } = classGroup("data-table-filter");
7
+ const filterClasses = {
8
+ button: base,
9
+ popover: b("popover"),
10
+ badges: b("badges"),
11
+ badge: b("badge"),
12
+ mobile: b("mobile"),
13
+ desktop: b("desktop"),
14
+ checkbox: b("checkbox"),
15
+ icon: b("icon"),
16
+ label: b("label"),
17
+ selected: b("selected"),
18
+ text: b("text"),
19
+ textMobile: b("text", "mobile")
20
+ };
21
+ const useDataTableFilterClasses = () => useClasses("data-table-filter", filterClasses);
22
+ export { filterClasses, useDataTableFilterClasses };
package/filter-fn.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type { FilterFn } from "@tanstack/react-table";
2
+ declare const filterBoolean: FilterFn<any>;
3
+ declare const filterNumber: FilterFn<any>;
4
+ declare const filterNumberMultiple: FilterFn<any>;
5
+ declare const filterString: FilterFn<any>;
6
+ declare const filterStringMultiple: FilterFn<any>;
7
+ export { filterBoolean, filterNumber, filterNumberMultiple, filterString, filterStringMultiple };
package/filter-fn.js ADDED
@@ -0,0 +1,76 @@
1
+ const isEmpty = (value, filterValue) => value == null || Array.isArray(filterValue) && filterValue.length === 0;
2
+ const filterBoolean = (row, columnId, filterValue) => {
3
+ const value = row.getValue(columnId);
4
+ if (Array.isArray(filterValue)) {
5
+ filterValue = filterValue[0];
6
+ }
7
+ if (value == null) {
8
+ return filterValue === "";
9
+ }
10
+ if (typeof filterValue === "boolean") {
11
+ return value === filterValue;
12
+ }
13
+ if (filterValue === "1") {
14
+ return value === true;
15
+ }
16
+ if (filterValue === "0") {
17
+ return value === false;
18
+ }
19
+ return false;
20
+ };
21
+ const isNumberValue = (value, filterValue) => {
22
+ return value === (typeof filterValue === "number" ? filterValue : parseInt(String(filterValue)));
23
+ };
24
+ const filterNumber = (row, columnId, filterValue) => {
25
+ const value = row.getValue(columnId);
26
+ if (isEmpty(value, filterValue)) {
27
+ return true;
28
+ }
29
+ if (typeof value !== "number") {
30
+ return false;
31
+ }
32
+ return isNumberValue(value, Array.isArray(filterValue) ? filterValue[0] : filterValue);
33
+ };
34
+ const filterNumberMultiple = (row, columnId, filterValue) => {
35
+ const value = row.getValue(columnId);
36
+ if (isEmpty(value, filterValue)) {
37
+ return true;
38
+ }
39
+ if (typeof value !== "number") {
40
+ return false;
41
+ }
42
+ if (Array.isArray(filterValue)) {
43
+ for (const val of filterValue) {
44
+ if (isNumberValue(value, val)) {
45
+ return true;
46
+ }
47
+ }
48
+ } else if (isNumberValue(value, filterValue)) {
49
+ return true;
50
+ }
51
+ return false;
52
+ };
53
+ const filterString = (row, columnId, filterValue) => {
54
+ const value = row.getValue(columnId);
55
+ if (isEmpty(value, filterValue)) {
56
+ return true;
57
+ }
58
+ return value === String(Array.isArray(filterValue) ? filterValue[0] : filterValue);
59
+ };
60
+ const filterStringMultiple = (row, columnId, filterValue) => {
61
+ const value = row.getValue(columnId);
62
+ if (isEmpty(value, filterValue)) {
63
+ return true;
64
+ }
65
+ if (Array.isArray(filterValue)) {
66
+ for (const val of filterValue) {
67
+ if (value === String(val)) {
68
+ return true;
69
+ }
70
+ }
71
+ } else if (value === String(filterValue)) {
72
+ return true;
73
+ }
74
+ return false;
75
+ };
76
+ export { filterBoolean, filterNumber, filterNumberMultiple, filterString, filterStringMultiple };
package/index.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ export * from "./classes";
2
+ export * from "./filter-classes";
3
+ export * from "./toolbar-classes";
4
+ export * from "./pagination-classes";
5
+ export * from "./context";
6
+ export * from "./cell-adapter-type";
7
+ export * from "./filter-adapter-type";
8
+ export * from "./data-table-content";
9
+ export * from "./data-table-pagination";
10
+ export * from "./data-table-toolbar";
11
+ export * from "./data-table-views-options";
12
+ export * from "./data-table";
13
+ export * from "./pagination-arrow";
14
+ export * from "./pagination-number";
15
+ export * from "./pagination-size-options";
16
+ export * from "./types";