@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 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.0",
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-ui": "1.32.7",
66
- "@wordrhyme/formily-shadcn": "1.13.2",
67
- "@wordrhyme/shadcn": "1.3.2"
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
  },