@orangecheck/design 0.7.6 → 0.9.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
@@ -67,6 +67,11 @@ function resolveTheme(id) {
67
67
  return isKnownTheme(id) ? id : DEFAULT_OC_THEME;
68
68
  }
69
69
  var OC_SKIN_COOKIE = "oc_skin";
70
+ var BLOBS = [1, 2, 3, 4, 5];
71
+ function OcAurora({ intensity, className }) {
72
+ const style = intensity == null ? void 0 : { "--oc-aurora-intensity": String(intensity) };
73
+ return /* @__PURE__ */ jsx("div", { className: cn("oc-aurora", className), style, "aria-hidden": "true", children: BLOBS.map((n) => /* @__PURE__ */ jsx("div", { className: `oc-aurora__blob oc-aurora__blob-${n}` }, n)) });
74
+ }
70
75
  var ONE_YEAR = 60 * 60 * 24 * 365;
71
76
  var ATTR = "data-oc-theme";
72
77
  function readSkinCookie() {
@@ -110,7 +115,11 @@ function applySkinChrome(skin) {
110
115
  if (meta) meta.setAttribute("content", accentFor(skin));
111
116
  }
112
117
  var OcSkinContext = createContext(null);
113
- function OcThemeProvider({ children, defaultSkin = DEFAULT_OC_THEME }) {
118
+ function OcThemeProvider({
119
+ children,
120
+ defaultSkin = DEFAULT_OC_THEME,
121
+ aurora = true
122
+ }) {
114
123
  const [skin, setSkinState] = useState(() => resolveTheme(defaultSkin));
115
124
  const hydratedRef = useRef(false);
116
125
  useEffect(() => {
@@ -148,7 +157,10 @@ function OcThemeProvider({ children, defaultSkin = DEFAULT_OC_THEME }) {
148
157
  () => ({ skin, setSkin, themes: OC_THEMES }),
149
158
  [skin, setSkin]
150
159
  );
151
- return /* @__PURE__ */ jsx(OcSkinContext.Provider, { value, children });
160
+ return /* @__PURE__ */ jsxs(OcSkinContext.Provider, { value, children: [
161
+ aurora !== false && /* @__PURE__ */ jsx(OcAurora, { intensity: typeof aurora === "object" ? aurora.intensity : void 0 }),
162
+ children
163
+ ] });
152
164
  }
153
165
  function useOcSkin() {
154
166
  const ctx = useContext(OcSkinContext);
@@ -1422,6 +1434,141 @@ function PopoverContent({
1422
1434
  function PopoverAnchor({ ...props }) {
1423
1435
  return /* @__PURE__ */ jsx(PopoverPrimitive.Anchor, { "data-slot": "popover-anchor", ...props });
1424
1436
  }
1437
+ var TOOLTIP_SURFACE_CLASS = "bg-popover text-popover-foreground border-border rounded-md border p-2.5 shadow-md";
1438
+ 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";
1439
+ function compose(theirs, ours) {
1440
+ return (e) => {
1441
+ theirs?.(e);
1442
+ ours(e);
1443
+ };
1444
+ }
1445
+ var lastInputWasKeyboard = false;
1446
+ var modalityInstalled = false;
1447
+ function installModalityTracking() {
1448
+ if (modalityInstalled || typeof window === "undefined") return;
1449
+ modalityInstalled = true;
1450
+ window.addEventListener("keydown", () => lastInputWasKeyboard = true, true);
1451
+ window.addEventListener("pointerdown", () => lastInputWasKeyboard = false, true);
1452
+ }
1453
+ function Tooltip({
1454
+ content,
1455
+ children,
1456
+ side = "bottom",
1457
+ align = "start",
1458
+ sideOffset = 8,
1459
+ collisionPadding = 12,
1460
+ openDelay = 300,
1461
+ closeDelay = 90,
1462
+ disabled = false,
1463
+ portal = true,
1464
+ zIndexClassName = "z-50",
1465
+ contentClassName
1466
+ }) {
1467
+ const [hovering, setHovering] = React2.useState(false);
1468
+ const [focusing, setFocusing] = React2.useState(false);
1469
+ const [isFinePointer, setIsFinePointer] = React2.useState(false);
1470
+ const openTimer = React2.useRef(null);
1471
+ const closeTimer = React2.useRef(null);
1472
+ React2.useEffect(() => {
1473
+ installModalityTracking();
1474
+ const mq = window.matchMedia("(hover: hover) and (pointer: fine)");
1475
+ const apply = () => setIsFinePointer(mq.matches);
1476
+ apply();
1477
+ mq.addEventListener("change", apply);
1478
+ return () => mq.removeEventListener("change", apply);
1479
+ }, []);
1480
+ const clearTimers = React2.useCallback(() => {
1481
+ if (openTimer.current) clearTimeout(openTimer.current);
1482
+ if (closeTimer.current) clearTimeout(closeTimer.current);
1483
+ }, []);
1484
+ React2.useEffect(() => clearTimers, [clearTimers]);
1485
+ React2.useEffect(() => {
1486
+ if (disabled) {
1487
+ clearTimers();
1488
+ setHovering(false);
1489
+ }
1490
+ }, [disabled, clearTimers]);
1491
+ const handlePointerEnter = () => {
1492
+ if (!isFinePointer) return;
1493
+ if (closeTimer.current) clearTimeout(closeTimer.current);
1494
+ openTimer.current = setTimeout(() => setHovering(true), openDelay);
1495
+ };
1496
+ const handlePointerLeave = () => {
1497
+ if (openTimer.current) clearTimeout(openTimer.current);
1498
+ closeTimer.current = setTimeout(() => setHovering(false), closeDelay);
1499
+ };
1500
+ const handlePointerDown = () => {
1501
+ clearTimers();
1502
+ setHovering(false);
1503
+ setFocusing(false);
1504
+ };
1505
+ const handleFocus = () => {
1506
+ if (lastInputWasKeyboard) {
1507
+ clearTimers();
1508
+ setFocusing(true);
1509
+ }
1510
+ };
1511
+ const handleBlur = () => {
1512
+ clearTimers();
1513
+ setFocusing(false);
1514
+ };
1515
+ const handleKeyDown = (e) => {
1516
+ if (e.key === "Escape") {
1517
+ clearTimers();
1518
+ setHovering(false);
1519
+ setFocusing(false);
1520
+ }
1521
+ };
1522
+ const effectiveOpen = !disabled && (isFinePointer && hovering || focusing);
1523
+ const extra = {};
1524
+ const childProps = children.props;
1525
+ extra.onPointerEnter = compose(childProps.onPointerEnter, handlePointerEnter);
1526
+ extra.onPointerLeave = compose(childProps.onPointerLeave, handlePointerLeave);
1527
+ extra.onPointerDown = compose(childProps.onPointerDown, handlePointerDown);
1528
+ extra.onFocus = compose(childProps.onFocus, handleFocus);
1529
+ extra.onBlur = compose(childProps.onBlur, handleBlur);
1530
+ extra.onKeyDown = compose(childProps.onKeyDown, handleKeyDown);
1531
+ const trigger = React2.cloneElement(children, extra);
1532
+ const contentEl = /* @__PURE__ */ jsx(
1533
+ PopoverPrimitive.Content,
1534
+ {
1535
+ side,
1536
+ align,
1537
+ sideOffset,
1538
+ collisionPadding,
1539
+ "aria-hidden": true,
1540
+ onOpenAutoFocus: (e) => e.preventDefault(),
1541
+ onCloseAutoFocus: (e) => e.preventDefault(),
1542
+ onFocusOutside: (e) => e.preventDefault(),
1543
+ className: cn(
1544
+ TOOLTIP_SURFACE_CLASS,
1545
+ TOOLTIP_MOTION_CLASS,
1546
+ "pointer-events-none",
1547
+ zIndexClassName,
1548
+ contentClassName
1549
+ ),
1550
+ children: content
1551
+ }
1552
+ );
1553
+ return /* @__PURE__ */ jsxs(
1554
+ PopoverPrimitive.Root,
1555
+ {
1556
+ open: effectiveOpen,
1557
+ onOpenChange: (o) => {
1558
+ if (!o) {
1559
+ clearTimers();
1560
+ setHovering(false);
1561
+ setFocusing(false);
1562
+ }
1563
+ },
1564
+ modal: false,
1565
+ children: [
1566
+ /* @__PURE__ */ jsx(PopoverPrimitive.Anchor, { asChild: true, children: trigger }),
1567
+ portal ? /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: contentEl }) : contentEl
1568
+ ]
1569
+ }
1570
+ );
1571
+ }
1425
1572
  var Accordion = AccordionPrimitive.Root;
1426
1573
  var AccordionItem = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AccordionPrimitive.Item, { ref, className: cn("border-b", className), ...props }));
1427
1574
  AccordionItem.displayName = "AccordionItem";
@@ -2672,6 +2819,31 @@ function MenuCategoryChip({ category }) {
2672
2819
  }
2673
2820
  );
2674
2821
  }
2822
+ function SwitcherTooltipCard({ current }) {
2823
+ const prop = findFamilyProperty(current);
2824
+ return /* @__PURE__ */ jsxs("div", { className: "w-[13rem] max-w-[calc(100vw-1.5rem)]", children: [
2825
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col leading-tight", children: [
2826
+ /* @__PURE__ */ jsxs("span", { className: "flex flex-wrap items-baseline gap-x-1.5", children: [
2827
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-mono text-[9px] tracking-widest uppercase", children: "you\u2019re on" }),
2828
+ /* @__PURE__ */ jsx("span", { className: "text-primary font-display text-[12px] font-semibold tracking-tight", children: prop?.label ?? "orangecheck family" })
2829
+ ] }),
2830
+ prop?.sub && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground mt-0.5 font-mono text-[10px] tracking-wide", children: prop.sub })
2831
+ ] }),
2832
+ /* @__PURE__ */ jsx("div", { className: "border-border -mx-2.5 my-2 border-t" }),
2833
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
2834
+ /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true, className: "text-muted-foreground h-3 w-3 shrink-0" }),
2835
+ /* @__PURE__ */ jsx("span", { className: "text-primary font-mono text-[10px] font-medium tracking-widest uppercase", children: "click" }),
2836
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-mono text-[10px]", children: "\xB7" }),
2837
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-mono text-[10px] tracking-wide", children: "switch site" })
2838
+ ] }),
2839
+ /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex items-center gap-1.5", children: [
2840
+ /* @__PURE__ */ jsx(CornerDownLeft, { "aria-hidden": true, className: "text-muted-foreground h-3 w-3 shrink-0" }),
2841
+ /* @__PURE__ */ jsx("span", { className: "text-primary font-mono text-[10px] font-medium tracking-widest uppercase", children: "double-click" }),
2842
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-mono text-[10px]", children: "\xB7" }),
2843
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-mono text-[10px] tracking-wide", children: "home" })
2844
+ ] })
2845
+ ] });
2846
+ }
2675
2847
  function OcLogoDropdown({
2676
2848
  current,
2677
2849
  homeHref = "/",
@@ -2721,31 +2893,45 @@ function OcLogoDropdown({
2721
2893
  "data-oc-current-category": currentCategory,
2722
2894
  "data-oc-site-state": siteState,
2723
2895
  children: [
2724
- /* @__PURE__ */ jsxs(
2725
- "button",
2896
+ /* @__PURE__ */ jsx(
2897
+ Tooltip,
2726
2898
  {
2727
- type: "button",
2728
- "aria-haspopup": "menu",
2729
- "aria-expanded": open,
2730
- "aria-controls": menuId,
2731
- "aria-label": "OrangeCheck family \xB7 click to open property menu, double-click to go home",
2732
- title: "single-click \xB7 family menu \xB7 double-click \xB7 go home",
2733
- onClick: handleTriggerClick,
2734
- 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" : ""),
2735
- "data-oc-logo-dropdown-trigger": "",
2736
- "data-oc-logo-dropdown-open": open ? "true" : "false",
2737
- children: [
2738
- children,
2739
- /* @__PURE__ */ jsx(CategoryChip, { category: currentCategory }),
2740
- /* @__PURE__ */ jsx(SiteStateBadge, { state: siteState }),
2741
- /* @__PURE__ */ jsx(
2742
- ChevronDown,
2743
- {
2744
- "aria-hidden": true,
2745
- 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" : "")
2746
- }
2747
- )
2748
- ]
2899
+ content: /* @__PURE__ */ jsx(SwitcherTooltipCard, { current }),
2900
+ disabled: open,
2901
+ side: "bottom",
2902
+ align: "start",
2903
+ sideOffset: 8,
2904
+ zIndexClassName: "z-[70]",
2905
+ children: /* @__PURE__ */ jsxs(
2906
+ "button",
2907
+ {
2908
+ type: "button",
2909
+ "aria-haspopup": "menu",
2910
+ "aria-expanded": open,
2911
+ "aria-controls": menuId,
2912
+ "aria-label": "orangecheck family menu",
2913
+ onClick: handleTriggerClick,
2914
+ className: cn(
2915
+ // focus indicator is guaranteed even if a consumer overrides triggerClassName
2916
+ "focus-visible:ring-primary/60 rounded-sm focus-visible:ring-2 focus-visible:outline-none",
2917
+ 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" : "")
2918
+ ),
2919
+ "data-oc-logo-dropdown-trigger": "",
2920
+ "data-oc-logo-dropdown-open": open ? "true" : "false",
2921
+ children: [
2922
+ children,
2923
+ /* @__PURE__ */ jsx(CategoryChip, { category: currentCategory }),
2924
+ /* @__PURE__ */ jsx(SiteStateBadge, { state: siteState }),
2925
+ /* @__PURE__ */ jsx(
2926
+ ChevronDown,
2927
+ {
2928
+ "aria-hidden": true,
2929
+ 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" : "")
2930
+ }
2931
+ )
2932
+ ]
2933
+ }
2934
+ )
2749
2935
  }
2750
2936
  ),
2751
2937
  /* @__PURE__ */ jsxs(
@@ -2774,7 +2960,7 @@ function OcLogoDropdown({
2774
2960
  {
2775
2961
  id: menuId,
2776
2962
  role: "menu",
2777
- "aria-label": "OrangeCheck family",
2963
+ "aria-label": "orangecheck family",
2778
2964
  className: popoverClassName ?? "bg-background absolute top-full left-0 z-[60] mt-2 w-[min(20rem,calc(100vw-1rem))] border shadow-lg",
2779
2965
  "data-oc-logo-dropdown-popover": "",
2780
2966
  children: [
@@ -3930,6 +4116,6 @@ function LayoutSubHeader({
3930
4116
  ] }) });
3931
4117
  }
3932
4118
 
3933
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertTitle, AlertWithAction, AlertWithCountdown, AppShell, Badge, Bar, BitcoinAddress, Button, Callout, Card, Checkbox, ConfirmHost, CopyButton, DEFAULT_OC_THEME, DataRow, DefinitionList, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, EcosystemSwitcher, EmptyState, ErrorBoundary, FAMILY_PROPERTIES, HelpHint, Input, Label, LayoutSubHeader, Modal, OC_DEFAULT_ACCENT, OC_SKIN_COOKIE, OC_THEMES, OcAccountMenu, OcAccountMenuView, OcAppearanceMenu, OcDashboardHub, OcDashboardShell, OcLogoDropdown, OcPrimaryNav, OcThemeBridge, OcThemePicker, OcThemeProvider, Pagination, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PromptHost, QrCode, REFERENCE_BTC_USD, RadioGroup, RadioGroupItem, SITE_STATE_LABEL, SatsAmount, SectionHeader, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Skeleton, Sparkline, StatBlock, StatCard, StatGrid, StatTile, StatusPill, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeToggle, ThemeToggleLink, Toaster, Working, WorkingPanel, accentFor, asOf, badgeVariants, buttonVariants, cn, confirm, explorerUrl, findFamilyProperty, formatSats, formatSatsCompact, getOcThemeInitScript, isKnownTheme, makeStatusPill, priceBoth, prompt, relativeTime, resolveTheme, satsToUsd, shortenAddress, usdToSats, useOcSkin, useSpotPrice };
4119
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertTitle, AlertWithAction, AlertWithCountdown, AppShell, Badge, Bar, BitcoinAddress, Button, Callout, Card, Checkbox, ConfirmHost, CopyButton, DEFAULT_OC_THEME, DataRow, DefinitionList, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, EcosystemSwitcher, EmptyState, ErrorBoundary, FAMILY_PROPERTIES, HelpHint, Input, Label, LayoutSubHeader, Modal, OC_DEFAULT_ACCENT, OC_SKIN_COOKIE, OC_THEMES, OcAccountMenu, OcAccountMenuView, OcAppearanceMenu, OcAurora, OcDashboardHub, OcDashboardShell, OcLogoDropdown, OcPrimaryNav, OcThemeBridge, OcThemePicker, OcThemeProvider, Pagination, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PromptHost, QrCode, REFERENCE_BTC_USD, RadioGroup, RadioGroupItem, SITE_STATE_LABEL, SatsAmount, SectionHeader, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Skeleton, Sparkline, StatBlock, StatCard, StatGrid, StatTile, StatusPill, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeToggle, ThemeToggleLink, Toaster, Tooltip, Working, WorkingPanel, accentFor, asOf, badgeVariants, buttonVariants, cn, confirm, explorerUrl, findFamilyProperty, formatSats, formatSatsCompact, getOcThemeInitScript, isKnownTheme, makeStatusPill, priceBoth, prompt, relativeTime, resolveTheme, satsToUsd, shortenAddress, usdToSats, useOcSkin, useSpotPrice };
3934
4120
  //# sourceMappingURL=index.mjs.map
3935
4121
  //# sourceMappingURL=index.mjs.map