@orangecheck/app-design 1.4.1 → 1.5.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.
@@ -1,10 +1,10 @@
1
- import { forwardRef, createContext, useContext, useState, useEffect, createElement, useRef, Children, isValidElement, cloneElement, useCallback, useMemo, Component, useId, useSyncExternalStore, Fragment as Fragment$1 } from 'react';
1
+ import { forwardRef, createContext, useContext, useState, useEffect, createElement, useRef, Children, isValidElement, cloneElement, useCallback, useMemo, Component, useSyncExternalStore, useId, Fragment as Fragment$1 } from 'react';
2
2
  import { clsx } from 'clsx';
3
3
  import { extendTailwindMerge } from 'tailwind-merge';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { cva } from 'class-variance-authority';
6
6
  import * as TabsPrimitive from '@radix-ui/react-tabs';
7
- import { ChevronDown, Check, Search, Copy, ArrowUpRight, ArrowRight, ChevronRight, CornerDownLeft, Download, FileText, Upload, ArrowLeft, Lock, CircleDashed, CircleMinus, CircleSlash, Clock, CircleX, CircleCheck } from 'lucide-react';
7
+ import { ChevronDown, Check, Search, Copy, Lock, ArrowUpRight, ArrowRight, ChevronRight, CornerDownLeft, Download, FileText, Upload, ArrowLeft, CircleDashed, CircleMinus, CircleSlash, Clock, CircleX, CircleCheck } from 'lucide-react';
8
8
  import { Slot } from '@radix-ui/react-slot';
9
9
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
10
10
  import 'next-themes';
@@ -532,7 +532,7 @@ var JS_TAG = /<\/?(?=[A-Za-z])/y;
532
532
  var JS_TAG_NAME = /[A-Za-z][\w$.:-]*/y;
