@richardmcquiston01/dashboard-widgets-toolkit 0.11.2 → 0.12.0

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/react.cjs CHANGED
@@ -825,6 +825,10 @@ var DEFAULT_LABELS = {
825
825
  confirmDeletePage: (title) => `Delete the page "${title}" and move its widgets to another page?`,
826
826
  movePageLeft: (title) => `Move ${title} page left`,
827
827
  movePageRight: (title) => `Move ${title} page right`,
828
+ arrangeWidget: (title) => `Arrange ${title}`,
829
+ menuMoveEarlier: "Move earlier",
830
+ menuMoveLater: "Move later",
831
+ menuHide: "Hide",
828
832
  moveToPage: (title) => `Move ${title} to another page`,
829
833
  moveToPagePlaceholder: "Move to page\u2026",
830
834
  moveToPageOption: (title, rowsFree) => `${title} (${rowsFree} ${rowsFree === 1 ? "row" : "rows"} free)`,
@@ -2420,22 +2424,23 @@ function moveWidgetToPage(definitions, layout, widgetKey, targetKey, options = {
2420
2424
  }
2421
2425
  return ok(moved);
2422
2426
  }
2423
- function MoveToPageMenu({
2427
+ var EditMenuInitialOpenContext = react.createContext(false);
2428
+ var ITEM_SELECTOR = '[role="menuitem"]:not(:disabled)';
2429
+ function WidgetEditMenu({
2424
2430
  label,
2425
- heading,
2426
- options,
2427
- onPick,
2428
- initialOpen = false
2431
+ items,
2432
+ initialOpen
2429
2433
  }) {
2430
2434
  const slot = useSlotClassName();
2435
+ const startOpen = react.useContext(EditMenuInitialOpenContext);
2431
2436
  const menuId = react.useId();
2432
- const [open, setOpen] = react.useState(initialOpen);
2437
+ const [open, setOpen] = react.useState(initialOpen ?? startOpen);
2433
2438
  const wrapper = react.useRef(null);
2434
2439
  const button = react.useRef(null);
2435
2440
  const menu = react.useRef(null);
2436
2441
  react.useEffect(() => {
2437
2442
  if (!open) return void 0;
2438
- menu.current?.querySelector('[role="menuitem"]')?.focus();
2443
+ menu.current?.querySelector(ITEM_SELECTOR)?.focus();
2439
2444
  const onPointerDown = (event) => {
2440
2445
  if (!wrapper.current?.contains(event.target)) setOpen(false);
2441
2446
  };
@@ -2452,28 +2457,29 @@ function MoveToPageMenu({
2452
2457
  close(true);
2453
2458
  return;
2454
2459
  }
2455
- const items = [
2456
- ...menu.current?.querySelectorAll('[role="menuitem"]') ?? []
2460
+ const enabled = [
2461
+ ...menu.current?.querySelectorAll(ITEM_SELECTOR) ?? []
2457
2462
  ];
2458
- const current = items.indexOf(
2463
+ if (enabled.length === 0) return;
2464
+ const current = enabled.indexOf(
2459
2465
  document.activeElement
2460
2466
  );
2461
2467
  let next;
2462
- if (event.key === "ArrowDown") next = (current + 1) % items.length;
2468
+ if (event.key === "ArrowDown") next = (current + 1) % enabled.length;
2463
2469
  else if (event.key === "ArrowUp") {
2464
- next = (current - 1 + items.length) % items.length;
2470
+ next = (current - 1 + enabled.length) % enabled.length;
2465
2471
  } else if (event.key === "Home") next = 0;
2466
- else if (event.key === "End") next = items.length - 1;
2472
+ else if (event.key === "End") next = enabled.length - 1;
2467
2473
  if (next !== void 0) {
2468
2474
  event.preventDefault();
2469
- items[next]?.focus();
2475
+ enabled[next]?.focus();
2470
2476
  }
2471
2477
  }
2472
2478
  return /* @__PURE__ */ jsxRuntime.jsxs(
2473
2479
  "span",
2474
2480
  {
2475
2481
  ref: wrapper,
2476
- className: "dwt-move-menu",
2482
+ className: "dwt-edit-menu",
2477
2483
  onBlur: (event) => {
2478
2484
  if (!event.currentTarget.contains(event.relatedTarget)) {
2479
2485
  setOpen(false);
@@ -2495,18 +2501,18 @@ function MoveToPageMenu({
2495
2501
  children: /* @__PURE__ */ jsxRuntime.jsx(
2496
2502
  "svg",
2497
2503
  {
2498
- viewBox: "0 0 16 16",
2499
- width: "14",
2500
- height: "14",
2504
+ viewBox: "0 0 24 24",
2505
+ width: "16",
2506
+ height: "16",
2501
2507
  "aria-hidden": "true",
2502
2508
  focusable: "false",
2503
2509
  children: /* @__PURE__ */ jsxRuntime.jsx(
2504
2510
  "path",
2505
2511
  {
2506
- d: "M2 8h8M7 5l3 3-3 3M13 3v10",
2512
+ d: "M5 9l-3 3 3 3M9 5l3-3 3 3M15 19l-3 3-3-3M19 9l3 3-3 3M2 12h20M12 2v20",
2507
2513
  fill: "none",
2508
2514
  stroke: "currentColor",
2509
- strokeWidth: "1.5",
2515
+ strokeWidth: "2",
2510
2516
  strokeLinecap: "round",
2511
2517
  strokeLinejoin: "round"
2512
2518
  }
@@ -2515,32 +2521,41 @@ function MoveToPageMenu({
2515
2521
  )
2516
2522
  }
2517
2523
  ),
2518
- open && /* @__PURE__ */ jsxRuntime.jsxs(
2524
+ open && /* @__PURE__ */ jsxRuntime.jsx(
2519
2525
  "div",
2520
2526
  {
2521
2527
  ref: menu,
2522
2528
  id: menuId,
2523
- className: "dwt-move-popover",
2529
+ className: "dwt-edit-popover",
2524
2530
  role: "menu",
2525
- "aria-label": heading,
2531
+ "aria-label": label,
2526
2532
  onKeyDown,
2527
- children: [
2528
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "dwt-move-heading", "aria-hidden": "true", children: heading }),
2529
- options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
2533
+ children: items.map(
2534
+ (item) => item.kind === "heading" ? /* @__PURE__ */ jsxRuntime.jsx(
2535
+ "p",
2536
+ {
2537
+ className: "dwt-edit-heading",
2538
+ role: "presentation",
2539
+ children: item.label
2540
+ },
2541
+ item.key
2542
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
2530
2543
  "button",
2531
2544
  {
2532
2545
  type: "button",
2533
2546
  role: "menuitem",
2534
- className: "dwt-move-option",
2547
+ className: "dwt-edit-option",
2548
+ ...item.ariaLabel === void 0 ? {} : { "aria-label": item.ariaLabel },
2549
+ disabled: item.disabled === true,
2535
2550
  onClick: () => {
2536
2551
  close(false);
2537
- onPick(option.value);
2552
+ item.onSelect();
2538
2553
  },
2539
- children: option.label
2554
+ children: item.label
2540
2555
  },
2541
- option.value
2542
- ))
2543
- ]
2556
+ item.key
2557
+ )
2558
+ )
2544
2559
  }
2545
2560
  )
2546
2561
  ]
@@ -3669,6 +3684,64 @@ function DashboardInner({
3669
3684
  const lockLabel = overrideLocks ? labels.lockedForViewers(title) : labels.locked(title);
3670
3685
  const canMoveEarlier = !lock.move && moveWidgetBy(pageDefs, view, key, -1) !== view;
3671
3686
  const canMoveLater = !lock.move && moveWidgetBy(pageDefs, view, key, 1) !== view;
3687
+ const pageTargets = paged && !lock.move ? [
3688
+ {
3689
+ kind: "heading",
3690
+ key: "page-heading",
3691
+ label: labels.moveToPagePlaceholder
3692
+ },
3693
+ ...pages.filter((page) => page.key !== activeKey).map((page) => ({
3694
+ kind: "action",
3695
+ key: `page:${page.key}`,
3696
+ label: labels.moveToPageOption(
3697
+ page.title,
3698
+ pageRoom(definitions, layout, page.key, roomOptions)?.rowsFree ?? 0
3699
+ ),
3700
+ ariaLabel: labels.moveToPageOption(
3701
+ page.title,
3702
+ pageRoom(definitions, layout, page.key, roomOptions)?.rowsFree ?? 0
3703
+ ),
3704
+ onSelect: () => moveWidgetAction(key, page.key)
3705
+ })),
3706
+ ...maxPages === void 0 || pages.length < maxPages ? [
3707
+ {
3708
+ kind: "action",
3709
+ key: "page:new",
3710
+ label: labels.newPageOption,
3711
+ onSelect: () => moveWidgetAction(key, NEW_PAGE_VALUE)
3712
+ }
3713
+ ] : []
3714
+ ] : [];
3715
+ const editItems = [
3716
+ ...lock.move ? [] : [
3717
+ {
3718
+ kind: "action",
3719
+ key: "earlier",
3720
+ label: labels.menuMoveEarlier,
3721
+ ariaLabel: labels.moveEarlier(title),
3722
+ disabled: index === 0 || !canMoveEarlier,
3723
+ onSelect: () => changePage(moveWidgetBy(pageDefs, view, key, -1))
3724
+ },
3725
+ {
3726
+ kind: "action",
3727
+ key: "later",
3728
+ label: labels.menuMoveLater,
3729
+ ariaLabel: labels.moveLater(title),
3730
+ disabled: index === shown.length - 1 || !canMoveLater,
3731
+ onSelect: () => changePage(moveWidgetBy(pageDefs, view, key, 1))
3732
+ }
3733
+ ],
3734
+ ...pageTargets,
3735
+ ...lock.hide ? [] : [
3736
+ {
3737
+ kind: "action",
3738
+ key: "hide",
3739
+ label: labels.menuHide,
3740
+ ariaLabel: labels.hide(title),
3741
+ onSelect: () => changePage(hideWidget(view, key))
3742
+ }
3743
+ ]
3744
+ ];
3672
3745
  const actions = controlsShown ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3673
3746
  isLocked && /* @__PURE__ */ jsxRuntime.jsx(
3674
3747
  "span",
@@ -3711,81 +3784,11 @@ function DashboardInner({
3711
3784
  )
3712
3785
  }
3713
3786
  ),
3714
- !lock.move && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3715
- /* @__PURE__ */ jsxRuntime.jsx(
3716
- "button",
3717
- {
3718
- type: "button",
3719
- className: slot(
3720
- "button",
3721
- "dwt-button",
3722
- "dwt-icon-button"
3723
- ),
3724
- "aria-label": labels.moveEarlier(title),
3725
- title: labels.moveEarlier(title),
3726
- disabled: index === 0 || !canMoveEarlier,
3727
- onClick: () => changePage(moveWidgetBy(pageDefs, view, key, -1)),
3728
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\u2191" })
3729
- }
3730
- ),
3731
- /* @__PURE__ */ jsxRuntime.jsx(
3732
- "button",
3733
- {
3734
- type: "button",
3735
- className: slot(
3736
- "button",
3737
- "dwt-button",
3738
- "dwt-icon-button"
3739
- ),
3740
- "aria-label": labels.moveLater(title),
3741
- title: labels.moveLater(title),
3742
- disabled: index === shown.length - 1 || !canMoveLater,
3743
- onClick: () => changePage(moveWidgetBy(pageDefs, view, key, 1)),
3744
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\u2193" })
3745
- }
3746
- ),
3747
- paged && /* @__PURE__ */ jsxRuntime.jsx(
3748
- MoveToPageMenu,
3749
- {
3750
- label: labels.moveToPage(title),
3751
- heading: labels.moveToPagePlaceholder,
3752
- onPick: (pageKey) => moveWidgetAction(key, pageKey),
3753
- options: [
3754
- ...pages.filter((page) => page.key !== activeKey).map((page) => ({
3755
- value: page.key,
3756
- label: labels.moveToPageOption(
3757
- page.title,
3758
- pageRoom(
3759
- definitions,
3760
- layout,
3761
- page.key,
3762
- roomOptions
3763
- )?.rowsFree ?? 0
3764
- )
3765
- })),
3766
- ...maxPages === void 0 || pages.length < maxPages ? [
3767
- {
3768
- value: NEW_PAGE_VALUE,
3769
- label: labels.newPageOption
3770
- }
3771
- ] : []
3772
- ]
3773
- }
3774
- )
3775
- ] }),
3776
- !lock.hide && /* @__PURE__ */ jsxRuntime.jsx(
3777
- "button",
3787
+ editItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
3788
+ WidgetEditMenu,
3778
3789
  {
3779
- type: "button",
3780
- className: slot(
3781
- "button",
3782
- "dwt-button",
3783
- "dwt-icon-button"
3784
- ),
3785
- "aria-label": labels.hide(title),
3786
- title: labels.hide(title),
3787
- onClick: () => changePage(hideWidget(view, key)),
3788
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\xD7" })
3790
+ label: labels.arrangeWidget(title),
3791
+ items: editItems
3789
3792
  }
3790
3793
  )
3791
3794
  ] }) : void 0;