@orangecheck/design 0.8.0 → 0.9.1

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/chrome.js CHANGED
@@ -2,16 +2,37 @@
2
2
 
3
3
  var lucideReact = require('lucide-react');
4
4
  var Link5 = require('next/link');
5
- var react = require('react');
5
+ var React = require('react');
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
7
  var router = require('next/router');
8
- var authClient = require('@orangecheck/auth-client');
8
+ var Popover = require('@radix-ui/react-popover');
9
9
  var clsx = require('clsx');
10
10
  var tailwindMerge = require('tailwind-merge');
11
+ var authClient = require('@orangecheck/auth-client');
11
12
 
12
13
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
14
 
15
+ function _interopNamespace(e) {
16
+ if (e && e.__esModule) return e;
17
+ var n = Object.create(null);
18
+ if (e) {
19
+ Object.keys(e).forEach(function (k) {
20
+ if (k !== 'default') {
21
+ var d = Object.getOwnPropertyDescriptor(e, k);
22
+ Object.defineProperty(n, k, d.get ? d : {
23
+ enumerable: true,
24
+ get: function () { return e[k]; }
25
+ });
26
+ }
27
+ });
28
+ }
29
+ n.default = e;
30
+ return Object.freeze(n);
31
+ }
32
+
14
33
  var Link5__default = /*#__PURE__*/_interopDefault(Link5);
34
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
35
+ var Popover__namespace = /*#__PURE__*/_interopNamespace(Popover);
15
36
 
16
37
  // src/chrome/ecosystem-switcher.tsx