533
533
  var JS_PUNCT = /=>|\.\.\.|[{}()[\];,.<>=+\-*/%!?:&|^~#]/y;
534
534
  var JSX_BEFORE = /* @__PURE__ */ new Set(["(", ",", "=", "?", ":", "{", "[", ";", ">", "&&", "||", "=>", "return"]);
535
- function scanJs(src, emit, jsx35) {
535
+ function scanJs(src, emit, jsx36) {
536
536
  let i = 0;
537
537
  let prev = "";
538
538
  let tagDepth = 0;
@@ -558,7 +558,7 @@ function scanJs(src, emit, jsx35) {
558
558
  sig('"');
559
559
  continue;
560
560
  }
561
- if (jsx35 && tagDepth === 0 && (m = at(JS_TAG, src, i)) && (prev === "" || JSX_BEFORE.has(prev))) {
561
+ if (jsx36 && tagDepth === 0 && (m = at(JS_TAG, src, i)) && (prev === "" || JSX_BEFORE.has(prev))) {
562
562
  const name = at(JS_TAG_NAME, src, i + m.length);
563
563
  if (name) {
564
564
  emit(m);
@@ -570,7 +570,7 @@ function scanJs(src, emit, jsx35) {
570
570
  continue;
571
571
  }
572
572
  }
573
- if (jsx35 && tagDepth > 0 && braceInTag === 0) {
573
+ if (jsx36 && tagDepth > 0 && braceInTag === 0) {
574
574
  if (src.startsWith("/>", i) || src[i] === ">") {
575
575
  const close = src[i] === ">" ? ">" : "/>";
576
576
  emit(close);
@@ -590,7 +590,7 @@ function scanJs(src, emit, jsx35) {
590
590
  continue;
591
591
  }
592
592
  if (src[i] === "{") braceInTag = 1;
593
- } else if (jsx35 && tagDepth > 0 && braceInTag > 0) {
593
+ } else if (jsx36 && tagDepth > 0 && braceInTag > 0) {
594
594
  if (src[i] === "{") braceInTag++;
595
595
  else if (src[i] === "}") braceInTag--;
596
596
  }
@@ -2474,6 +2474,131 @@ function ErrorPage({
2474
2474
  art !== null ? /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "oca-enter hidden justify-center md:col-span-5 md:flex [--enter-delay:120ms]", children: art ?? /* @__PURE__ */ jsx(MarkOutline, { className: "w-full max-w-[20rem] text-oca-hairline-strong" }) }) : null
2475
2475
  ] }) });
2476
2476
  }
2477
+ function onSecond(tick) {
2478
+ const id = setInterval(tick, 1e3);
2479
+ return () => clearInterval(id);
2480
+ }
2481
+ var nowSeconds = () => Math.floor(Date.now() / 1e3);
2482
+ function CountdownRing({
2483
+ period,
2484
+ remaining,
2485
+ warnAt = 5,
2486
+ size = 18,
2487
+ showSeconds = true,
2488
+ className
2489
+ }) {
2490
+ const now = useSyncExternalStore(onSecond, nowSeconds, () => null);
2491
+ const left = remaining ?? (now === null ? null : period - now % period);
2492
+ const share = left === null ? 1 : Math.max(0, Math.min(1, left / period));
2493
+ const warn = left !== null && left <= warnAt;
2494
+ const r = size / 2 - 1.5;
2495
+ const c = 2 * Math.PI * r;
2496
+ return /* @__PURE__ */ jsxs(
2497
+ "span",
2498
+ {
2499
+ role: "timer",
2500
+ "aria-label": left === null ? void 0 : `${left} second${left === 1 ? "" : "s"} left`,
2501
+ className: cn("inline-flex items-center gap-1.5", warn ? "text-destructive" : "text-muted-foreground", className),
2502
+ children: [
2503
+ /* @__PURE__ */ jsxs("svg", { "aria-hidden": true, width: size, height: size, viewBox: `0 0 ${size} ${size}`, className: "-rotate-90", children: [
2504
+ /* @__PURE__ */ jsx("circle", { cx: size / 2, cy: size / 2, r, fill: "none", stroke: "var(--border)", strokeWidth: 2 }),
2505
+ /* @__PURE__ */ jsx(
2506
+ "circle",
2507
+ {
2508
+ cx: size / 2,
2509
+ cy: size / 2,
2510
+ r,
2511
+ fill: "none",
2512
+ stroke: "currentColor",
2513
+ strokeWidth: 2,
2514
+ strokeLinecap: "round",
2515
+ strokeDasharray: c,
2516
+ strokeDashoffset: c * (1 - share),
2517
+ className: cn(left !== null && left < period && "transition-[stroke-dashoffset] duration-1000 ease-linear motion-reduce:transition-none")
2518
+ }
2519
+ )
2520
+ ] }),
2521
+ showSeconds && left !== null ? /* @__PURE__ */ jsxs("span", { className: "text-[0.8125rem] oca-tabular", children: [
2522
+ left,
2523
+ "s"
2524
+ ] }) : null
2525
+ ]
2526
+ }
2527
+ );
2528
+ }
2529
+ function PlanCard({
2530
+ name,
2531
+ subtitle,
2532
+ price,
2533
+ period,
2534
+ footnote,
2535
+ features = [],
2536
+ action,
2537
+ badge,
2538
+ badgeTone = "neutral",
2539
+ highlight: highlight2 = false,
2540
+ className
2541
+ }) {
2542
+ return /* @__PURE__ */ jsxs(
2543
+ "section",
2544
+ {
2545
+ className: cn(
2546
+ "flex h-full flex-col gap-5 rounded-[1.25rem] border bg-card p-6",
2547
+ highlight2 ? "border-foreground shadow-sm ring-1 ring-foreground" : "border-border",
2548
+ className
2549
+ ),
2550
+ children: [
2551
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
2552
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
2553
+ /* @__PURE__ */ jsx("h3", { className: "text-[1.0625rem] font-medium leading-snug", children: name }),
2554
+ badge ? /* @__PURE__ */ jsx(Badge, { tone: badgeTone, children: badge }) : null
2555
+ ] }),
2556
+ subtitle ? /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] leading-snug text-muted-foreground", children: subtitle }) : null
2557
+ ] }),
2558
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
2559
+ /* @__PURE__ */ jsxs("p", { className: "flex flex-wrap items-baseline gap-x-1.5", children: [
2560
+ /* @__PURE__ */ jsx("span", { className: "oca-display-3 oca-tabular", children: price }),
2561
+ period ? /* @__PURE__ */ jsx("span", { className: "text-[0.9375rem] text-muted-foreground", children: period }) : null
2562
+ ] }),
2563
+ footnote ? /* @__PURE__ */ jsx("p", { className: "text-[0.8125rem] text-muted-foreground", children: footnote }) : null
2564
+ ] }),
2565
+ features.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-2.5 text-[0.9375rem]", children: features.map((f, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2.5", children: [
2566
+ /* @__PURE__ */ jsx(Check, { "aria-hidden": true, className: "mt-1 size-4 shrink-0 text-muted-foreground" }),
2567
+ /* @__PURE__ */ jsx("span", { className: "min-w-0", children: f })
2568
+ ] }, i)) }) : null,
2569
+ action ? /* @__PURE__ */ jsx("div", { className: "mt-auto flex flex-col pt-1 [&>*]:w-full", children: action }) : null
2570
+ ]
2571
+ }
2572
+ );
2573
+ }
2574
+ function LockedPreview({
2575
+ title,
2576
+ description,
2577
+ action,
2578
+ children,
2579
+ className
2580
+ }) {
2581
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
2582
+ children ? /* @__PURE__ */ jsx(
2583
+ "div",
2584
+ {
2585
+ inert: true,
2586
+ "aria-hidden": true,
2587
+ "data-oca-locked": "",
2588
+ className: "pointer-events-none max-h-[28rem] select-none overflow-hidden [mask-image:linear-gradient(to_bottom,#000_25%,transparent_85%)]",
2589
+ children
2590
+ }
2591
+ ) : null,
2592
+ /* @__PURE__ */ jsxs("div", { className: cn("relative mx-auto flex max-w-md flex-col items-center gap-4 rounded-[1.25rem] border border-border bg-card px-6 py-7 text-center shadow-sm", children && "-mt-40"), children: [
2593
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "flex size-10 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ jsx(Lock, { className: "size-[1.125rem]" }) }),
2594
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
2595
+ /* @__PURE__ */ jsx("p", { className: "text-[1.0625rem] font-medium leading-snug", children: title }),
2596
+ description ? /* @__PURE__ */ jsx("p", { className: "text-[0.9375rem] leading-snug text-muted-foreground", children: description }) : null
2597
+ ] }),
2598
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap justify-center gap-2", children: action })
2599
+ ] })
2600
+ ] });
2601
+ }
2477
2602
  function IsoCheck({ size = 360, settle = false, shadow = true, tilt = false, title, className }) {
2478
2603
  const ref = useRef(null);
2479
2604
  useEffect(() => {
@@ -3934,6 +4059,7 @@ function SearchDialog({
3934
4059
  idle,
3935
4060
  defaultQuery = "",
3936
4061
  debounceMs = 120,
4062
+ browse = false,
3937
4063
  className
3938
4064
  }) {
3939
4065
  const [own, setOwn] = useState(false);
@@ -3970,7 +4096,7 @@ function SearchDialog({
3970
4096
  }, [hotkey]);
3971
4097
  useEffect(() => {
3972
4098
  const q = query.trim();
3973
- if (!q) {
4099
+ if (!q && !(browse && open)) {
3974
4100
  setGroups([]);
3975
4101
  setState("idle");
3976
4102
  return;
@@ -3992,14 +4118,15 @@ function SearchDialog({
3992
4118
  clearTimeout(t);
3993
4119
  ctl.abort();
3994
4120
  };
3995
- }, [query, debounceMs]);
4121
+ }, [query, debounceMs, browse, open]);
3996
4122
  useEffect(() => {
3997
4123
  listRef.current?.querySelector('[aria-selected="true"]')?.scrollIntoView({ block: "nearest" });
3998
4124
  }, [active]);
3999
4125
  const choose = (r) => {
4000
4126
  setOpen(false);
4001
- if (onSelect) onSelect(r);
4002
- else window.location.assign(r.href);
4127
+ if (r.run) r.run();
4128
+ else if (onSelect) onSelect(r);
4129
+ else if (r.href) window.location.assign(r.href);
4003
4130
  };
4004
4131
  const optionId = (i) => `${listId}-o${i}`;
4005
4132
  const showList = state === "done" && flat.length > 0;
@@ -4070,25 +4197,28 @@ function SearchDialog({
4070
4197
  index++;
4071
4198
  const i = index;
4072
4199
  const on = i === active;
4200
+ const Option = r.href ? "a" : "div";
4073
4201
  return /* @__PURE__ */ jsxs(
4074
- "a",
4202
+ Option,
4075
4203
  {
4076
4204
  id: optionId(i),
4077
- href: r.href,
4205
+ ...r.href ? { href: r.href } : {},
4078
4206
  role: "option",
4079
4207
  "aria-selected": on,
4080
4208
  tabIndex: -1,
4081
4209
  onMouseMove: () => setActive(i),
4082
4210
  onClick: (e) => {
4083
- if (e.metaKey || e.ctrlKey || e.shiftKey) return;
4211
+ if (r.href && (e.metaKey || e.ctrlKey || e.shiftKey)) return;
4084
4212
  e.preventDefault();
4085
4213
  choose(r);
4086
4214
  },
4087
4215
  className: cn(
4088
4216
  "flex items-start gap-3 rounded-xl px-3 py-2.5 transition-colors",
4089
- on ? "bg-accent" : "hover:bg-accent"
4217
+ on ? "bg-accent" : "hover:bg-accent",
4218
+ !r.href && "cursor-pointer"
4090
4219
  ),
4091
4220
  children: [
4221
+ r.icon ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "mt-0.5 flex size-5 shrink-0 items-center justify-center text-muted-foreground [&_svg]:size-[1.0625rem]", children: r.icon }) : null,
4092
4222
  /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
4093
4223
  /* @__PURE__ */ jsx("span", { className: "truncate text-[0.9375rem] font-medium text-foreground", children: r.title }),
4094
4224
  r.section ? /* @__PURE__ */ jsx("span", { className: "truncate text-[0.8125rem] text-muted-foreground", children: r.section }) : null,
@@ -4100,6 +4230,7 @@ function SearchDialog({
4100
4230
  }
4101
4231
  ) : r.excerpt ? /* @__PURE__ */ jsx("span", { className: "line-clamp-2 text-[0.875rem] leading-snug text-muted-foreground", children: r.excerpt }) : null
4102
4232
  ] }),
4233
+ r.meta ? /* @__PURE__ */ jsx("span", { className: "mt-0.5 shrink-0 text-[0.8125rem] text-muted-foreground", children: r.meta }) : null,
4103
4234
  /* @__PURE__ */ jsx(CornerDownLeft, { "aria-hidden": true, className: cn("mt-1 size-4 shrink-0 text-muted-foreground", !on && "invisible") })
4104
4235
  ]
4105
4236
  },
@@ -4108,11 +4239,11 @@ function SearchDialog({
4108
4239
  })
4109
4240
  ] }, gi)) }),
