@open-mercato/ui 0.7.1-develop.7193.1.910a5b0a1e → 0.7.1-develop.7195.1.b5efd1d51a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/backend/AppShell.js +66 -7
  3. package/dist/backend/AppShell.js.map +2 -2
  4. package/dist/backend/CrudForm.js +14 -8
  5. package/dist/backend/CrudForm.js.map +2 -2
  6. package/dist/backend/DataTable.js +108 -11
  7. package/dist/backend/DataTable.js.map +2 -2
  8. package/dist/backend/forms/ActionsDropdown.js +35 -5
  9. package/dist/backend/forms/ActionsDropdown.js.map +2 -2
  10. package/dist/backend/forms/index.js.map +2 -2
  11. package/dist/backend/icons/lucideRegistry.generated.js +6 -0
  12. package/dist/backend/icons/lucideRegistry.generated.js.map +2 -2
  13. package/dist/backend/injection/spotIds.js +2 -0
  14. package/dist/backend/injection/spotIds.js.map +2 -2
  15. package/dist/backend/inputs/DurationInput.js +182 -0
  16. package/dist/backend/inputs/DurationInput.js.map +7 -0
  17. package/dist/backend/inputs/EventSelect.js.map +2 -2
  18. package/dist/backend/inputs/index.js +1 -0
  19. package/dist/backend/inputs/index.js.map +2 -2
  20. package/dist/backend/nav/navBadges.js +38 -0
  21. package/dist/backend/nav/navBadges.js.map +7 -0
  22. package/dist/primitives/segmented-control.js +4 -4
  23. package/dist/primitives/segmented-control.js.map +1 -1
  24. package/dist/primitives/sheet.js +21 -11
  25. package/dist/primitives/sheet.js.map +2 -2
  26. package/dist/primitives/textarea.js +54 -4
  27. package/dist/primitives/textarea.js.map +2 -2
  28. package/package.json +3 -3
  29. package/src/backend/AppShell.tsx +106 -2
  30. package/src/backend/CrudForm.tsx +28 -9
  31. package/src/backend/DataTable.tsx +176 -22
  32. package/src/backend/__tests__/CrudForm.density.test.tsx +113 -0
  33. package/src/backend/__tests__/DataTable.propBulkActions.test.tsx +200 -0
  34. package/src/backend/__tests__/DataTable.render.test.tsx +76 -0
  35. package/src/backend/__tests__/navBadges.test.ts +57 -0
  36. package/src/backend/forms/ActionsDropdown.tsx +73 -6
  37. package/src/backend/forms/index.ts +1 -1
  38. package/src/backend/icons/lucideRegistry.generated.tsx +6 -0
  39. package/src/backend/injection/spotIds.ts +8 -0
  40. package/src/backend/inputs/DurationInput.tsx +207 -0
  41. package/src/backend/inputs/EventSelect.tsx +2 -0
  42. package/src/backend/inputs/__tests__/DurationInput.test.tsx +220 -0
  43. package/src/backend/inputs/index.ts +1 -0
  44. package/src/backend/nav/navBadges.ts +61 -0
  45. package/src/primitives/__tests__/segmented-control.test.tsx +2 -2
  46. package/src/primitives/__tests__/textarea.test.tsx +50 -0
  47. package/src/primitives/segmented-control.tsx +7 -7
  48. package/src/primitives/sheet.tsx +7 -1
  49. package/src/primitives/textarea.tsx +77 -4
@@ -1,3 +1,3 @@
1
- Generated lucide registry with 165 icons -> /home/runner/work/open-mercato/open-mercato/packages/ui/src/backend/icons/lucideRegistry.generated.tsx
2
- [build:ui] found 403 entry points
1
+ Generated lucide registry with 168 icons -> /home/runner/work/open-mercato/open-mercato/packages/ui/src/backend/icons/lucideRegistry.generated.tsx
2
+ [build:ui] found 405 entry points
3
3
  [build:ui] built successfully
@@ -33,6 +33,7 @@ import { slugifySidebarId } from "@open-mercato/shared/modules/navigation/sideba
33
33
  import { readVersionedPreference, writeVersionedPreference } from "@open-mercato/shared/lib/browser/versionedPreference";
34
34
  import { cloneSidebarGroups } from "./sidebar/customization-helpers.js";
35
35
  import { InjectionSpot } from "./injection/InjectionSpot.js";