17
38
  var ENTRIES = [
@@ -107,9 +128,9 @@ function EcosystemSwitcher({
107
128
  className,
108
129
  showOwnerEntries = false
109
130
  }) {
110
- const [open, setOpen] = react.useState(false);
111
- const containerRef = react.useRef(null);
112
- react.useEffect(() => {
131
+ const [open, setOpen] = React.useState(false);
132
+ const containerRef = React.useRef(null);
133
+ React.useEffect(() => {
113
134
  if (!open) return;
114
135
  function onDoc(e) {
115
136
  if (!containerRef.current) return;
@@ -192,6 +213,144 @@ function EcosystemSwitcher({
192
213
  )
193
214
  ] });
194
215
  }
216
+ function cn(...inputs) {
217
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
218
+ }
219
+ var TOOLTIP_SURFACE_CLASS = "bg-popover text-popover-foreground border-border rounded-md border p-2.5 shadow-md";
220
+ var TOOLTIP_MOTION_CLASS = "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-1 data-[side=top]:slide-in-from-bottom-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 origin-(--radix-popover-content-transform-origin) duration-150 ease-out";
221
+ function compose(theirs, ours) {
222
+ return (e) => {
223
+ theirs?.(e);
224
+ ours(e);
225
+ };
226
+ }
227
+ var lastInputWasKeyboard = false;
228
+ var modalityInstalled = false;
229
+ function installModalityTracking() {
230
+ if (modalityInstalled || typeof window === "undefined") return;
231
+ modalityInstalled = true;
232
+ window.addEventListener("keydown", () => lastInputWasKeyboard = true, true);
233
+ window.addEventListener("pointerdown", () => lastInputWasKeyboard = false, true);
234
+ }
235
+ function Tooltip({
236
+ content,
237
+ children,
238
+ side = "bottom",
239
+ align = "start",
240
+ sideOffset = 8,
241
+ collisionPadding = 12,
242
+ openDelay = 300,
243
+ closeDelay = 90,
244
+ disabled = false,
245
+ portal = true,
246
+ zIndexClassName = "z-50",
247
+ contentClassName
248
+ }) {
249
+ const [hovering, setHovering] = React__namespace.useState(false);
250
+ const [focusing, setFocusing] = React__namespace.useState(false);
251
+ const [isFinePointer, setIsFinePointer] = React__namespace.useState(false);
252
+ const openTimer = React__namespace.useRef(null);
253
+ const closeTimer = React__namespace.useRef(null);
254
+ React__namespace.useEffect(() => {
255
+ installModalityTracking();
256
+ const mq = window.matchMedia("(hover: hover) and (pointer: fine)");
257
+ const apply = () => setIsFinePointer(mq.matches);
258
+ apply();
259
+ mq.addEventListener("change", apply);
260
+ return () => mq.removeEventListener("change", apply);
261
+ }, []);
262
+ const clearTimers = React__namespace.useCallback(() => {
263
+ if (openTimer.current) clearTimeout(openTimer.current);
264
+ if (closeTimer.current) clearTimeout(closeTimer.current);
265
+ }, []);
266
+ React__namespace.useEffect(() => clearTimers, [clearTimers]);
267
+ React__namespace.useEffect(() => {
268
+ if (disabled) {
269
+ clearTimers();
270
+ setHovering(false);
271
+ }
272
+ }, [disabled, clearTimers]);
273
+ const handlePointerEnter = () => {
274
+ if (!isFinePointer) return;
275
+ if (closeTimer.current) clearTimeout(closeTimer.current);
276
+ openTimer.current = setTimeout(() => setHovering(true), openDelay);
277
+ };
278
+ const handlePointerLeave = () => {
279
+ if (openTimer.current) clearTimeout(openTimer.current);
280
+ closeTimer.current = setTimeout(() => setHovering(false), closeDelay);
281
+ };
282
+ const handlePointerDown = () => {
283
+ clearTimers();
284
+ setHovering(false);
285
+ setFocusing(false);
286
+ };
287
+ const handleFocus = () => {
288
+ if (lastInputWasKeyboard) {
289
+ clearTimers();
290
+ setFocusing(true);
291
+ }
292
+ };
293
+ const handleBlur = () => {
294
+ clearTimers();
295
+ setFocusing(false);
296
+ };
297
+ const handleKeyDown = (e) => {
298
+ if (e.key === "Escape") {
299
+ clearTimers();
300
+ setHovering(false);
301
+ setFocusing(false);
302
+ }
303
+ };
304
+ const effectiveOpen = !disabled && (isFinePointer && hovering || focusing);
305
+ const extra = {};
306
+ const childProps = children.props;
307
+ extra.onPointerEnter = compose(childProps.onPointerEnter, handlePointerEnter);
308
+ extra.onPointerLeave = compose(childProps.onPointerLeave, handlePointerLeave);
309
+ extra.onPointerDown = compose(childProps.onPointerDown, handlePointerDown);
310
+ extra.onFocus = compose(childProps.onFocus, handleFocus);
311
+ extra.onBlur = compose(childProps.onBlur, handleBlur);
312
+ extra.onKeyDown = compose(childProps.onKeyDown, handleKeyDown);
313
+ const trigger = React__namespace.cloneElement(children, extra);
314
+ const contentEl = /* @__PURE__ */ jsxRuntime.jsx(
315
+ Popover__namespace.Content,
316
+ {
317
+ side,
318
+ align,
319
+ sideOffset,
320
+ collisionPadding,
321
+ "aria-hidden": true,
322
+ onOpenAutoFocus: (e) => e.preventDefault(),
323
+ onCloseAutoFocus: (e) => e.preventDefault(),
324
+ onFocusOutside: (e) => e.preventDefault(),
325
+ className: cn(
326
+ TOOLTIP_SURFACE_CLASS,
327
+ TOOLTIP_MOTION_CLASS,
328
+ "pointer-events-none",
329
+ zIndexClassName,
330
+ contentClassName
331
+ ),
332
+ children: content
333
+ }
334
+ );
335
+ return /* @__PURE__ */ jsxRuntime.jsxs(
336
+ Popover__namespace.Root,
337
+ {
338
+ open: effectiveOpen,
339
+ onOpenChange: (o) => {
340
+ if (!o) {
341
+ clearTimers();
342
+ setHovering(false);
343
+ setFocusing(false);
344
+ }
345
+ },
346
+ modal: false,
347
+ children: [
348
+ /* @__PURE__ */ jsxRuntime.jsx(Popover__namespace.Anchor, { asChild: true, children: trigger }),
349
+ portal ? /* @__PURE__ */ jsxRuntime.jsx(Popover__namespace.Portal, { children: contentEl }) : contentEl
350
+ ]
351
+ }
352
+ );
353
+ }
195
354
 
196
355
  // src/chrome/family-properties.ts
197
356
  var FAMILY_PROPERTIES = [
@@ -356,6 +515,31 @@ function MenuCategoryChip({ category }) {
356
515
  }
357
516
  );
358
517
  }
518
+ function SwitcherTooltipCard({ current }) {
519
+ const prop = findFamilyProperty(current);
520
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-[13rem] max-w-[calc(100vw-1.5rem)]", children: [
521
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col leading-tight", children: [
522
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-wrap items-baseline gap-x-1.5", children: [
523
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground font-mono text-[9px] tracking-widest uppercase", children: "you\u2019re on" }),
524
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary font-display text-[12px] font-semibold tracking-tight", children: prop?.label ?? "orangecheck family" })
525
+ ] }),
526
+ prop?.sub && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground mt-0.5 font-mono text-[10px] tracking-wide", children: prop.sub })
527
+ ] }),
528
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-border -mx-2.5 my-2 border-t" }),
529
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
530
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { "aria-hidden": true, className: "text-muted-foreground h-3 w-3 shrink-0" }),
531
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary font-mono text-[10px] font-medium tracking-widest uppercase", children: "click" }),
532
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground font-mono text-[10px]", children: "\xB7" }),
533
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground font-mono text-[10px] tracking-wide", children: "switch site" })
534
+ ] }),
535
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1.5 flex items-center gap-1.5", children: [
536
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownLeft, { "aria-hidden": true, className: "text-muted-foreground h-3 w-3 shrink-0" }),
537
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary font-mono text-[10px] font-medium tracking-widest uppercase", children: "double-click" }),
538
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground font-mono text-[10px]", children: "\xB7" }),
539
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground font-mono text-[10px] tracking-wide", children: "home" })
540
+ ] })
541
+ ] });
542
+ }
359
543
  function OcLogoDropdown({
360
544
  current,
361
545
  homeHref = "/",
@@ -366,9 +550,9 @@ function OcLogoDropdown({
366
550
  popoverClassName,
367
551
  showOwnerEntries = false
368
552
  }) {
369
- const [open, setOpen] = react.useState(false);
370
- const containerRef = react.useRef(null);
371
- const menuId = react.useId();
553
+ const [open, setOpen] = React.useState(false);
554
+ const containerRef = React.useRef(null);
555
+ const menuId = React.useId();
372
556
  const router$1 = router.useRouter();
373
557
  const currentCategory = findFamilyProperty(current)?.category ?? "hub";
374
558
  function handleTriggerClick(e) {
@@ -380,7 +564,7 @@ function OcLogoDropdown({
380
564
  }
381
565
  setOpen((v) => !v);
382
566
  }
383
- react.useEffect(() => {
567
+ React.useEffect(() => {
384
568
  if (!open) return;
385
569
  function onDoc(e) {
386
570
  if (!containerRef.current) return;
@@ -405,31 +589,45 @@ function OcLogoDropdown({
405
589
  "data-oc-current-category": currentCategory,
406
590
  "data-oc-site-state": siteState,
407
591
  children: [
408
- /* @__PURE__ */ jsxRuntime.jsxs(
409
- "button",
592
+ /* @__PURE__ */ jsxRuntime.jsx(
593
+ Tooltip,
410
594
  {
411
- type: "button",
412
- "aria-haspopup": "menu",
413
- "aria-expanded": open,
414
- "aria-controls": menuId,
415
- "aria-label": "OrangeCheck family \xB7 click to open property menu, double-click to go home",
416
- title: "single-click \xB7 family menu \xB7 double-click \xB7 go home",
417
- onClick: handleTriggerClick,
418
- className: triggerClassName ?? "group hover:bg-accent/30 -mx-1.5 -my-1 flex min-h-[40px] items-center gap-2 rounded-sm px-1.5 py-1 transition-colors " + (open ? "bg-accent/20" : ""),
419
- "data-oc-logo-dropdown-trigger": "",
420
- "data-oc-logo-dropdown-open": open ? "true" : "false",
421
- children: [
422
- children,
423
- /* @__PURE__ */ jsxRuntime.jsx(CategoryChip, { category: currentCategory }),
424
- /* @__PURE__ */ jsxRuntime.jsx(SiteStateBadge, { state: siteState }),
425
- /* @__PURE__ */ jsxRuntime.jsx(
426
- lucideReact.ChevronDown,
427
- {
428
- "aria-hidden": true,
429
- className: "text-muted-foreground/70 group-hover:text-foreground/80 h-3.5 w-3.5 shrink-0 transition-transform duration-200 " + (open ? "rotate-180" : "")
430
- }
431
- )
432
- ]
595
+ content: /* @__PURE__ */ jsxRuntime.jsx(SwitcherTooltipCard, { current }),
596
+ disabled: open,
597
+ side: "bottom",
598
+ align: "start",
599
+ sideOffset: 8,
600
+ zIndexClassName: "z-[70]",
601
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
602
+ "button",
603
+ {
604
+ type: "button",
605
+ "aria-haspopup": "menu",
606
+ "aria-expanded": open,
607
+ "aria-controls": menuId,
608
+ "aria-label": "orangecheck family menu",
609
+ onClick: handleTriggerClick,
610
+ className: cn(
611
+ // focus indicator is guaranteed even if a consumer overrides triggerClassName
612
+ "focus-visible:ring-primary/60 rounded-sm focus-visible:ring-2 focus-visible:outline-none",
613
+ triggerClassName ?? "group hover:bg-accent/30 -mx-1.5 -my-1 flex min-h-[40px] items-center gap-2 rounded-sm px-1.5 py-1 transition-colors " + (open ? "bg-accent/20" : "")
614
+ ),
615
+ "data-oc-logo-dropdown-trigger": "",
616
+ "data-oc-logo-dropdown-open": open ? "true" : "false",
617
+ children: [
618
+ children,
619
+ /* @__PURE__ */ jsxRuntime.jsx(CategoryChip, { category: currentCategory }),
620
+ /* @__PURE__ */ jsxRuntime.jsx(SiteStateBadge, { state: siteState }),
621
+ /* @__PURE__ */ jsxRuntime.jsx(
622
+ lucideReact.ChevronDown,
623
+ {
624
+ "aria-hidden": true,
625
+ className: "text-muted-foreground/70 group-hover:text-foreground/80 h-3.5 w-3.5 shrink-0 transition-transform duration-200 " + (open ? "rotate-180" : "")
626
+ }
627
+ )
628
+ ]
629
+ }
630
+ )
433
631
  }
434
632
  ),
435
633
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -458,7 +656,7 @@ function OcLogoDropdown({
458
656
  {
459
657
  id: menuId,
460
658
  role: "menu",
461
- "aria-label": "OrangeCheck family",
659
+ "aria-label": "orangecheck family",
462
660
  className: popoverClassName ?? "bg-background absolute top-full left-0 z-[60] mt-2 w-[min(20rem,calc(100vw-1rem))] border shadow-lg",
463
661
  "data-oc-logo-dropdown-popover": "",
464
662
  children: [
@@ -567,9 +765,9 @@ async function writeClipboard(text) {
567
765
  }
568
766
  }
569
767
  function CopyableDid({ did }) {
570
- const [copied, setCopied] = react.useState(false);
571
- const timerRef = react.useRef(null);
572
- react.useEffect(
768
+ const [copied, setCopied] = React.useState(false);
769
+ const timerRef = React.useRef(null);
770
+ React.useEffect(
573
771
  () => () => {
574
772
  if (timerRef.current) clearTimeout(timerRef.current);
575
773
  },
@@ -615,9 +813,9 @@ function PromoteRow({
615
813
  disabled,
616
814
  onPromote
617
815
  }) {
618
- const [copied, setCopied] = react.useState(false);
619
- const timerRef = react.useRef(null);
620
- react.useEffect(
816
+ const [copied, setCopied] = React.useState(false);
817
+ const timerRef = React.useRef(null);
818
+ React.useEffect(
621
819
  () => () => {
622
820
  if (timerRef.current) clearTimeout(timerRef.current);
623
821
  },
@@ -688,12 +886,12 @@ function IdentityPromoteSection({
688
886
  open,
689
887
  setDisplayIdentity
690
888
  }) {
691
- const [identities, setIdentities] = react.useState(null);
692
- const [loadFailed, setLoadFailed] = react.useState(false);
693
- const [promoting, setPromoting] = react.useState(null);
694
- const [promoteErr, setPromoteErr] = react.useState(null);
695
- const lastFetchKeyRef = react.useRef(null);
696
- react.useEffect(() => {
889
+ const [identities, setIdentities] = React.useState(null);
890
+ const [loadFailed, setLoadFailed] = React.useState(false);
891
+ const [promoting, setPromoting] = React.useState(null);
892
+ const [promoteErr, setPromoteErr] = React.useState(null);
893
+ const lastFetchKeyRef = React.useRef(null);
894
+ React.useEffect(() => {
697
895
  if (!open) return;
698
896
  if (lastFetchKeyRef.current === didOc) return;
699
897
  lastFetchKeyRef.current = didOc;
@@ -802,15 +1000,15 @@ function OcAccountMenuView({
802
1000
  switchAccount,
803
1001
  addAccountUrl
804
1002
  } = session;
805
- const [hydrated, setHydrated] = react.useState(false);
806
- const [open, setOpen] = react.useState(false);
807
- const wrapRef = react.useRef(null);
1003
+ const [hydrated, setHydrated] = React.useState(false);
1004
+ const [open, setOpen] = React.useState(false);
1005
+ const wrapRef = React.useRef(null);
808
1006
  const property = findFamilyProperty(current);
809
1007
  const hostname = property?.hostname ?? `${current}.ochk.io`;
810
1008
  const isHome = current === "home";
811
1009
  const familyDashboardEnabled = showFamilyDashboard ?? !isHome;
812
- react.useEffect(() => setHydrated(true), []);
813
- react.useEffect(() => {
1010
+ React.useEffect(() => setHydrated(true), []);
1011
+ React.useEffect(() => {
814
1012
  const onWake = () => {
815
1013
  if (document.visibilityState === "visible") void refresh();
816
1014
  };
@@ -822,7 +1020,7 @@ function OcAccountMenuView({
822
1020
  window.removeEventListener("focus", onFocus);
823
1021
  };
824
1022
  }, [refresh]);
825
- react.useEffect(() => {
1023
+ React.useEffect(() => {
826
1024
  if (!open) return;
827
1025
  const onClick = (e) => {
828
1026
  if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
@@ -1058,8 +1256,8 @@ function AccountsSection({
1058
1256
  signOut,
1059
1257
  onActionStart
1060
1258
  }) {
1061
- const [switching, setSwitching] = react.useState(null);
1062
- const [err, setErr] = react.useState(null);
1259
+ const [switching, setSwitching] = React.useState(null);
1260
+ const [err, setErr] = React.useState(null);
1063
1261
  if (!addAccountUrl) return null;
1064
1262
  const onSwitch = async (didOc) => {
1065
1263
  if (!switchAccount || switching) return;
@@ -1322,8 +1520,8 @@ function OcDashboardShell({
1322
1520
  children,
1323
1521
  className
1324
1522
  }) {
1325
- const [drawerOpen, setDrawerOpen] = react.useState(false);
1326
- react.useEffect(() => {
1523
+ const [drawerOpen, setDrawerOpen] = React.useState(false);
1524
+ React.useEffect(() => {
1327
1525
  if (!drawerOpen) return;
1328
1526
  function onKey(e) {
1329
1527
  if (e.key === "Escape") setDrawerOpen(false);
@@ -1592,9 +1790,6 @@ function AppShell({
1592
1790
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: hasHeader ? "mt-8 pb-12" : "pb-12", children })
1593
1791
  ] }) }) }) });
1594
1792
  }
1595
- function cn(...inputs) {
1596
- return tailwindMerge.twMerge(clsx.clsx(inputs));
1597
- }
1598
1793
  var HIDE = {
1599
1794
  sm: "hidden sm:inline",
1600
1795
  md: "hidden md:inline",