4110
4241
  state === "idle" ? /* @__PURE__ */ jsx("div", { className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: idle ?? "Type a word: a protocol, a function, an error." }) : null,
4111
- state === "done" && flat.length === 0 ? /* @__PURE__ */ jsxs("p", { role: "status", className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: [
4242
+ state === "done" && flat.length === 0 ? /* @__PURE__ */ jsx("p", { role: "status", className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: query.trim() ? /* @__PURE__ */ jsxs(Fragment, { children: [
4112
4243
  "No results for \u201C",
4113
4244
  query.trim(),
4114
4245
  "\u201D."
4115
- ] }) : null,
4246
+ ] }) : "Nothing here yet." }) : null,
4116
4247
  state === "error" ? /* @__PURE__ */ jsx("p", { role: "status", className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: "Search is not available right now. Try again in a moment." }) : null
4117
4248
  ] }),
4118
4249
  /* @__PURE__ */ jsxs("div", { "aria-hidden": true, className: "hidden shrink-0 items-center gap-4 border-t border-border px-5 py-2.5 text-[0.75rem] text-muted-foreground sm:flex", children: [
@@ -4137,6 +4268,13 @@ function SearchDialog({
4137
4268
  ] }) })
4138
4269
  ] });
4139
4270
  }
4271
+ function CommandDialog({
4272
+ label = "Commands",
4273
+ placeholder = "Search, or run a command",
4274
+ ...props
4275
+ }) {
4276
+ return /* @__PURE__ */ jsx(SearchDialog, { ...props, label, placeholder, button: false, browse: true });
4277
+ }
4140
4278
  function pretty(content) {
4141
4279
  try {
4142
4280
  return JSON.stringify(JSON.parse(content), null, 2);
@@ -4565,6 +4703,13 @@ function BlockCountdown({
4565
4703
  ] }) : null
4566
4704
  ] });