36
+ import { useNavBadge } from "./nav/navBadges.js";
36
37
  import {
37
38
  BackendRecordInjectionContextProvider
38
39
  } from "./injection/recordContext.js";
@@ -57,7 +58,8 @@ import {
57
58
  BACKEND_SIDEBAR_NAV_INJECTION_SPOT_ID,
58
59
  BACKEND_TOPBAR_ACTIONS_INJECTION_SPOT_ID,
59
60
  GLOBAL_HEADER_STATUS_INDICATORS_INJECTION_SPOT_ID,
60
- GLOBAL_SIDEBAR_STATUS_BADGES_INJECTION_SPOT_ID
61
+ GLOBAL_SIDEBAR_STATUS_BADGES_INJECTION_SPOT_ID,
62
+ BACKEND_NAV_BADGES_INJECTION_SPOT_ID
61
63
  } from "./injection/spotIds.js";
62
64
  const SIDEBAR_OPEN_GROUPS_KEY = "om:sidebarOpenGroups";
63
65
  const SIDEBAR_OPEN_GROUPS_VERSION = 1;
@@ -270,6 +272,20 @@ function resolveItemKey(item) {
270
272
  function sidebarBlockPadding(compact) {
271
273
  return `${compact ? "px-2" : "px-3"} transition-[padding] duration-200 ease-out`;
272
274
  }
275
+ function NavItemBadge({ href, compact }) {
276
+ const badge = useNavBadge(href);
277
+ if (!badge || badge.count <= 0) return null;
278
+ const display = badge.count > 99 ? "99+" : String(badge.count);
279
+ const tone = badge.tone === "attention" ? "bg-status-warning-bg text-status-warning-text" : "bg-muted text-muted-foreground";
280
+ return /* @__PURE__ */ jsx(
281
+ "span",
282
+ {
283
+ className: `ml-auto inline-flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-xs font-medium ${tone} ${compact ? "absolute right-0 top-0 -mr-1 -mt-1" : ""}`,
284
+ "aria-label": badge.label ?? display,
285
+ children: display
286
+ }
287
+ );
288
+ }
273
289
  function sidebarInjectionWrapper(compact) {
274
290
  return `${sidebarBlockPadding(compact)} empty:hidden`;
275
291
  }
@@ -286,6 +302,19 @@ function renderIcon(icon, iconName, iconMarkup, fallback) {
286
302
  return fallback;
287
303
  }
288
304
  const HeaderContext = createContext(null);
305
+ const noopSidebarCollapse = {
306
+ collapsed: false,
307
+ setCollapsed: () => {
308
+ },
309
+ requestCollapse: () => {
310
+ },
311
+ releaseRequest: () => {
312
+ }
313
+ };
314
+ const SidebarCollapseContext = createContext(null);
315
+ function useSidebarCollapse() {
316
+ return useContext(SidebarCollapseContext) ?? noopSidebarCollapse;
317
+ }
289
318
  function ApplyBreadcrumb({ breadcrumb, title, titleKey }) {
290
319
  const ctx = useContext(HeaderContext);
291
320
  const t = useT();
@@ -365,6 +394,8 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
365
394
  if (!mobileOpen) setMobileDrawerView("auto");
366
395
  }, [mobileOpen]);
367
396
  const [collapsed, setCollapsed] = React.useState(sidebarCollapsedDefault);
397
+ const [externalCollapseRequest, setExternalCollapseRequest] = React.useState(null);
398
+ const collapsedBeforeExternalRequestRef = React.useRef(null);
368
399
  const [navGroups, setNavGroups] = React.useState(resolvedGroups);
369
400
  const [openGroups, setOpenGroups] = React.useState(
370
401
  () => Object.fromEntries(resolvedGroups.map((g) => [resolveGroupKey(g), true]))
@@ -379,8 +410,24 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
379
410
  if (!label) return false;
380
411
  return label.toLowerCase().includes(navQueryNorm);
381
412
  }, [navQueryActive, navQueryNorm]);
382
- const effectiveCollapsed = collapsed;
413
+ const effectiveCollapsed = externalCollapseRequest === true ? true : collapsed;
383
414
  const expandedSidebarWidth = "240px";
