@the-portland-company/shell 0.97.0 → 0.98.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/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PageHeaderProps, B as BreadcrumbBarProps, N as NavItem } from './index-BaUIPQpN.cjs';
2
- export { A as AI_CREDITS_STATE_TITLES, a as AiCreditsState, b as AiCreditsStateKind, C as Card, c as CommsNotification, d as CommsNotificationKind, F as FormColumn, H as HeaderTabBar, e as HeaderTabBarItem, K as KNOWN_TAB_GLYPHS, f as NotificationsAdapter, g as NotificationsFeed, R as RowMenu, h as RowMenuItem, i as RowMenuPlacement, T as TabGlyphComponent, j as aiCreditsWalletUrl, k as createCommsNotificationsAdapter, l as emptyNotificationsFeed, n as normalizeNotificationsFeed, r as resolveTabGlyph, m as rowMenuPosition } from './index-BaUIPQpN.cjs';
1
+ import { P as PageHeaderProps, B as BreadcrumbBarProps, N as NavItem } from './index-CUPeC2Ji.cjs';
2
+ export { A as AI_CREDITS_STATE_TITLES, a as AiCreditsState, b as AiCreditsStateKind, C as Card, c as CommsNotification, d as CommsNotificationKind, F as FormColumn, H as HeaderTabBar, e as HeaderTabBarItem, K as KNOWN_TAB_GLYPHS, f as NotificationsAdapter, g as NotificationsFeed, R as RowMenu, h as RowMenuItem, i as RowMenuPlacement, T as TabGlyphComponent, V as VRM_TIER_LABELS, j as VRM_VERIFIED_TOOLTIP, k as VrmVerifiedBadge, l as VrmVerifiedBadgeProps, m as VrmVerifiedTier, n as aiCreditsWalletUrl, o as createCommsNotificationsAdapter, p as emptyNotificationsFeed, q as normalizeNotificationsFeed, r as resolveTabGlyph, s as rowMenuPosition } from './index-CUPeC2Ji.cjs';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode, CSSProperties } from 'react';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PageHeaderProps, B as BreadcrumbBarProps, N as NavItem } from './index-BEMGfLpI.js';
2
- export { A as AI_CREDITS_STATE_TITLES, a as AiCreditsState, b as AiCreditsStateKind, C as Card, c as CommsNotification, d as CommsNotificationKind, F as FormColumn, H as HeaderTabBar, e as HeaderTabBarItem, K as KNOWN_TAB_GLYPHS, f as NotificationsAdapter, g as NotificationsFeed, R as RowMenu, h as RowMenuItem, i as RowMenuPlacement, T as TabGlyphComponent, j as aiCreditsWalletUrl, k as createCommsNotificationsAdapter, l as emptyNotificationsFeed, n as normalizeNotificationsFeed, r as resolveTabGlyph, m as rowMenuPosition } from './index-BEMGfLpI.js';
1
+ import { P as PageHeaderProps, B as BreadcrumbBarProps, N as NavItem } from './index-DAD6tSfV.js';
2
+ export { A as AI_CREDITS_STATE_TITLES, a as AiCreditsState, b as AiCreditsStateKind, C as Card, c as CommsNotification, d as CommsNotificationKind, F as FormColumn, H as HeaderTabBar, e as HeaderTabBarItem, K as KNOWN_TAB_GLYPHS, f as NotificationsAdapter, g as NotificationsFeed, R as RowMenu, h as RowMenuItem, i as RowMenuPlacement, T as TabGlyphComponent, V as VRM_TIER_LABELS, j as VRM_VERIFIED_TOOLTIP, k as VrmVerifiedBadge, l as VrmVerifiedBadgeProps, m as VrmVerifiedTier, n as aiCreditsWalletUrl, o as createCommsNotificationsAdapter, p as emptyNotificationsFeed, q as normalizeNotificationsFeed, r as resolveTabGlyph, s as rowMenuPosition } from './index-DAD6tSfV.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode, CSSProperties } from 'react';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { PageHeaderView, warnDeprecated, BreadcrumbBarView } from './chunk-VAQNZD37.js';
2
- export { AI_CREDITS_STATE_TITLES, AiCreditsState, Card, FormColumn, HeaderTabBar, KNOWN_TAB_GLYPHS, RowMenu, RowMenuItem, SpeculationRulesScript, aiCreditsWalletUrl, buildNavSpeculationRules, buildSpeculationRules, collectSiblingAppUrls, createCommsNotificationsAdapter, emptyNotificationsFeed, normalizeNotificationsFeed, resolveTabGlyph, rowMenuPosition } from './chunk-VAQNZD37.js';
1
+ import { PageHeaderView, warnDeprecated, BreadcrumbBarView } from './chunk-WOOBPM4V.js';
2
+ export { AI_CREDITS_STATE_TITLES, AiCreditsState, Card, FormColumn, HeaderTabBar, KNOWN_TAB_GLYPHS, RowMenu, RowMenuItem, SpeculationRulesScript, VRM_TIER_LABELS, VRM_VERIFIED_TOOLTIP, VrmVerifiedBadge, aiCreditsWalletUrl, buildNavSpeculationRules, buildSpeculationRules, collectSiblingAppUrls, createCommsNotificationsAdapter, emptyNotificationsFeed, normalizeNotificationsFeed, resolveTabGlyph, rowMenuPosition } from './chunk-WOOBPM4V.js';
3
3
  import { readResolvedTheme } from './chunk-BHRVZPZ7.js';