4567
4705
  }
4706
+ var METER_FILL = {
4707
+ ink: "bg-foreground",
4708
+ brand: "bg-oca-orange-deep",
4709
+ good: "bg-success",
4710
+ caution: "bg-warning",
4711
+ bad: "bg-destructive"
4712
+ };
4568
4713
  function Meter({
4569
4714
  value,
4570
4715
  max,
@@ -4599,7 +4744,7 @@ function Meter({
4599
4744
  /* @__PURE__ */ jsx(
4600
4745
  "div",
4601
4746
  {
4602
- className: cn("h-full shrink-0 rounded-full", tone === "brand" ? "bg-oca-orange-deep" : "bg-foreground"),
4747
+ className: cn("h-full shrink-0 rounded-full", METER_FILL[tone]),
4603
4748
  style: { width: `${v * 100}%` }
4604
4749
  }
4605
4750
  ),
@@ -4713,6 +4858,6 @@ function ToolGrid({
4713
4858
  );
4714
4859
  }
4715
4860
 
4716
- export { Accent, ActivityList, AnchorStatus, ApiTable, AppCard, AppGrid, ArtifactView, BlockCountdown, BlockHeight, Breadcrumbs, BrowserFrame, Callout, CardGrid, Closing, CodeBlock, CodeTabs, ComparisonTable, Container, CopyButton, DataTable, Diagram, Display, DocHeader, DocLayout, DocsHeading, DocsPager, DropZone, EmptyLine, EmptyState, EndpointList, ErrorBoundary, ErrorPage, Eyebrow, FactBlock, FactRows, Faq, FilterChips, FloatChip, Footnote, FormSection, HashChip, InstallTabs, KeyValueList, Lead, LegalDocument, LinkCard, LoadingBlock, MdxTable, Meter, Monogram, Notice, OnThisPage, PackageCard, PageHeader, PageHero, PhoneFrame, ProgressSteps, ProofStrip, Prose, ProtocolGrid, ProtocolHero, ProtocolNav, Reveal, Sats, SatsFigure, ScrollStory, SearchButton, SearchDialog, Section, SectionHeading, SectionIntro, SignMessage, SpecCard, SplitBar, StatCard, StatGrid, StateBadge, Step, StepGrid, Steps, TextLink, Ticker, ToolGrid, TruthTable, UsdApprox, VerifyBox, VerifyReport, createStateBadge, languageName, monogramGround, monogramLetter, satsText, sectionVariants, useActiveHeading, useCopy, useHeadings, useInView };
4861
+ export { Accent, ActivityList, AnchorStatus, ApiTable, AppCard, AppGrid, ArtifactView, BlockCountdown, BlockHeight, Breadcrumbs, BrowserFrame, Callout, CardGrid, Closing, CodeBlock, CodeTabs, CommandDialog, ComparisonTable, Container, CopyButton, CountdownRing, DataTable, Diagram, Display, DocHeader, DocLayout, DocsHeading, DocsPager, DropZone, EmptyLine, EmptyState, EndpointList, ErrorBoundary, ErrorPage, Eyebrow, FactBlock, FactRows, Faq, FilterChips, FloatChip, Footnote, FormSection, HashChip, InstallTabs, KeyValueList, Lead, LegalDocument, LinkCard, LoadingBlock, LockedPreview, MdxTable, Meter, Monogram, Notice, OnThisPage, PackageCard, PageHeader, PageHero, PhoneFrame, PlanCard, ProgressSteps, ProofStrip, Prose, ProtocolGrid, ProtocolHero, ProtocolNav, Reveal, Sats, SatsFigure, ScrollStory, SearchButton, SearchDialog, Section, SectionHeading, SectionIntro, SignMessage, SpecCard, SplitBar, StatCard, StatGrid, StateBadge, Step, StepGrid, Steps, TextLink, Ticker, ToolGrid, TruthTable, UsdApprox, VerifyBox, VerifyReport, createStateBadge, languageName, monogramGround, monogramLetter, satsText, sectionVariants, useActiveHeading, useCopy, useHeadings, useInView };
4717
4862
  //# sourceMappingURL=components.mjs.map
4718
4863
  //# sourceMappingURL=components.mjs.map