@orangecheck/design 0.14.1 → 0.16.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.mjs CHANGED
@@ -4,7 +4,7 @@ import * as React2 from 'react';
4
4
  import { createContext, useState, useRef, useEffect, useCallback, useMemo, useContext, Fragment as Fragment$1, useId } from 'react';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
6
  import { useTheme } from 'next-themes';
7
- import { ChevronDown, Palette, Check, Sun, Moon, Monitor, CheckIcon, CircleIcon, X, XIcon, AlertTriangle, Pencil, ChevronLeft, ChevronRight, ChevronDownIcon, ChevronUpIcon, Maximize2, Copy, HelpCircle, Boxes, CornerDownLeft, Plus, Loader2 } from 'lucide-react';
7
+ import { ChevronDown, Palette, Check, Sun, Moon, Monitor, CheckIcon, CircleIcon, X, XIcon, AlertTriangle, Pencil, ChevronLeft, ChevronRight, ChevronDownIcon, ChevronUpIcon, Maximize2, Copy, HelpCircle, Boxes, CornerDownLeft, Plus, Loader2, Menu } from 'lucide-react';
8
8
  import { Slot } from '@radix-ui/react-slot';
9
9
  import { cva } from 'class-variance-authority';
10
10
  import * as LabelPrimitive from '@radix-ui/react-label';
@@ -3325,7 +3325,11 @@ function OcAccountMenu(props) {
3325
3325
  // context (oc-www) can opt in incrementally.
3326
3326
  roster: session.roster,
3327
3327
  switchAccount: session.switchAccount,
3328
- addAccountUrl: session.addAccountUrl
3328
+ addAccountUrl: session.addAccountUrl,
3329
+ // Structural read keeps the auth-client peer floor at
3330
+ // ^2.17.0 — `tabPinned` ships in 2.18.0 and is simply
3331
+ // undefined (no hint) on older providers.
3332
+ tabPinned: session.tabPinned
3329
3333
  }
3330
3334
  }
3331
3335
  );