4
- export { BRAND_APPLE_ICON_LINK_ID, BRAND_FAVICON_LINK_ID, BrandFavicon, applyBrandFavicon, watchBrandFavicon } from './chunk-BMR5WAWH.js';
4
+ export { BRAND_APPLE_ICON_LINK_ID, BRAND_FAVICON_LINK_ID, BrandFavicon, applyBrandFavicon, watchBrandFavicon } from './chunk-Q5DTPY5N.js';
5
5
  import { extendTheme, ChakraProvider, useColorMode } from '@chakra-ui/react';
6
6
  import { jsx, jsxs } from 'react/jsx-runtime';
7
7
  import clsx from 'clsx';
package/dist/native.cjs CHANGED
@@ -694,19 +694,26 @@ function TopBarCountBadge({ count }) {
694
694
  }
695
695
  function TopBarTooltip({
696
696
  title,
697
- description
697
+ description,
698
+ align = "center"
698
699
  }) {
700
+ const bodyPosition = align === "end" ? "right-0" : "left-1/2 -translate-x-1/2";
701
+ const arrowPosition = align === "end" ? "" : "left-1/2 -translate-x-1/2";
702
+ const arrowStyle = align === "end" ? { right: "calc(var(--topbar-icon-button-size, 34px) / 2 - 5px)" } : void 0;
699
703
  return /* @__PURE__ */ jsxRuntime.jsxs(
700
704
  "span",
701
705
  {
702
706
  role: "tooltip",
703
- className: "pointer-events-none absolute left-1/2 top-full z-50 mt-2 hidden w-max max-w-56 -translate-x-1/2 flex-col rounded-lg border border-[color:var(--app-btn-tooltip-bg,#2F3136)] bg-[color:var(--app-btn-tooltip-bg,#2F3136)] px-3 py-2 text-left shadow-[var(--shadow-soft)] group-hover/tbtip:flex group-focus-visible/tbtip:flex",
707
+ "data-tooltip-align": align,
708
+ className: `pointer-events-none absolute ${bodyPosition} top-full z-50 mt-2 hidden w-max max-w-56 flex-col rounded-lg border border-[color:var(--app-btn-tooltip-bg,#2F3136)] bg-[color:var(--app-btn-tooltip-bg,#2F3136)] px-3 py-2 text-left shadow-[var(--shadow-soft)] group-hover/tbtip:flex group-focus-visible/tbtip:flex`,
704
709
  children: [
705
710
  /* @__PURE__ */ jsxRuntime.jsx(
706
711
  "span",
707
712
  {
708
713
  "aria-hidden": true,
709
- className: "absolute -top-[5px] left-1/2 h-2.5 w-2.5 -translate-x-1/2 rotate-45 border-l border-t border-[color:var(--app-btn-tooltip-bg,#2F3136)] bg-[color:var(--app-btn-tooltip-bg,#2F3136)]"
714
+ "data-tooltip-arrow": true,
715
+ style: arrowStyle,
716
+ className: `absolute -top-[5px] ${arrowPosition} h-2.5 w-2.5 rotate-45 border-l border-t border-[color:var(--app-btn-tooltip-bg,#2F3136)] bg-[color:var(--app-btn-tooltip-bg,#2F3136)]`
710
717
  }
711
718
  ),
712
719
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-[color:var(--app-btn-tooltip-fg,#FFFFFF)]", children: title }),
@@ -2379,7 +2386,7 @@ function useThemePreference() {
2379
2386
  function TopBarLinkAction({ label, description, href, icon: Icon }) {
2380
2387
  return /* @__PURE__ */ jsxRuntime.jsxs("a", { href, "aria-label": label, className: topBarIconButtonClass(), children: [
2381
2388
  /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: TOPBAR_GLYPH_SIZE, className: "text-current" }),
2382
- /* @__PURE__ */ jsxRuntime.jsx(TopBarTooltip, { title: label, description })
2389
+ /* @__PURE__ */ jsxRuntime.jsx(TopBarTooltip, { title: label, description, align: "end" })
2383
2390
  ] });
2384
2391
  }
2385
2392
  function OrganizationSettingsAction({ href }) {
@@ -2423,6 +2430,30 @@ function readBrandAsset(kind) {
2423
2430
  return null;
2424
2431
  }
2425
2432
  }
2433
+ var RETRY_MS = [0, 250, 1e3, 3e3];
2434
+ function useBrandAsset(kind) {
2435
+ const [url, setUrl] = react.useState(null);
2436
+ react.useEffect(() => {
2437
+ let done = false;
2438
+ const read = () => {
2439
+ if (done) return;
2440
+ const next = readBrandAsset(kind);
2441
+ setUrl((prev) => prev === next ? prev : next);
2442
+ };
2443
+ const links = Array.from(
2444
+ document.querySelectorAll('link[rel="stylesheet"][href*="api/tokens"]')
2445
+ );
2446
+ links.forEach((l) => l.addEventListener("load", read));
2447
+ const timers = RETRY_MS.map((ms) => window.setTimeout(read, ms));
2448
+ read();
2449
+ return () => {
2450
+ done = true;
2451
+ links.forEach((l) => l.removeEventListener("load", read));
2452
+ timers.forEach((t) => window.clearTimeout(t));
2453
+ };
2454
+ }, [kind]);
2455
+ return url;
2456
+ }
2426
2457
 
2427
2458
  // src/lib/brandFavicon.ts
2428
2459
  var BRAND_FAVICON_LINK_ID = "politogy-brand-favicon";
@@ -2447,7 +2478,7 @@ function applyBrandFavicon() {
2447
2478
  if (apple) upsertLink(BRAND_APPLE_ICON_LINK_ID, "apple-touch-icon", apple);
2448
2479
  return true;
2449
2480
  }
2450
- var RETRY_MS = [0, 250, 1e3, 3e3];
2481
+ var RETRY_MS2 = [0, 250, 1e3, 3e3];
2451
2482
  function watchBrandFavicon() {
2452
2483
  if (typeof document === "undefined") return () => {
2453
2484
  };
@@ -2464,7 +2495,7 @@ function watchBrandFavicon() {
2464
2495
  });
2465
2496
  };
2466
2497
  listen();
2467
- const timers = RETRY_MS.map((ms) => window.setTimeout(apply, ms));
2498
+ const timers = RETRY_MS2.map((ms) => window.setTimeout(apply, ms));
2468
2499
  const observer = typeof MutationObserver === "undefined" ? null : new MutationObserver(() => {
2469
2500
  listen();
2470
2501
  apply();
@@ -3006,6 +3037,90 @@ function RowMenuItem({
3006
3037
  }
3007
3038
  );
3008
3039
  }
3040
+ var VRM_VERIFIED_TOOLTIP = "Politogy has confirmed this is a real, registered voter.";
3041
+ var VRM_TIER_LABELS = {
3042
+ verified: "VRM Verified",
3043
+ identified: "Identified",
3044
+ anonymous: "Anonymous",
3045
+ stale: "Stale",
3046
+ inactive: "Inactive"
3047
+ };
3048
+ var TIER_TOOLTIPS = {
3049
+ verified: VRM_VERIFIED_TOOLTIP,
3050
+ identified: "Identified: we know who this is, but Politogy has not verified them.",
3051
+ anonymous: "Anonymous: nothing identifying has been captured yet.",
3052
+ stale: "Stale: was VRM Verified, but the proof is more than 12 months old.",
3053
+ inactive: "Inactive: the voter file marks this registration inactive or canceled."
3054
+ };
3055
+ var DOT_FALLBACK = {
3056
+ identified: "#a855f7",
3057
+ anonymous: "var(--color-graphite, #2b2b2b)",
3058
+ stale: "#eab308",
3059
+ inactive: "var(--muted, #8a8a8a)"
3060
+ };
3061
+ function VrmVerifiedBadge({ tier, size, showLabel = true, className, style }) {
3062
+ const icon = useBrandAsset("verified-icon");
3063
+ const known = tier && tier in VRM_TIER_LABELS ? tier : null;
3064
+ const label = known ? VRM_TIER_LABELS[known] : "Not yet computed";
3065
+ const title = known ? TIER_TOOLTIPS[known] : "The VRM Verified tier has not been worked out yet.";
3066
+ const iconSize = size ?? 16;
3067
+ const dotSize = size ?? 8;
3068
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3069
+ "span",
3070
+ {
3071
+ "data-vrm-tier": known ?? "none",
3072
+ title,
3073
+ "aria-label": showLabel ? void 0 : label,
3074
+ role: showLabel ? void 0 : "img",
3075
+ className,
3076
+ style: {
3077
+ display: "inline-flex",
3078
+ alignItems: "center",
3079
+ gap: 6,
3080
+ borderRadius: 9999,
3081
+ border: "1px solid var(--line, #e5e5e5)",
3082
+ padding: "2px 10px",
3083
+ fontSize: 12,
3084
+ fontWeight: 600,
3085
+ lineHeight: 1.4,
3086
+ whiteSpace: "nowrap",
3087
+ ...style
3088
+ },
3089
+ children: [
3090
+ known === "verified" ? (
3091
+ // The box is reserved while the Brand sheet loads; nothing stands in.
3092
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, style: { display: "inline-block", width: iconSize, height: iconSize, flexShrink: 0 }, children: icon ? /* @__PURE__ */ jsxRuntime.jsx(
3093
+ "img",
3094
+ {
3095
+ src: icon,
3096
+ alt: "",
3097
+ width: iconSize,
3098
+ height: iconSize,
3099
+ draggable: false,
3100
+ "data-testid": "vrm-verified-icon",
3101
+ style: { display: "block", width: iconSize, height: iconSize }
3102
+ }
3103
+ ) : null })
3104
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
3105
+ "span",
3106
+ {
3107
+ "aria-hidden": true,
3108
+ style: {
3109
+ display: "inline-block",
3110
+ width: dotSize,
3111
+ height: dotSize,
3112
+ borderRadius: 9999,
3113
+ flexShrink: 0,
3114
+ background: known ? `var(--vrm-tier-${known}, ${DOT_FALLBACK[known]})` : "transparent",
3115
+ border: known ? void 0 : "1px dashed var(--muted, #8a8a8a)"
3116
+ }
3117
+ }
3118
+ ),
3119
+ showLabel ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }) : null
3120
+ ]
3121
+ }
3122
+ );
3123
+ }
3009
3124
  var standardNavIcons = {
3010
3125
  home: lu.LuHouse,
3011
3126
  users: lu.LuUsers,
@@ -3424,6 +3539,33 @@ function shortEnvLabel(label) {
3424
3539
  if (l === "development") return "dev";
3425
3540
  return l;
3426
3541
  }
3542
+ function buildLineParts(meta) {
3543
+ const version = meta.version ? `v${meta.version.replace(/^v/, "")}` : null;
3544
+ const parsed = meta.commitDate ? new Date(meta.commitDate) : null;
3545
+ const date = parsed && !Number.isNaN(parsed.getTime()) ? parsed.toLocaleDateString(void 0, { month: "short", day: "numeric" }) : null;
3546
+ const line = [version, date].filter(Boolean).join(" \xB7 ");
3547
+ const detail2 = [
3548
+ meta.envLabel ? shortEnvLabel(meta.envLabel) : null,
3549
+ meta.commit ? meta.commit.slice(0, 12) : null,
3550
+ version,
3551
+ date,
3552
+ meta.commitAuthor ? meta.commitAuthor.split(/\s+/)[0] : null
3553
+ ].filter(Boolean).join(" | ");
3554
+ return { line, detail: detail2 };
3555
+ }
3556
+ function ShellBuildLine({ footer, hidden }) {
3557
+ const { line, detail: detail2 } = buildLineParts(footer);
3558
+ if (!line && !detail2) return null;
3559
+ return /* @__PURE__ */ jsxRuntime.jsx(
3560
+ "div",
3561
+ {
3562
+ "data-shell-meta": true,
3563
+ title: detail2,
3564
+ className: `mt-1.5 truncate text-center font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[10px] leading-[1.2] text-[color:var(--sidebar-row-text,rgba(255,255,255,0.66))] ${hidden}`,
3565
+ children: line || detail2
3566
+ }
3567
+ );
3568
+ }
3427
3569
  function envChipClasses(label) {
3428
3570
  const l = label.toLowerCase();
3429
3571
  if (l === "production" || l === "prod")
@@ -3926,31 +4068,7 @@ function NavSidebar({
3926
4068
  }
3927
4069
  )
3928
4070
  ] }, l.label)) }) : null,
