@mshuja288/aksuicore 0.4.2 → 0.4.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/CHANGELOG.md CHANGED
@@ -7,6 +7,19 @@ Versioning follows [VERSIONING.md](./VERSIONING.md).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.4] — 2026-10-29
11
+
12
+ ### Fixed
13
+
14
+ - `Dialog` no longer closes immediately when opened from a View/Update click (backdrop ignored the opening gesture; close on backdrop `mousedown` only when the target is the backdrop)
15
+
16
+ ## [0.4.3] — 2026-10-13
17
+
18
+ ### Added
19
+
20
+ - `RecordWorkspace` persists preview on/off and side-rail expand/collapse globally (`aksui.workspace.chrome`) across all tables
21
+ - Filter values persist per screen at `${columnPrefsKey}.filters` when `columnPrefsKey` is set
22
+
10
23
  ## [0.4.1] — 2026-10-12
11
24
 
12
25
  ### Fixed
package/dist/index.cjs CHANGED
@@ -414,17 +414,35 @@ function Dialog({
414
414
  children,
415
415
  wide = true
416
416
  }) {
417
+ const allowBackdropClose = react.useRef(false);
418
+ react.useEffect(() => {
419
+ if (!open) {
420
+ allowBackdropClose.current = false;
421
+ return;
422
+ }
423
+ allowBackdropClose.current = false;
424
+ const timer = window.setTimeout(() => {
425
+ allowBackdropClose.current = true;
426
+ }, 0);
427
+ return () => window.clearTimeout(timer);
428
+ }, [open]);
417
429
  if (!open) {
418
430
  return null;
419
431
  }
420
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dialog-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(
432
+ function onBackdropMouseDown(event) {
433
+ if (event.target !== event.currentTarget || !allowBackdropClose.current) {
434
+ return;
435
+ }
436
+ onClose();
437
+ }
438
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dialog-backdrop", onMouseDown: onBackdropMouseDown, children: /* @__PURE__ */ jsxRuntime.jsxs(
421
439
  "div",
422
440
  {
423
441
  className: wide ? "dialog form-dialog" : "dialog",
424
442
  role: "dialog",
425
443
  "aria-modal": "true",
426
444
  "aria-label": title,
427
- onClick: (event) => event.stopPropagation(),
445
+ onMouseDown: (event) => event.stopPropagation(),
428
446
  children: [
429
447
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dialog-head", children: [
430
448
  /* @__PURE__ */ jsxRuntime.jsx("h2", { children: title }),
@@ -877,6 +895,37 @@ var BULK_IMPORT_MODE_OPTIONS = [
877
895
  function defaultVisibleKeys(columns) {
878
896
  return columns.filter((column) => column.defaultVisible !== false).map((column) => column.key);
879
897
  }
898
+ var WORKSPACE_CHROME_KEY = "aksui.workspace.chrome";
899
+ function readWorkspaceChrome() {
900
+ if (typeof window === "undefined") {
901
+ return { previewEnabled: false, sideOpen: false };
902
+ }
903
+ try {
904
+ const raw = window.localStorage.getItem(WORKSPACE_CHROME_KEY);
905
+ if (!raw) {
906
+ return { previewEnabled: false, sideOpen: false };
907
+ }
908
+ const parsed = JSON.parse(raw);
909
+ return {
910
+ previewEnabled: Boolean(parsed.previewEnabled),
911
+ sideOpen: Boolean(parsed.sideOpen)
912
+ };
913
+ } catch {
914
+ return { previewEnabled: false, sideOpen: false };
915
+ }
916
+ }
917
+ function writeWorkspaceChrome(chrome) {
918
+ if (typeof window === "undefined") {
919
+ return;
920
+ }
921
+ try {
922
+ window.localStorage.setItem(WORKSPACE_CHROME_KEY, JSON.stringify(chrome));
923
+ } catch {
924
+ }
925
+ }
926
+ function filtersPrefsKey(columnPrefsKey) {
927
+ return columnPrefsKey ? `${columnPrefsKey}.filters` : void 0;
928
+ }
880
929
  function readStoredColumnKeys(prefsKey, fallback, allowed) {
881
930
  if (!prefsKey || typeof window === "undefined") {
882
931
  return fallback;
@@ -905,6 +954,45 @@ function writeStoredColumnKeys(prefsKey, keys) {
905
954
  } catch {
906
955
  }
907
956
  }
957
+ function readStoredFilters(prefsKey, allowed) {
958
+ if (!prefsKey || typeof window === "undefined") {
959
+ return {};
960
+ }
961
+ try {
962
+ const raw = window.localStorage.getItem(prefsKey);
963
+ if (!raw) {
964
+ return {};
965
+ }
966
+ const parsed = JSON.parse(raw);
967
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
968
+ return {};
969
+ }
970
+ const next = {};
971
+ for (const [key, value] of Object.entries(parsed)) {
972
+ if (allowed.has(key) && typeof value === "string" && value.trim()) {
973
+ next[key] = value;
974
+ }
975
+ }
976
+ return next;
977
+ } catch {
978
+ return {};
979
+ }
980
+ }
981
+ function writeStoredFilters(prefsKey, filters) {
982
+ if (!prefsKey || typeof window === "undefined") {
983
+ return;
984
+ }
985
+ try {
986
+ const trimmed = {};
987
+ for (const [key, value] of Object.entries(filters)) {
988
+ if (value.trim()) {
989
+ trimmed[key] = value;
990
+ }
991
+ }
992
+ window.localStorage.setItem(prefsKey, JSON.stringify(trimmed));
993
+ } catch {
994
+ }
995
+ }
908
996
  function compareColumnValues(column, left, right) {
909
997
  const leftRaw = column.display ? column.display(left) : column.value(left);
910
998
  const rightRaw = column.display ? column.display(right) : column.value(right);
@@ -1028,9 +1116,12 @@ function RecordWorkspace({
1028
1116
  const [internalVisibleKeys, setInternalVisibleKeys] = react.useState(
1029
1117
  () => readStoredColumnKeys(columnPrefsKey, fallbackKeys, allowedKeys)
1030
1118
  );
1031
- const [filters, setFilters] = react.useState({});
1119
+ const filterStorageKey = filtersPrefsKey(columnPrefsKey);
1120
+ const [filters, setFilters] = react.useState(
1121
+ () => readStoredFilters(filterStorageKey, allowedKeys)
1122
+ );
1032
1123
  const [sort, setSort] = react.useState(null);
1033
- const [sideOpen, setSideOpen] = react.useState(false);
1124
+ const [sideOpen, setSideOpen] = react.useState(() => readWorkspaceChrome().sideOpen);
1034
1125
  const [toolsDrawerOpen, setToolsDrawerOpen] = react.useState(false);
1035
1126
  const [downloadOpen, setDownloadOpen] = react.useState(false);
1036
1127
  const [bulkOpen, setBulkOpen] = react.useState(false);
@@ -1039,7 +1130,7 @@ function RecordWorkspace({
1039
1130
  const [bulkReport, setBulkReport] = react.useState(null);
1040
1131
  const bulkFileInputRef = react.useRef(null);
1041
1132
  const [columnsOpen, setColumnsOpen] = react.useState(false);
1042
- const [previewEnabled, setPreviewEnabled] = react.useState(false);
1133
+ const [previewEnabled, setPreviewEnabled] = react.useState(() => readWorkspaceChrome().previewEnabled);
1043
1134
  const [previewKey, setPreviewKey] = react.useState(null);
1044
1135
  const [tooltip, setTooltip] = react.useState(null);
1045
1136
  const [pageSize, setPageSize] = react.useState("15");
@@ -1054,6 +1145,9 @@ function RecordWorkspace({
1054
1145
  }
1055
1146
  setInternalVisibleKeys(readStoredColumnKeys(columnPrefsKey, fallbackKeys, allowedKeys));
1056
1147
  }, [allowedKeys, columnPrefsKey, fallbackKeys, isControlled]);
1148
+ react.useEffect(() => {
1149
+ setFilters(readStoredFilters(filtersPrefsKey(columnPrefsKey), allowedKeys));
1150
+ }, [allowedKeys, columnPrefsKey]);
1057
1151
  const resolvedVisibleKeys = react.useMemo(() => {
1058
1152
  const source = isControlled ? visibleColumnKeys : internalVisibleKeys;
1059
1153
  const filtered2 = source.filter((key) => allowedKeys.has(key));
@@ -1214,13 +1308,22 @@ function RecordWorkspace({
1214
1308
  }
1215
1309
  const previewTitle = previewItem && visibleColumns[0] ? cellText(visibleColumns[0], previewItem) : null;
1216
1310
  function changeFilter(key, value) {
1217
- setFilters((current) => ({ ...current, [key]: value }));
1311
+ setFilters((current) => {
1312
+ const next = { ...current, [key]: value };
1313
+ writeStoredFilters(filterStorageKey, next);
1314
+ return next;
1315
+ });
1218
1316
  setPage(1);
1219
1317
  }
1220
1318
  function clearFilters() {
1221
1319
  setFilters({});
1320
+ writeStoredFilters(filterStorageKey, {});
1222
1321
  setPage(1);
1223
1322
  }
1323
+ function setSideOpenValue(open) {
1324
+ setSideOpen(open);
1325
+ writeWorkspaceChrome({ previewEnabled, sideOpen: open });
1326
+ }
1224
1327
  function toggleSort(column) {
1225
1328
  if (column.sortable === false) {
1226
1329
  return;
@@ -1238,6 +1341,7 @@ function RecordWorkspace({
1238
1341
  }
1239
1342
  function setPreviewEnabledValue(enabled) {
1240
1343
  setPreviewEnabled(enabled);
1344
+ writeWorkspaceChrome({ previewEnabled: enabled, sideOpen });
1241
1345
  setTooltip(null);
1242
1346
  if (!enabled) {
1243
1347
  setPreviewKey(null);
@@ -1298,7 +1402,7 @@ function RecordWorkspace({
1298
1402
  title: "Columns",
1299
1403
  "aria-label": "Columns",
1300
1404
  onClick: () => {
1301
- setSideOpen(true);
1405
+ setSideOpenValue(true);
1302
1406
  setColumnsOpen(true);
1303
1407
  },
1304
1408
  children: [
@@ -1316,7 +1420,7 @@ function RecordWorkspace({
1316
1420
  "aria-label": "Download",
1317
1421
  disabled: downloadBusy,
1318
1422
  onClick: () => {
1319
- setSideOpen(true);
1423
+ setSideOpenValue(true);
1320
1424
  setDownloadOpen(true);
1321
1425
  },
1322
1426
  children: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, {})
@@ -1331,7 +1435,7 @@ function RecordWorkspace({
1331
1435
  "aria-label": "Bulk entry",
1332
1436
  disabled: importBusy,
1333
1437
  onClick: () => {
1334
- setSideOpen(true);
1438
+ setSideOpenValue(true);
1335
1439
  setBulkOpen(true);
1336
1440
  },
1337
1441
  children: /* @__PURE__ */ jsxRuntime.jsx(UploadIcon, {})
@@ -1344,7 +1448,7 @@ function RecordWorkspace({
1344
1448
  className: "ghost side-rail-icon",
1345
1449
  title: "Show filters",
1346
1450
  "aria-label": "Show filters",
1347
- onClick: () => setSideOpen(true),
1451
+ onClick: () => setSideOpenValue(true),
1348
1452
  children: [
1349
1453
  /* @__PURE__ */ jsxRuntime.jsx(FilterIcon, {}),
1350
1454
  activeFilterCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "filter-badge", children: activeFilterCount }) : null
@@ -1733,7 +1837,7 @@ function RecordWorkspace({
1733
1837
  className: "ghost side-rail-toggle",
1734
1838
  "aria-expanded": sideOpen,
1735
1839
  title: sideOpen ? "Collapse" : "Expand",
1736
- onClick: () => setSideOpen((open) => !open),
1840
+ onClick: () => setSideOpenValue(!sideOpen),
1737
1841
  children: [
1738
1842
  /* @__PURE__ */ jsxRuntime.jsx(ChevronIcon, { open: sideOpen }),
1739
1843
  sideOpen ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Collapse" }) : null