@@ -3354,7 +3358,8 @@ function OcAccountMenuView({
3354
3358
  setDisplayIdentity,
3355
3359
  roster,
3356
3360
  switchAccount,
3357
- addAccountUrl
3361
+ addAccountUrl,
3362
+ tabPinned
3358
3363
  } = session;
3359
3364
  const [hydrated, setHydrated] = useState(false);
3360
3365
  const [open, setOpen] = useState(false);
@@ -3424,11 +3429,11 @@ function OcAccountMenuView({
3424
3429
  "aria-haspopup": "menu",
3425
3430
  "aria-expanded": open,
3426
3431
  "aria-label": `Signed in as ${account.didOc}. Open account menu.`,
3427
- className: triggerClassName ?? "border-primary/40 bg-card hover:bg-accent inline-flex h-8 items-center gap-1.5 rounded-md border px-3 font-mono text-[11px] tracking-wide transition-colors",
3432
+ className: triggerClassName ?? "border-primary/40 bg-card hover:bg-accent inline-flex h-8 items-center gap-1.5 rounded-md border px-2 font-mono text-[11px] tracking-wide transition-colors sm:px-3",
3428
3433
  "data-oc-account-menu-trigger": "",
3429
3434
  children: [
3430
- /* @__PURE__ */ jsx("span", { className: "bg-primary inline-block size-1.5 rounded-full", "aria-hidden": true }),
3431
- /* @__PURE__ */ jsx("span", { className: "text-foreground", children: label }),
3435
+ /* @__PURE__ */ jsx("span", { className: "bg-primary inline-block size-1.5 shrink-0 rounded-full", "aria-hidden": true }),
3436
+ /* @__PURE__ */ jsx("span", { className: "text-foreground hidden max-w-[16ch] truncate sm:inline", children: label }),
3432
3437
  /* @__PURE__ */ jsx(
3433
3438
  "svg",
3434
3439
  {
@@ -3463,7 +3468,19 @@ function OcAccountMenuView({
3463
3468
  /* @__PURE__ */ jsxs("div", { className: "border-border border-b p-3", children: [
3464
3469
  /* @__PURE__ */ jsxs("div", { className: "text-primary mb-1 font-mono text-[10px] tracking-widest uppercase", children: [
3465
3470
  "\xA7 signed in \xB7 ",
3466
- hostname
3471
+ hostname,
3472
+ tabPinned ? /* @__PURE__ */ jsxs(
3473
+ "span",
3474
+ {
3475
+ className: "text-muted-foreground/70 normal-case",
3476
+ "data-oc-account-menu-tab-pin": "",
3477
+ title: "This tab keeps this account even if you switch accounts in another tab",
3478
+ children: [
3479
+ " ",
3480
+ "\xB7 this tab"
3481
+ ]
3482
+ }
3483
+ ) : null
3467
3484
  ] }),
3468
3485
  /* @__PURE__ */ jsx(CopyableDid, { did: account.didOc }),
3469
3486
  displayName ? /* @__PURE__ */ jsx("div", { className: "text-muted-foreground/80 mt-1 font-mono text-[10px] tracking-wide", children: displayName }) : null
@@ -3818,54 +3835,146 @@ function isActive(pathname, link) {
3818
3835
  if (link.href === "/") return pathname === "/";
3819
3836
  return pathname === link.href || pathname.startsWith(link.href + "/");
3820
3837
  }
3838
+ function ExternalGlyph() {
3839
+ return /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-muted-foreground/60 ml-1 text-[9px]", children: "\u2197" });
3840
+ }
3821
3841
  function OcPrimaryNav({
3822
3842
  activePath,
3823
3843
  links,
3824
3844
  className
3825
3845
  }) {
3826
- return /* @__PURE__ */ jsx(
3827
- "nav",
3846
+ const [open, setOpen] = useState(false);
3847
+ const ref = useRef(null);
3848
+ const menuId = useId();
3849
+ useEffect(() => {
3850
+ setOpen(false);
3851
+ }, [activePath]);
3852
+ useEffect(() => {
3853
+ if (!open) return;
3854
+ const onClick = (e) => {
3855
+ if (ref.current && !ref.current.contains(e.target)) setOpen(false);
3856
+ };
3857
+ const onKey = (e) => {
3858
+ if (e.key === "Escape") setOpen(false);
3859
+ };
3860
+ document.addEventListener("mousedown", onClick);
3861
+ document.addEventListener("keydown", onKey);
3862
+ return () => {
3863
+ document.removeEventListener("mousedown", onClick);
3864
+ document.removeEventListener("keydown", onKey);
3865
+ };
3866
+ }, [open]);
3867
+ const inlineClass = (active) => "font-display shrink-0 px-2 py-1 sm:px-3 text-[11px] sm:text-[12px] font-semibold tracking-wider uppercase transition-colors " + (active ? "text-primary" : "text-muted-foreground hover:text-foreground");
3868
+ const rowClass = (active) => "font-display flex items-center gap-2 px-3 py-2 text-[12px] font-semibold tracking-wider uppercase transition-colors " + (active ? "text-primary" : "text-muted-foreground hover:text-foreground hover:bg-accent");
3869
+ function renderInline(link) {
3870
+ const active = isActive(activePath, link);
3871
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
3872
+ link.label,
3873
+ link.external ? /* @__PURE__ */ jsx(ExternalGlyph, {}) : null
3874
+ ] });
3875
+ return link.external ? /* @__PURE__ */ jsx(
3876
+ "a",
3877
+ {
3878
+ href: link.href,
3879
+ target: "_blank",
3880
+ rel: "noreferrer",
3881
+ className: inlineClass(false),
3882
+ "data-oc-primary-nav-item": "",
3883
+ children: inner
3884
+ },
3885
+ link.href
3886
+ ) : /* @__PURE__ */ jsx(
3887
+ Link6,
3888
+ {
3889
+ href: link.href,
3890
+ "aria-current": active ? "page" : void 0,
3891
+ className: inlineClass(active),
3892
+ "data-oc-primary-nav-item": active ? "active" : "sibling",
3893
+ children: inner
3894
+ },
3895
+ link.href
3896
+ );
3897
+ }
3898
+ function renderRow(link) {
3899
+ const active = isActive(activePath, link);
3900
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
3901
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "\u2192" }),
3902
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: link.label }),
3903
+ link.external ? /* @__PURE__ */ jsx(ExternalGlyph, {}) : null
3904
+ ] });
3905
+ return link.external ? /* @__PURE__ */ jsx(
3906
+ "a",
3907
+ {
3908
+ href: link.href,
3909
+ target: "_blank",
3910
+ rel: "noreferrer",
3911
+ role: "menuitem",
3912
+ onClick: () => setOpen(false),
3913
+ className: rowClass(false),
3914
+ "data-oc-primary-nav-item": "",
3915
+ children: inner
3916
+ },
3917
+ link.href
3918
+ ) : /* @__PURE__ */ jsx(
3919
+ Link6,
3920
+ {
3921
+ href: link.href,
3922
+ role: "menuitem",
3923
+ "aria-current": active ? "page" : void 0,
3924
+ onClick: () => setOpen(false),
3925
+ className: rowClass(active),
3926
+ "data-oc-primary-nav-item": active ? "active" : "sibling",
3927
+ children: inner
3928
+ },
3929
+ link.href
3930
+ );
3931
+ }
3932
+ return /* @__PURE__ */ jsxs(
3933
+ "div",
3828
3934
  {
3829
- "aria-label": "primary",
3830
- className: "flex min-w-0 items-center justify-start overflow-x-auto gap-0.5 sm:gap-1 whitespace-nowrap [scrollbar-width:none] [&::-webkit-scrollbar]:hidden " + (className ?? ""),
3935
+ ref,
3936
+ className: "relative flex items-center justify-center " + (className ?? ""),
3831
3937
  "data-oc-primary-nav": "",
3832
- children: links.map((link) => {
3833
- const active = isActive(activePath, link);
3834
- const className2 = "font-display shrink-0 px-2 py-1 sm:px-3 text-[11px] sm:text-[12px] font-semibold tracking-wider uppercase transition-colors " + (active ? "text-primary" : "text-muted-foreground hover:text-foreground");
3835
- const content = /* @__PURE__ */ jsxs(Fragment, { children: [
3836
- link.label,
3837
- link.external ? /* @__PURE__ */ jsx(
3838
- "span",
3938
+ children: [
3939
+ /* @__PURE__ */ jsx(
3940
+ "nav",
3941
+ {
3942
+ "aria-label": "primary",
3943
+ className: "hidden items-center gap-0.5 sm:gap-1 md:flex",
3944
+ children: links.map(renderInline)
3945
+ }
3946
+ ),
3947
+ /* @__PURE__ */ jsxs("div", { className: "md:hidden", children: [
3948
+ /* @__PURE__ */ jsx(
3949
+ "button",
3839
3950
  {
3840
- "aria-hidden": true,
3841
- className: "text-muted-foreground/60 ml-1 text-[9px]",
3842
- children: "\u2197"
3951
+ type: "button",
3952
+ onClick: () => setOpen((v) => !v),
3953
+ "aria-haspopup": "menu",
3954
+ "aria-expanded": open,
3955
+ "aria-controls": menuId,
3956
+ "aria-label": "site navigation",
3957
+ className: "border-input bg-background hover:bg-accent text-muted-foreground inline-flex size-8 items-center justify-center rounded-md border transition-colors",
3958
+ "data-oc-primary-nav-toggle": "",
3959
+ children: open ? /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": true }) : /* @__PURE__ */ jsx(Menu, { className: "size-4", "aria-hidden": true })
3843
3960
  }
3844
- ) : null
3845
- ] });
3846
- return link.external ? /* @__PURE__ */ jsx(
3847
- "a",
3848
- {
3849
- href: link.href,
3850
- target: "_blank",
3851
- rel: "noreferrer",
3852
- className: className2,
3853
- "data-oc-primary-nav-item": "",
3854
- children: content
3855
- },
3856
- link.href
3857
- ) : /* @__PURE__ */ jsx(
3858
- Link6,
3859
- {
3860
- href: link.href,
3861
- "aria-current": active ? "page" : void 0,
3862
- className: className2,
3863
- "data-oc-primary-nav-item": active ? "active" : "sibling",
3864
- children: content
3865
- },
3866
- link.href
3867
- );
3868
- })
3961
+ ),
3962
+ open && /* @__PURE__ */ jsxs(
3963
+ "div",
3964
+ {
3965
+ id: menuId,
3966
+ role: "menu",
3967
+ "aria-label": "primary",
3968
+ className: "border-border bg-popover text-popover-foreground absolute top-[calc(100%+8px)] left-1/2 z-50 w-[min(15rem,calc(100vw-1rem))] -translate-x-1/2 border p-1 shadow-xl",
3969
+ "data-oc-primary-nav-popover": "",
3970
+ children: [
3971
+ /* @__PURE__ */ jsx("div", { className: "text-muted-foreground/60 px-3 pt-2 pb-1 font-mono text-[10px] tracking-widest uppercase", children: "\xA7 navigate" }),
3972
+ links.map(renderRow)
3973
+ ]
3974
+ }
3975
+ )
3976
+ ] })
3977
+ ]
3869
3978
  }
3870
3979
  );
3871
3980
  }
@@ -4162,13 +4271,19 @@ function LayoutSubHeader({
4162
4271
  noHeartbeat = false,
4163
4272
  className
4164
4273
  }) {
4165
- return /* @__PURE__ */ jsx("div", { className: cn("border-b", className), children: /* @__PURE__ */ jsxs("div", { className: "container flex flex-wrap items-center justify-between gap-x-6 gap-y-1 py-2 font-mono text-[11px]", children: [
4166
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
4167
- !noHeartbeat && /* @__PURE__ */ jsx("span", { className: "bg-primary inline-block h-1.5 w-1.5 animate-pulse rounded-full" }),
4168
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground tracking-widest uppercase", children: status }),
4169
- /* @__PURE__ */ jsx("span", { className: "text-foreground", children: product })
4274
+ return /* @__PURE__ */ jsx("div", { className: cn("oc-substrip border-b", className), children: /* @__PURE__ */ jsxs("div", { className: "container flex items-center justify-between gap-x-6 py-2 font-mono text-[11px]", children: [
4275
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [
4276
+ !noHeartbeat && /* @__PURE__ */ jsx(
4277
+ "span",
4278
+ {
4279
+ className: "bg-primary inline-block size-1.5 shrink-0 animate-pulse rounded-full ring-2 ring-[color-mix(in_oklch,var(--primary),transparent_78%)]",
4280
+ "aria-hidden": true
4281
+ }
4282
+ ),
4283
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground hidden tracking-widest whitespace-nowrap uppercase sm:inline", children: status }),
4284
+ /* @__PURE__ */ jsx("span", { className: "text-foreground truncate", children: product })
4170
4285
  ] }),
4171
- tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground flex flex-wrap items-center gap-x-4 gap-y-1 tracking-widest uppercase", children: tags.map((tag, i) => /* @__PURE__ */ jsx("span", { className: tag.hideBelow ? HIDE[tag.hideBelow] : void 0, children: tag.label }, i)) })
4286
+ tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground/55 hidden shrink-0 items-center gap-x-3 tracking-wider whitespace-nowrap uppercase sm:flex", children: tags.map((tag, i) => /* @__PURE__ */ jsx("span", { className: tag.hideBelow ? HIDE[tag.hideBelow] : void 0, children: tag.label }, i)) })
4172
4287
  ] }) });
4173
4288
  }
4174
4289
  function OcAppBar({