3929
- footer.envLabel || footer.commit || footer.version ? /* @__PURE__ */ jsxRuntime.jsxs(
3930
- "div",
3931
- {
3932
- "data-shell-meta": true,
3933
- className: `mt-1.5 flex flex-col items-center gap-0.5 font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[11px] text-[color:var(--sidebar-meta-text,rgba(255,255,255,0.72))] ${rc("max-md:hidden")}`,
3934
- children: [
3935
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5", children: [
3936
- footer.envLabel ? shortEnvLabel(footer.envLabel) : null,
3937
- footer.commit ? footer.commit.slice(-4) : null,
3938
- footer.version ? `v${footer.version.replace(/^v/, "")}` : null
3939
- ].filter((v) => Boolean(v)).map((v, i) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
3940
- i > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: "|" }) : null,
3941
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: v })
3942
- ] }, i)) }),
3943
- footer.commitDate || footer.commitAuthor ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
3944
- footer.commitDate ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: new Date(footer.commitDate).toLocaleDateString(void 0, {
3945
- month: "short",
3946
- day: "numeric"
3947
- }) }) : null,
3948
- footer.commitDate && footer.commitAuthor ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: "|" }) : null,
3949
- footer.commitAuthor ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: footer.commitAuthor.split(/\s+/)[0] }) : null
3950
- ] }) : null
3951
- ]
3952
- }
3953
- ) : null
4071
+ footer.envLabel || footer.commit || footer.version ? /* @__PURE__ */ jsxRuntime.jsx(ShellBuildLine, { footer, hidden: rc("max-md:hidden") }) : null
3954
4072
  ] }) : null
3955
4073
  ]
3956
4074
  }
@@ -5009,8 +5127,12 @@ exports.TopBarPanelArrow = TopBarPanelArrow;
5009
5127
  exports.TopBarPopover = TopBarPopover;
5010
5128
  exports.TopBarTooltip = TopBarTooltip;
5011
5129
  exports.TopBarWidgetSlot = TopBarWidgetSlot;
5130
+ exports.VRM_TIER_LABELS = VRM_TIER_LABELS;
5131
+ exports.VRM_VERIFIED_TOOLTIP = VRM_VERIFIED_TOOLTIP;
5132
+ exports.VrmVerifiedBadge = VrmVerifiedBadge;
5012
5133
  exports.aiCreditsWalletUrl = aiCreditsWalletUrl;
5013
5134
  exports.applyBrandFavicon = applyBrandFavicon;
5135
+ exports.buildLineParts = buildLineParts;
5014
5136
  exports.clearBetaBannerDismissal = clearBetaBannerDismissal;
5015
5137
  exports.creditGaugeRatio = creditGaugeRatio;
5016
5138
  exports.creditStateWord = creditStateWord;