@carefully-built/crud 0.1.2 → 0.1.4

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/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { ActionHandlers, ActionType, Column, FilterConfig, ResponsiveSheetClassNames, SortState } from "@carefully-built/ui";
1
+ import { ActionHandlers, ActionType, Column, FilterConfig, ResponsiveSheetClassNames, SheetOutsideInteractionGuard, SortState, TableToolbarLabelsInput } from "@carefully-built/ui";
2
2
  import { ReactNode } from "react";
3
3
 
4
4
  //#region src/pagination.d.ts
@@ -18,6 +18,7 @@ interface CrudFilterDefinition<TItem> {
18
18
  readonly key: Extract<keyof TItem, string>;
19
19
  readonly config: FilterConfig;
20
20
  readonly allowAll?: boolean;
21
+ readonly allOptionLabel?: string;
21
22
  readonly clearable?: boolean;
22
23
  }
23
24
  interface UseCrudTableStateOptions<TItem> {
@@ -50,8 +51,10 @@ interface CrudTableViewProps<TItem> {
50
51
  readonly columns: readonly Column<TItem>[];
51
52
  readonly isLoading: boolean;
52
53
  readonly searchPlaceholder?: string;
54
+ readonly toolbarLabels?: TableToolbarLabelsInput;
53
55
  readonly filters?: readonly CrudFilterDefinition<TItem>[];
54
56
  readonly actions?: readonly ActionType[];
57
+ readonly actionLabels?: Partial<Record<ActionType, string>>;
55
58
  readonly actionHandlers?: ActionHandlers<TItem>;
56
59
  readonly renderActions?: (item: TItem) => ReactNode;
57
60
  readonly noDataMessage?: string;
@@ -69,6 +72,7 @@ interface CrudDataTableProps<TItem> {
69
72
  readonly columns: readonly Column<TItem>[];
70
73
  readonly isLoading: boolean;
71
74
  readonly actions?: readonly ActionType[];
75
+ readonly actionLabels?: Partial<Record<ActionType, string>>;
72
76
  readonly actionHandlers?: ActionHandlers<TItem>;
73
77
  readonly renderActions?: (item: TItem) => ReactNode;
74
78
  readonly noDataMessage?: string;
@@ -87,6 +91,7 @@ interface CrudDataTableProps<TItem> {
87
91
  //#region src/crud-data-table.d.ts
88
92
  declare function CrudDataTable<TItem extends object>({
89
93
  actions,
94
+ actionLabels,
90
95
  actionHandlers,
91
96
  columns,
92
97
  data,
@@ -125,6 +130,7 @@ interface CrudResourceSheetProps {
125
130
  readonly confirmLoading?: boolean;
126
131
  readonly confirmCloseWhenDirty?: boolean;
127
132
  readonly width?: number;
133
+ readonly outsideInteractionGuard?: SheetOutsideInteractionGuard;
128
134
  readonly className?: string;
129
135
  readonly contentClassName?: string;
130
136
  readonly footerClassName?: string;
@@ -135,6 +141,7 @@ declare function CrudResourceSheet({
135
141
  formId,
136
142
  onConfirm,
137
143
  confirmCloseWhenDirty: _confirmCloseWhenDirty,
144
+ outsideInteractionGuard,
138
145
  ...sheetProps
139
146
  }: CrudResourceSheetProps): React.ReactElement;
140
147
  //#endregion
@@ -144,8 +151,10 @@ declare function CrudTableView<TItem extends object>({
144
151
  columns,
145
152
  isLoading,
146
153
  searchPlaceholder,
154
+ toolbarLabels,
147
155
  filters,
148
156
  actions,
157
+ actionLabels,
149
158
  actionHandlers,
150
159
  renderActions,
151
160
  noDataMessage,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/pagination.ts","../src/types.ts","../src/crud-data-table.tsx","../src/crud-list-table.tsx","../src/crud-resource-sheet.tsx","../src/crud-table-view.tsx","../src/use-crud-table-state.ts","../src/use-url-string-filters.ts","../src/use-url-pagination.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/pagination.ts","../src/types.ts","../src/crud-data-table.tsx","../src/crud-list-table.tsx","../src/crud-resource-sheet.tsx","../src/crud-table-view.tsx","../src/use-crud-table-state.ts","../src/use-url-string-filters.ts","../src/use-url-pagination.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,15 +1,16 @@
1
1
  import { ResponsiveSheet, SmartTable, TableToolbar, useTableSorting } from "@carefully-built/ui";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { useCallback, useMemo, useState } from "react";
3
+ import { useCallback, useMemo } from "react";
4
4
  import { parseAsInteger, parseAsString, useQueryState, useQueryStates } from "nuqs";
5
5
 
6
6
  //#region src/crud-data-table.tsx
7
- function CrudDataTable({ actions, actionHandlers, columns, data, fullHeight = true, getRowKey, isLoading, maxHeight, noDataContent, noDataMessage, onRowClick, pagination, renderActions, renderMobileCard, sortState, stickyHeader = true, onSortChange }) {
7
+ function CrudDataTable({ actions, actionLabels, actionHandlers, columns, data, fullHeight = true, getRowKey, isLoading, maxHeight, noDataContent, noDataMessage, onRowClick, pagination, renderActions, renderMobileCard, sortState, stickyHeader = true, onSortChange }) {
8
8
  return /* @__PURE__ */ jsx(SmartTable, {
9
9
  data: [...data],
10
10
  columns: [...columns],
11
11
  isLoading,
12
12
  actions: actions ? [...actions] : void 0,
13
+ actionLabels,
13
14
  actionHandlers,
14
15
  renderActions,
15
16
  noDataMessage,
@@ -34,7 +35,7 @@ function CrudListTable(props) {
34
35
 
35
36
  //#endregion
36
37
  //#region src/crud-resource-sheet.tsx
37
- function CrudResourceSheet({ children, formId, onConfirm, confirmCloseWhenDirty: _confirmCloseWhenDirty, ...sheetProps }) {
38
+ function CrudResourceSheet({ children, formId, onConfirm, confirmCloseWhenDirty: _confirmCloseWhenDirty, outsideInteractionGuard, ...sheetProps }) {
38
39
  const submitForm = () => {
39
40
  const form = formId ? document.getElementById(formId) : null;
40
41
  if (form instanceof HTMLFormElement) {
@@ -45,6 +46,7 @@ function CrudResourceSheet({ children, formId, onConfirm, confirmCloseWhenDirty:
45
46
  };
46
47
  return /* @__PURE__ */ jsx(ResponsiveSheet, {
47
48
  ...sheetProps,
49
+ outsideInteractionGuard,
48
50
  onConfirm: formId || onConfirm ? submitForm : void 0,
49
51
  children
50
52
  });
@@ -52,7 +54,7 @@ function CrudResourceSheet({ children, formId, onConfirm, confirmCloseWhenDirty:
52
54
 
53
55
  //#endregion
54
56
  //#region src/crud-table-view.tsx
55
- function CrudTableView({ state, columns, isLoading, searchPlaceholder = "Search...", filters = [], actions, actionHandlers, renderActions, noDataMessage, initialEmptyContent, noResultsContent, getRowKey, onRowClick, renderMobileCard, stickyHeader = true, fullHeight = true, maxHeight }) {
57
+ function CrudTableView({ state, columns, isLoading, searchPlaceholder = "Search...", toolbarLabels, filters = [], actions, actionLabels, actionHandlers, renderActions, noDataMessage, initialEmptyContent, noResultsContent, getRowKey, onRowClick, renderMobileCard, stickyHeader = true, fullHeight = true, maxHeight }) {
56
58
  const emptyContent = state.emptyState === "no-results" ? noResultsContent : initialEmptyContent;
57
59
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
58
60
  className: "shrink-0",
@@ -69,16 +71,19 @@ function CrudTableView({ state, columns, isLoading, searchPlaceholder = "Search.
69
71
  state.setFilter(filter.key, value);
70
72
  },
71
73
  allowAll: filter.allowAll,
74
+ allOptionLabel: filter.allOptionLabel,
72
75
  clearable: filter.clearable
73
76
  })),
74
77
  onClearAll: state.clearAll,
75
- getDraftResultCount: state.getDraftFilterResultCount
78
+ getDraftResultCount: state.getDraftFilterResultCount,
79
+ labels: toolbarLabels
76
80
  })
77
81
  }), /* @__PURE__ */ jsx(SmartTable, {
78
82
  data: state.paginatedData,
79
83
  columns: [...columns],
80
84
  isLoading,
81
85
  actions: actions ? [...actions] : void 0,
86
+ actionLabels,
82
87
  actionHandlers,
83
88
  renderActions,
84
89
  noDataMessage,
@@ -110,13 +115,104 @@ function matchesCrudSearch(searchText, query) {
110
115
  }
111
116
 
112
117
  //#endregion
113
- //#region src/pagination.ts
114
- function getValidPage(page, totalPages) {
115
- return Math.min(Math.max(1, page), totalPages);
116
- }
117
- function paginateCrudData(data, currentPage, pageSize) {
118
+ //#region src/use-url-pagination.ts
119
+ function useUrlPagination({ totalItems, pageSize = 20, pageParam = "page" }) {
120
+ const [page, setPage] = useQueryState(pageParam, parseAsInteger.withDefault(1));
121
+ const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
122
+ const currentPage = Math.min(Math.max(1, page), totalPages);
118
123
  const startIndex = (currentPage - 1) * pageSize;
119
- return data.slice(startIndex, startIndex + pageSize);
124
+ const endIndex = Math.min(startIndex + pageSize, totalItems);
125
+ const hasPrevPage = currentPage > 1;
126
+ const hasNextPage = currentPage < totalPages;
127
+ const goToPage = useCallback((newPage) => {
128
+ const validPage = Math.min(Math.max(1, newPage), totalPages);
129
+ setPage(validPage === 1 ? null : validPage);
130
+ }, [setPage, totalPages]);
131
+ const nextPage = useCallback(() => {
132
+ if (hasNextPage) goToPage(currentPage + 1);
133
+ }, [
134
+ currentPage,
135
+ goToPage,
136
+ hasNextPage
137
+ ]);
138
+ const prevPage = useCallback(() => {
139
+ if (hasPrevPage) goToPage(currentPage - 1);
140
+ }, [
141
+ currentPage,
142
+ goToPage,
143
+ hasPrevPage
144
+ ]);
145
+ const firstPage = useCallback(() => {
146
+ goToPage(1);
147
+ }, [goToPage]);
148
+ const lastPage = useCallback(() => {
149
+ goToPage(totalPages);
150
+ }, [goToPage, totalPages]);
151
+ const paginate = useCallback((data) => data.slice(startIndex, endIndex), [endIndex, startIndex]);
152
+ return useMemo(() => ({
153
+ currentPage,
154
+ pageSize,
155
+ totalPages,
156
+ totalItems,
157
+ startIndex,
158
+ endIndex,
159
+ hasPrevPage,
160
+ hasNextPage,
161
+ goToPage,
162
+ nextPage,
163
+ prevPage,
164
+ firstPage,
165
+ lastPage,
166
+ paginate,
167
+ onPageChange: goToPage
168
+ }), [
169
+ currentPage,
170
+ endIndex,
171
+ firstPage,
172
+ goToPage,
173
+ hasNextPage,
174
+ hasPrevPage,
175
+ lastPage,
176
+ nextPage,
177
+ pageSize,
178
+ paginate,
179
+ prevPage,
180
+ startIndex,
181
+ totalItems,
182
+ totalPages
183
+ ]);
184
+ }
185
+
186
+ //#endregion
187
+ //#region src/use-url-string-filters.ts
188
+ function buildParserMap(definitions) {
189
+ return Object.fromEntries(definitions.map((definition) => [definition.param ?? definition.key, parseAsString.withDefault(definition.defaultValue ?? "all")]));
190
+ }
191
+ function normalizeFilterValue(value, definition) {
192
+ if (value === (definition.clearValue ?? definition.defaultValue ?? "all")) return null;
193
+ return value.length > 0 ? value : null;
194
+ }
195
+ function useUrlStringFilters(definitions) {
196
+ const [params, setParams] = useQueryStates(useMemo(() => buildParserMap(definitions), [definitions]));
197
+ const values = useMemo(() => Object.fromEntries(definitions.map((definition) => {
198
+ const param = definition.param ?? definition.key;
199
+ return [definition.key, params[param] ?? definition.defaultValue ?? "all"];
200
+ })), [definitions, params]);
201
+ return {
202
+ values,
203
+ setValue: useCallback((key, value) => {
204
+ const definition = definitions.find((item) => item.key === key);
205
+ if (!definition) return;
206
+ setParams({ [definition.param ?? definition.key]: normalizeFilterValue(value, definition) });
207
+ }, [definitions, setParams]),
208
+ clear: useCallback(() => {
209
+ setParams(Object.fromEntries(definitions.map((definition) => [definition.param ?? definition.key, null])));
210
+ }, [definitions, setParams]),
211
+ getDraftValues: useCallback((draftValues) => ({
212
+ ...values,
213
+ ...draftValues
214
+ }), [values])
215
+ };
120
216
  }
121
217
 
122
218
  //#endregion
@@ -139,45 +235,49 @@ function filterCrudData(data, search, filters, searchFields) {
139
235
  });
140
236
  }
141
237
  function useCrudTableState({ data, columns, searchFields = [], filters: filterDefinitions = [], pageSize = 20, initialSortState = null }) {
142
- const [search, setSearch] = useState("");
143
- const [filters, setFilters] = useState(() => buildInitialFilters(filterDefinitions));
144
- const [currentPage, setCurrentPage] = useState(1);
238
+ const urlFilters = useUrlStringFilters(useMemo(() => [{
239
+ key: "search",
240
+ defaultValue: "",
241
+ clearValue: ""
242
+ }, ...filterDefinitions.map((filter) => ({
243
+ key: filter.key,
244
+ defaultValue: "all",
245
+ clearValue: "all"
246
+ }))], [filterDefinitions]));
247
+ const search = urlFilters.values.search ?? "";
248
+ const filters = useMemo(() => ({
249
+ ...buildInitialFilters(filterDefinitions),
250
+ ...Object.fromEntries(filterDefinitions.map((filter) => [filter.key, urlFilters.values[filter.key] ?? "all"]))
251
+ }), [filterDefinitions, urlFilters.values]);
145
252
  const filteredData = useMemo(() => filterCrudData(data, search, filters, searchFields), [
146
253
  data,
147
254
  filters,
148
255
  search,
149
256
  searchFields
150
257
  ]);
258
+ const pagination = useUrlPagination({
259
+ totalItems: filteredData.length,
260
+ pageSize
261
+ });
262
+ const setCurrentPage = pagination.onPageChange;
151
263
  const { sortedData, sortState, setSortState } = useTableSorting({
152
264
  data: filteredData,
153
265
  columns,
154
266
  initialSortState
155
267
  });
156
- const totalPages = Math.max(1, Math.ceil(filteredData.length / pageSize));
157
- const validCurrentPage = getValidPage(currentPage, totalPages);
158
- const startIndex = (validCurrentPage - 1) * pageSize;
159
- const endIndex = Math.min(startIndex + pageSize, filteredData.length);
160
- const paginatedData = useMemo(() => paginateCrudData(sortedData, validCurrentPage, pageSize), [
161
- pageSize,
162
- sortedData,
163
- validCurrentPage
164
- ]);
268
+ const paginatedData = useMemo(() => pagination.paginate(sortedData), [pagination, sortedData]);
165
269
  const setFilter = useCallback((key, value) => {
166
- setFilters((currentFilters) => ({
167
- ...currentFilters,
168
- [key]: value
169
- }));
270
+ urlFilters.setValue(key, value);
170
271
  setCurrentPage(1);
171
- }, []);
272
+ }, [setCurrentPage, urlFilters]);
172
273
  const updateSearch = useCallback((value) => {
173
- setSearch(value);
274
+ urlFilters.setValue("search", value);
174
275
  setCurrentPage(1);
175
- }, []);
276
+ }, [setCurrentPage, urlFilters]);
176
277
  const clearAll = useCallback(() => {
177
- setSearch("");
178
- setFilters(buildInitialFilters(filterDefinitions));
278
+ urlFilters.clear();
179
279
  setCurrentPage(1);
180
- }, [filterDefinitions]);
280
+ }, [setCurrentPage, urlFilters]);
181
281
  const getDraftFilterResultCount = useCallback((draftValues) => filterCrudData(data, search, {
182
282
  ...filters,
183
283
  ...draftValues
@@ -204,119 +304,10 @@ function useCrudTableState({ data, columns, searchFields = [], filters: filterDe
204
304
  emptyState: hasSearch || hasFilters ? "no-results" : "initial",
205
305
  sortState,
206
306
  setSortState,
207
- pagination: {
208
- currentPage: validCurrentPage,
209
- totalPages,
210
- totalItems: filteredData.length,
211
- pageSize,
212
- startIndex,
213
- endIndex,
214
- onPageChange: setCurrentPage
215
- }
216
- };
217
- }
218
-
219
- //#endregion
220
- //#region src/use-url-string-filters.ts
221
- function buildParserMap(definitions) {
222
- return Object.fromEntries(definitions.map((definition) => [definition.param ?? definition.key, parseAsString.withDefault(definition.defaultValue ?? "all")]));
223
- }
224
- function normalizeFilterValue(value, definition) {
225
- if (value === (definition.clearValue ?? definition.defaultValue ?? "all")) return null;
226
- return value.length > 0 ? value : null;
227
- }
228
- function useUrlStringFilters(definitions) {
229
- const [params, setParams] = useQueryStates(useMemo(() => buildParserMap(definitions), [definitions]));
230
- const values = useMemo(() => Object.fromEntries(definitions.map((definition) => {
231
- const param = definition.param ?? definition.key;
232
- return [definition.key, params[param] ?? definition.defaultValue ?? "all"];
233
- })), [definitions, params]);
234
- return {
235
- values,
236
- setValue: useCallback((key, value) => {
237
- const definition = definitions.find((item) => item.key === key);
238
- if (!definition) return;
239
- setParams({ [definition.param ?? definition.key]: normalizeFilterValue(value, definition) });
240
- }, [definitions, setParams]),
241
- clear: useCallback(() => {
242
- setParams(Object.fromEntries(definitions.map((definition) => [definition.param ?? definition.key, null])));
243
- }, [definitions, setParams]),
244
- getDraftValues: useCallback((draftValues) => ({
245
- ...values,
246
- ...draftValues
247
- }), [values])
307
+ pagination
248
308
  };
249
309
  }
250
310
 
251
- //#endregion
252
- //#region src/use-url-pagination.ts
253
- function useUrlPagination({ totalItems, pageSize = 20, pageParam = "page" }) {
254
- const [page, setPage] = useQueryState(pageParam, parseAsInteger.withDefault(1));
255
- const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
256
- const currentPage = Math.min(Math.max(1, page), totalPages);
257
- const startIndex = (currentPage - 1) * pageSize;
258
- const endIndex = Math.min(startIndex + pageSize, totalItems);
259
- const hasPrevPage = currentPage > 1;
260
- const hasNextPage = currentPage < totalPages;
261
- const goToPage = useCallback((newPage) => {
262
- const validPage = Math.min(Math.max(1, newPage), totalPages);
263
- setPage(validPage === 1 ? null : validPage);
264
- }, [setPage, totalPages]);
265
- const nextPage = useCallback(() => {
266
- if (hasNextPage) goToPage(currentPage + 1);
267
- }, [
268
- currentPage,
269
- goToPage,
270
- hasNextPage
271
- ]);
272
- const prevPage = useCallback(() => {
273
- if (hasPrevPage) goToPage(currentPage - 1);
274
- }, [
275
- currentPage,
276
- goToPage,
277
- hasPrevPage
278
- ]);
279
- const firstPage = useCallback(() => {
280
- goToPage(1);
281
- }, [goToPage]);
282
- const lastPage = useCallback(() => {
283
- goToPage(totalPages);
284
- }, [goToPage, totalPages]);
285
- const paginate = useCallback((data) => data.slice(startIndex, endIndex), [endIndex, startIndex]);
286
- return useMemo(() => ({
287
- currentPage,
288
- pageSize,
289
- totalPages,
290
- totalItems,
291
- startIndex,
292
- endIndex,
293
- hasPrevPage,
294
- hasNextPage,
295
- goToPage,
296
- nextPage,
297
- prevPage,
298
- firstPage,
299
- lastPage,
300
- paginate,
301
- onPageChange: goToPage
302
- }), [
303
- currentPage,
304
- endIndex,
305
- firstPage,
306
- goToPage,
307
- hasNextPage,
308
- hasPrevPage,
309
- lastPage,
310
- nextPage,
311
- pageSize,
312
- paginate,
313
- prevPage,
314
- startIndex,
315
- totalItems,
316
- totalPages
317
- ]);
318
- }
319
-
320
311
  //#endregion
321
312
  export { CrudDataTable, CrudListTable, CrudResourceSheet, CrudTableView, useCrudTableState, useUrlPagination, useUrlStringFilters };
322
313
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/crud-data-table.tsx","../src/crud-list-table.tsx","../src/crud-resource-sheet.tsx","../src/crud-table-view.tsx","../src/search.ts","../src/pagination.ts","../src/use-crud-table-state.ts","../src/use-url-string-filters.ts","../src/use-url-pagination.ts"],"sourcesContent":["\"use client\";\n\nimport { SmartTable } from \"@carefully-built/ui\";\n\nimport type {\n CrudDataTableProps,\n} from \"./types\";\n\nexport function CrudDataTable<TItem extends object>({\n actions,\n actionHandlers,\n columns,\n data,\n fullHeight = true,\n getRowKey,\n isLoading,\n maxHeight,\n noDataContent,\n noDataMessage,\n onRowClick,\n pagination,\n renderActions,\n renderMobileCard,\n sortState,\n stickyHeader = true,\n onSortChange,\n}: CrudDataTableProps<TItem>): React.ReactElement {\n return (\n <SmartTable\n data={[...data]}\n columns={[...columns]}\n isLoading={isLoading}\n actions={actions ? [...actions] : undefined}\n actionHandlers={actionHandlers}\n renderActions={renderActions}\n noDataMessage={noDataMessage}\n noDataContent={noDataContent}\n getRowKey={getRowKey}\n onRowClick={onRowClick}\n renderMobileCard={renderMobileCard}\n stickyHeader={stickyHeader}\n fullHeight={fullHeight}\n maxHeight={maxHeight}\n sortState={sortState}\n onSortChange={onSortChange}\n pagination={pagination}\n />\n );\n}\n","\"use client\";\n\nimport { CrudDataTable } from \"./crud-data-table\";\nimport type { CrudDataTableProps } from \"./types\";\n\nexport type CrudListTableProps<TItem extends object> = CrudDataTableProps<TItem>;\n\nexport function CrudListTable<TItem extends object>(\n props: CrudListTableProps<TItem>,\n): React.ReactElement {\n return <CrudDataTable {...props} />;\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\nimport { ResponsiveSheet } from \"@carefully-built/ui\";\nimport type { ResponsiveSheetClassNames } from \"@carefully-built/ui\";\n\nexport interface CrudResourceSheetProps {\n readonly open: boolean;\n readonly onOpenChange: (open: boolean) => void;\n readonly title: ReactNode;\n readonly children: ReactNode;\n readonly formId?: string;\n readonly description?: ReactNode;\n readonly onCancel?: () => void;\n readonly cancelLabel?: ReactNode;\n readonly onConfirm?: () => void;\n readonly confirmLabel?: ReactNode;\n readonly confirmDisabled?: boolean;\n readonly confirmLoading?: boolean;\n readonly confirmCloseWhenDirty?: boolean;\n readonly width?: number;\n readonly className?: string;\n readonly contentClassName?: string;\n readonly footerClassName?: string;\n readonly classes?: ResponsiveSheetClassNames;\n}\n\nexport function CrudResourceSheet({\n children,\n formId,\n onConfirm,\n confirmCloseWhenDirty: _confirmCloseWhenDirty,\n ...sheetProps\n}: CrudResourceSheetProps): React.ReactElement {\n const submitForm = (): void => {\n const form = formId ? document.getElementById(formId) : null;\n\n if (form instanceof HTMLFormElement) {\n form.requestSubmit();\n return;\n }\n\n onConfirm?.();\n };\n\n return (\n <ResponsiveSheet\n {...sheetProps}\n onConfirm={formId || onConfirm ? submitForm : undefined}\n >\n {children}\n </ResponsiveSheet>\n );\n}\n","\"use client\";\n\nimport type { CrudTableViewProps } from \"./types\";\n\nimport { SmartTable, TableToolbar } from \"@carefully-built/ui\";\n\nexport function CrudTableView<TItem extends object>({\n state,\n columns,\n isLoading,\n searchPlaceholder = \"Search...\",\n filters = [],\n actions,\n actionHandlers,\n renderActions,\n noDataMessage,\n initialEmptyContent,\n noResultsContent,\n getRowKey,\n onRowClick,\n renderMobileCard,\n stickyHeader = true,\n fullHeight = true,\n maxHeight,\n}: CrudTableViewProps<TItem>): React.ReactElement {\n const emptyContent =\n state.emptyState === \"no-results\" ? noResultsContent : initialEmptyContent;\n\n return (\n <>\n <div className=\"shrink-0\">\n <TableToolbar\n search={{\n value: state.search,\n onChange: state.setSearch,\n placeholder: searchPlaceholder,\n }}\n filters={filters.map((filter) => ({\n config: filter.config,\n value: state.filters[filter.key] ?? \"all\",\n onChange: (value) => {\n state.setFilter(filter.key, value);\n },\n allowAll: filter.allowAll,\n clearable: filter.clearable,\n }))}\n onClearAll={state.clearAll}\n getDraftResultCount={state.getDraftFilterResultCount}\n />\n </div>\n\n <SmartTable\n data={state.paginatedData}\n columns={[...columns]}\n isLoading={isLoading}\n actions={actions ? [...actions] : undefined}\n actionHandlers={actionHandlers}\n renderActions={renderActions}\n noDataMessage={noDataMessage}\n noDataContent={emptyContent}\n getRowKey={getRowKey}\n onRowClick={onRowClick}\n renderMobileCard={renderMobileCard}\n stickyHeader={stickyHeader}\n fullHeight={fullHeight}\n maxHeight={maxHeight}\n sortState={state.sortState}\n onSortChange={state.setSortState}\n pagination={state.pagination}\n />\n </>\n );\n}\n","function normalizeSearchText(value: string): string {\n return value\n .toLocaleLowerCase()\n .normalize(\"NFD\")\n .replace(/\\p{Diacritic}/gu, \"\")\n .trim();\n}\n\nexport function buildCrudSearchText(values: readonly unknown[]): string {\n return normalizeSearchText(\n values\n .filter(\n (value): value is string | number =>\n typeof value === \"string\" || typeof value === \"number\",\n )\n .map(String)\n .join(\" \"),\n );\n}\n\nexport function matchesCrudSearch(searchText: string, query: string): boolean {\n const normalizedQuery = normalizeSearchText(query);\n\n if (!normalizedQuery) {\n return true;\n }\n\n return normalizedQuery\n .split(/\\s+/)\n .every((token) => searchText.includes(token));\n}\n","export interface CrudPaginationState {\n readonly currentPage: number;\n readonly totalPages: number;\n readonly totalItems: number;\n readonly pageSize: number;\n readonly startIndex: number;\n readonly endIndex: number;\n readonly onPageChange: (page: number) => void;\n}\n\nexport function getValidPage(page: number, totalPages: number): number {\n return Math.min(Math.max(1, page), totalPages);\n}\n\nexport function paginateCrudData<T>(\n data: readonly T[],\n currentPage: number,\n pageSize: number,\n): T[] {\n const startIndex = (currentPage - 1) * pageSize;\n return data.slice(startIndex, startIndex + pageSize);\n}\n","\"use client\";\n\nimport { useCallback, useMemo, useState } from \"react\";\n\nimport type { UseCrudTableStateOptions, CrudTableState } from \"./types\";\n\nimport { useTableSorting } from \"@carefully-built/ui\";\n\nimport { buildCrudSearchText, matchesCrudSearch } from \"./search\";\nimport { getValidPage, paginateCrudData } from \"./pagination\";\n\nfunction buildInitialFilters<TItem>(\n filters: readonly { readonly key: Extract<keyof TItem, string> }[],\n): Record<string, string> {\n return Object.fromEntries(filters.map((filter) => [filter.key, \"all\"]));\n}\n\nfunction itemMatchesFilters<TItem extends object>(\n item: TItem,\n filters: Record<string, string>,\n): boolean {\n const record = item as Record<string, unknown>;\n\n return Object.entries(filters).every(([key, filterValue]) => {\n if (!filterValue || filterValue === \"all\") {\n return true;\n }\n\n return record[key] === filterValue;\n });\n}\n\nfunction filterCrudData<TItem extends object>(\n data: readonly TItem[],\n search: string,\n filters: Record<string, string>,\n searchFields: readonly Extract<keyof TItem, string>[],\n): TItem[] {\n return data.filter((item) => {\n if (!itemMatchesFilters(item, filters)) {\n return false;\n }\n\n const record = item as Record<string, unknown>;\n const searchText = buildCrudSearchText(\n searchFields.map((field) => record[field]),\n );\n return matchesCrudSearch(searchText, search);\n });\n}\n\nexport function useCrudTableState<TItem extends object>({\n data,\n columns,\n searchFields = [],\n filters: filterDefinitions = [],\n pageSize = 20,\n initialSortState = null,\n}: UseCrudTableStateOptions<TItem>): CrudTableState<TItem> {\n const [search, setSearch] = useState(\"\");\n const [filters, setFilters] = useState<Record<string, string>>(() =>\n buildInitialFilters(filterDefinitions),\n );\n const [currentPage, setCurrentPage] = useState(1);\n\n const filteredData = useMemo(\n () => filterCrudData(data, search, filters, searchFields),\n [data, filters, search, searchFields],\n );\n const { sortedData, sortState, setSortState } = useTableSorting({\n data: filteredData,\n columns,\n initialSortState,\n });\n\n const totalPages = Math.max(1, Math.ceil(filteredData.length / pageSize));\n const validCurrentPage = getValidPage(currentPage, totalPages);\n const startIndex = (validCurrentPage - 1) * pageSize;\n const endIndex = Math.min(startIndex + pageSize, filteredData.length);\n const paginatedData = useMemo(\n () => paginateCrudData(sortedData, validCurrentPage, pageSize),\n [pageSize, sortedData, validCurrentPage],\n );\n\n const setFilter = useCallback((key: string, value: string) => {\n setFilters((currentFilters) => ({\n ...currentFilters,\n [key]: value,\n }));\n setCurrentPage(1);\n }, []);\n\n const updateSearch = useCallback((value: string) => {\n setSearch(value);\n setCurrentPage(1);\n }, []);\n\n const clearAll = useCallback(() => {\n setSearch(\"\");\n setFilters(buildInitialFilters(filterDefinitions));\n setCurrentPage(1);\n }, [filterDefinitions]);\n\n const getDraftFilterResultCount = useCallback(\n (draftValues: Record<string, string>) =>\n filterCrudData(\n data,\n search,\n {\n ...filters,\n ...draftValues,\n },\n searchFields,\n ).length,\n [data, filters, search, searchFields],\n );\n\n const hasSearch = search.trim().length > 0;\n const hasFilters = Object.values(filters).some(\n (value) => value && value !== \"all\",\n );\n\n return {\n filteredData,\n sortedData,\n paginatedData,\n search,\n setSearch: updateSearch,\n filters,\n setFilter,\n clearAll,\n getDraftFilterResultCount,\n hasSearch,\n hasFilters,\n emptyState: hasSearch || hasFilters ? \"no-results\" : \"initial\",\n sortState,\n setSortState,\n pagination: {\n currentPage: validCurrentPage,\n totalPages,\n totalItems: filteredData.length,\n pageSize,\n startIndex,\n endIndex,\n onPageChange: setCurrentPage,\n },\n };\n}\n","\"use client\";\n\nimport { parseAsString, useQueryStates } from \"nuqs\";\nimport { useCallback, useMemo } from \"react\";\n\nexport interface UrlStringFilterDefinition<TKey extends string = string> {\n readonly key: TKey;\n readonly param?: string;\n readonly defaultValue?: string;\n readonly clearValue?: string;\n}\n\ntype UrlStringFilterValues<TDefinitions extends readonly UrlStringFilterDefinition[]> = {\n readonly [TDefinition in TDefinitions[number] as TDefinition[\"key\"]]: string;\n};\n\nexport interface UrlStringFiltersState<\n TDefinitions extends readonly UrlStringFilterDefinition[],\n> {\n readonly values: UrlStringFilterValues<TDefinitions>;\n readonly setValue: (key: TDefinitions[number][\"key\"], value: string) => void;\n readonly clear: () => void;\n readonly getDraftValues: (\n draftValues: Record<string, string>,\n ) => UrlStringFilterValues<TDefinitions>;\n}\n\nfunction buildParserMap(definitions: readonly UrlStringFilterDefinition[]) {\n return Object.fromEntries(\n definitions.map((definition) => [\n definition.param ?? definition.key,\n parseAsString.withDefault(definition.defaultValue ?? \"all\"),\n ]),\n );\n}\n\nfunction normalizeFilterValue(\n value: string,\n definition: UrlStringFilterDefinition,\n): string | null {\n const clearValue = definition.clearValue ?? definition.defaultValue ?? \"all\";\n\n if (value === clearValue) {\n return null;\n }\n\n return value.length > 0 ? value : null;\n}\n\nexport function useUrlStringFilters<\n const TDefinitions extends readonly UrlStringFilterDefinition[],\n>(definitions: TDefinitions): UrlStringFiltersState<TDefinitions> {\n const parserMap = useMemo(() => buildParserMap(definitions), [definitions]);\n const [params, setParams] = useQueryStates(parserMap);\n\n const values = useMemo(\n () =>\n Object.fromEntries(\n definitions.map((definition) => {\n const param = definition.param ?? definition.key;\n return [definition.key, params[param] ?? definition.defaultValue ?? \"all\"];\n }),\n ) as UrlStringFilterValues<TDefinitions>,\n [definitions, params],\n );\n\n const setValue = useCallback(\n (key: TDefinitions[number][\"key\"], value: string) => {\n const definition = definitions.find((item) => item.key === key);\n\n if (!definition) {\n return;\n }\n\n void setParams({\n [definition.param ?? definition.key]: normalizeFilterValue(value, definition),\n });\n },\n [definitions, setParams],\n );\n\n const clear = useCallback(() => {\n void setParams(\n Object.fromEntries(\n definitions.map((definition) => [definition.param ?? definition.key, null]),\n ),\n );\n }, [definitions, setParams]);\n\n const getDraftValues = useCallback(\n (draftValues: Record<string, string>) =>\n ({\n ...values,\n ...draftValues,\n }) as UrlStringFilterValues<TDefinitions>,\n [values],\n );\n\n return {\n values,\n setValue,\n clear,\n getDraftValues,\n };\n}\n","\"use client\";\n\nimport { parseAsInteger, useQueryState } from \"nuqs\";\nimport { useCallback, useMemo } from \"react\";\n\nimport type { CrudPaginationState } from \"./pagination\";\n\nexport interface UseUrlPaginationOptions {\n readonly totalItems: number;\n readonly pageSize?: number;\n readonly pageParam?: string;\n}\n\nexport interface UrlPaginationState extends CrudPaginationState {\n readonly hasPrevPage: boolean;\n readonly hasNextPage: boolean;\n readonly goToPage: (page: number) => void;\n readonly nextPage: () => void;\n readonly prevPage: () => void;\n readonly firstPage: () => void;\n readonly lastPage: () => void;\n readonly paginate: <T>(data: readonly T[]) => T[];\n}\n\nexport function useUrlPagination({\n totalItems,\n pageSize = 20,\n pageParam = \"page\",\n}: UseUrlPaginationOptions): UrlPaginationState {\n const [page, setPage] = useQueryState(\n pageParam,\n parseAsInteger.withDefault(1),\n );\n\n const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));\n const currentPage = Math.min(Math.max(1, page), totalPages);\n const startIndex = (currentPage - 1) * pageSize;\n const endIndex = Math.min(startIndex + pageSize, totalItems);\n const hasPrevPage = currentPage > 1;\n const hasNextPage = currentPage < totalPages;\n\n const goToPage = useCallback(\n (newPage: number) => {\n const validPage = Math.min(Math.max(1, newPage), totalPages);\n void setPage(validPage === 1 ? null : validPage);\n },\n [setPage, totalPages],\n );\n\n const nextPage = useCallback(() => {\n if (hasNextPage) {\n goToPage(currentPage + 1);\n }\n }, [currentPage, goToPage, hasNextPage]);\n\n const prevPage = useCallback(() => {\n if (hasPrevPage) {\n goToPage(currentPage - 1);\n }\n }, [currentPage, goToPage, hasPrevPage]);\n\n const firstPage = useCallback(() => {\n goToPage(1);\n }, [goToPage]);\n\n const lastPage = useCallback(() => {\n goToPage(totalPages);\n }, [goToPage, totalPages]);\n\n const paginate = useCallback(\n <T,>(data: readonly T[]): T[] => data.slice(startIndex, endIndex),\n [endIndex, startIndex],\n );\n\n return useMemo(\n () => ({\n currentPage,\n pageSize,\n totalPages,\n totalItems,\n startIndex,\n endIndex,\n hasPrevPage,\n hasNextPage,\n goToPage,\n nextPage,\n prevPage,\n firstPage,\n lastPage,\n paginate,\n onPageChange: goToPage,\n }),\n [\n currentPage,\n endIndex,\n firstPage,\n goToPage,\n hasNextPage,\n hasPrevPage,\n lastPage,\n nextPage,\n pageSize,\n paginate,\n prevPage,\n startIndex,\n totalItems,\n totalPages,\n ],\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/crud-data-table.tsx","../src/crud-list-table.tsx","../src/crud-resource-sheet.tsx","../src/crud-table-view.tsx","../src/search.ts","../src/use-url-pagination.ts","../src/use-url-string-filters.ts","../src/use-crud-table-state.ts"],"sourcesContent":["\"use client\";\n\nimport { SmartTable } from \"@carefully-built/ui\";\n\nimport type {\n CrudDataTableProps,\n} from \"./types\";\n\nexport function CrudDataTable<TItem extends object>({\n actions,\n actionLabels,\n actionHandlers,\n columns,\n data,\n fullHeight = true,\n getRowKey,\n isLoading,\n maxHeight,\n noDataContent,\n noDataMessage,\n onRowClick,\n pagination,\n renderActions,\n renderMobileCard,\n sortState,\n stickyHeader = true,\n onSortChange,\n}: CrudDataTableProps<TItem>): React.ReactElement {\n return (\n <SmartTable\n data={[...data]}\n columns={[...columns]}\n isLoading={isLoading}\n actions={actions ? [...actions] : undefined}\n actionLabels={actionLabels}\n actionHandlers={actionHandlers}\n renderActions={renderActions}\n noDataMessage={noDataMessage}\n noDataContent={noDataContent}\n getRowKey={getRowKey}\n onRowClick={onRowClick}\n renderMobileCard={renderMobileCard}\n stickyHeader={stickyHeader}\n fullHeight={fullHeight}\n maxHeight={maxHeight}\n sortState={sortState}\n onSortChange={onSortChange}\n pagination={pagination}\n />\n );\n}\n","\"use client\";\n\nimport { CrudDataTable } from \"./crud-data-table\";\nimport type { CrudDataTableProps } from \"./types\";\n\nexport type CrudListTableProps<TItem extends object> = CrudDataTableProps<TItem>;\n\nexport function CrudListTable<TItem extends object>(\n props: CrudListTableProps<TItem>,\n): React.ReactElement {\n return <CrudDataTable {...props} />;\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\nimport { ResponsiveSheet } from \"@carefully-built/ui\";\nimport type { ResponsiveSheetClassNames, SheetOutsideInteractionGuard } from \"@carefully-built/ui\";\n\nexport interface CrudResourceSheetProps {\n readonly open: boolean;\n readonly onOpenChange: (open: boolean) => void;\n readonly title: ReactNode;\n readonly children: ReactNode;\n readonly formId?: string;\n readonly description?: ReactNode;\n readonly onCancel?: () => void;\n readonly cancelLabel?: ReactNode;\n readonly onConfirm?: () => void;\n readonly confirmLabel?: ReactNode;\n readonly confirmDisabled?: boolean;\n readonly confirmLoading?: boolean;\n readonly confirmCloseWhenDirty?: boolean;\n readonly width?: number;\n readonly outsideInteractionGuard?: SheetOutsideInteractionGuard;\n readonly className?: string;\n readonly contentClassName?: string;\n readonly footerClassName?: string;\n readonly classes?: ResponsiveSheetClassNames;\n}\n\nexport function CrudResourceSheet({\n children,\n formId,\n onConfirm,\n confirmCloseWhenDirty: _confirmCloseWhenDirty,\n outsideInteractionGuard,\n ...sheetProps\n}: CrudResourceSheetProps): React.ReactElement {\n const submitForm = (): void => {\n const form = formId ? document.getElementById(formId) : null;\n\n if (form instanceof HTMLFormElement) {\n form.requestSubmit();\n return;\n }\n\n onConfirm?.();\n };\n\n return (\n <ResponsiveSheet\n {...sheetProps}\n outsideInteractionGuard={outsideInteractionGuard}\n onConfirm={formId || onConfirm ? submitForm : undefined}\n >\n {children}\n </ResponsiveSheet>\n );\n}\n","\"use client\";\n\nimport type { CrudTableViewProps } from \"./types\";\n\nimport { SmartTable, TableToolbar } from \"@carefully-built/ui\";\n\nexport function CrudTableView<TItem extends object>({\n state,\n columns,\n isLoading,\n searchPlaceholder = \"Search...\",\n toolbarLabels,\n filters = [],\n actions,\n actionLabels,\n actionHandlers,\n renderActions,\n noDataMessage,\n initialEmptyContent,\n noResultsContent,\n getRowKey,\n onRowClick,\n renderMobileCard,\n stickyHeader = true,\n fullHeight = true,\n maxHeight,\n}: CrudTableViewProps<TItem>): React.ReactElement {\n const emptyContent =\n state.emptyState === \"no-results\" ? noResultsContent : initialEmptyContent;\n\n return (\n <>\n <div className=\"shrink-0\">\n <TableToolbar\n search={{\n value: state.search,\n onChange: state.setSearch,\n placeholder: searchPlaceholder,\n }}\n filters={filters.map((filter) => ({\n config: filter.config,\n value: state.filters[filter.key] ?? \"all\",\n onChange: (value) => {\n state.setFilter(filter.key, value);\n },\n allowAll: filter.allowAll,\n allOptionLabel: filter.allOptionLabel,\n clearable: filter.clearable,\n }))}\n onClearAll={state.clearAll}\n getDraftResultCount={state.getDraftFilterResultCount}\n labels={toolbarLabels}\n />\n </div>\n\n <SmartTable\n data={state.paginatedData}\n columns={[...columns]}\n isLoading={isLoading}\n actions={actions ? [...actions] : undefined}\n actionLabels={actionLabels}\n actionHandlers={actionHandlers}\n renderActions={renderActions}\n noDataMessage={noDataMessage}\n noDataContent={emptyContent}\n getRowKey={getRowKey}\n onRowClick={onRowClick}\n renderMobileCard={renderMobileCard}\n stickyHeader={stickyHeader}\n fullHeight={fullHeight}\n maxHeight={maxHeight}\n sortState={state.sortState}\n onSortChange={state.setSortState}\n pagination={state.pagination}\n />\n </>\n );\n}\n","function normalizeSearchText(value: string): string {\n return value\n .toLocaleLowerCase()\n .normalize(\"NFD\")\n .replace(/\\p{Diacritic}/gu, \"\")\n .trim();\n}\n\nexport function buildCrudSearchText(values: readonly unknown[]): string {\n return normalizeSearchText(\n values\n .filter(\n (value): value is string | number =>\n typeof value === \"string\" || typeof value === \"number\",\n )\n .map(String)\n .join(\" \"),\n );\n}\n\nexport function matchesCrudSearch(searchText: string, query: string): boolean {\n const normalizedQuery = normalizeSearchText(query);\n\n if (!normalizedQuery) {\n return true;\n }\n\n return normalizedQuery\n .split(/\\s+/)\n .every((token) => searchText.includes(token));\n}\n","\"use client\";\n\nimport { parseAsInteger, useQueryState } from \"nuqs\";\nimport { useCallback, useMemo } from \"react\";\n\nimport type { CrudPaginationState } from \"./pagination\";\n\nexport interface UseUrlPaginationOptions {\n readonly totalItems: number;\n readonly pageSize?: number;\n readonly pageParam?: string;\n}\n\nexport interface UrlPaginationState extends CrudPaginationState {\n readonly hasPrevPage: boolean;\n readonly hasNextPage: boolean;\n readonly goToPage: (page: number) => void;\n readonly nextPage: () => void;\n readonly prevPage: () => void;\n readonly firstPage: () => void;\n readonly lastPage: () => void;\n readonly paginate: <T>(data: readonly T[]) => T[];\n}\n\nexport function useUrlPagination({\n totalItems,\n pageSize = 20,\n pageParam = \"page\",\n}: UseUrlPaginationOptions): UrlPaginationState {\n const [page, setPage] = useQueryState(\n pageParam,\n parseAsInteger.withDefault(1),\n );\n\n const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));\n const currentPage = Math.min(Math.max(1, page), totalPages);\n const startIndex = (currentPage - 1) * pageSize;\n const endIndex = Math.min(startIndex + pageSize, totalItems);\n const hasPrevPage = currentPage > 1;\n const hasNextPage = currentPage < totalPages;\n\n const goToPage = useCallback(\n (newPage: number) => {\n const validPage = Math.min(Math.max(1, newPage), totalPages);\n void setPage(validPage === 1 ? null : validPage);\n },\n [setPage, totalPages],\n );\n\n const nextPage = useCallback(() => {\n if (hasNextPage) {\n goToPage(currentPage + 1);\n }\n }, [currentPage, goToPage, hasNextPage]);\n\n const prevPage = useCallback(() => {\n if (hasPrevPage) {\n goToPage(currentPage - 1);\n }\n }, [currentPage, goToPage, hasPrevPage]);\n\n const firstPage = useCallback(() => {\n goToPage(1);\n }, [goToPage]);\n\n const lastPage = useCallback(() => {\n goToPage(totalPages);\n }, [goToPage, totalPages]);\n\n const paginate = useCallback(\n <T,>(data: readonly T[]): T[] => data.slice(startIndex, endIndex),\n [endIndex, startIndex],\n );\n\n return useMemo(\n () => ({\n currentPage,\n pageSize,\n totalPages,\n totalItems,\n startIndex,\n endIndex,\n hasPrevPage,\n hasNextPage,\n goToPage,\n nextPage,\n prevPage,\n firstPage,\n lastPage,\n paginate,\n onPageChange: goToPage,\n }),\n [\n currentPage,\n endIndex,\n firstPage,\n goToPage,\n hasNextPage,\n hasPrevPage,\n lastPage,\n nextPage,\n pageSize,\n paginate,\n prevPage,\n startIndex,\n totalItems,\n totalPages,\n ],\n );\n}\n","\"use client\";\n\nimport { parseAsString, useQueryStates } from \"nuqs\";\nimport { useCallback, useMemo } from \"react\";\n\nexport interface UrlStringFilterDefinition<TKey extends string = string> {\n readonly key: TKey;\n readonly param?: string;\n readonly defaultValue?: string;\n readonly clearValue?: string;\n}\n\ntype UrlStringFilterValues<TDefinitions extends readonly UrlStringFilterDefinition[]> = {\n readonly [TDefinition in TDefinitions[number] as TDefinition[\"key\"]]: string;\n};\n\nexport interface UrlStringFiltersState<\n TDefinitions extends readonly UrlStringFilterDefinition[],\n> {\n readonly values: UrlStringFilterValues<TDefinitions>;\n readonly setValue: (key: TDefinitions[number][\"key\"], value: string) => void;\n readonly clear: () => void;\n readonly getDraftValues: (\n draftValues: Record<string, string>,\n ) => UrlStringFilterValues<TDefinitions>;\n}\n\nfunction buildParserMap(definitions: readonly UrlStringFilterDefinition[]) {\n return Object.fromEntries(\n definitions.map((definition) => [\n definition.param ?? definition.key,\n parseAsString.withDefault(definition.defaultValue ?? \"all\"),\n ]),\n );\n}\n\nfunction normalizeFilterValue(\n value: string,\n definition: UrlStringFilterDefinition,\n): string | null {\n const clearValue = definition.clearValue ?? definition.defaultValue ?? \"all\";\n\n if (value === clearValue) {\n return null;\n }\n\n return value.length > 0 ? value : null;\n}\n\nexport function useUrlStringFilters<\n const TDefinitions extends readonly UrlStringFilterDefinition[],\n>(definitions: TDefinitions): UrlStringFiltersState<TDefinitions> {\n const parserMap = useMemo(() => buildParserMap(definitions), [definitions]);\n const [params, setParams] = useQueryStates(parserMap);\n\n const values = useMemo(\n () =>\n Object.fromEntries(\n definitions.map((definition) => {\n const param = definition.param ?? definition.key;\n return [definition.key, params[param] ?? definition.defaultValue ?? \"all\"];\n }),\n ) as UrlStringFilterValues<TDefinitions>,\n [definitions, params],\n );\n\n const setValue = useCallback(\n (key: TDefinitions[number][\"key\"], value: string) => {\n const definition = definitions.find((item) => item.key === key);\n\n if (!definition) {\n return;\n }\n\n void setParams({\n [definition.param ?? definition.key]: normalizeFilterValue(value, definition),\n });\n },\n [definitions, setParams],\n );\n\n const clear = useCallback(() => {\n void setParams(\n Object.fromEntries(\n definitions.map((definition) => [definition.param ?? definition.key, null]),\n ),\n );\n }, [definitions, setParams]);\n\n const getDraftValues = useCallback(\n (draftValues: Record<string, string>) =>\n ({\n ...values,\n ...draftValues,\n }) as UrlStringFilterValues<TDefinitions>,\n [values],\n );\n\n return {\n values,\n setValue,\n clear,\n getDraftValues,\n };\n}\n","\"use client\";\n\nimport { useCallback, useMemo } from \"react\";\n\nimport type { UseCrudTableStateOptions, CrudTableState } from \"./types\";\n\nimport { useTableSorting } from \"@carefully-built/ui\";\n\nimport { buildCrudSearchText, matchesCrudSearch } from \"./search\";\nimport { useUrlPagination } from \"./use-url-pagination\";\nimport { useUrlStringFilters, type UrlStringFilterDefinition } from \"./use-url-string-filters\";\n\nfunction buildInitialFilters<TItem>(\n filters: readonly { readonly key: Extract<keyof TItem, string> }[],\n): Record<string, string> {\n return Object.fromEntries(filters.map((filter) => [filter.key, \"all\"]));\n}\n\nfunction itemMatchesFilters<TItem extends object>(\n item: TItem,\n filters: Record<string, string>,\n): boolean {\n const record = item as Record<string, unknown>;\n\n return Object.entries(filters).every(([key, filterValue]) => {\n if (!filterValue || filterValue === \"all\") {\n return true;\n }\n\n return record[key] === filterValue;\n });\n}\n\nfunction filterCrudData<TItem extends object>(\n data: readonly TItem[],\n search: string,\n filters: Record<string, string>,\n searchFields: readonly Extract<keyof TItem, string>[],\n): TItem[] {\n return data.filter((item) => {\n if (!itemMatchesFilters(item, filters)) {\n return false;\n }\n\n const record = item as Record<string, unknown>;\n const searchText = buildCrudSearchText(\n searchFields.map((field) => record[field]),\n );\n return matchesCrudSearch(searchText, search);\n });\n}\n\nexport function useCrudTableState<TItem extends object>({\n data,\n columns,\n searchFields = [],\n filters: filterDefinitions = [],\n pageSize = 20,\n initialSortState = null,\n}: UseCrudTableStateOptions<TItem>): CrudTableState<TItem> {\n const urlFilterDefinitions = useMemo(\n () =>\n [\n { key: \"search\", defaultValue: \"\", clearValue: \"\" },\n ...filterDefinitions.map((filter) => ({\n key: filter.key,\n defaultValue: \"all\",\n clearValue: \"all\",\n })),\n ] satisfies readonly UrlStringFilterDefinition[],\n [filterDefinitions],\n );\n const urlFilters = useUrlStringFilters(urlFilterDefinitions);\n const search = urlFilters.values.search ?? \"\";\n const filters = useMemo(\n () => ({\n ...buildInitialFilters(filterDefinitions),\n ...Object.fromEntries(\n filterDefinitions.map((filter) => [filter.key, urlFilters.values[filter.key] ?? \"all\"]),\n ),\n }),\n [filterDefinitions, urlFilters.values],\n );\n\n const filteredData = useMemo(\n () => filterCrudData(data, search, filters, searchFields),\n [data, filters, search, searchFields],\n );\n const pagination = useUrlPagination({\n totalItems: filteredData.length,\n pageSize,\n });\n const setCurrentPage = pagination.onPageChange;\n const { sortedData, sortState, setSortState } = useTableSorting({\n data: filteredData,\n columns,\n initialSortState,\n });\n\n const paginatedData = useMemo(\n () => pagination.paginate(sortedData),\n [pagination, sortedData],\n );\n\n const setFilter = useCallback((key: string, value: string) => {\n urlFilters.setValue(key, value);\n void setCurrentPage(1);\n }, [setCurrentPage, urlFilters]);\n\n const updateSearch = useCallback((value: string) => {\n urlFilters.setValue(\"search\", value);\n void setCurrentPage(1);\n }, [setCurrentPage, urlFilters]);\n\n const clearAll = useCallback(() => {\n urlFilters.clear();\n void setCurrentPage(1);\n }, [setCurrentPage, urlFilters]);\n\n const getDraftFilterResultCount = useCallback(\n (draftValues: Record<string, string>) =>\n filterCrudData(\n data,\n search,\n {\n ...filters,\n ...draftValues,\n },\n searchFields,\n ).length,\n [data, filters, search, searchFields],\n );\n\n const hasSearch = search.trim().length > 0;\n const hasFilters = Object.values(filters).some(\n (value) => value && value !== \"all\",\n );\n\n return {\n filteredData,\n sortedData,\n paginatedData,\n search,\n setSearch: updateSearch,\n filters,\n setFilter,\n clearAll,\n getDraftFilterResultCount,\n hasSearch,\n hasFilters,\n emptyState: hasSearch || hasFilters ? \"no-results\" : \"initial\",\n sortState,\n setSortState,\n pagination,\n };\n}\n"],"mappings":";;;;;;AAQA,SAAgB,cAAoC,EAClD,SACA,cACA,gBACA,SACA,MACA,aAAa,MACb,WACA,WACA,WACA,eACA,eACA,YACA,YACA,eACA,kBACA,WACA,eAAe,MACf,gBACgD;AAChD,QACE,oBAAC;EACC,MAAM,CAAC,GAAG,KAAK;EACf,SAAS,CAAC,GAAG,QAAQ;EACV;EACX,SAAS,UAAU,CAAC,GAAG,QAAQ,GAAG;EACpB;EACE;EACD;EACA;EACA;EACJ;EACC;EACM;EACJ;EACF;EACD;EACA;EACG;EACF;GACZ;;;;;ACzCN,SAAgB,cACd,OACoB;AACpB,QAAO,oBAAC,iBAAc,GAAI,QAAS;;;;;ACmBrC,SAAgB,kBAAkB,EAChC,UACA,QACA,WACA,uBAAuB,wBACvB,yBACA,GAAG,cAC0C;CAC7C,MAAM,mBAAyB;EAC7B,MAAM,OAAO,SAAS,SAAS,eAAe,OAAO,GAAG;AAExD,MAAI,gBAAgB,iBAAiB;AACnC,QAAK,eAAe;AACpB;;AAGF,eAAa;;AAGf,QACE,oBAAC;EACC,GAAI;EACqB;EACzB,WAAW,UAAU,YAAY,aAAa;EAE7C;GACe;;;;;ACjDtB,SAAgB,cAAoC,EAClD,OACA,SACA,WACA,oBAAoB,aACpB,eACA,UAAU,EAAE,EACZ,SACA,cACA,gBACA,eACA,eACA,qBACA,kBACA,WACA,YACA,kBACA,eAAe,MACf,aAAa,MACb,aACgD;CAChD,MAAM,eACJ,MAAM,eAAe,eAAe,mBAAmB;AAEzD,QACE,4CACE,oBAAC;EAAI,WAAU;YACb,oBAAC;GACC,QAAQ;IACN,OAAO,MAAM;IACb,UAAU,MAAM;IAChB,aAAa;IACd;GACD,SAAS,QAAQ,KAAK,YAAY;IAChC,QAAQ,OAAO;IACf,OAAO,MAAM,QAAQ,OAAO,QAAQ;IACpC,WAAW,UAAU;AACnB,WAAM,UAAU,OAAO,KAAK,MAAM;;IAEpC,UAAU,OAAO;IACjB,gBAAgB,OAAO;IACvB,WAAW,OAAO;IACnB,EAAE;GACH,YAAY,MAAM;GAClB,qBAAqB,MAAM;GAC3B,QAAQ;IACR;GACE,EAEN,oBAAC;EACC,MAAM,MAAM;EACZ,SAAS,CAAC,GAAG,QAAQ;EACV;EACX,SAAS,UAAU,CAAC,GAAG,QAAQ,GAAG;EACpB;EACE;EACD;EACA;EACf,eAAe;EACJ;EACC;EACM;EACJ;EACF;EACD;EACX,WAAW,MAAM;EACjB,cAAc,MAAM;EACpB,YAAY,MAAM;GAClB,IACD;;;;;AC3EP,SAAS,oBAAoB,OAAuB;AAClD,QAAO,MACJ,mBAAmB,CACnB,UAAU,MAAM,CAChB,QAAQ,mBAAmB,GAAG,CAC9B,MAAM;;AAGX,SAAgB,oBAAoB,QAAoC;AACtE,QAAO,oBACL,OACG,QACE,UACC,OAAO,UAAU,YAAY,OAAO,UAAU,SACjD,CACA,IAAI,OAAO,CACX,KAAK,IAAI,CACb;;AAGH,SAAgB,kBAAkB,YAAoB,OAAwB;CAC5E,MAAM,kBAAkB,oBAAoB,MAAM;AAElD,KAAI,CAAC,gBACH,QAAO;AAGT,QAAO,gBACJ,MAAM,MAAM,CACZ,OAAO,UAAU,WAAW,SAAS,MAAM,CAAC;;;;;ACLjD,SAAgB,iBAAiB,EAC/B,YACA,WAAW,IACX,YAAY,UACkC;CAC9C,MAAM,CAAC,MAAM,WAAW,cACtB,WACA,eAAe,YAAY,EAAE,CAC9B;CAED,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,aAAa,SAAS,CAAC;CAChE,MAAM,cAAc,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,EAAE,WAAW;CAC3D,MAAM,cAAc,cAAc,KAAK;CACvC,MAAM,WAAW,KAAK,IAAI,aAAa,UAAU,WAAW;CAC5D,MAAM,cAAc,cAAc;CAClC,MAAM,cAAc,cAAc;CAElC,MAAM,WAAW,aACd,YAAoB;EACnB,MAAM,YAAY,KAAK,IAAI,KAAK,IAAI,GAAG,QAAQ,EAAE,WAAW;AAC5D,EAAK,QAAQ,cAAc,IAAI,OAAO,UAAU;IAElD,CAAC,SAAS,WAAW,CACtB;CAED,MAAM,WAAW,kBAAkB;AACjC,MAAI,YACF,UAAS,cAAc,EAAE;IAE1B;EAAC;EAAa;EAAU;EAAY,CAAC;CAExC,MAAM,WAAW,kBAAkB;AACjC,MAAI,YACF,UAAS,cAAc,EAAE;IAE1B;EAAC;EAAa;EAAU;EAAY,CAAC;CAExC,MAAM,YAAY,kBAAkB;AAClC,WAAS,EAAE;IACV,CAAC,SAAS,CAAC;CAEd,MAAM,WAAW,kBAAkB;AACjC,WAAS,WAAW;IACnB,CAAC,UAAU,WAAW,CAAC;CAE1B,MAAM,WAAW,aACV,SAA4B,KAAK,MAAM,YAAY,SAAS,EACjE,CAAC,UAAU,WAAW,CACvB;AAED,QAAO,eACE;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAAc;EACf,GACD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF;;;;;ACjFH,SAAS,eAAe,aAAmD;AACzE,QAAO,OAAO,YACZ,YAAY,KAAK,eAAe,CAC9B,WAAW,SAAS,WAAW,KAC/B,cAAc,YAAY,WAAW,gBAAgB,MAAM,CAC5D,CAAC,CACH;;AAGH,SAAS,qBACP,OACA,YACe;AAGf,KAAI,WAFe,WAAW,cAAc,WAAW,gBAAgB,OAGrE,QAAO;AAGT,QAAO,MAAM,SAAS,IAAI,QAAQ;;AAGpC,SAAgB,oBAEd,aAAgE;CAEhE,MAAM,CAAC,QAAQ,aAAa,eADV,cAAc,eAAe,YAAY,EAAE,CAAC,YAAY,CAAC,CACtB;CAErD,MAAM,SAAS,cAEX,OAAO,YACL,YAAY,KAAK,eAAe;EAC9B,MAAM,QAAQ,WAAW,SAAS,WAAW;AAC7C,SAAO,CAAC,WAAW,KAAK,OAAO,UAAU,WAAW,gBAAgB,MAAM;GAC1E,CACH,EACH,CAAC,aAAa,OAAO,CACtB;AAkCD,QAAO;EACL;EACA,UAlCe,aACd,KAAkC,UAAkB;GACnD,MAAM,aAAa,YAAY,MAAM,SAAS,KAAK,QAAQ,IAAI;AAE/D,OAAI,CAAC,WACH;AAGF,GAAK,UAAU,GACZ,WAAW,SAAS,WAAW,MAAM,qBAAqB,OAAO,WAAW,EAC9E,CAAC;KAEJ,CAAC,aAAa,UAAU,CACzB;EAsBC,OApBY,kBAAkB;AAC9B,GAAK,UACH,OAAO,YACL,YAAY,KAAK,eAAe,CAAC,WAAW,SAAS,WAAW,KAAK,KAAK,CAAC,CAC5E,CACF;KACA,CAAC,aAAa,UAAU,CAAC;EAe1B,gBAbqB,aACpB,iBACE;GACC,GAAG;GACH,GAAG;GACJ,GACH,CAAC,OAAO,CACT;EAOA;;;;;AC3FH,SAAS,oBACP,SACwB;AACxB,QAAO,OAAO,YAAY,QAAQ,KAAK,WAAW,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC;;AAGzE,SAAS,mBACP,MACA,SACS;CACT,MAAM,SAAS;AAEf,QAAO,OAAO,QAAQ,QAAQ,CAAC,OAAO,CAAC,KAAK,iBAAiB;AAC3D,MAAI,CAAC,eAAe,gBAAgB,MAClC,QAAO;AAGT,SAAO,OAAO,SAAS;GACvB;;AAGJ,SAAS,eACP,MACA,QACA,SACA,cACS;AACT,QAAO,KAAK,QAAQ,SAAS;AAC3B,MAAI,CAAC,mBAAmB,MAAM,QAAQ,CACpC,QAAO;EAGT,MAAM,SAAS;AAIf,SAAO,kBAHY,oBACjB,aAAa,KAAK,UAAU,OAAO,OAAO,CAC3C,EACoC,OAAO;GAC5C;;AAGJ,SAAgB,kBAAwC,EACtD,MACA,SACA,eAAe,EAAE,EACjB,SAAS,oBAAoB,EAAE,EAC/B,WAAW,IACX,mBAAmB,QACsC;CAazD,MAAM,aAAa,oBAZU,cAEzB,CACE;EAAE,KAAK;EAAU,cAAc;EAAI,YAAY;EAAI,EACnD,GAAG,kBAAkB,KAAK,YAAY;EACpC,KAAK,OAAO;EACZ,cAAc;EACd,YAAY;EACb,EAAE,CACJ,EACH,CAAC,kBAAkB,CACpB,CAC2D;CAC5D,MAAM,SAAS,WAAW,OAAO,UAAU;CAC3C,MAAM,UAAU,eACP;EACL,GAAG,oBAAoB,kBAAkB;EACzC,GAAG,OAAO,YACR,kBAAkB,KAAK,WAAW,CAAC,OAAO,KAAK,WAAW,OAAO,OAAO,QAAQ,MAAM,CAAC,CACxF;EACF,GACD,CAAC,mBAAmB,WAAW,OAAO,CACvC;CAED,MAAM,eAAe,cACb,eAAe,MAAM,QAAQ,SAAS,aAAa,EACzD;EAAC;EAAM;EAAS;EAAQ;EAAa,CACtC;CACD,MAAM,aAAa,iBAAiB;EAClC,YAAY,aAAa;EACzB;EACD,CAAC;CACF,MAAM,iBAAiB,WAAW;CAClC,MAAM,EAAE,YAAY,WAAW,iBAAiB,gBAAgB;EAC9D,MAAM;EACN;EACA;EACD,CAAC;CAEF,MAAM,gBAAgB,cACd,WAAW,SAAS,WAAW,EACrC,CAAC,YAAY,WAAW,CACzB;CAED,MAAM,YAAY,aAAa,KAAa,UAAkB;AAC5D,aAAW,SAAS,KAAK,MAAM;AAC/B,EAAK,eAAe,EAAE;IACrB,CAAC,gBAAgB,WAAW,CAAC;CAEhC,MAAM,eAAe,aAAa,UAAkB;AAClD,aAAW,SAAS,UAAU,MAAM;AACpC,EAAK,eAAe,EAAE;IACrB,CAAC,gBAAgB,WAAW,CAAC;CAEhC,MAAM,WAAW,kBAAkB;AACjC,aAAW,OAAO;AAClB,EAAK,eAAe,EAAE;IACrB,CAAC,gBAAgB,WAAW,CAAC;CAEhC,MAAM,4BAA4B,aAC/B,gBACC,eACE,MACA,QACA;EACE,GAAG;EACH,GAAG;EACJ,EACD,aACD,CAAC,QACJ;EAAC;EAAM;EAAS;EAAQ;EAAa,CACtC;CAED,MAAM,YAAY,OAAO,MAAM,CAAC,SAAS;CACzC,MAAM,aAAa,OAAO,OAAO,QAAQ,CAAC,MACvC,UAAU,SAAS,UAAU,MAC/B;AAED,QAAO;EACL;EACA;EACA;EACA;EACA,WAAW;EACX;EACA;EACA;EACA;EACA;EACA;EACA,YAAY,aAAa,aAAa,eAAe;EACrD;EACA;EACA;EACD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carefully-built/crud",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Config-driven CRUD table and form helpers for Carefully Built SaaS apps.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -45,7 +45,7 @@
45
45
  "access": "public"
46
46
  },
47
47
  "peerDependencies": {
48
- "@carefully-built/ui": ">=0.1.4",
48
+ "@carefully-built/ui": ">=0.1.15",
49
49
  "nuqs": ">=2.0.0",
50
50
  "react": ">=18.2.0 || >=19.0.0",
51
51
  "react-dom": ">=18.2.0 || >=19.0.0"