@wordrhyme/auto-crud 1.5.0 → 1.5.2
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.cjs +68 -43
- package/dist/index.js +69 -44
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -380,9 +380,77 @@ function getDefaultFilterOperator(filterVariant) {
|
|
|
380
380
|
return getFilterOperators(filterVariant)[0]?.value ?? (filterVariant === "text" ? "iLike" : "eq");
|
|
381
381
|
}
|
|
382
382
|
|
|
383
|
+
//#endregion
|
|
384
|
+
//#region src/lib/format.ts
|
|
385
|
+
let hostDateFormatters = [];
|
|
386
|
+
let dateFormatterVersion = 0;
|
|
387
|
+
const dateFormatterListeners = /* @__PURE__ */ new Set();
|
|
388
|
+
function notifyDateFormatterChange() {
|
|
389
|
+
dateFormatterVersion += 1;
|
|
390
|
+
dateFormatterListeners.forEach((listener) => listener());
|
|
391
|
+
}
|
|
392
|
+
function subscribeDateFormatter(listener) {
|
|
393
|
+
dateFormatterListeners.add(listener);
|
|
394
|
+
return () => {
|
|
395
|
+
dateFormatterListeners.delete(listener);
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
function getDateFormatterVersion() {
|
|
399
|
+
return dateFormatterVersion;
|
|
400
|
+
}
|
|
401
|
+
function useDateFormatterVersion() {
|
|
402
|
+
return (0, react.useSyncExternalStore)(subscribeDateFormatter, getDateFormatterVersion, getDateFormatterVersion);
|
|
403
|
+
}
|
|
404
|
+
function getHostDateFormatter() {
|
|
405
|
+
return hostDateFormatters[hostDateFormatters.length - 1]?.formatter;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Register the host's process-wide date presentation policy without coupling
|
|
409
|
+
* AutoCrud to locale or timezone selection. The returned cleanup removes only
|
|
410
|
+
* this registration, so overlapping registrations may be disposed out of order.
|
|
411
|
+
* Passing undefined clears every registration.
|
|
412
|
+
*/
|
|
413
|
+
function setDateFormatter(formatter) {
|
|
414
|
+
if (formatter === void 0) {
|
|
415
|
+
const hadFormatter = hostDateFormatters.length > 0;
|
|
416
|
+
hostDateFormatters = [];
|
|
417
|
+
if (hadFormatter) notifyDateFormatterChange();
|
|
418
|
+
return () => void 0;
|
|
419
|
+
}
|
|
420
|
+
const registration = {
|
|
421
|
+
formatter,
|
|
422
|
+
token: Symbol("date-formatter")
|
|
423
|
+
};
|
|
424
|
+
hostDateFormatters.push(registration);
|
|
425
|
+
notifyDateFormatterChange();
|
|
426
|
+
return () => {
|
|
427
|
+
const currentFormatter = getHostDateFormatter();
|
|
428
|
+
const previousLength = hostDateFormatters.length;
|
|
429
|
+
hostDateFormatters = hostDateFormatters.filter(({ token }) => token !== registration.token);
|
|
430
|
+
if (hostDateFormatters.length !== previousLength && getHostDateFormatter() !== currentFormatter) notifyDateFormatterChange();
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
function formatDate(date, opts = {}) {
|
|
434
|
+
if (date === void 0) return "";
|
|
435
|
+
try {
|
|
436
|
+
const value = new Date(date);
|
|
437
|
+
const options = {
|
|
438
|
+
month: opts.month ?? "long",
|
|
439
|
+
day: opts.day ?? "numeric",
|
|
440
|
+
year: opts.year ?? "numeric",
|
|
441
|
+
...opts
|
|
442
|
+
};
|
|
443
|
+
const hostDateFormatter = getHostDateFormatter();
|
|
444
|
+
return hostDateFormatter ? hostDateFormatter(value, options) : new Intl.DateTimeFormat("en-US", options).format(value);
|
|
445
|
+
} catch {
|
|
446
|
+
return "";
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
383
450
|
//#endregion
|
|
384
451
|
//#region src/components/data-table/data-table.tsx
|
|
385
452
|
function DataTable({ table, actionBar, children, className,...props }) {
|
|
453
|
+
useDateFormatterVersion();
|
|
386
454
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
387
455
|
className: cn("flex w-full flex-col gap-2.5 overflow-auto", className),
|
|
388
456
|
...props,
|
|
@@ -921,49 +989,6 @@ function useDebouncedCallback(callback, delay) {
|
|
|
921
989
|
}, [handleCallback, delay]);
|
|
922
990
|
}
|
|
923
991
|
|
|
924
|
-
//#endregion
|
|
925
|
-
//#region src/lib/format.ts
|
|
926
|
-
let hostDateFormatters = [];
|
|
927
|
-
function getHostDateFormatter() {
|
|
928
|
-
return hostDateFormatters[hostDateFormatters.length - 1]?.formatter;
|
|
929
|
-
}
|
|
930
|
-
/**
|
|
931
|
-
* Register the host's process-wide date presentation policy without coupling
|
|
932
|
-
* AutoCrud to locale or timezone selection. The returned cleanup removes only
|
|
933
|
-
* this registration, so overlapping registrations may be disposed out of order.
|
|
934
|
-
* Passing undefined clears every registration.
|
|
935
|
-
*/
|
|
936
|
-
function setDateFormatter(formatter) {
|
|
937
|
-
if (formatter === void 0) {
|
|
938
|
-
hostDateFormatters = [];
|
|
939
|
-
return () => void 0;
|
|
940
|
-
}
|
|
941
|
-
const registration = {
|
|
942
|
-
formatter,
|
|
943
|
-
token: Symbol("date-formatter")
|
|
944
|
-
};
|
|
945
|
-
hostDateFormatters.push(registration);
|
|
946
|
-
return () => {
|
|
947
|
-
hostDateFormatters = hostDateFormatters.filter(({ token }) => token !== registration.token);
|
|
948
|
-
};
|
|
949
|
-
}
|
|
950
|
-
function formatDate(date, opts = {}) {
|
|
951
|
-
if (date === void 0) return "";
|
|
952
|
-
try {
|
|
953
|
-
const value = new Date(date);
|
|
954
|
-
const options = {
|
|
955
|
-
month: opts.month ?? "long",
|
|
956
|
-
day: opts.day ?? "numeric",
|
|
957
|
-
year: opts.year ?? "numeric",
|
|
958
|
-
...opts
|
|
959
|
-
};
|
|
960
|
-
const hostDateFormatter = getHostDateFormatter();
|
|
961
|
-
return hostDateFormatter ? hostDateFormatter(value, options) : new Intl.DateTimeFormat("en-US", options).format(value);
|
|
962
|
-
} catch {
|
|
963
|
-
return "";
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
|
|
967
992
|
//#endregion
|
|
968
993
|
//#region src/components/data-table/data-table-filter-list.tsx
|
|
969
994
|
const DEBOUNCE_MS$2 = 300;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef, useState } from "react";
|
|
2
|
+
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
|
|
3
3
|
import { ArrowDownUp, BadgeCheck, CalendarIcon, Check, CheckCircle2, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, ChevronsLeft, ChevronsRight, ChevronsUpDown, CommandIcon, Download, Ellipsis, EyeOff, FileDown, FileSpreadsheetIcon, GripVertical, ListFilter, ListFilterIcon, Loader2, PlusCircle, RefreshCw, Settings2, Text, Trash2, Upload, X, XCircle } from "lucide-react";
|
|
4
4
|
import { flexRender, getCoreRowModel, getFacetedMinMaxValues, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table";
|
|
5
5
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Badge, Button, Calendar, Checkbox, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, Input, Label, Popover, PopoverContent, PopoverTrigger, Select as Select$1, SelectContent, SelectItem, SelectTrigger, SelectValue, Separator, Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, Slider, Switch, Table as Table$1, TableBody, TableCell, TableHead, TableHeader, TableRow, cn as cn$1 } from "@wordrhyme/shadcn";
|
|
@@ -343,9 +343,77 @@ function getDefaultFilterOperator(filterVariant) {
|
|
|
343
343
|
return getFilterOperators(filterVariant)[0]?.value ?? (filterVariant === "text" ? "iLike" : "eq");
|
|
344
344
|
}
|
|
345
345
|
|
|
346
|
+
//#endregion
|
|
347
|
+
//#region src/lib/format.ts
|
|
348
|
+
let hostDateFormatters = [];
|
|
349
|
+
let dateFormatterVersion = 0;
|
|
350
|
+
const dateFormatterListeners = /* @__PURE__ */ new Set();
|
|
351
|
+
function notifyDateFormatterChange() {
|
|
352
|
+
dateFormatterVersion += 1;
|
|
353
|
+
dateFormatterListeners.forEach((listener) => listener());
|
|
354
|
+
}
|
|
355
|
+
function subscribeDateFormatter(listener) {
|
|
356
|
+
dateFormatterListeners.add(listener);
|
|
357
|
+
return () => {
|
|
358
|
+
dateFormatterListeners.delete(listener);
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
function getDateFormatterVersion() {
|
|
362
|
+
return dateFormatterVersion;
|
|
363
|
+
}
|
|
364
|
+
function useDateFormatterVersion() {
|
|
365
|
+
return useSyncExternalStore(subscribeDateFormatter, getDateFormatterVersion, getDateFormatterVersion);
|
|
366
|
+
}
|
|
367
|
+
function getHostDateFormatter() {
|
|
368
|
+
return hostDateFormatters[hostDateFormatters.length - 1]?.formatter;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Register the host's process-wide date presentation policy without coupling
|
|
372
|
+
* AutoCrud to locale or timezone selection. The returned cleanup removes only
|
|
373
|
+
* this registration, so overlapping registrations may be disposed out of order.
|
|
374
|
+
* Passing undefined clears every registration.
|
|
375
|
+
*/
|
|
376
|
+
function setDateFormatter(formatter) {
|
|
377
|
+
if (formatter === void 0) {
|
|
378
|
+
const hadFormatter = hostDateFormatters.length > 0;
|
|
379
|
+
hostDateFormatters = [];
|
|
380
|
+
if (hadFormatter) notifyDateFormatterChange();
|
|
381
|
+
return () => void 0;
|
|
382
|
+
}
|
|
383
|
+
const registration = {
|
|
384
|
+
formatter,
|
|
385
|
+
token: Symbol("date-formatter")
|
|
386
|
+
};
|
|
387
|
+
hostDateFormatters.push(registration);
|
|
388
|
+
notifyDateFormatterChange();
|
|
389
|
+
return () => {
|
|
390
|
+
const currentFormatter = getHostDateFormatter();
|
|
391
|
+
const previousLength = hostDateFormatters.length;
|
|
392
|
+
hostDateFormatters = hostDateFormatters.filter(({ token }) => token !== registration.token);
|
|
393
|
+
if (hostDateFormatters.length !== previousLength && getHostDateFormatter() !== currentFormatter) notifyDateFormatterChange();
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
function formatDate(date, opts = {}) {
|
|
397
|
+
if (date === void 0) return "";
|
|
398
|
+
try {
|
|
399
|
+
const value = new Date(date);
|
|
400
|
+
const options = {
|
|
401
|
+
month: opts.month ?? "long",
|
|
402
|
+
day: opts.day ?? "numeric",
|
|
403
|
+
year: opts.year ?? "numeric",
|
|
404
|
+
...opts
|
|
405
|
+
};
|
|
406
|
+
const hostDateFormatter = getHostDateFormatter();
|
|
407
|
+
return hostDateFormatter ? hostDateFormatter(value, options) : new Intl.DateTimeFormat("en-US", options).format(value);
|
|
408
|
+
} catch {
|
|
409
|
+
return "";
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
346
413
|
//#endregion
|
|
347
414
|
//#region src/components/data-table/data-table.tsx
|
|
348
415
|
function DataTable({ table, actionBar, children, className,...props }) {
|
|
416
|
+
useDateFormatterVersion();
|
|
349
417
|
return /* @__PURE__ */ jsxs("div", {
|
|
350
418
|
className: cn("flex w-full flex-col gap-2.5 overflow-auto", className),
|
|
351
419
|
...props,
|
|
@@ -884,49 +952,6 @@ function useDebouncedCallback(callback, delay) {
|
|
|
884
952
|
}, [handleCallback, delay]);
|
|
885
953
|
}
|
|
886
954
|
|
|
887
|
-
//#endregion
|
|
888
|
-
//#region src/lib/format.ts
|
|
889
|
-
let hostDateFormatters = [];
|
|
890
|
-
function getHostDateFormatter() {
|
|
891
|
-
return hostDateFormatters[hostDateFormatters.length - 1]?.formatter;
|
|
892
|
-
}
|
|
893
|
-
/**
|
|
894
|
-
* Register the host's process-wide date presentation policy without coupling
|
|
895
|
-
* AutoCrud to locale or timezone selection. The returned cleanup removes only
|
|
896
|
-
* this registration, so overlapping registrations may be disposed out of order.
|
|
897
|
-
* Passing undefined clears every registration.
|
|
898
|
-
*/
|
|
899
|
-
function setDateFormatter(formatter) {
|
|
900
|
-
if (formatter === void 0) {
|
|
901
|
-
hostDateFormatters = [];
|
|
902
|
-
return () => void 0;
|
|
903
|
-
}
|
|
904
|
-
const registration = {
|
|
905
|
-
formatter,
|
|
906
|
-
token: Symbol("date-formatter")
|
|
907
|
-
};
|
|
908
|
-
hostDateFormatters.push(registration);
|
|
909
|
-
return () => {
|
|
910
|
-
hostDateFormatters = hostDateFormatters.filter(({ token }) => token !== registration.token);
|
|
911
|
-
};
|
|
912
|
-
}
|
|
913
|
-
function formatDate(date, opts = {}) {
|
|
914
|
-
if (date === void 0) return "";
|
|
915
|
-
try {
|
|
916
|
-
const value = new Date(date);
|
|
917
|
-
const options = {
|
|
918
|
-
month: opts.month ?? "long",
|
|
919
|
-
day: opts.day ?? "numeric",
|
|
920
|
-
year: opts.year ?? "numeric",
|
|
921
|
-
...opts
|
|
922
|
-
};
|
|
923
|
-
const hostDateFormatter = getHostDateFormatter();
|
|
924
|
-
return hostDateFormatter ? hostDateFormatter(value, options) : new Intl.DateTimeFormat("en-US", options).format(value);
|
|
925
|
-
} catch {
|
|
926
|
-
return "";
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
|
|
930
955
|
//#endregion
|
|
931
956
|
//#region src/components/data-table/data-table-filter-list.tsx
|
|
932
957
|
const DEBOUNCE_MS$2 = 300;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordrhyme/auto-crud",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.2",
|
|
5
5
|
"description": "Schema-first CRUD components with auto-generated tables and forms",
|
|
6
6
|
"author": "wordrhyme",
|
|
7
7
|
"license": "MIT",
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"nanoid": "^5.1.6",
|
|
63
63
|
"tailwind-merge": "^3.5.0",
|
|
64
64
|
"vaul": "^1.1.2",
|
|
65
|
-
"@wordrhyme/shadcn
|
|
66
|
-
"@wordrhyme/
|
|
67
|
-
"@wordrhyme/shadcn": "1.3
|
|
65
|
+
"@wordrhyme/shadcn": "1.3.3",
|
|
66
|
+
"@wordrhyme/shadcn-ui": "1.32.8",
|
|
67
|
+
"@wordrhyme/formily-shadcn": "1.13.3"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@storybook/react": "^8.6.18",
|
|
@@ -85,8 +85,8 @@
|
|
|
85
85
|
"typescript": "^5.9.3",
|
|
86
86
|
"vitest": "^3.2.4",
|
|
87
87
|
"@internal/prettier-config": "0.0.1",
|
|
88
|
-
"@internal/eslint-config": "0.3.0",
|
|
89
88
|
"@internal/tsconfig": "0.1.0",
|
|
89
|
+
"@internal/eslint-config": "0.3.0",
|
|
90
90
|
"@internal/tsdown-config": "0.1.0",
|
|
91
91
|
"@internal/vitest-config": "0.1.0"
|
|
92
92
|
},
|