415
+ const requestCollapse = React.useCallback((next) => {
416
+ setExternalCollapseRequest((prev) => {
417
+ if (prev === null) collapsedBeforeExternalRequestRef.current = collapsed;
418
+ return next;
419
+ });
420
+ }, [collapsed]);
421
+ const releaseRequest = React.useCallback(() => {
422
+ collapsedBeforeExternalRequestRef.current = null;
423
+ setExternalCollapseRequest(null);
424
+ }, []);
425
+ const sidebarCollapseValue = React.useMemo(() => ({
426
+ collapsed: effectiveCollapsed,
427
+ setCollapsed: (next) => setCollapsed(next),
428
+ requestCollapse,
429
+ releaseRequest
430
+ }), [effectiveCollapsed, requestCollapse, releaseRequest]);
384
431
  const sidebarAsideRef = React.useRef(null);
385
432
  const [sidebarScrollState, setSidebarScrollState] = React.useState("down");
386
433
  const sidebarScrollIntentRef = React.useRef(null);
@@ -627,7 +674,8 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
627
674
  item.iconMarkup,
628
675
  item.href.includes("/backend/entities/user/") && item.href.endsWith("/records") ? DataTableIcon : DefaultIcon
629
676
  ) }),
630
- !compact && /* @__PURE__ */ jsx("span", { className: "truncate", children: label })
677
+ !compact && /* @__PURE__ */ jsx("span", { className: "truncate", children: label }),
678
+ /* @__PURE__ */ jsx(NavItemBadge, { href: item.href, compact })
631
679
  ]
632
680
  }
633
681
  ),
@@ -979,12 +1027,21 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
979
1027
  }),
980
1028
  [t, topbarInjectedMenuItems]
981
1029
  );
982
- return /* @__PURE__ */ jsxs(HeaderContext.Provider, { value: headerCtxValue, children: [
1030
+ return /* @__PURE__ */ jsx(HeaderContext.Provider, { value: headerCtxValue, children: /* @__PURE__ */ jsxs(SidebarCollapseContext.Provider, { value: sidebarCollapseValue, children: [
983
1031
  /* @__PURE__ */ jsxs(
984
1032
  "div",
985
1033
  {
986
1034
  className: `relative min-h-svh lg:grid transition-[grid-template-columns] duration-200 ease-out ${gridColsClass}`,
987
- style: { "--topbar-height": "61px" },
1035
+ style: {
1036
+ "--topbar-height": "61px",
1037
+ // Left offset of the content column (sidebar, plus the section sidebar on
1038
+ // settings/profile routes). Exposed so full-bleed pages — e.g. the
1039
+ // workflow visual editor — can size themselves to the content column with
1040
+ // `calc(100vw - var(--app-content-offset))` instead of being capped by
1041
+ // `main`'s centered max-width. Only meaningful at `lg` and up, where the
1042
+ // grid (and the sidebar) is active.
1043
+ "--app-content-offset": isSectionView ? `calc(${asideWidth} + 240px)` : asideWidth
1044
+ },
988
1045
  children: [
989
1046
  /* @__PURE__ */ jsx(
990
1047
  "a",
@@ -1120,6 +1177,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
1120
1177
  ] }),
1121
1178
  /* @__PURE__ */ jsx(ProgressTopBar, { t, className: "sticky top-0 z-sticky", completedAutoHideMs: progressCompletedAutoHideMs }),
1122
1179
  /* @__PURE__ */ jsxs("main", { id: "main-content", tabIndex: -1, className: "flex-1 p-4 lg:p-6 mx-auto w-full max-w-screen-2xl", children: [
1180
+ /* @__PURE__ */ jsx(InjectionSpot, { spotId: BACKEND_NAV_BADGES_INJECTION_SPOT_ID, context: injectionContext }),
1123
1181
  /* @__PURE__ */ jsx(InjectionSpot, { spotId: BACKEND_LAYOUT_TOP_INJECTION_SPOT_ID, context: injectionContext }),
1124
1182
  /* @__PURE__ */ jsx(FlashMessages, {}),
1125
1183
  /* @__PURE__ */ jsx(PartialIndexBanner, {}),
@@ -1207,10 +1265,11 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
1207
1265
  }
1208
1266
  ),
1209
1267
  /* @__PURE__ */ jsx(UmesDevToolsPanel, {})
1210
- ] });
1268
+ ] }) });
1211
1269
  }
1212
1270
  export {
1213
1271
  AppShell,
1214
- ApplyBreadcrumb
1272
+ ApplyBreadcrumb,
1273
+ useSidebarCollapse
1215
1274
  };
1216
1275
  //# sourceMappingURL=AppShell.js.map