@orangecheck/app-design 1.0.0 → 1.1.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/README.md +21 -5
- package/dist/chrome.d.mts +31 -42
- package/dist/chrome.d.ts +31 -42
- package/dist/chrome.js +500 -23
- package/dist/chrome.js.map +1 -1
- package/dist/chrome.mjs +495 -25
- package/dist/chrome.mjs.map +1 -1
- package/dist/code.d.mts +52 -0
- package/dist/code.d.ts +52 -0
- package/dist/code.js +534 -0
- package/dist/code.js.map +1 -0
- package/dist/code.mjs +522 -0
- package/dist/code.mjs.map +1 -0
- package/dist/components.d.mts +61 -117
- package/dist/components.d.ts +61 -117
- package/dist/components.js +2170 -105
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +2142 -109
- package/dist/components.mjs.map +1 -1
- package/dist/docs-DhnstueM.d.ts +219 -0
- package/dist/docs-DiR6s43s.d.mts +219 -0
- package/dist/format.d.mts +12 -0
- package/dist/format.d.ts +12 -0
- package/dist/format.js +65 -0
- package/dist/format.js.map +1 -0
- package/dist/format.mjs +58 -0
- package/dist/format.mjs.map +1 -0
- package/dist/hero-Dn37il-9.d.mts +31 -0
- package/dist/hero-Dn37il-9.d.ts +31 -0
- package/dist/index.d.mts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +2668 -131
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2614 -134
- package/dist/index.mjs.map +1 -1
- package/dist/mdx.d.mts +58 -0
- package/dist/mdx.d.ts +58 -0
- package/dist/mdx.js +1712 -0
- package/dist/mdx.js.map +1 -0
- package/dist/mdx.mjs +1685 -0
- package/dist/mdx.mjs.map +1 -0
- package/dist/primitives.d.mts +22 -5
- package/dist/primitives.d.ts +22 -5
- package/dist/primitives.js +51 -5
- package/dist/primitives.js.map +1 -1
- package/dist/primitives.mjs +51 -7
- package/dist/primitives.mjs.map +1 -1
- package/dist/session.d.mts +18 -0
- package/dist/session.d.ts +18 -0
- package/dist/session.js +432 -0
- package/dist/session.js.map +1 -0
- package/dist/session.mjs +401 -0
- package/dist/session.mjs.map +1 -0
- package/dist/styles/code.css +97 -0
- package/dist/styles/theme.css +2 -0
- package/dist/styles/tokens.css +40 -0
- package/dist/styles.css +1 -0
- package/dist/tool-shell-B1C7ahKE.d.ts +81 -0
- package/dist/tool-shell-BDx_N5ai.d.mts +81 -0
- package/dist/tools-BggNN5DV.d.ts +131 -0
- package/dist/tools-DFIxIj5p.d.mts +131 -0
- package/package.json +31 -2
package/dist/components.js
CHANGED
|
@@ -5,6 +5,7 @@ var clsx = require('clsx');
|
|
|
5
5
|
var tailwindMerge = require('tailwind-merge');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
var classVarianceAuthority = require('class-variance-authority');
|
|
8
|
+
var TabsPrimitive = require('@radix-ui/react-tabs');
|
|
8
9
|
var lucideReact = require('lucide-react');
|
|
9
10
|
var reactSlot = require('@radix-ui/react-slot');
|
|
10
11
|
var SeparatorPrimitive = require('@radix-ui/react-separator');
|
|
@@ -15,6 +16,7 @@ var LabelPrimitive = require('@radix-ui/react-label');
|
|
|
15
16
|
var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
|
|
16
17
|
var SelectPrimitive = require('@radix-ui/react-select');
|
|
17
18
|
var SwitchPrimitive = require('@radix-ui/react-switch');
|
|
19
|
+
var DialogPrimitive = require('@radix-ui/react-dialog');
|
|
18
20
|
|
|
19
21
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
22
|
|
|
@@ -36,6 +38,7 @@ function _interopNamespace(e) {
|
|
|
36
38
|
return Object.freeze(n);
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
|
|
39
42
|
var SeparatorPrimitive__namespace = /*#__PURE__*/_interopNamespace(SeparatorPrimitive);
|
|
40
43
|
var Link__default = /*#__PURE__*/_interopDefault(Link);
|
|
41
44
|
var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
|
|
@@ -43,6 +46,7 @@ var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
|
|
|
43
46
|
var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
|
|
44
47
|
var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
|
|
45
48
|
var SwitchPrimitive__namespace = /*#__PURE__*/_interopNamespace(SwitchPrimitive);
|
|
49
|
+
var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
|
|
46
50
|
|
|
47
51
|
var merge = tailwindMerge.extendTailwindMerge({
|
|
48
52
|
extend: {
|
|
@@ -306,6 +310,7 @@ function useActiveHeading(ids) {
|
|
|
306
310
|
const [active, setActive] = react.useState(ids[0]);
|
|
307
311
|
const key = ids.join("|");
|
|
308
312
|
react.useEffect(() => {
|
|
313
|
+
setActive(key.split("|")[0] || void 0);
|
|
309
314
|
const els = key.split("|").map((id) => document.getElementById(id)).filter((el) => el !== null);
|
|
310
315
|
if (els.length === 0 || typeof IntersectionObserver === "undefined") return;
|
|
311
316
|
const io = new IntersectionObserver(
|
|
@@ -455,6 +460,487 @@ function StepGrid({ items, look = "cards", className }) {
|
|
|
455
460
|
] }) }, i)
|
|
456
461
|
) });
|
|
457
462
|
}
|
|
463
|
+
var KIND = {
|
|
464
|
+
package: "text-oca-code-package",
|
|
465
|
+
tag: "text-oca-code-tag",
|
|
466
|
+
link: "text-oca-code-link"
|
|
467
|
+
};
|
|
468
|
+
function PackageCard({ items, className }) {
|
|
469
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
470
|
+
"div",
|
|
471
|
+
{
|
|
472
|
+
className: cn(
|
|
473
|
+
"grid gap-x-10 gap-y-7 rounded-[1.25rem] border border-oca-ink-line bg-oca-ink-card p-6 text-oca-ink-foreground md:grid-cols-2 md:p-9",
|
|
474
|
+
className
|
|
475
|
+
),
|
|
476
|
+
children: items.map((it, i) => {
|
|
477
|
+
const code = /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[0.9375rem]", KIND[it.kind ?? "package"]), children: it.code });
|
|
478
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1.5", children: [
|
|
479
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[1.125rem] font-semibold tracking-[-0.01em] text-oca-ink-title", children: it.title }),
|
|
480
|
+
it.href ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: it.href, className: "w-fit underline decoration-transparent underline-offset-4 hover:decoration-current", children: code }) : code,
|
|
481
|
+
it.note ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[0.9375rem] leading-relaxed text-oca-ink-subtle", children: [
|
|
482
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, children: "// " }),
|
|
483
|
+
it.note
|
|
484
|
+
] }) : null
|
|
485
|
+
] }, i);
|
|
486
|
+
})
|
|
487
|
+
}
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// src/code/highlight.ts
|
|
492
|
+
var TOKEN_CLASS = {
|
|
493
|
+
keyword: "oca-k",
|
|
494
|
+
string: "oca-s",
|
|
495
|
+
number: "oca-n",
|
|
496
|
+
function: "oca-f",
|
|
497
|
+
type: "oca-y",
|
|
498
|
+
property: "oca-p",
|
|
499
|
+
comment: "oca-c",
|
|
500
|
+
tag: "oca-g",
|
|
501
|
+
url: "oca-u"
|
|
502
|
+
};
|
|
503
|
+
var ALIASES = {
|
|
504
|
+
ts: "js",
|
|
505
|
+
typescript: "js",
|
|
506
|
+
tsx: "js",
|
|
507
|
+
js: "js",
|
|
508
|
+
javascript: "js",
|
|
509
|
+
jsx: "js",
|
|
510
|
+
mjs: "js",
|
|
511
|
+
cjs: "js",
|
|
512
|
+
json: "json",
|
|
513
|
+
jsonc: "json",
|
|
514
|
+
json5: "json",
|
|
515
|
+
bash: "shell",
|
|
516
|
+
sh: "shell",
|
|
517
|
+
shell: "shell",
|
|
518
|
+
zsh: "shell",
|
|
519
|
+
console: "shell",
|
|
520
|
+
terminal: "shell",
|
|
521
|
+
py: "python",
|
|
522
|
+
python: "python",
|
|
523
|
+
yaml: "yaml",
|
|
524
|
+
yml: "yaml",
|
|
525
|
+
diff: "diff"
|
|
526
|
+
};
|
|
527
|
+
function grammarOf(lang) {
|
|
528
|
+
return lang && ALIASES[lang.toLowerCase()] || "plain";
|
|
529
|
+
}
|
|
530
|
+
function collector() {
|
|
531
|
+
const tokens = [];
|
|
532
|
+
const emit = (text, kind) => {
|
|
533
|
+
if (!text) return;
|
|
534
|
+
const last = tokens[tokens.length - 1];
|
|
535
|
+
if (last && last.kind === kind) last.text += text;
|
|
536
|
+
else tokens.push(kind ? { text, kind } : { text });
|
|
537
|
+
};
|
|
538
|
+
return { emit, tokens };
|
|
539
|
+
}
|
|
540
|
+
function at(re, src, i) {
|
|
541
|
+
re.lastIndex = i;
|
|
542
|
+
const m = re.exec(src);
|
|
543
|
+
return m ? m[0] : null;
|
|
544
|
+
}
|
|
545
|
+
var WS = /[ \t]+/y;
|
|
546
|
+
var NEWLINE = /\r?\n/y;
|
|
547
|
+
var JS_KEYWORDS = new Set(
|
|
548
|
+
"abstract as async await break case catch class const continue debugger declare default delete do else enum export extends finally for from function get if implements import in infer instanceof interface is keyof let module namespace new of override private protected public readonly return satisfies set static super switch this throw try type typeof unique var void while with yield".split(" ")
|
|
549
|
+
);
|
|
550
|
+
var JS_CONSTANTS = /* @__PURE__ */ new Set(["true", "false", "null", "undefined", "NaN", "Infinity"]);
|
|
551
|
+
var TS_PRIMITIVES = /* @__PURE__ */ new Set(["string", "number", "boolean", "bigint", "symbol", "object", "unknown", "any", "never"]);
|
|
552
|
+
var isConstant = (m) => /^[A-Z][A-Z\d_]+$/.test(m) && (m.includes("_") || m.length > 4);
|
|
553
|
+
var JS_LINE_COMMENT = /\/\/[^\n]*/y;
|
|
554
|
+
var JS_BLOCK_COMMENT = /\/\*[\s\S]*?(?:\*\/|$)/y;
|
|
555
|
+
var JS_TEMPLATE = /`(?:\\[\s\S]|[^\\`])*`?/y;
|
|
556
|
+
var JS_STRING = /'(?:\\.|[^\\'\n])*'?|"(?:\\.|[^\\"\n])*"?/y;
|
|
557
|
+
var JS_NUMBER = /(?:0[xX][\da-fA-F_]+|0[bB][01_]+|0[oO][0-7_]+|\d[\d_]*(?:\.[\d_]+)?(?:[eE][+-]?\d+)?|\.\d[\d_]*(?:[eE][+-]?\d+)?)n?/y;
|
|
558
|
+
var JS_IDENT = /[A-Za-z_$][\w$]*/y;
|
|
559
|
+
var JS_DECORATOR = /@[A-Za-z_$][\w$.]*/y;
|
|
560
|
+
var JS_CALL_AFTER = /\s*(?:<[\w$\s,.[\]|&'"]*>)?\s*\(/y;
|
|
561
|
+
var JS_TAG = /<\/?(?=[A-Za-z])/y;
|
|
562
|
+
var JS_TAG_NAME = /[A-Za-z][\w$.:-]*/y;
|
|
563
|
+
var JS_PUNCT = /=>|\.\.\.|[{}()[\];,.<>=+\-*/%!?:&|^~#]/y;
|
|
564
|
+
var JSX_BEFORE = /* @__PURE__ */ new Set(["(", ",", "=", "?", ":", "{", "[", ";", ">", "&&", "||", "=>", "return"]);
|
|
565
|
+
function scanJs(src, emit, jsx35) {
|
|
566
|
+
let i = 0;
|
|
567
|
+
let prev = "";
|
|
568
|
+
let tagDepth = 0;
|
|
569
|
+
let braceInTag = 0;
|
|
570
|
+
const sig = (t) => {
|
|
571
|
+
prev = t;
|
|
572
|
+
};
|
|
573
|
+
while (i < src.length) {
|
|
574
|
+
let m;
|
|
575
|
+
if ((m = at(WS, src, i)) || (m = at(NEWLINE, src, i))) {
|
|
576
|
+
emit(m);
|
|
577
|
+
i += m.length;
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
if ((m = at(JS_LINE_COMMENT, src, i)) || (m = at(JS_BLOCK_COMMENT, src, i))) {
|
|
581
|
+
emit(m, "comment");
|
|
582
|
+
i += m.length;
|
|
583
|
+
continue;
|
|
584
|
+
}
|
|
585
|
+
if ((m = at(JS_TEMPLATE, src, i)) || (m = at(JS_STRING, src, i))) {
|
|
586
|
+
emit(m, "string");
|
|
587
|
+
i += m.length;
|
|
588
|
+
sig('"');
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
591
|
+
if (jsx35 && tagDepth === 0 && (m = at(JS_TAG, src, i)) && (prev === "" || JSX_BEFORE.has(prev))) {
|
|
592
|
+
const name = at(JS_TAG_NAME, src, i + m.length);
|
|
593
|
+
if (name) {
|
|
594
|
+
emit(m);
|
|
595
|
+
emit(name, "tag");
|
|
596
|
+
i += m.length + name.length;
|
|
597
|
+
tagDepth = 1;
|
|
598
|
+
braceInTag = 0;
|
|
599
|
+
sig("tag");
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
if (jsx35 && tagDepth > 0 && braceInTag === 0) {
|
|
604
|
+
if (src.startsWith("/>", i) || src[i] === ">") {
|
|
605
|
+
const close = src[i] === ">" ? ">" : "/>";
|
|
606
|
+
emit(close);
|
|
607
|
+
i += close.length;
|
|
608
|
+
tagDepth = 0;
|
|
609
|
+
sig(">");
|
|
610
|
+
continue;
|
|
611
|
+
}
|
|
612
|
+
if ((m = at(JS_IDENT, src, i)) && /^\s*=/.test(src.slice(i + m.length, i + m.length + 4))) {
|
|
613
|
+
emit(m, "property");
|
|
614
|
+
i += m.length;
|
|
615
|
+
continue;
|
|
616
|
+
}
|
|
617
|
+
if (m = at(JS_IDENT, src, i)) {
|
|
618
|
+
emit(m, "property");
|
|
619
|
+
i += m.length;
|
|
620
|
+
continue;
|
|
621
|
+
}
|
|
622
|
+
if (src[i] === "{") braceInTag = 1;
|
|
623
|
+
} else if (jsx35 && tagDepth > 0 && braceInTag > 0) {
|
|
624
|
+
if (src[i] === "{") braceInTag++;
|
|
625
|
+
else if (src[i] === "}") braceInTag--;
|
|
626
|
+
}
|
|
627
|
+
if (m = at(JS_DECORATOR, src, i)) {
|
|
628
|
+
emit(m, "function");
|
|
629
|
+
i += m.length;
|
|
630
|
+
sig("@");
|
|
631
|
+
continue;
|
|
632
|
+
}
|
|
633
|
+
if (m = at(JS_IDENT, src, i)) {
|
|
634
|
+
const end = i + m.length;
|
|
635
|
+
let kind;
|
|
636
|
+
if (prev !== "." && JS_CONSTANTS.has(m)) kind = "number";
|
|
637
|
+
else if (prev !== "." && JS_KEYWORDS.has(m)) kind = "keyword";
|
|
638
|
+
else if (at(JS_CALL_AFTER, src, end) !== null) kind = "function";
|
|
639
|
+
else if (prev !== "." && TS_PRIMITIVES.has(m)) kind = "type";
|
|
640
|
+
else if (isConstant(m)) kind = "number";
|
|
641
|
+
else if (/^[A-Z]/.test(m)) kind = "type";
|
|
642
|
+
emit(m, kind);
|
|
643
|
+
i = end;
|
|
644
|
+
sig(kind === "keyword" ? m : "id");
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
if (m = at(JS_NUMBER, src, i)) {
|
|
648
|
+
emit(m, "number");
|
|
649
|
+
i += m.length;
|
|
650
|
+
sig("0");
|
|
651
|
+
continue;
|
|
652
|
+
}
|
|
653
|
+
if (m = at(JS_PUNCT, src, i)) {
|
|
654
|
+
emit(m);
|
|
655
|
+
i += m.length;
|
|
656
|
+
sig(m === "." ? "." : m);
|
|
657
|
+
continue;
|
|
658
|
+
}
|
|
659
|
+
emit(src[i]);
|
|
660
|
+
i++;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
var JSON_STRING = /"(?:\\.|[^\\"\n])*"?/y;
|
|
664
|
+
var JSON_KEY_AFTER = /\s*:/y;
|
|
665
|
+
var JSON_NUMBER = /-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/y;
|
|
666
|
+
var JSON_WORD = /true|false|null/y;
|
|
667
|
+
function scanJson(src, emit) {
|
|
668
|
+
let i = 0;
|
|
669
|
+
while (i < src.length) {
|
|
670
|
+
let m;
|
|
671
|
+
if ((m = at(JS_LINE_COMMENT, src, i)) || (m = at(JS_BLOCK_COMMENT, src, i))) {
|
|
672
|
+
emit(m, "comment");
|
|
673
|
+
} else if (m = at(JSON_STRING, src, i)) {
|
|
674
|
+
emit(m, at(JSON_KEY_AFTER, src, i + m.length) !== null ? "property" : "string");
|
|
675
|
+
} else if ((m = at(JSON_NUMBER, src, i)) || (m = at(JSON_WORD, src, i))) {
|
|
676
|
+
emit(m, "number");
|
|
677
|
+
} else {
|
|
678
|
+
m = src[i];
|
|
679
|
+
emit(m);
|
|
680
|
+
}
|
|
681
|
+
i += m.length;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
var SH_KEYWORDS = new Set(
|
|
685
|
+
"if then else elif fi for in do done case esac while until function return export local select time".split(" ")
|
|
686
|
+
);
|
|
687
|
+
var SH_PROMPT = /\$ (?=\S)/y;
|
|
688
|
+
var SH_COMMENT = /#[^\n]*/y;
|
|
689
|
+
var SH_SINGLE = /'[^']*'?/y;
|
|
690
|
+
var SH_DOUBLE = /"(?:\\.|[^\\"])*"?/y;
|
|
691
|
+
var SH_VAR = /\$(?:\{[^}\n]*\}?|[A-Za-z_][\w]*|[@*#?$!\d])/y;
|
|
692
|
+
var SH_URL = /https?:\/\/[^\s'"`)]+/y;
|
|
693
|
+
var SH_FLAG = /--?[A-Za-z][\w-]*/y;
|
|
694
|
+
var SH_ASSIGN = /[A-Za-z_][\w]*(?==)/y;
|
|
695
|
+
var SH_VALUE = /=[^\s|&;()<>'"`$]*/y;
|
|
696
|
+
var SH_WORD = /[^\s|&;()<>'"`$#]+/y;
|
|
697
|
+
var SH_OPERATOR = /\|\||&&|[|;&]|\$\(|[()<>]/y;
|
|
698
|
+
function scanShell(src, emit) {
|
|
699
|
+
let i = 0;
|
|
700
|
+
let command = true;
|
|
701
|
+
let lineStart = true;
|
|
702
|
+
while (i < src.length) {
|
|
703
|
+
let m;
|
|
704
|
+
if (m = at(NEWLINE, src, i)) {
|
|
705
|
+
emit(m);
|
|
706
|
+
i += m.length;
|
|
707
|
+
command = !/\\\s*$/.test(src.slice(0, i - m.length));
|
|
708
|
+
lineStart = true;
|
|
709
|
+
continue;
|
|
710
|
+
}
|
|
711
|
+
if (m = at(WS, src, i)) {
|
|
712
|
+
emit(m);
|
|
713
|
+
i += m.length;
|
|
714
|
+
continue;
|
|
715
|
+
}
|
|
716
|
+
if (lineStart && (m = at(SH_PROMPT, src, i))) {
|
|
717
|
+
emit(m, "comment");
|
|
718
|
+
i += m.length;
|
|
719
|
+
lineStart = false;
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
lineStart = false;
|
|
723
|
+
if ((m = at(SH_COMMENT, src, i)) && (i === 0 || /\s/.test(src[i - 1]))) {
|
|
724
|
+
emit(m, "comment");
|
|
725
|
+
i += m.length;
|
|
726
|
+
continue;
|
|
727
|
+
}
|
|
728
|
+
if ((m = at(SH_SINGLE, src, i)) || (m = at(SH_DOUBLE, src, i))) {
|
|
729
|
+
emit(m, "string");
|
|
730
|
+
i += m.length;
|
|
731
|
+
command = false;
|
|
732
|
+
continue;
|
|
733
|
+
}
|
|
734
|
+
if (m = at(SH_OPERATOR, src, i)) {
|
|
735
|
+
emit(m);
|
|
736
|
+
i += m.length;
|
|
737
|
+
command = m !== ")" && m !== ">" && m !== "<";
|
|
738
|
+
continue;
|
|
739
|
+
}
|
|
740
|
+
if (m = at(SH_VAR, src, i)) {
|
|
741
|
+
emit(m, "type");
|
|
742
|
+
i += m.length;
|
|
743
|
+
command = false;
|
|
744
|
+
continue;
|
|
745
|
+
}
|
|
746
|
+
if (m = at(SH_URL, src, i)) {
|
|
747
|
+
emit(m, "url");
|
|
748
|
+
i += m.length;
|
|
749
|
+
command = false;
|
|
750
|
+
continue;
|
|
751
|
+
}
|
|
752
|
+
if (command && (m = at(SH_ASSIGN, src, i))) {
|
|
753
|
+
emit(m, "property");
|
|
754
|
+
i += m.length;
|
|
755
|
+
const v = at(SH_VALUE, src, i);
|
|
756
|
+
emit(v);
|
|
757
|
+
i += v.length;
|
|
758
|
+
continue;
|
|
759
|
+
}
|
|
760
|
+
if ((m = at(SH_FLAG, src, i)) && !command) {
|
|
761
|
+
emit(m, "keyword");
|
|
762
|
+
i += m.length;
|
|
763
|
+
continue;
|
|
764
|
+
}
|
|
765
|
+
if (m = at(SH_WORD, src, i)) {
|
|
766
|
+
if (command && SH_KEYWORDS.has(m)) emit(m, "keyword");
|
|
767
|
+
else if (command) {
|
|
768
|
+
emit(m, "function");
|
|
769
|
+
command = m === "sudo" || m === "npx" || m === "env" || m === "time";
|
|
770
|
+
i += m.length;
|
|
771
|
+
continue;
|
|
772
|
+
} else emit(m);
|
|
773
|
+
i += m.length;
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
emit(src[i]);
|
|
777
|
+
i++;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
var PY_KEYWORDS = new Set(
|
|
781
|
+
"and as assert async await break class continue def del elif else except finally for from global if import in is lambda match case nonlocal not or pass raise return try while with yield self cls".split(" ")
|
|
782
|
+
);
|
|
783
|
+
var PY_CONSTANTS = /* @__PURE__ */ new Set(["True", "False", "None"]);
|
|
784
|
+
var PY_TYPES = /* @__PURE__ */ new Set(["int", "str", "bool", "float", "bytes", "list", "dict", "tuple", "set", "object"]);
|
|
785
|
+
var PY_COMMENT = /#[^\n]*/y;
|
|
786
|
+
var PY_TRIPLE = /[rRbBuUfF]{0,2}(?:"""[\s\S]*?(?:"""|$)|'''[\s\S]*?(?:'''|$))/y;
|
|
787
|
+
var PY_STRING = /[rRbBuUfF]{0,2}(?:'(?:\\.|[^\\'\n])*'?|"(?:\\.|[^\\"\n])*"?)/y;
|
|
788
|
+
var PY_NUMBER = /(?:0[xX][\da-fA-F_]+|\d[\d_]*(?:\.[\d_]*)?(?:[eE][+-]?\d+)?j?)/y;
|
|
789
|
+
var PY_IDENT = /[A-Za-z_]\w*/y;
|
|
790
|
+
var PY_DECORATOR = /@[A-Za-z_][\w.]*/y;
|
|
791
|
+
var PY_CALL_AFTER = /\s*\(/y;
|
|
792
|
+
function scanPython(src, emit) {
|
|
793
|
+
let i = 0;
|
|
794
|
+
let prev = "";
|
|
795
|
+
while (i < src.length) {
|
|
796
|
+
let m;
|
|
797
|
+
if ((m = at(WS, src, i)) || (m = at(NEWLINE, src, i))) {
|
|
798
|
+
emit(m);
|
|
799
|
+
i += m.length;
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
if (m = at(PY_COMMENT, src, i)) {
|
|
803
|
+
emit(m, "comment");
|
|
804
|
+
} else if ((m = at(PY_TRIPLE, src, i)) || (m = at(PY_STRING, src, i))) {
|
|
805
|
+
if (/^[A-Za-z]+$/.test(m)) {
|
|
806
|
+
emit(m);
|
|
807
|
+
} else emit(m, "string");
|
|
808
|
+
prev = '"';
|
|
809
|
+
} else if (m = at(PY_DECORATOR, src, i)) {
|
|
810
|
+
emit(m, "function");
|
|
811
|
+
prev = "@";
|
|
812
|
+
} else if (m = at(PY_IDENT, src, i)) {
|
|
813
|
+
let kind;
|
|
814
|
+
if (PY_CONSTANTS.has(m)) kind = "number";
|
|
815
|
+
else if (prev !== "." && PY_KEYWORDS.has(m)) kind = "keyword";
|
|
816
|
+
else if (prev === "def" || at(PY_CALL_AFTER, src, i + m.length) !== null) kind = "function";
|
|
817
|
+
else if (prev === "class" || /^[A-Z][a-z]/.test(m) || PY_TYPES.has(m)) kind = "type";
|
|
818
|
+
else if (isConstant(m)) kind = "number";
|
|
819
|
+
emit(m, kind);
|
|
820
|
+
prev = kind === "keyword" ? m : "id";
|
|
821
|
+
} else if (m = at(PY_NUMBER, src, i)) {
|
|
822
|
+
emit(m, "number");
|
|
823
|
+
prev = "0";
|
|
824
|
+
} else {
|
|
825
|
+
m = src[i];
|
|
826
|
+
emit(m);
|
|
827
|
+
prev = m;
|
|
828
|
+
}
|
|
829
|
+
i += m.length;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
var YAML_KEY = /[ \t]*(?:- )?[\w.$/-]+(?=[ \t]*:(?:\s|$))/y;
|
|
833
|
+
var YAML_VALUE_WORD = /(?:true|false|null|yes|no|~|-?\d+(?:\.\d+)?)(?=\s*(?:#|$))/y;
|
|
834
|
+
function scanYaml(src, emit) {
|
|
835
|
+
let i = 0;
|
|
836
|
+
let lineStart = true;
|
|
837
|
+
while (i < src.length) {
|
|
838
|
+
let m;
|
|
839
|
+
if (m = at(NEWLINE, src, i)) {
|
|
840
|
+
emit(m);
|
|
841
|
+
i += m.length;
|
|
842
|
+
lineStart = true;
|
|
843
|
+
continue;
|
|
844
|
+
}
|
|
845
|
+
if (lineStart && (m = at(YAML_KEY, src, i))) {
|
|
846
|
+
const dash = m.match(/^([ \t]*(?:- )?)/)[1];
|
|
847
|
+
emit(dash);
|
|
848
|
+
emit(m.slice(dash.length), "property");
|
|
849
|
+
i += m.length;
|
|
850
|
+
lineStart = false;
|
|
851
|
+
continue;
|
|
852
|
+
}
|
|
853
|
+
lineStart = false;
|
|
854
|
+
if ((m = at(SH_COMMENT, src, i)) && (i === 0 || /\s/.test(src[i - 1]))) emit(m, "comment");
|
|
855
|
+
else if ((m = at(SH_SINGLE, src, i)) || (m = at(JSON_STRING, src, i))) emit(m, "string");
|
|
856
|
+
else if (m = at(YAML_VALUE_WORD, src, i)) emit(m, "number");
|
|
857
|
+
else if (m = at(SH_URL, src, i)) emit(m, "url");
|
|
858
|
+
else {
|
|
859
|
+
m = src[i];
|
|
860
|
+
emit(m);
|
|
861
|
+
}
|
|
862
|
+
i += m.length;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
function toLines(tokens) {
|
|
866
|
+
const lines = [[]];
|
|
867
|
+
for (const t of tokens) {
|
|
868
|
+
const parts = t.text.split(/\r?\n/);
|
|
869
|
+
parts.forEach((part, j) => {
|
|
870
|
+
if (j > 0) lines.push([]);
|
|
871
|
+
if (part) lines[lines.length - 1].push(t.kind ? { text: part, kind: t.kind } : { text: part });
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
return lines;
|
|
875
|
+
}
|
|
876
|
+
function highlight(code, lang) {
|
|
877
|
+
const src = code.replace(/\r?\n$/, "");
|
|
878
|
+
const grammar = grammarOf(lang);
|
|
879
|
+
const { emit, tokens } = collector();
|
|
880
|
+
const name = (lang ?? "").toLowerCase();
|
|
881
|
+
switch (grammar) {
|
|
882
|
+
case "js":
|
|
883
|
+
scanJs(src, emit, name === "tsx" || name === "jsx");
|
|
884
|
+
break;
|
|
885
|
+
case "json":
|
|
886
|
+
scanJson(src, emit);
|
|
887
|
+
break;
|
|
888
|
+
case "shell":
|
|
889
|
+
scanShell(src, emit);
|
|
890
|
+
break;
|
|
891
|
+
case "python":
|
|
892
|
+
scanPython(src, emit);
|
|
893
|
+
break;
|
|
894
|
+
case "yaml":
|
|
895
|
+
scanYaml(src, emit);
|
|
896
|
+
break;
|
|
897
|
+
default:
|
|
898
|
+
emit(src);
|
|
899
|
+
}
|
|
900
|
+
return toLines(tokens);
|
|
901
|
+
}
|
|
902
|
+
function readDiff(code) {
|
|
903
|
+
const diff = /* @__PURE__ */ new Map();
|
|
904
|
+
const lines = code.replace(/\r?\n$/, "").split(/\r?\n/);
|
|
905
|
+
const out = lines.map((line, i) => {
|
|
906
|
+
const c = line[0];
|
|
907
|
+
if (c === "+" || c === "-") {
|
|
908
|
+
diff.set(i + 1, c === "+" ? "add" : "remove");
|
|
909
|
+
return line.slice(1);
|
|
910
|
+
}
|
|
911
|
+
return c === " " ? line.slice(1) : line;
|
|
912
|
+
});
|
|
913
|
+
return { code: out.join("\n"), diff };
|
|
914
|
+
}
|
|
915
|
+
function parseLineRanges(spec) {
|
|
916
|
+
if (!spec) return /* @__PURE__ */ new Set();
|
|
917
|
+
if (typeof spec !== "string") return new Set(spec);
|
|
918
|
+
const out = /* @__PURE__ */ new Set();
|
|
919
|
+
for (const part of spec.split(",")) {
|
|
920
|
+
const m = part.trim().match(/^(\d+)(?:\s*-\s*(\d+))?$/);
|
|
921
|
+
if (!m) continue;
|
|
922
|
+
const a = Number(m[1]);
|
|
923
|
+
const b = m[2] ? Number(m[2]) : a;
|
|
924
|
+
for (let n = Math.min(a, b); n <= Math.max(a, b) && n - a < 1e4; n++) out.add(n);
|
|
925
|
+
}
|
|
926
|
+
return out;
|
|
927
|
+
}
|
|
928
|
+
var ESCAPE = { "&": "&", "<": "<", ">": ">", '"': """ };
|
|
929
|
+
function escapeHtml(s) {
|
|
930
|
+
return s.replace(/[&<>"]/g, (c) => ESCAPE[c]);
|
|
931
|
+
}
|
|
932
|
+
function linesToHtml(lines, marks = {}) {
|
|
933
|
+
return lines.map((line, i) => {
|
|
934
|
+
const n = i + 1;
|
|
935
|
+
const attrs = [
|
|
936
|
+
'data-line=""',
|
|
937
|
+
marks.highlight?.has(n) ? 'data-mark=""' : "",
|
|
938
|
+
marks.diff?.has(n) ? `data-diff="${marks.diff.get(n)}"` : ""
|
|
939
|
+
].filter(Boolean).join(" ");
|
|
940
|
+
const body = line.map((t) => t.kind ? `<span class="${TOKEN_CLASS[t.kind]}">${escapeHtml(t.text)}</span>` : escapeHtml(t.text)).join("");
|
|
941
|
+
return `<span ${attrs}>${body}</span>`;
|
|
942
|
+
}).join("\n");
|
|
943
|
+
}
|
|
458
944
|
function ScrollFade({ fade = "var(--card)", className, innerClassName, children, ...props }) {
|
|
459
945
|
const ref = react.useRef(null);
|
|
460
946
|
const [edges, setEdges] = react.useState({ left: false, right: false });
|
|
@@ -513,7 +999,73 @@ function ScrollFade({ fade = "var(--card)", className, innerClassName, children,
|
|
|
513
999
|
)
|
|
514
1000
|
] });
|
|
515
1001
|
}
|
|
516
|
-
|
|
1002
|
+
|
|
1003
|
+
// src/format/index.ts
|
|
1004
|
+
var EXPLORER = "https://mempool.space";
|
|
1005
|
+
function explorerUrl(kind, value, network = "mainnet") {
|
|
1006
|
+
const net = network === "mainnet" ? "" : `/${network}`;
|
|
1007
|
+
return `${EXPLORER}${net}/${kind}/${encodeURIComponent(String(value))}`;
|
|
1008
|
+
}
|
|
1009
|
+
function shortenMiddle(value, head = 8, tail = 6) {
|
|
1010
|
+
return value.length <= head + tail + 1 ? value : `${value.slice(0, head)}\u2026${value.slice(-tail)}`;
|
|
1011
|
+
}
|
|
1012
|
+
function formatBlockHeight(height) {
|
|
1013
|
+
return Math.trunc(height).toLocaleString("en-US");
|
|
1014
|
+
}
|
|
1015
|
+
function blocksToDuration(blocks, minutesPerBlock = 10) {
|
|
1016
|
+
const minutes = Math.max(0, Math.round(blocks * minutesPerBlock));
|
|
1017
|
+
if (minutes < 60) return `about ${minutes} minute${minutes === 1 ? "" : "s"}`;
|
|
1018
|
+
const units = [
|
|
1019
|
+
[60 * 24 * 7, "week"],
|
|
1020
|
+
[60 * 24, "day"],
|
|
1021
|
+
[60, "hour"],
|
|
1022
|
+
[1, "minute"]
|
|
1023
|
+
];
|
|
1024
|
+
const parts = [];
|
|
1025
|
+
let rest = minutes;
|
|
1026
|
+
for (const [size, word] of units) {
|
|
1027
|
+
const n = Math.floor(rest / size);
|
|
1028
|
+
if (n > 0 && parts.length < 2) {
|
|
1029
|
+
parts.push(`${n} ${word}${n === 1 ? "" : "s"}`);
|
|
1030
|
+
rest -= n * size;
|
|
1031
|
+
} else if (parts.length > 0) break;
|
|
1032
|
+
}
|
|
1033
|
+
return `about ${parts.join(" ")}`;
|
|
1034
|
+
}
|
|
1035
|
+
var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
1036
|
+
function formatUtc(at2, opts = {}) {
|
|
1037
|
+
const d = typeof at2 === "number" ? new Date(at2 * 1e3) : new Date(at2);
|
|
1038
|
+
if (Number.isNaN(d.getTime())) return "\u2014";
|
|
1039
|
+
const day = `${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]} ${d.getUTCFullYear()}`;
|
|
1040
|
+
if (opts.date) return day;
|
|
1041
|
+
const hh = String(d.getUTCHours()).padStart(2, "0");
|
|
1042
|
+
const mm = String(d.getUTCMinutes()).padStart(2, "0");
|
|
1043
|
+
return `${day}, ${hh}:${mm} UTC`;
|
|
1044
|
+
}
|
|
1045
|
+
function formatBytes(bytes) {
|
|
1046
|
+
if (!Number.isFinite(bytes) || bytes < 0) return "\u2014";
|
|
1047
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
1048
|
+
const units = ["KB", "MB", "GB", "TB"];
|
|
1049
|
+
let v = bytes / 1024;
|
|
1050
|
+
let u = 0;
|
|
1051
|
+
while (v >= 1024 && u < units.length - 1) {
|
|
1052
|
+
v /= 1024;
|
|
1053
|
+
u++;
|
|
1054
|
+
}
|
|
1055
|
+
return `${v < 10 ? v.toFixed(1).replace(/\.0$/, "") : Math.round(v)} ${units[u]}`;
|
|
1056
|
+
}
|
|
1057
|
+
function sharedContext(name, initial) {
|
|
1058
|
+
const key = /* @__PURE__ */ Symbol.for(`@orangecheck/app-design/${name}`);
|
|
1059
|
+
const store = globalThis;
|
|
1060
|
+
return store[key] ?? (store[key] = react.createContext(initial));
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
// src/lib/density.ts
|
|
1064
|
+
var DensityContext = sharedContext("density", "comfortable");
|
|
1065
|
+
function useDensity() {
|
|
1066
|
+
return react.useContext(DensityContext);
|
|
1067
|
+
}
|
|
1068
|
+
var ShellContext = sharedContext("shell-place", {});
|
|
517
1069
|
function useShellPlace() {
|
|
518
1070
|
return react.useContext(ShellContext);
|
|
519
1071
|
}
|
|
@@ -568,6 +1120,18 @@ react.forwardRef(function Separator2({ className, orientation = "horizontal", de
|
|
|
568
1120
|
}
|
|
569
1121
|
);
|
|
570
1122
|
});
|
|
1123
|
+
function Kbd({ className, ...props }) {
|
|
1124
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1125
|
+
"kbd",
|
|
1126
|
+
{
|
|
1127
|
+
className: cn(
|
|
1128
|
+
"inline-flex h-5 min-w-5 items-center justify-center rounded-md border border-border bg-card px-1.5 font-mono text-[11px] text-muted-foreground",
|
|
1129
|
+
className
|
|
1130
|
+
),
|
|
1131
|
+
...props
|
|
1132
|
+
}
|
|
1133
|
+
);
|
|
1134
|
+
}
|
|
571
1135
|
var buttonVariants = classVarianceAuthority.cva(
|
|
572
1136
|
[
|
|
573
1137
|
"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-full font-medium",
|
|
@@ -641,26 +1205,30 @@ function PageHeader({
|
|
|
641
1205
|
] });
|
|
642
1206
|
}
|
|
643
1207
|
var InStatGrid = react.createContext(false);
|
|
644
|
-
function StatCard({ label, value, hint, className }) {
|
|
1208
|
+
function StatCard({ label, value, hint, size, className }) {
|
|
645
1209
|
const inGrid = react.useContext(InStatGrid);
|
|
1210
|
+
const density = useDensity();
|
|
1211
|
+
const sm = (size ?? (density === "compact" ? "sm" : "md")) === "sm";
|
|
646
1212
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
647
1213
|
"div",
|
|
648
1214
|
{
|
|
649
1215
|
"data-ui": "stat",
|
|
650
1216
|
className: cn(
|
|
651
|
-
"
|
|
1217
|
+
"border border-border bg-card",
|
|
1218
|
+
sm ? "rounded-2xl p-4" : "rounded-[1.25rem] p-5 md:p-6",
|
|
652
1219
|
// In a grid, label, value and hint each share a row with their
|
|
653
1220
|
// neighbours, so values line up whatever wraps above them.
|
|
654
1221
|
inGrid ? "row-span-3 grid grid-rows-subgrid gap-1.5" : "flex flex-col gap-2",
|
|
655
1222
|
className
|
|
656
1223
|
),
|
|
657
1224
|
children: [
|
|
658
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.
|
|
1225
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("leading-snug text-muted-foreground", sm ? "text-[0.8125rem]" : "text-[0.875rem]"), children: label }),
|
|
659
1226
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
660
1227
|
"span",
|
|
661
1228
|
{
|
|
662
1229
|
className: cn(
|
|
663
|
-
"break-words oca-tabular
|
|
1230
|
+
"break-words oca-tabular leading-tight tracking-[-0.02em]",
|
|
1231
|
+
sm ? "text-[1.25rem]" : "text-[1.5rem] md:text-[1.75rem]",
|
|
664
1232
|
inGrid && "self-end"
|
|
665
1233
|
),
|
|
666
1234
|
children: value
|
|
@@ -722,6 +1290,7 @@ function StatGrid({ columns, empty, isEmpty, className, children, ...props }) {
|
|
|
722
1290
|
const items = react.Children.toArray(children).filter(react.isValidElement);
|
|
723
1291
|
const n = items.length;
|
|
724
1292
|
const allZero = n > 0 && items.every((el) => "raw" in el.props && (el.props.raw === 0 || el.props.raw === null));
|
|
1293
|
+
const compact = useDensity() === "compact";
|
|
725
1294
|
if (isEmpty ?? allZero) return /* @__PURE__ */ jsxRuntime.jsx(EmptyLine, { className, children: empty ?? "Nothing here yet." });
|
|
726
1295
|
const lg = columns ?? statColumns(n);
|
|
727
1296
|
const md = lg > 4 ? 3 : lg;
|
|
@@ -731,7 +1300,8 @@ function StatGrid({ columns, empty, isEmpty, className, children, ...props }) {
|
|
|
731
1300
|
"div",
|
|
732
1301
|
{
|
|
733
1302
|
className: cn(
|
|
734
|
-
"grid
|
|
1303
|
+
"grid",
|
|
1304
|
+
compact ? "gap-2.5 md:gap-3" : "gap-3 md:gap-4",
|
|
735
1305
|
n === 1 ? "grid-cols-1" : "grid-cols-2",
|
|
736
1306
|
MD_COLS[md],
|
|
737
1307
|
LG_COLS[lg],
|
|
@@ -750,11 +1320,40 @@ function StatGrid({ columns, empty, isEmpty, className, children, ...props }) {
|
|
|
750
1320
|
}
|
|
751
1321
|
) });
|
|
752
1322
|
}
|
|
753
|
-
function KeyValueList({
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
1323
|
+
function KeyValueList({
|
|
1324
|
+
items,
|
|
1325
|
+
dense,
|
|
1326
|
+
className
|
|
1327
|
+
}) {
|
|
1328
|
+
const density = useDensity();
|
|
1329
|
+
const tight = dense ?? density === "compact";
|
|
1330
|
+
return (
|
|
1331
|
+
// The rows go side by side when the list itself is wide enough, wherever it sits: a narrow card stacks them.
|
|
1332
|
+
/* @__PURE__ */ jsxRuntime.jsx("dl", { className: cn("@container divide-y divide-border border border-border bg-card", tight ? "rounded-2xl" : "rounded-[1.25rem]", className), children: items.map((it, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1333
|
+
"div",
|
|
1334
|
+
{
|
|
1335
|
+
className: cn(
|
|
1336
|
+
"flex flex-col gap-1 @md:flex-row @md:items-baseline",
|
|
1337
|
+
tight ? "px-4 py-2.5 @md:gap-5" : "px-5 py-3.5 @md:gap-6"
|
|
1338
|
+
),
|
|
1339
|
+
children: [
|
|
1340
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { className: cn("shrink-0 text-muted-foreground", tight ? "text-[0.8125rem] @md:w-36" : "text-[0.875rem] @md:w-48"), children: it.label }),
|
|
1341
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1342
|
+
"dd",
|
|
1343
|
+
{
|
|
1344
|
+
className: cn(
|
|
1345
|
+
"min-w-0 break-words",
|
|
1346
|
+
tight ? "text-[0.875rem]" : "text-[0.9375rem]",
|
|
1347
|
+
it.mono && (tight ? "font-mono text-[0.8125rem]" : "font-mono text-[0.875rem]")
|
|
1348
|
+
),
|
|
1349
|
+
children: it.value
|
|
1350
|
+
}
|
|
1351
|
+
)
|
|
1352
|
+
]
|
|
1353
|
+
},
|
|
1354
|
+
i
|
|
1355
|
+
)) })
|
|
1356
|
+
);
|
|
758
1357
|
}
|
|
759
1358
|
function DataTable({
|
|
760
1359
|
columns,
|
|
@@ -763,8 +1362,11 @@ function DataTable({
|
|
|
763
1362
|
empty,
|
|
764
1363
|
caption,
|
|
765
1364
|
phone = "cards",
|
|
1365
|
+
dense,
|
|
766
1366
|
className
|
|
767
1367
|
}) {
|
|
1368
|
+
const density = useDensity();
|
|
1369
|
+
const tight = dense ?? density === "compact";
|
|
768
1370
|
if (rows.length === 0 && empty) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: empty });
|
|
769
1371
|
const primary = columns.find((c) => c.primary) ?? columns[0];
|
|
770
1372
|
const right = (c) => c.numeric || c.align === "end";
|
|
@@ -772,11 +1374,12 @@ function DataTable({
|
|
|
772
1374
|
"div",
|
|
773
1375
|
{
|
|
774
1376
|
className: cn(
|
|
775
|
-
"overflow-hidden
|
|
1377
|
+
"overflow-hidden border border-border bg-card",
|
|
1378
|
+
tight ? "rounded-2xl" : "rounded-[1.25rem]",
|
|
776
1379
|
phone === "cards" && "max-sm:hidden",
|
|
777
1380
|
className
|
|
778
1381
|
),
|
|
779
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse text-left text-[0.9375rem]", children: [
|
|
1382
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: cn("w-full border-collapse text-left", tight ? "text-[0.875rem]" : "text-[0.9375rem]"), children: [
|
|
780
1383
|
caption ? /* @__PURE__ */ jsxRuntime.jsx("caption", { className: "sr-only", children: caption }) : null,
|
|
781
1384
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "border-b border-border", children: columns.map((c) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
782
1385
|
"th",
|
|
@@ -784,7 +1387,8 @@ function DataTable({
|
|
|
784
1387
|
scope: "col",
|
|
785
1388
|
style: { width: c.width, minWidth: c.minWidth },
|
|
786
1389
|
className: cn(
|
|
787
|
-
"whitespace-nowrap
|
|
1390
|
+
"whitespace-nowrap text-[0.8125rem] font-medium text-muted-foreground",
|
|
1391
|
+
tight ? "px-4 py-2.5" : "px-5 py-3",
|
|
788
1392
|
right(c) && "text-right",
|
|
789
1393
|
c.wide && "hidden md:table-cell"
|
|
790
1394
|
),
|
|
@@ -797,7 +1401,8 @@ function DataTable({
|
|
|
797
1401
|
{
|
|
798
1402
|
style: { minWidth: c.minWidth },
|
|
799
1403
|
className: cn(
|
|
800
|
-
"
|
|
1404
|
+
"align-middle",
|
|
1405
|
+
tight ? "px-4 py-2" : "px-5 py-3.5",
|
|
801
1406
|
right(c) && "text-right",
|
|
802
1407
|
c.numeric && "whitespace-nowrap oca-tabular",
|
|
803
1408
|
c.wide && "hidden md:table-cell"
|
|
@@ -817,8 +1422,12 @@ function DataTable({
|
|
|
817
1422
|
"ul",
|
|
818
1423
|
{
|
|
819
1424
|
"aria-label": caption,
|
|
820
|
-
className: cn(
|
|
821
|
-
|
|
1425
|
+
className: cn(
|
|
1426
|
+
"divide-y divide-border border border-border bg-card sm:hidden",
|
|
1427
|
+
tight ? "rounded-2xl" : "rounded-[1.25rem]",
|
|
1428
|
+
className
|
|
1429
|
+
),
|
|
1430
|
+
children: rows.map((r, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: cn("flex flex-col gap-2.5 px-4", tight ? "py-3" : "py-4"), children: [
|
|
822
1431
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 break-words text-[0.9375rem] font-medium", children: primary?.cell(r) }),
|
|
823
1432
|
rest.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("dl", { className: "grid grid-cols-[minmax(5.5rem,auto)_minmax(0,1fr)] gap-x-4 gap-y-1.5 text-[0.875rem]", children: rest.map((c) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "contents", children: [
|
|
824
1433
|
/* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-muted-foreground", children: c.header }),
|
|
@@ -865,13 +1474,14 @@ function Notice({
|
|
|
865
1474
|
title,
|
|
866
1475
|
children,
|
|
867
1476
|
action,
|
|
1477
|
+
role,
|
|
868
1478
|
className
|
|
869
1479
|
}) {
|
|
870
1480
|
const kind = NOTICE_KIND[tone];
|
|
871
1481
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
872
1482
|
"div",
|
|
873
1483
|
{
|
|
874
|
-
role: tone === "danger" || tone === "warning" ? "alert" : "note",
|
|
1484
|
+
role: role ?? (tone === "danger" || tone === "warning" ? "alert" : "note"),
|
|
875
1485
|
"data-tone": kind,
|
|
876
1486
|
className: cn(
|
|
877
1487
|
"flex flex-col gap-3 rounded-2xl border border-border bg-card px-5 py-4 sm:flex-row sm:items-start sm:justify-between",
|
|
@@ -921,45 +1531,66 @@ function LoadingBlock({
|
|
|
921
1531
|
}
|
|
922
1532
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "status", "aria-label": label, className: cn("flex flex-col gap-3", className), children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-16 rounded-2xl" }, i)) });
|
|
923
1533
|
}
|
|
924
|
-
function
|
|
925
|
-
|
|
1534
|
+
async function wipeIfUnchanged(expected) {
|
|
1535
|
+
try {
|
|
1536
|
+
if (await navigator.clipboard.readText() !== expected) return;
|
|
1537
|
+
} catch {
|
|
1538
|
+
}
|
|
1539
|
+
try {
|
|
1540
|
+
await navigator.clipboard.writeText("");
|
|
1541
|
+
} catch {
|
|
1542
|
+
}
|
|
926
1543
|
}
|
|
927
1544
|
function useCopy(timeoutMs = 1600) {
|
|
928
1545
|
const [copied, setCopied] = react.useState(false);
|
|
929
1546
|
const t = react.useRef(null);
|
|
930
|
-
react.
|
|
931
|
-
|
|
932
|
-
|
|
1547
|
+
const wipe = react.useRef(null);
|
|
1548
|
+
react.useEffect(
|
|
1549
|
+
() => () => {
|
|
1550
|
+
if (t.current) clearTimeout(t.current);
|
|
1551
|
+
},
|
|
1552
|
+
[]
|
|
1553
|
+
);
|
|
933
1554
|
const copy = react.useCallback(
|
|
934
|
-
async (text) => {
|
|
1555
|
+
async (text, opts = {}) => {
|
|
935
1556
|
try {
|
|
936
1557
|
await navigator.clipboard.writeText(text);
|
|
937
1558
|
setCopied(true);
|
|
938
1559
|
if (t.current) clearTimeout(t.current);
|
|
939
1560
|
t.current = setTimeout(() => setCopied(false), timeoutMs);
|
|
1561
|
+
if (opts.clearAfter && opts.clearAfter > 0) {
|
|
1562
|
+
if (wipe.current) clearTimeout(wipe.current);
|
|
1563
|
+
wipe.current = setTimeout(() => void wipeIfUnchanged(text), opts.clearAfter);
|
|
1564
|
+
}
|
|
1565
|
+
return true;
|
|
940
1566
|
} catch {
|
|
941
1567
|
setCopied(false);
|
|
1568
|
+
return false;
|
|
942
1569
|
}
|
|
943
1570
|
},
|
|
944
1571
|
[timeoutMs]
|
|
945
1572
|
);
|
|
946
1573
|
return { copied, copy };
|
|
947
1574
|
}
|
|
948
|
-
function CopyButton({ value, label = "Copy", className }) {
|
|
1575
|
+
function CopyButton({ value, label = "Copy", clearAfter, onCopied, className }) {
|
|
949
1576
|
const { copied, copy } = useCopy();
|
|
1577
|
+
const done = copied ? clearAfter ? `Copied. Cleared in ${Math.round(clearAfter / 1e3)} seconds` : "Copied" : "";
|
|
950
1578
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
951
1579
|
"button",
|
|
952
1580
|
{
|
|
953
1581
|
type: "button",
|
|
954
|
-
onClick: () =>
|
|
1582
|
+
onClick: async () => {
|
|
1583
|
+
if (await copy(typeof value === "function" ? value() : value, { clearAfter })) onCopied?.();
|
|
1584
|
+
},
|
|
955
1585
|
"aria-label": copied ? "Copied" : label,
|
|
1586
|
+
title: label,
|
|
956
1587
|
className: cn(
|
|
957
1588
|
"inline-flex size-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
958
1589
|
className
|
|
959
1590
|
),
|
|
960
1591
|
children: [
|
|
961
1592
|
copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-4 text-success" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "size-4" }),
|
|
962
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-live": "polite", className: "sr-only", children:
|
|
1593
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-live": "polite", className: "sr-only", children: done })
|
|
963
1594
|
]
|
|
964
1595
|
}
|
|
965
1596
|
);
|
|
@@ -970,12 +1601,27 @@ function HashChip({
|
|
|
970
1601
|
tail = 6,
|
|
971
1602
|
copy = true,
|
|
972
1603
|
href,
|
|
1604
|
+
explorer,
|
|
1605
|
+
network = "mainnet",
|
|
973
1606
|
className
|
|
974
1607
|
}) {
|
|
975
|
-
const shown =
|
|
1608
|
+
const shown = shortenMiddle(value, head, tail);
|
|
1609
|
+
const link = href ?? (explorer ? explorerUrl(explorer, value, network) : void 0);
|
|
1610
|
+
const offsite = !!link && /^https?:\/\//.test(link);
|
|
976
1611
|
const text = /* @__PURE__ */ jsxRuntime.jsx("span", { title: value, className: "font-mono text-[0.875rem]", children: shown });
|
|
977
1612
|
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("inline-flex max-w-full items-center gap-1", className), children: [
|
|
978
|
-
|
|
1613
|
+
link ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1614
|
+
"a",
|
|
1615
|
+
{
|
|
1616
|
+
href: link,
|
|
1617
|
+
...offsite ? { target: "_blank", rel: "noreferrer" } : {},
|
|
1618
|
+
className: "underline decoration-foreground/35 underline-offset-4 hover:decoration-foreground",
|
|
1619
|
+
children: [
|
|
1620
|
+
text,
|
|
1621
|
+
offsite ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: " (opens in a new tab)" }) : null
|
|
1622
|
+
]
|
|
1623
|
+
}
|
|
1624
|
+
) : text,
|
|
979
1625
|
copy ? /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value, label: "Copy full value" }) : null
|
|
980
1626
|
] });
|
|
981
1627
|
}
|
|
@@ -1029,96 +1675,269 @@ function ActivityList({ items, empty, className }) {
|
|
|
1029
1675
|
return /* @__PURE__ */ jsxRuntime.jsx("li", { children: it.href ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: it.href, className: "block transition-colors hover:bg-accent/60", children: body }) : body }, it.id);
|
|
1030
1676
|
}) });
|
|
1031
1677
|
}
|
|
1032
|
-
var
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1678
|
+
var LANG_NAME = {
|
|
1679
|
+
ts: "TypeScript",
|
|
1680
|
+
typescript: "TypeScript",
|
|
1681
|
+
tsx: "TSX",
|
|
1682
|
+
js: "JavaScript",
|
|
1683
|
+
javascript: "JavaScript",
|
|
1684
|
+
jsx: "JSX",
|
|
1685
|
+
mjs: "JavaScript",
|
|
1686
|
+
json: "JSON",
|
|
1687
|
+
jsonc: "JSON",
|
|
1688
|
+
bash: "Shell",
|
|
1689
|
+
sh: "Shell",
|
|
1690
|
+
shell: "Shell",
|
|
1691
|
+
zsh: "Shell",
|
|
1692
|
+
console: "Terminal",
|
|
1693
|
+
terminal: "Terminal",
|
|
1694
|
+
python: "Python",
|
|
1695
|
+
py: "Python",
|
|
1696
|
+
yaml: "YAML",
|
|
1697
|
+
yml: "YAML",
|
|
1698
|
+
diff: "Diff",
|
|
1699
|
+
text: "Text"
|
|
1036
1700
|
};
|
|
1037
|
-
function
|
|
1038
|
-
return
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1701
|
+
function languageName(lang) {
|
|
1702
|
+
return lang ? LANG_NAME[lang.toLowerCase()] ?? lang : void 0;
|
|
1703
|
+
}
|
|
1704
|
+
function forClipboard(text, lang) {
|
|
1705
|
+
if (grammarOf(lang) !== "shell") return text;
|
|
1706
|
+
const lines = text.split("\n");
|
|
1707
|
+
if (!lines.some((l) => l.startsWith("$ "))) return text;
|
|
1708
|
+
return lines.filter((l) => l.startsWith("$ ")).map((l) => l.slice(2)).join("\n");
|
|
1709
|
+
}
|
|
1710
|
+
function linesFromDom(pre) {
|
|
1711
|
+
if (!pre) return null;
|
|
1712
|
+
const lines = pre.querySelectorAll("[data-line]");
|
|
1713
|
+
if (lines.length === 0) return pre.textContent ?? "";
|
|
1714
|
+
return Array.from(lines).filter((l) => l.getAttribute("data-diff") !== "remove").map((l) => l.textContent ?? "").join("\n");
|
|
1715
|
+
}
|
|
1716
|
+
function prepare(code, lang, marks, diff) {
|
|
1717
|
+
const d = diff ? readDiff(code) : null;
|
|
1718
|
+
const src = d ? d.code : code.replace(/\r?\n$/, "");
|
|
1719
|
+
const lines = highlight(src, lang === "diff" ? void 0 : lang);
|
|
1720
|
+
const kept = d ? src.split("\n").filter((_, i) => d.diff.get(i + 1) !== "remove") : null;
|
|
1721
|
+
return {
|
|
1722
|
+
html: linesToHtml(lines, { highlight: parseLineRanges(marks), diff: d?.diff }),
|
|
1723
|
+
copy: kept ? kept.join("\n") : src,
|
|
1724
|
+
lines: lines.length,
|
|
1725
|
+
diff: !!d
|
|
1726
|
+
};
|
|
1727
|
+
}
|
|
1728
|
+
function Well({
|
|
1729
|
+
preRef,
|
|
1730
|
+
html,
|
|
1731
|
+
children,
|
|
1732
|
+
lang,
|
|
1733
|
+
lines,
|
|
1734
|
+
maxLines,
|
|
1735
|
+
diff,
|
|
1736
|
+
lineNumbers
|
|
1737
|
+
}) {
|
|
1738
|
+
const foldable = maxLines !== void 0 && lines > maxLines + 2;
|
|
1739
|
+
const [open, setOpen] = react.useState(false);
|
|
1740
|
+
const folded = foldable && !open;
|
|
1741
|
+
const lined = html !== void 0;
|
|
1742
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1743
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1744
|
+
"div",
|
|
1745
|
+
{
|
|
1746
|
+
className: cn(folded && "overflow-hidden"),
|
|
1747
|
+
style: folded ? { maxHeight: `calc(${maxLines} * 1.625em + 2rem)` } : void 0,
|
|
1748
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--oca-code-surface)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1749
|
+
"pre",
|
|
1750
|
+
{
|
|
1751
|
+
ref: preRef,
|
|
1752
|
+
"data-diff": diff ? "" : void 0,
|
|
1753
|
+
"data-line-numbers": lineNumbers ? "" : void 0,
|
|
1754
|
+
className: cn(
|
|
1755
|
+
"oca-code w-max min-w-full py-4 font-mono text-[0.875rem] leading-[1.625] text-oca-ink-muted [font-variant-ligatures:none]",
|
|
1756
|
+
!lined && "px-5"
|
|
1757
|
+
),
|
|
1758
|
+
children: lined ? /* @__PURE__ */ jsxRuntime.jsx("code", { className: "block", "data-lang": lang, dangerouslySetInnerHTML: { __html: html } }) : /* @__PURE__ */ jsxRuntime.jsx("code", { className: "block", "data-lang": lang, children })
|
|
1759
|
+
}
|
|
1760
|
+
) })
|
|
1761
|
+
}
|
|
1762
|
+
),
|
|
1763
|
+
foldable ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1764
|
+
"div",
|
|
1765
|
+
{
|
|
1766
|
+
className: cn("flex justify-center px-5 pb-4", folded && "absolute inset-x-0 bottom-0 pt-16"),
|
|
1767
|
+
style: folded ? { background: "linear-gradient(to top, var(--oca-code-surface) 40%, transparent)" } : void 0,
|
|
1768
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1769
|
+
"button",
|
|
1770
|
+
{
|
|
1771
|
+
type: "button",
|
|
1772
|
+
onClick: () => setOpen((v) => !v),
|
|
1773
|
+
"aria-expanded": open,
|
|
1774
|
+
className: "rounded-full border border-white/20 px-4 py-1.5 text-[0.8125rem] text-white transition-colors hover:bg-white/10",
|
|
1775
|
+
children: open ? "Show less" : `Show all ${lines} lines`
|
|
1776
|
+
}
|
|
1777
|
+
)
|
|
1778
|
+
}
|
|
1779
|
+
) : null
|
|
1780
|
+
] });
|
|
1058
1781
|
}
|
|
1782
|
+
var FRAME = "overflow-hidden rounded-[1.25rem] border border-[var(--oca-code-line)] bg-[var(--oca-code-surface)]";
|
|
1783
|
+
var COPY_ON_INK = "text-oca-ink-subtle hover:bg-white/10 hover:text-white";
|
|
1059
1784
|
function CodeBlock({
|
|
1060
1785
|
code,
|
|
1786
|
+
html,
|
|
1787
|
+
children,
|
|
1788
|
+
lang,
|
|
1061
1789
|
caption,
|
|
1062
1790
|
copy = true,
|
|
1791
|
+
clearAfter,
|
|
1063
1792
|
maxLines,
|
|
1793
|
+
highlight: marks,
|
|
1794
|
+
diff,
|
|
1795
|
+
lineNumbers,
|
|
1796
|
+
actions,
|
|
1064
1797
|
className
|
|
1065
1798
|
}) {
|
|
1066
|
-
const
|
|
1067
|
-
const
|
|
1068
|
-
const
|
|
1069
|
-
const
|
|
1799
|
+
const preRef = react.useRef(null);
|
|
1800
|
+
const isDiff = diff || lang === "diff";
|
|
1801
|
+
const markKey = typeof marks === "string" ? marks : marks?.join(",");
|
|
1802
|
+
const prepared = react.useMemo(
|
|
1803
|
+
() => html === void 0 && children === void 0 && code !== void 0 ? prepare(code, lang, markKey, !!isDiff) : null,
|
|
1804
|
+
[code, html, children, lang, markKey, isDiff]
|
|
1805
|
+
);
|
|
1806
|
+
const markup = prepared?.html ?? html;
|
|
1807
|
+
const lines = prepared?.lines ?? (html !== void 0 ? html.split("\n").length : code?.split("\n").length ?? 0);
|
|
1808
|
+
const read = () => forClipboard(prepared?.copy ?? linesFromDom(preRef.current) ?? code ?? "", lang);
|
|
1809
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("figure", { className: cn(FRAME, className), children: [
|
|
1810
|
+
/* @__PURE__ */ jsxRuntime.jsxs("figcaption", { className: "flex h-11 items-center justify-between gap-3 border-b border-[var(--oca-code-line)] pl-5 pr-2", children: [
|
|
1811
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[0.8125rem] text-oca-ink-subtle", children: caption ?? languageName(lang) ?? "Code" }),
|
|
1812
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
1813
|
+
actions,
|
|
1814
|
+
copy ? /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: read, label: "Copy code", clearAfter, className: COPY_ON_INK }) : null
|
|
1815
|
+
] })
|
|
1816
|
+
] }),
|
|
1817
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1818
|
+
Well,
|
|
1819
|
+
{
|
|
1820
|
+
preRef,
|
|
1821
|
+
html: markup,
|
|
1822
|
+
lang,
|
|
1823
|
+
lines,
|
|
1824
|
+
maxLines,
|
|
1825
|
+
diff: prepared ? prepared.diff : isDiff,
|
|
1826
|
+
lineNumbers,
|
|
1827
|
+
children
|
|
1828
|
+
}
|
|
1829
|
+
)
|
|
1830
|
+
] });
|
|
1831
|
+
}
|
|
1832
|
+
var tabListeners = /* @__PURE__ */ new Map();
|
|
1833
|
+
var tabMemory = /* @__PURE__ */ new Map();
|
|
1834
|
+
var storeKey = (k) => `oca-code-tab:${k}`;
|
|
1835
|
+
function readTab(key) {
|
|
1836
|
+
if (tabMemory.has(key)) return tabMemory.get(key);
|
|
1837
|
+
try {
|
|
1838
|
+
return window.localStorage.getItem(storeKey(key));
|
|
1839
|
+
} catch {
|
|
1840
|
+
return null;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
function writeTab(key, value) {
|
|
1844
|
+
tabMemory.set(key, value);
|
|
1845
|
+
try {
|
|
1846
|
+
window.localStorage.setItem(storeKey(key), value);
|
|
1847
|
+
} catch {
|
|
1848
|
+
}
|
|
1849
|
+
tabListeners.get(key)?.forEach((l) => l());
|
|
1850
|
+
}
|
|
1851
|
+
function useSyncedTab(key) {
|
|
1852
|
+
const subscribe = react.useCallback(
|
|
1853
|
+
(cb) => {
|
|
1854
|
+
if (!key) return () => {
|
|
1855
|
+
};
|
|
1856
|
+
const set = tabListeners.get(key) ?? /* @__PURE__ */ new Set();
|
|
1857
|
+
set.add(cb);
|
|
1858
|
+
tabListeners.set(key, set);
|
|
1859
|
+
return () => {
|
|
1860
|
+
set.delete(cb);
|
|
1861
|
+
};
|
|
1862
|
+
},
|
|
1863
|
+
[key]
|
|
1864
|
+
);
|
|
1865
|
+
const value = react.useSyncExternalStore(
|
|
1866
|
+
subscribe,
|
|
1867
|
+
() => key ? readTab(key) : null,
|
|
1868
|
+
() => null
|
|
1869
|
+
);
|
|
1870
|
+
return [value, (v) => key && writeTab(key, v)];
|
|
1871
|
+
}
|
|
1872
|
+
function CodeTabs({
|
|
1873
|
+
items,
|
|
1874
|
+
syncKey,
|
|
1875
|
+
defaultValue,
|
|
1876
|
+
maxLines,
|
|
1877
|
+
className
|
|
1878
|
+
}) {
|
|
1879
|
+
const [synced, setSynced] = useSyncedTab(syncKey);
|
|
1880
|
+
const [local, setLocal] = react.useState(null);
|
|
1881
|
+
const labels = items.map((it) => it.label);
|
|
1882
|
+
const pick = [local, synced, defaultValue].find((v) => !!v && labels.includes(v)) ?? labels[0] ?? "";
|
|
1883
|
+
const active = items.find((it) => it.label === pick);
|
|
1884
|
+
const prepared = react.useMemo(() => items.map((it) => prepare(it.code, it.lang, void 0, it.lang === "diff")), [items]);
|
|
1070
1885
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1071
|
-
|
|
1886
|
+
TabsPrimitive__namespace.Root,
|
|
1072
1887
|
{
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1888
|
+
value: pick,
|
|
1889
|
+
onValueChange: (v) => {
|
|
1890
|
+
setLocal(v);
|
|
1891
|
+
setSynced(v);
|
|
1892
|
+
},
|
|
1893
|
+
className: cn(FRAME, className),
|
|
1077
1894
|
children: [
|
|
1078
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
1079
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
1080
|
-
|
|
1081
|
-
CopyButton,
|
|
1082
|
-
{
|
|
1083
|
-
value: code,
|
|
1084
|
-
label: "Copy code",
|
|
1085
|
-
className: "text-oca-ink-subtle hover:bg-white/10 hover:text-white"
|
|
1086
|
-
}
|
|
1087
|
-
) : null
|
|
1088
|
-
] }),
|
|
1089
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1090
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1091
|
-
"div",
|
|
1092
|
-
{
|
|
1093
|
-
className: cn(folded && "overflow-hidden"),
|
|
1094
|
-
style: folded ? { maxHeight: `calc(${maxLines} * 1.625em + 2.5rem)` } : void 0,
|
|
1095
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--oca-code-surface)", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "w-max min-w-full p-5 font-mono text-[0.875rem] leading-[1.625] text-oca-ink-muted [font-variant-ligatures:none]", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: code }) }) })
|
|
1096
|
-
}
|
|
1097
|
-
),
|
|
1098
|
-
foldable ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1099
|
-
"div",
|
|
1895
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-11 items-center justify-between gap-3 border-b border-[var(--oca-code-line)] pl-2 pr-2", children: [
|
|
1896
|
+
/* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--oca-code-surface)", className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(TabsPrimitive__namespace.List, { "aria-label": "Versions", className: "flex w-max items-center gap-0.5", children: items.map((it) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1897
|
+
TabsPrimitive__namespace.Trigger,
|
|
1100
1898
|
{
|
|
1899
|
+
value: it.label,
|
|
1101
1900
|
className: cn(
|
|
1102
|
-
"flex
|
|
1103
|
-
|
|
1901
|
+
"relative inline-flex h-11 items-center whitespace-nowrap px-3 text-[0.8125rem] text-oca-ink-subtle outline-none transition-colors",
|
|
1902
|
+
"hover:text-white focus-visible:text-white focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
|
|
1903
|
+
"data-[state=active]:text-white",
|
|
1904
|
+
"after:absolute after:inset-x-3 after:bottom-0 after:h-0.5 after:rounded-full after:bg-transparent data-[state=active]:after:bg-oca-orange"
|
|
1104
1905
|
),
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1906
|
+
children: it.label
|
|
1907
|
+
},
|
|
1908
|
+
it.label
|
|
1909
|
+
)) }) }),
|
|
1910
|
+
active ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1911
|
+
CopyButton,
|
|
1912
|
+
{
|
|
1913
|
+
value: () => forClipboard(prepared[items.indexOf(active)]?.copy ?? active.code, active.lang),
|
|
1914
|
+
label: `Copy ${active.label}`,
|
|
1915
|
+
className: COPY_ON_INK
|
|
1115
1916
|
}
|
|
1116
1917
|
) : null
|
|
1117
|
-
] })
|
|
1918
|
+
] }),
|
|
1919
|
+
items.map((it, i) => /* @__PURE__ */ jsxRuntime.jsx(TabsPrimitive__namespace.Content, { value: it.label, className: "outline-none", tabIndex: -1, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1920
|
+
Well,
|
|
1921
|
+
{
|
|
1922
|
+
html: prepared[i].html,
|
|
1923
|
+
lang: it.lang,
|
|
1924
|
+
lines: prepared[i].lines,
|
|
1925
|
+
maxLines,
|
|
1926
|
+
diff: prepared[i].diff
|
|
1927
|
+
}
|
|
1928
|
+
) }, it.label))
|
|
1118
1929
|
]
|
|
1119
1930
|
}
|
|
1120
1931
|
);
|
|
1121
1932
|
}
|
|
1933
|
+
function InstallTabs({ pkg, dev = false, className }) {
|
|
1934
|
+
const items = [
|
|
1935
|
+
{ label: "npm", code: `npm install ${dev ? "--save-dev " : ""}${pkg}`, lang: "bash" },
|
|
1936
|
+
{ label: "yarn", code: `yarn add ${dev ? "--dev " : ""}${pkg}`, lang: "bash" },
|
|
1937
|
+
{ label: "pnpm", code: `pnpm add ${dev ? "--save-dev " : ""}${pkg}`, lang: "bash" }
|
|
1938
|
+
];
|
|
1939
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CodeTabs, { items, syncKey: "package-manager", className });
|
|
1940
|
+
}
|
|
1122
1941
|
function SplitBar({
|
|
1123
1942
|
segments,
|
|
1124
1943
|
caption,
|
|
@@ -2046,7 +2865,14 @@ function ProtocolGrid({
|
|
|
2046
2865
|
] }),
|
|
2047
2866
|
p.status !== "live" ? /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: p.status }) : null
|
|
2048
2867
|
] }),
|
|
2049
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "oca-display-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2868
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "oca-display-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2869
|
+
"a",
|
|
2870
|
+
{
|
|
2871
|
+
href: link === "tool" ? p.toolHref : link === "docs" ? `${DOCS_HREF}/${p.slug}` : p.pageHref,
|
|
2872
|
+
className: STRETCH,
|
|
2873
|
+
children: p.label
|
|
2874
|
+
}
|
|
2875
|
+
) }),
|
|
2050
2876
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-body", children: p.line }),
|
|
2051
2877
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-auto flex items-center justify-between gap-3 pt-2 text-[0.875rem] text-muted-foreground", children: [
|
|
2052
2878
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "oca-tabular", children: [
|
|
@@ -2098,9 +2924,25 @@ var fieldBase = [
|
|
|
2098
2924
|
"disabled:cursor-not-allowed disabled:opacity-55",
|
|
2099
2925
|
"aria-[invalid=true]:border-destructive aria-[invalid=true]:focus:ring-[color-mix(in_oklab,var(--destructive)_14%,transparent)]"
|
|
2100
2926
|
];
|
|
2101
|
-
var
|
|
2102
|
-
|
|
2103
|
-
|
|
2927
|
+
var FIELD_SIZE = {
|
|
2928
|
+
md: "h-11 px-3.5",
|
|
2929
|
+
sm: "h-9 rounded-[0.625rem] px-3 md:text-[0.875rem]"
|
|
2930
|
+
};
|
|
2931
|
+
var Input = react.forwardRef(function Input2({ className, type = "text", size, ...props }, ref) {
|
|
2932
|
+
const density = useDensity();
|
|
2933
|
+
const s = size ?? (density === "compact" ? "sm" : "md");
|
|
2934
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2935
|
+
"input",
|
|
2936
|
+
{
|
|
2937
|
+
ref,
|
|
2938
|
+
type,
|
|
2939
|
+
"data-ui": "input",
|
|
2940
|
+
"data-size": s,
|
|
2941
|
+
className: cn(fieldBase, FIELD_SIZE[s], className),
|
|
2942
|
+
...props
|
|
2943
|
+
}
|
|
2944
|
+
);
|
|
2945
|
+
});
|
|
2104
2946
|
var Textarea = react.forwardRef(
|
|
2105
2947
|
function Textarea2({ className, ...props }, ref) {
|
|
2106
2948
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2156,12 +2998,19 @@ function Field({ label, hint, optional, error, children, className, hideLabel, a
|
|
|
2156
2998
|
error ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, role: "alert", className: "text-[0.8125rem] leading-snug text-destructive", children: error }) : null
|
|
2157
2999
|
] });
|
|
2158
3000
|
}
|
|
2159
|
-
|
|
3001
|
+
var SelectFieldContext = sharedContext("select-field", null);
|
|
3002
|
+
react.forwardRef(function SelectTrigger2({ className, children, size, ...props }, ref) {
|
|
3003
|
+
const density = useDensity();
|
|
3004
|
+
const field = react.useContext(SelectFieldContext);
|
|
3005
|
+
const s = size ?? (density === "compact" ? "sm" : "md");
|
|
2160
3006
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2161
3007
|
SelectPrimitive__namespace.Trigger,
|
|
2162
3008
|
{
|
|
2163
3009
|
ref,
|
|
2164
|
-
|
|
3010
|
+
id: field?.id,
|
|
3011
|
+
"aria-describedby": field?.["aria-describedby"],
|
|
3012
|
+
"aria-invalid": field?.["aria-invalid"],
|
|
3013
|
+
className: cn(fieldBase, FIELD_SIZE[s], "flex items-center justify-between gap-2 text-left", className),
|
|
2165
3014
|
...props,
|
|
2166
3015
|
children: [
|
|
2167
3016
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children }),
|
|
@@ -2510,6 +3359,7 @@ function VerifyReport({
|
|
|
2510
3359
|
facts,
|
|
2511
3360
|
notChecked,
|
|
2512
3361
|
actions,
|
|
3362
|
+
as: Heading = "h2",
|
|
2513
3363
|
className
|
|
2514
3364
|
}) {
|
|
2515
3365
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2520,7 +3370,7 @@ function VerifyReport({
|
|
|
2520
3370
|
children: [
|
|
2521
3371
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col items-start gap-3 p-6 md:p-8", children: [
|
|
2522
3372
|
/* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: verdict }),
|
|
2523
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3373
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { className: "oca-display-3", children: title }),
|
|
2524
3374
|
summary ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-body max-w-[40rem]", children: summary }) : null
|
|
2525
3375
|
] }),
|
|
2526
3376
|
/* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": "Checks", className: "divide-y divide-border border-t border-border", children: checks.map((c, i) => {
|
|
@@ -2620,21 +3470,1219 @@ function SignMessage({
|
|
|
2620
3470
|
)
|
|
2621
3471
|
] });
|
|
2622
3472
|
}
|
|
3473
|
+
var isInternal = (href) => href.startsWith("/") || href.startsWith("#");
|
|
3474
|
+
function DocLink({ href, className, children, ...rest }) {
|
|
3475
|
+
return isInternal(href) ? /* @__PURE__ */ jsxRuntime.jsx(Link__default.default, { href, className, ...rest, children }) : /* @__PURE__ */ jsxRuntime.jsx("a", { href, className, ...rest, children });
|
|
3476
|
+
}
|
|
3477
|
+
function Breadcrumbs({ items, action, className }) {
|
|
3478
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex min-h-11 items-center justify-between gap-4 sm:min-h-0", className), children: [
|
|
3479
|
+
/* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Breadcrumb", className: "min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "flex min-w-0 items-center gap-1.5 text-[0.875rem] text-muted-foreground", children: items.map((c, i) => {
|
|
3480
|
+
const last = i === items.length - 1;
|
|
3481
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: cn("flex items-center gap-1.5", last ? "min-w-0" : "shrink-0"), children: [
|
|
3482
|
+
c.href && !last ? /* @__PURE__ */ jsxRuntime.jsx(DocLink, { href: c.href, className: "inline-flex min-h-11 items-center transition-colors hover:text-foreground sm:min-h-0", children: c.label }) : /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-current": last ? "page" : void 0, className: cn("truncate", last && "text-foreground"), children: c.label }),
|
|
3483
|
+
!last ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": true, className: "size-3.5 shrink-0 text-oca-subtle" }) : null
|
|
3484
|
+
] }, i);
|
|
3485
|
+
}) }) }),
|
|
3486
|
+
action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 text-[0.875rem]", children: action }) : null
|
|
3487
|
+
] });
|
|
3488
|
+
}
|
|
3489
|
+
function DocsPager({ prev, next, className }) {
|
|
3490
|
+
if (!prev && !next) return null;
|
|
3491
|
+
const card = (l, dir) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3492
|
+
DocLink,
|
|
3493
|
+
{
|
|
3494
|
+
href: l.href,
|
|
3495
|
+
className: cn(
|
|
3496
|
+
"group flex min-h-20 flex-col justify-center gap-1 rounded-2xl border border-border bg-card px-5 py-4 transition-colors hover:border-oca-hairline-strong",
|
|
3497
|
+
dir === "next" && "items-end text-right sm:col-start-2"
|
|
3498
|
+
),
|
|
3499
|
+
children: [
|
|
3500
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5 text-[0.8125rem] text-muted-foreground", children: [
|
|
3501
|
+
dir === "prev" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { "aria-hidden": true, className: "size-3.5" }) : null,
|
|
3502
|
+
dir === "prev" ? "Previous" : "Next",
|
|
3503
|
+
l.section ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, children: "\xB7" }) : null,
|
|
3504
|
+
l.section ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: l.section }) : null,
|
|
3505
|
+
dir === "next" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { "aria-hidden": true, className: "size-3.5" }) : null
|
|
3506
|
+
] }),
|
|
3507
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: l.label })
|
|
3508
|
+
]
|
|
3509
|
+
}
|
|
3510
|
+
);
|
|
3511
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("nav", { "aria-label": "Previous and next page", className: cn("grid grid-cols-1 gap-3 border-t border-border pt-8 sm:grid-cols-2", className), children: [
|
|
3512
|
+
prev ? card(prev, "prev") : null,
|
|
3513
|
+
next ? card(next, "next") : null
|
|
3514
|
+
] });
|
|
3515
|
+
}
|
|
3516
|
+
function useHeadings(selector = "#docs-content", key) {
|
|
3517
|
+
const [items, setItems] = react.useState([]);
|
|
3518
|
+
react.useEffect(() => {
|
|
3519
|
+
const read = () => {
|
|
3520
|
+
const root = document.querySelector(selector);
|
|
3521
|
+
if (!root) return setItems([]);
|
|
3522
|
+
setItems(
|
|
3523
|
+
Array.from(root.querySelectorAll("h2[id], h3[id]")).map((h) => ({
|
|
3524
|
+
id: h.id,
|
|
3525
|
+
// The anchor link's "#" is not part of the name.
|
|
3526
|
+
label: (h.querySelector("[data-heading-text]") ?? h).textContent?.trim() ?? "",
|
|
3527
|
+
level: h.tagName === "H3" ? 3 : 2
|
|
3528
|
+
}))
|
|
3529
|
+
);
|
|
3530
|
+
};
|
|
3531
|
+
const raf = requestAnimationFrame(read);
|
|
3532
|
+
const t = setTimeout(read, 80);
|
|
3533
|
+
return () => {
|
|
3534
|
+
cancelAnimationFrame(raf);
|
|
3535
|
+
clearTimeout(t);
|
|
3536
|
+
};
|
|
3537
|
+
}, [selector, key]);
|
|
3538
|
+
const activeId = useActiveHeading(items.map((i) => i.id));
|
|
3539
|
+
return { items, activeId };
|
|
3540
|
+
}
|
|
3541
|
+
function OnThisPage({
|
|
3542
|
+
items,
|
|
3543
|
+
activeId,
|
|
3544
|
+
title = "On this page",
|
|
3545
|
+
onNavigate,
|
|
3546
|
+
className
|
|
3547
|
+
}) {
|
|
3548
|
+
const id = react.useId();
|
|
3549
|
+
if (items.length === 0) return null;
|
|
3550
|
+
return (
|
|
3551
|
+
// With no visible title (a folded list under its own summary) the name is still "On this page".
|
|
3552
|
+
/* @__PURE__ */ jsxRuntime.jsxs("nav", { "aria-labelledby": title ? id : void 0, "aria-label": title ? void 0 : "On this page", className, children: [
|
|
3553
|
+
title ? /* @__PURE__ */ jsxRuntime.jsx("p", { id, className: "mb-3 text-[0.875rem] font-medium", children: title }) : null,
|
|
3554
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { children: items.map((t) => {
|
|
3555
|
+
const on = t.id === activeId;
|
|
3556
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3557
|
+
"a",
|
|
3558
|
+
{
|
|
3559
|
+
href: `#${t.id}`,
|
|
3560
|
+
onClick: onNavigate,
|
|
3561
|
+
"aria-current": on ? "location" : void 0,
|
|
3562
|
+
className: cn(
|
|
3563
|
+
"block border-l py-1.5 text-[0.875rem] leading-snug transition-colors",
|
|
3564
|
+
t.level === 3 ? "pl-7" : "pl-4",
|
|
3565
|
+
on ? "border-foreground text-foreground" : "border-border text-muted-foreground hover:text-foreground"
|
|
3566
|
+
),
|
|
3567
|
+
children: t.label
|
|
3568
|
+
}
|
|
3569
|
+
) }, t.id);
|
|
3570
|
+
}) })
|
|
3571
|
+
] })
|
|
3572
|
+
);
|
|
3573
|
+
}
|
|
3574
|
+
var CALLOUT_TONE = { note: "neutral", warning: "brand", danger: "danger" };
|
|
3575
|
+
function Callout({
|
|
3576
|
+
tone = "note",
|
|
3577
|
+
title,
|
|
3578
|
+
children,
|
|
3579
|
+
className
|
|
3580
|
+
}) {
|
|
3581
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3582
|
+
Notice,
|
|
3583
|
+
{
|
|
3584
|
+
tone: CALLOUT_TONE[tone],
|
|
3585
|
+
title,
|
|
3586
|
+
role: "note",
|
|
3587
|
+
className: cn("my-6 [&_p]:my-0 [&_p]:text-[0.9375rem] [&_p]:leading-relaxed [&_p+p]:mt-3", className),
|
|
3588
|
+
children
|
|
3589
|
+
}
|
|
3590
|
+
);
|
|
3591
|
+
}
|
|
3592
|
+
function Step({ title, id, children }) {
|
|
3593
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "relative pb-8 pl-11 last:pb-0 [counter-increment:oca-step]", children: [
|
|
3594
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3595
|
+
"span",
|
|
3596
|
+
{
|
|
3597
|
+
"aria-hidden": true,
|
|
3598
|
+
className: "absolute left-0 top-0 flex size-7 items-center justify-center rounded-full border border-oca-hairline-strong bg-card text-[0.8125rem] oca-tabular text-foreground before:content-[counter(oca-step)]"
|
|
3599
|
+
}
|
|
3600
|
+
),
|
|
3601
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "absolute bottom-1 left-[0.8125rem] top-9 w-px bg-border" }),
|
|
3602
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { id, className: "scroll-mt-28 pt-0.5 text-[1.0625rem] font-medium leading-snug tracking-[-0.008em] text-foreground", children: title }),
|
|
3603
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 text-muted-foreground [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", children })
|
|
3604
|
+
] });
|
|
3605
|
+
}
|
|
3606
|
+
function Steps({ children, className }) {
|
|
3607
|
+
return /* @__PURE__ */ jsxRuntime.jsx("ol", { className: cn("not-prose my-8 flex flex-col [counter-reset:oca-step] [&>li:last-child>span:nth-child(2)]:hidden", className), children });
|
|
3608
|
+
}
|
|
3609
|
+
function LinkCard({
|
|
3610
|
+
href,
|
|
3611
|
+
title,
|
|
3612
|
+
description,
|
|
3613
|
+
icon,
|
|
3614
|
+
meta,
|
|
3615
|
+
className
|
|
3616
|
+
}) {
|
|
3617
|
+
const Arrow = isInternal(href) ? lucideReact.ArrowRight : lucideReact.ArrowUpRight;
|
|
3618
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3619
|
+
DocLink,
|
|
3620
|
+
{
|
|
3621
|
+
href,
|
|
3622
|
+
className: cn(
|
|
3623
|
+
"group flex h-full flex-col gap-3 rounded-[1.25rem] border border-border bg-card p-5 transition-colors hover:border-oca-hairline-strong",
|
|
3624
|
+
className
|
|
3625
|
+
),
|
|
3626
|
+
children: [
|
|
3627
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-start justify-between gap-3", children: [
|
|
3628
|
+
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-xl bg-muted text-foreground [&_svg]:size-[1.125rem]", children: icon }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: title }),
|
|
3629
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center gap-2", children: [
|
|
3630
|
+
meta,
|
|
3631
|
+
/* @__PURE__ */ jsxRuntime.jsx(Arrow, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-hover:translate-x-0.5 group-hover:text-foreground" })
|
|
3632
|
+
] })
|
|
3633
|
+
] }),
|
|
3634
|
+
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: title }) : null,
|
|
3635
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.9375rem] leading-relaxed text-muted-foreground", children: description }) : null
|
|
3636
|
+
]
|
|
3637
|
+
}
|
|
3638
|
+
);
|
|
3639
|
+
}
|
|
3640
|
+
function CardGrid({ columns = 2, children, className }) {
|
|
3641
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("not-prose my-6 grid grid-cols-1 gap-3 sm:grid-cols-2", columns === 3 && "lg:grid-cols-3", className), children });
|
|
3642
|
+
}
|
|
3643
|
+
function MdxTable({ className, ...props }) {
|
|
3644
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "not-prose my-6 overflow-hidden rounded-2xl border border-border bg-card", children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3645
|
+
"table",
|
|
3646
|
+
{
|
|
3647
|
+
className: cn(
|
|
3648
|
+
"w-full border-collapse text-left text-[0.875rem] leading-relaxed",
|
|
3649
|
+
"[&_th]:whitespace-nowrap [&_th]:border-b [&_th]:border-oca-hairline-strong [&_th]:bg-oca-table-head [&_th]:px-4 [&_th]:py-2.5 [&_th]:text-[0.8125rem] [&_th]:font-medium [&_th]:text-foreground",
|
|
3650
|
+
"[&_td]:border-t [&_td]:border-border [&_td]:px-4 [&_td]:py-2.5 [&_td]:align-top [&_td]:text-muted-foreground [&_tbody_tr:first-child_td]:border-t-0",
|
|
3651
|
+
"[&_td_code]:bg-transparent [&_td_code]:p-0 [&_td_code]:text-foreground [&_td:first-child]:text-foreground",
|
|
3652
|
+
"[&_[align=center]]:text-center [&_[align=right]]:text-right",
|
|
3653
|
+
// On a phone a cell keeps a readable width; the table scrolls instead of crushing it.
|
|
3654
|
+
"max-sm:[&_td]:min-w-[9rem]",
|
|
3655
|
+
className
|
|
3656
|
+
),
|
|
3657
|
+
...props
|
|
3658
|
+
}
|
|
3659
|
+
) }) });
|
|
3660
|
+
}
|
|
3661
|
+
function ApiTable({
|
|
3662
|
+
rows,
|
|
3663
|
+
caption,
|
|
3664
|
+
nameHeader = "Name",
|
|
3665
|
+
className
|
|
3666
|
+
}) {
|
|
3667
|
+
const hasDefault = rows.some((r) => r.default !== void 0);
|
|
3668
|
+
const marks = (r) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3669
|
+
r.required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.75rem] text-oca-accent-ink", children: "Required" }) : null,
|
|
3670
|
+
r.deprecated ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: "muted", children: "Deprecated" }) : null,
|
|
3671
|
+
r.status ? /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: r.status }) : null
|
|
3672
|
+
] });
|
|
3673
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("not-prose my-6", className), children: [
|
|
3674
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-2xl border border-border bg-card max-sm:hidden", children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse text-left text-[0.875rem]", children: [
|
|
3675
|
+
caption ? /* @__PURE__ */ jsxRuntime.jsx("caption", { className: "sr-only", children: caption }) : null,
|
|
3676
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b border-oca-hairline-strong bg-oca-table-head text-[0.8125rem]", children: [
|
|
3677
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: nameHeader }),
|
|
3678
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Type" }),
|
|
3679
|
+
hasDefault ? /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Default" }) : null,
|
|
3680
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Description" })
|
|
3681
|
+
] }) }),
|
|
3682
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-border", children: rows.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "align-top", children: [
|
|
3683
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "row", className: "px-4 py-3 text-left font-normal", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col items-start gap-1", children: [
|
|
3684
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: cn("font-mono text-[0.8125rem] text-foreground", r.deprecated && "line-through decoration-oca-subtle"), children: r.name }),
|
|
3685
|
+
marks(r)
|
|
3686
|
+
] }) }),
|
|
3687
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 font-mono text-[0.8125rem] text-muted-foreground", children: r.type ?? "\u2014" }),
|
|
3688
|
+
hasDefault ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 font-mono text-[0.8125rem] text-muted-foreground", children: r.default ?? "\u2014" }) : null,
|
|
3689
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 leading-relaxed text-muted-foreground", children: r.description })
|
|
3690
|
+
] }, r.name)) })
|
|
3691
|
+
] }) }) }),
|
|
3692
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": caption, className: "divide-y divide-border rounded-2xl border border-border bg-card sm:hidden", children: rows.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex flex-col gap-1.5 px-4 py-3.5", children: [
|
|
3693
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-1", children: [
|
|
3694
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: cn("font-mono text-[0.875rem] text-foreground", r.deprecated && "line-through decoration-oca-subtle"), children: r.name }),
|
|
3695
|
+
r.type ? /* @__PURE__ */ jsxRuntime.jsx("code", { className: "break-all font-mono text-[0.8125rem] text-muted-foreground", children: r.type }) : null
|
|
3696
|
+
] }),
|
|
3697
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex flex-wrap items-center gap-2 empty:hidden", children: marks(r) }),
|
|
3698
|
+
r.description ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.875rem] leading-relaxed text-muted-foreground", children: r.description }) : null,
|
|
3699
|
+
r.default !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[0.8125rem] text-muted-foreground", children: [
|
|
3700
|
+
"Default ",
|
|
3701
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-foreground", children: r.default })
|
|
3702
|
+
] }) : null
|
|
3703
|
+
] }, r.name)) })
|
|
3704
|
+
] });
|
|
3705
|
+
}
|
|
3706
|
+
function useDarkMode() {
|
|
3707
|
+
const [dark, setDark] = react.useState(false);
|
|
3708
|
+
react.useEffect(() => {
|
|
3709
|
+
const root = document.documentElement;
|
|
3710
|
+
const read = () => setDark(root.classList.contains("dark"));
|
|
3711
|
+
read();
|
|
3712
|
+
const mo = new MutationObserver(read);
|
|
3713
|
+
mo.observe(root, { attributes: true, attributeFilter: ["class"] });
|
|
3714
|
+
return () => mo.disconnect();
|
|
3715
|
+
}, []);
|
|
3716
|
+
return dark;
|
|
3717
|
+
}
|
|
3718
|
+
function mermaidTheme(el) {
|
|
3719
|
+
const css = getComputedStyle(el);
|
|
3720
|
+
const v = (name) => css.getPropertyValue(name).trim();
|
|
3721
|
+
const card = v("--card");
|
|
3722
|
+
const muted = v("--muted");
|
|
3723
|
+
const text = v("--foreground");
|
|
3724
|
+
const subtle = v("--muted-foreground");
|
|
3725
|
+
const line = v("--input");
|
|
3726
|
+
const hair = v("--oca-hairline-strong");
|
|
3727
|
+
return {
|
|
3728
|
+
background: "transparent",
|
|
3729
|
+
fontFamily: css.fontFamily,
|
|
3730
|
+
fontSize: "14px",
|
|
3731
|
+
textColor: text,
|
|
3732
|
+
mainBkg: card,
|
|
3733
|
+
primaryColor: card,
|
|
3734
|
+
primaryTextColor: text,
|
|
3735
|
+
primaryBorderColor: hair,
|
|
3736
|
+
secondaryColor: muted,
|
|
3737
|
+
secondaryTextColor: text,
|
|
3738
|
+
secondaryBorderColor: hair,
|
|
3739
|
+
tertiaryColor: muted,
|
|
3740
|
+
tertiaryTextColor: text,
|
|
3741
|
+
tertiaryBorderColor: hair,
|
|
3742
|
+
nodeBorder: hair,
|
|
3743
|
+
lineColor: line,
|
|
3744
|
+
edgeLabelBackground: card,
|
|
3745
|
+
clusterBkg: muted,
|
|
3746
|
+
clusterBorder: hair,
|
|
3747
|
+
titleColor: text,
|
|
3748
|
+
noteBkgColor: muted,
|
|
3749
|
+
noteTextColor: text,
|
|
3750
|
+
noteBorderColor: hair,
|
|
3751
|
+
actorBkg: card,
|
|
3752
|
+
actorBorder: hair,
|
|
3753
|
+
actorTextColor: text,
|
|
3754
|
+
actorLineColor: line,
|
|
3755
|
+
signalColor: text,
|
|
3756
|
+
signalTextColor: text,
|
|
3757
|
+
labelBoxBkgColor: card,
|
|
3758
|
+
labelBoxBorderColor: hair,
|
|
3759
|
+
labelTextColor: text,
|
|
3760
|
+
loopTextColor: subtle,
|
|
3761
|
+
activationBkgColor: muted,
|
|
3762
|
+
activationBorderColor: hair,
|
|
3763
|
+
sequenceNumberColor: card
|
|
3764
|
+
};
|
|
3765
|
+
}
|
|
3766
|
+
function naturalSize(svg) {
|
|
3767
|
+
const w = svg.match(/viewBox="[\d.-]+ [\d.-]+ ([\d.]+) [\d.]+"/)?.[1];
|
|
3768
|
+
if (!w) return svg;
|
|
3769
|
+
return svg.replace(/<svg([^>]*?)\swidth="100%"/, `<svg$1 width="${Math.ceil(Number(w))}"`).replace(/max-width:\s*[\d.]+px;?/, "");
|
|
3770
|
+
}
|
|
3771
|
+
function Diagram({ chart, caption, load, className }) {
|
|
3772
|
+
const ref = react.useRef(null);
|
|
3773
|
+
const dark = useDarkMode();
|
|
3774
|
+
const raw = react.useId();
|
|
3775
|
+
const [svg, setSvg] = react.useState(null);
|
|
3776
|
+
const [failed, setFailed] = react.useState(false);
|
|
3777
|
+
react.useEffect(() => {
|
|
3778
|
+
let live = true;
|
|
3779
|
+
const el = ref.current;
|
|
3780
|
+
if (!el) return;
|
|
3781
|
+
(async () => {
|
|
3782
|
+
try {
|
|
3783
|
+
const mod = await load();
|
|
3784
|
+
const mermaid = "default" in mod ? mod.default : mod;
|
|
3785
|
+
mermaid.initialize({ startOnLoad: false, securityLevel: "strict", theme: "base", themeVariables: mermaidTheme(el) });
|
|
3786
|
+
const { svg: drawn } = await mermaid.render(`oca-diagram-${raw.replace(/[^a-zA-Z0-9]/g, "")}-${dark ? "d" : "l"}`, chart);
|
|
3787
|
+
if (live) {
|
|
3788
|
+
setSvg(naturalSize(drawn));
|
|
3789
|
+
setFailed(false);
|
|
3790
|
+
}
|
|
3791
|
+
} catch {
|
|
3792
|
+
if (live) setFailed(true);
|
|
3793
|
+
}
|
|
3794
|
+
})();
|
|
3795
|
+
return () => {
|
|
3796
|
+
live = false;
|
|
3797
|
+
};
|
|
3798
|
+
}, [chart, dark, load, raw]);
|
|
3799
|
+
if (failed) return /* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { code: chart, caption: "Diagram (shown as its source)", className: cn("my-6", className) });
|
|
3800
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("figure", { ref, className: cn("not-prose my-6 overflow-hidden rounded-[1.25rem] border border-border bg-card", className), children: [
|
|
3801
|
+
svg ? /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3802
|
+
"div",
|
|
3803
|
+
{
|
|
3804
|
+
className: "flex w-max min-w-full justify-center p-6 [&_svg]:h-auto [&_svg]:max-w-none",
|
|
3805
|
+
role: "img",
|
|
3806
|
+
"aria-label": typeof caption === "string" ? caption : "Diagram",
|
|
3807
|
+
dangerouslySetInnerHTML: { __html: svg }
|
|
3808
|
+
}
|
|
3809
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { role: "status", "aria-label": "Drawing the diagram", className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-40 w-full rounded-xl" }) }),
|
|
3810
|
+
caption ? /* @__PURE__ */ jsxRuntime.jsx("figcaption", { className: "border-t border-border px-5 py-3 text-[0.8125rem] text-muted-foreground", children: caption }) : null
|
|
3811
|
+
] });
|
|
3812
|
+
}
|
|
3813
|
+
var HEADING = {
|
|
3814
|
+
h1: "oca-display-3 mb-4 text-foreground",
|
|
3815
|
+
h2: "mb-3 mt-12 text-[1.375rem] font-medium leading-tight tracking-[-0.015em] text-foreground md:text-[1.5rem]",
|
|
3816
|
+
h3: "mb-2 mt-9 text-[1.125rem] font-medium leading-snug tracking-[-0.01em] text-foreground",
|
|
3817
|
+
h4: "mb-2 mt-7 text-[1rem] font-medium leading-snug text-foreground"
|
|
3818
|
+
};
|
|
3819
|
+
function DocsHeading({
|
|
3820
|
+
as: Tag,
|
|
3821
|
+
id,
|
|
3822
|
+
children,
|
|
3823
|
+
className,
|
|
3824
|
+
...props
|
|
3825
|
+
}) {
|
|
3826
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Tag, { id, className: cn("group scroll-mt-28", HEADING[Tag], className), ...props, children: [
|
|
3827
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-heading-text": "", children }),
|
|
3828
|
+
id && Tag !== "h1" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3829
|
+
"a",
|
|
3830
|
+
{
|
|
3831
|
+
href: `#${id}`,
|
|
3832
|
+
className: "ml-2 inline-block rounded-md px-1 align-baseline text-[0.85em] font-normal text-oca-subtle no-underline opacity-0 transition-opacity hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100",
|
|
3833
|
+
children: [
|
|
3834
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, children: "#" }),
|
|
3835
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Link to this section" })
|
|
3836
|
+
]
|
|
3837
|
+
}
|
|
3838
|
+
) : null
|
|
3839
|
+
] });
|
|
3840
|
+
}
|
|
3841
|
+
function useMacKeys() {
|
|
3842
|
+
const [mac, setMac] = react.useState(true);
|
|
3843
|
+
react.useEffect(() => {
|
|
3844
|
+
setMac(/Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent));
|
|
3845
|
+
}, []);
|
|
3846
|
+
return mac;
|
|
3847
|
+
}
|
|
3848
|
+
var typing = (el) => el instanceof HTMLElement && (el.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(el.tagName));
|
|
3849
|
+
var SearchButton = react.forwardRef(function SearchButton2({ label = "Search", onClick, className }, ref) {
|
|
3850
|
+
const mac = useMacKeys();
|
|
3851
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3852
|
+
"button",
|
|
3853
|
+
{
|
|
3854
|
+
ref,
|
|
3855
|
+
type: "button",
|
|
3856
|
+
onClick,
|
|
3857
|
+
"aria-keyshortcuts": mac ? "Meta+K" : "Control+K",
|
|
3858
|
+
className: cn(
|
|
3859
|
+
"inline-flex size-10 items-center justify-center gap-2 rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
3860
|
+
"md:h-10 md:w-56 md:justify-start md:border md:border-border md:bg-card md:pl-3.5 md:pr-2 md:hover:border-oca-hairline-strong md:hover:bg-card",
|
|
3861
|
+
className
|
|
3862
|
+
),
|
|
3863
|
+
children: [
|
|
3864
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { "aria-hidden": true, className: "size-[1.125rem] shrink-0 md:size-4" }),
|
|
3865
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only flex-1 text-left text-[0.9375rem] md:not-sr-only", children: label }),
|
|
3866
|
+
/* @__PURE__ */ jsxRuntime.jsx(Kbd, { "aria-hidden": true, className: "hidden md:inline-flex", children: mac ? "\u2318K" : "Ctrl K" })
|
|
3867
|
+
]
|
|
3868
|
+
}
|
|
3869
|
+
);
|
|
3870
|
+
});
|
|
3871
|
+
function SearchDialog({
|
|
3872
|
+
onQuery,
|
|
3873
|
+
open: openProp,
|
|
3874
|
+
onOpenChange,
|
|
3875
|
+
onSelect,
|
|
3876
|
+
button = true,
|
|
3877
|
+
hotkey = true,
|
|
3878
|
+
label = "Search",
|
|
3879
|
+
placeholder = "Search the docs",
|
|
3880
|
+
idle,
|
|
3881
|
+
defaultQuery = "",
|
|
3882
|
+
debounceMs = 120,
|
|
3883
|
+
className
|
|
3884
|
+
}) {
|
|
3885
|
+
const [own, setOwn] = react.useState(false);
|
|
3886
|
+
const open = openProp ?? own;
|
|
3887
|
+
const setOpen = (v) => {
|
|
3888
|
+
if (openProp === void 0) setOwn(v);
|
|
3889
|
+
onOpenChange?.(v);
|
|
3890
|
+
};
|
|
3891
|
+
const [query, setQuery] = react.useState(defaultQuery);
|
|
3892
|
+
const [groups, setGroups] = react.useState([]);
|
|
3893
|
+
const [state, setState] = react.useState("idle");
|
|
3894
|
+
const [active, setActive] = react.useState(0);
|
|
3895
|
+
const listId = react.useId();
|
|
3896
|
+
const listRef = react.useRef(null);
|
|
3897
|
+
const buttonRef = react.useRef(null);
|
|
3898
|
+
const returnTo = react.useRef(null);
|
|
3899
|
+
const flat = react.useMemo(() => groups.flatMap((g) => g.results), [groups]);
|
|
3900
|
+
const latest = react.useRef({ open, setOpen, onQuery });
|
|
3901
|
+
latest.current = { open, setOpen, onQuery };
|
|
3902
|
+
react.useEffect(() => {
|
|
3903
|
+
if (!hotkey) return;
|
|
3904
|
+
const onKey = (e) => {
|
|
3905
|
+
const { open: isOpen, setOpen: set } = latest.current;
|
|
3906
|
+
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
|
|
3907
|
+
e.preventDefault();
|
|
3908
|
+
set(!isOpen);
|
|
3909
|
+
} else if (e.key === "/" && !isOpen && !typing(e.target)) {
|
|
3910
|
+
e.preventDefault();
|
|
3911
|
+
set(true);
|
|
3912
|
+
}
|
|
3913
|
+
};
|
|
3914
|
+
window.addEventListener("keydown", onKey);
|
|
3915
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
3916
|
+
}, [hotkey]);
|
|
3917
|
+
react.useEffect(() => {
|
|
3918
|
+
const q = query.trim();
|
|
3919
|
+
if (!q) {
|
|
3920
|
+
setGroups([]);
|
|
3921
|
+
setState("idle");
|
|
3922
|
+
return;
|
|
3923
|
+
}
|
|
3924
|
+
const ctl = new AbortController();
|
|
3925
|
+
setState("loading");
|
|
3926
|
+
const t = setTimeout(async () => {
|
|
3927
|
+
try {
|
|
3928
|
+
const out = await latest.current.onQuery(q, ctl.signal);
|
|
3929
|
+
if (ctl.signal.aborted) return;
|
|
3930
|
+
setGroups(out.filter((g) => g.results.length > 0));
|
|
3931
|
+
setActive(0);
|
|
3932
|
+
setState("done");
|
|
3933
|
+
} catch {
|
|
3934
|
+
if (!ctl.signal.aborted) setState("error");
|
|
3935
|
+
}
|
|
3936
|
+
}, debounceMs);
|
|
3937
|
+
return () => {
|
|
3938
|
+
clearTimeout(t);
|
|
3939
|
+
ctl.abort();
|
|
3940
|
+
};
|
|
3941
|
+
}, [query, debounceMs]);
|
|
3942
|
+
react.useEffect(() => {
|
|
3943
|
+
listRef.current?.querySelector('[aria-selected="true"]')?.scrollIntoView({ block: "nearest" });
|
|
3944
|
+
}, [active]);
|
|
3945
|
+
const choose = (r) => {
|
|
3946
|
+
setOpen(false);
|
|
3947
|
+
if (onSelect) onSelect(r);
|
|
3948
|
+
else window.location.assign(r.href);
|
|
3949
|
+
};
|
|
3950
|
+
const optionId = (i) => `${listId}-o${i}`;
|
|
3951
|
+
const showList = state === "done" && flat.length > 0;
|
|
3952
|
+
let index = -1;
|
|
3953
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3954
|
+
button ? /* @__PURE__ */ jsxRuntime.jsx(SearchButton, { ref: buttonRef, label, onClick: () => setOpen(true), className }) : null,
|
|
3955
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Root, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Portal, { children: [
|
|
3956
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Overlay, { className: "oca-animate-fade fixed inset-0 z-50 bg-[rgb(10_10_10/0.38)] backdrop-blur-[2px]" }),
|
|
3957
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3958
|
+
DialogPrimitive__namespace.Content,
|
|
3959
|
+
{
|
|
3960
|
+
"aria-describedby": void 0,
|
|
3961
|
+
onOpenAutoFocus: () => {
|
|
3962
|
+
const el = document.activeElement;
|
|
3963
|
+
returnTo.current = el instanceof HTMLElement && el !== document.body ? el : null;
|
|
3964
|
+
},
|
|
3965
|
+
onCloseAutoFocus: (e) => {
|
|
3966
|
+
const back = returnTo.current?.isConnected ? returnTo.current : buttonRef.current;
|
|
3967
|
+
if (back) {
|
|
3968
|
+
e.preventDefault();
|
|
3969
|
+
back.focus();
|
|
3970
|
+
}
|
|
3971
|
+
},
|
|
3972
|
+
className: "oca-animate-rise fixed left-1/2 top-3 z-50 flex max-h-[calc(100dvh-1.5rem)] w-[calc(100vw-1.5rem)] -translate-x-1/2 flex-col overflow-hidden rounded-[1.5rem] border border-border bg-popover text-popover-foreground shadow-xl outline-none sm:top-[12vh] sm:max-h-[min(36rem,76vh)] sm:w-[min(92vw,40rem)]",
|
|
3973
|
+
children: [
|
|
3974
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Title, { className: "sr-only", children: label }),
|
|
3975
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-14 shrink-0 items-center gap-3 border-b border-border pl-5 pr-3", children: [
|
|
3976
|
+
state === "loading" ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { className: "size-[1.125rem] text-muted-foreground" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { "aria-hidden": true, className: "size-[1.125rem] shrink-0 text-muted-foreground" }),
|
|
3977
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3978
|
+
"input",
|
|
3979
|
+
{
|
|
3980
|
+
autoFocus: true,
|
|
3981
|
+
value: query,
|
|
3982
|
+
onChange: (e) => setQuery(e.target.value),
|
|
3983
|
+
onKeyDown: (e) => {
|
|
3984
|
+
if (!showList) return;
|
|
3985
|
+
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
3986
|
+
e.preventDefault();
|
|
3987
|
+
const d = e.key === "ArrowDown" ? 1 : -1;
|
|
3988
|
+
setActive((a) => (a + d + flat.length) % flat.length);
|
|
3989
|
+
} else if (e.key === "Enter" && flat[active]) {
|
|
3990
|
+
e.preventDefault();
|
|
3991
|
+
choose(flat[active]);
|
|
3992
|
+
}
|
|
3993
|
+
},
|
|
3994
|
+
placeholder,
|
|
3995
|
+
role: "combobox",
|
|
3996
|
+
"aria-label": label,
|
|
3997
|
+
"aria-expanded": showList,
|
|
3998
|
+
"aria-controls": listId,
|
|
3999
|
+
"aria-autocomplete": "list",
|
|
4000
|
+
"aria-activedescendant": showList ? optionId(active) : void 0,
|
|
4001
|
+
spellCheck: false,
|
|
4002
|
+
autoComplete: "off",
|
|
4003
|
+
className: "h-full min-w-0 flex-1 bg-transparent text-base text-foreground outline-none placeholder:text-oca-subtle"
|
|
4004
|
+
}
|
|
4005
|
+
),
|
|
4006
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "inline-flex h-8 shrink-0 items-center rounded-md border border-border px-2 text-[0.75rem] text-muted-foreground transition-colors hover:text-foreground", children: [
|
|
4007
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sm:hidden", children: "Close" }),
|
|
4008
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-sm:hidden", "aria-hidden": true, children: "Esc" }),
|
|
4009
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only max-sm:hidden", children: "Close search" })
|
|
4010
|
+
] })
|
|
4011
|
+
] }),
|
|
4012
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: listRef, className: "min-h-0 flex-1 overflow-y-auto overscroll-contain p-2", children: [
|
|
4013
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { id: listId, role: "listbox", "aria-label": "Results", className: cn(!showList && "hidden"), children: groups.map((g, gi) => /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-label": typeof g.label === "string" ? g.label : void 0, className: "pb-1", children: [
|
|
4014
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { "aria-hidden": true, className: "px-3 pb-1.5 pt-3 text-[0.8125rem] text-muted-foreground", children: g.label }),
|
|
4015
|
+
g.results.map((r) => {
|
|
4016
|
+
index++;
|
|
4017
|
+
const i = index;
|
|
4018
|
+
const on = i === active;
|
|
4019
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4020
|
+
"a",
|
|
4021
|
+
{
|
|
4022
|
+
id: optionId(i),
|
|
4023
|
+
href: r.href,
|
|
4024
|
+
role: "option",
|
|
4025
|
+
"aria-selected": on,
|
|
4026
|
+
tabIndex: -1,
|
|
4027
|
+
onMouseMove: () => setActive(i),
|
|
4028
|
+
onClick: (e) => {
|
|
4029
|
+
if (e.metaKey || e.ctrlKey || e.shiftKey) return;
|
|
4030
|
+
e.preventDefault();
|
|
4031
|
+
choose(r);
|
|
4032
|
+
},
|
|
4033
|
+
className: cn(
|
|
4034
|
+
"flex items-start gap-3 rounded-xl px-3 py-2.5 transition-colors",
|
|
4035
|
+
on ? "bg-accent" : "hover:bg-accent"
|
|
4036
|
+
),
|
|
4037
|
+
children: [
|
|
4038
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
|
|
4039
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[0.9375rem] font-medium text-foreground", children: r.title }),
|
|
4040
|
+
r.section ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[0.8125rem] text-muted-foreground", children: r.section }) : null,
|
|
4041
|
+
r.excerptHtml ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4042
|
+
"span",
|
|
4043
|
+
{
|
|
4044
|
+
className: "line-clamp-2 text-[0.875rem] leading-snug text-muted-foreground [&_mark]:rounded-sm [&_mark]:bg-[color-mix(in_oklab,var(--oca-orange)_22%,transparent)] [&_mark]:px-0.5 [&_mark]:text-foreground",
|
|
4045
|
+
dangerouslySetInnerHTML: { __html: r.excerptHtml }
|
|
4046
|
+
}
|
|
4047
|
+
) : r.excerpt ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-2 text-[0.875rem] leading-snug text-muted-foreground", children: r.excerpt }) : null
|
|
4048
|
+
] }),
|
|
4049
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownLeft, { "aria-hidden": true, className: cn("mt-1 size-4 shrink-0 text-muted-foreground", !on && "invisible") })
|
|
4050
|
+
]
|
|
4051
|
+
},
|
|
4052
|
+
r.id
|
|
4053
|
+
);
|
|
4054
|
+
})
|
|
4055
|
+
] }, gi)) }),
|
|
4056
|
+
state === "idle" ? /* @__PURE__ */ jsxRuntime.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,
|
|
4057
|
+
state === "done" && flat.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("p", { role: "status", className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: [
|
|
4058
|
+
"No results for \u201C",
|
|
4059
|
+
query.trim(),
|
|
4060
|
+
"\u201D."
|
|
4061
|
+
] }) : null,
|
|
4062
|
+
state === "error" ? /* @__PURE__ */ jsxRuntime.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
|
|
4063
|
+
] }),
|
|
4064
|
+
/* @__PURE__ */ jsxRuntime.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: [
|
|
4065
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5", children: [
|
|
4066
|
+
/* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "\u2191" }),
|
|
4067
|
+
/* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "\u2193" }),
|
|
4068
|
+
" to move"
|
|
4069
|
+
] }),
|
|
4070
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5", children: [
|
|
4071
|
+
/* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "\u21B5" }),
|
|
4072
|
+
" to open"
|
|
4073
|
+
] }),
|
|
4074
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5", children: [
|
|
4075
|
+
/* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "esc" }),
|
|
4076
|
+
" to close"
|
|
4077
|
+
] })
|
|
4078
|
+
] }),
|
|
4079
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-live": "polite", className: "sr-only", children: state === "done" ? `${flat.length} result${flat.length === 1 ? "" : "s"}` : "" })
|
|
4080
|
+
]
|
|
4081
|
+
}
|
|
4082
|
+
)
|
|
4083
|
+
] }) })
|
|
4084
|
+
] });
|
|
4085
|
+
}
|
|
4086
|
+
function pretty(content) {
|
|
4087
|
+
try {
|
|
4088
|
+
return JSON.stringify(JSON.parse(content), null, 2);
|
|
4089
|
+
} catch {
|
|
4090
|
+
return null;
|
|
4091
|
+
}
|
|
4092
|
+
}
|
|
4093
|
+
function download(content, filename, mime) {
|
|
4094
|
+
const url = URL.createObjectURL(new Blob([content], { type: mime }));
|
|
4095
|
+
const a = document.createElement("a");
|
|
4096
|
+
a.href = url;
|
|
4097
|
+
a.download = filename;
|
|
4098
|
+
document.body.appendChild(a);
|
|
4099
|
+
a.click();
|
|
4100
|
+
a.remove();
|
|
4101
|
+
setTimeout(() => URL.revokeObjectURL(url), 0);
|
|
4102
|
+
}
|
|
4103
|
+
var BAR_BUTTON = "inline-flex h-7 items-center gap-1.5 rounded-full px-2.5 text-[0.75rem] text-oca-ink-subtle transition-colors hover:bg-white/10 hover:text-white";
|
|
4104
|
+
function ArtifactView({
|
|
4105
|
+
content,
|
|
4106
|
+
title,
|
|
4107
|
+
filename,
|
|
4108
|
+
mime,
|
|
4109
|
+
defaultView = "formatted",
|
|
4110
|
+
maxLines = 28,
|
|
4111
|
+
className
|
|
4112
|
+
}) {
|
|
4113
|
+
const formatted = react.useMemo(() => pretty(content), [content]);
|
|
4114
|
+
const [view, setView] = react.useState(formatted ? defaultView : "raw");
|
|
4115
|
+
const shown = view === "formatted" && formatted ? formatted : content;
|
|
4116
|
+
const json = formatted !== null;
|
|
4117
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4118
|
+
CodeBlock,
|
|
4119
|
+
{
|
|
4120
|
+
code: shown,
|
|
4121
|
+
lang: json ? "json" : void 0,
|
|
4122
|
+
caption: title,
|
|
4123
|
+
maxLines,
|
|
4124
|
+
className,
|
|
4125
|
+
actions: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4126
|
+
json ? /* @__PURE__ */ jsxRuntime.jsx("span", { role: "group", "aria-label": "View", className: "mr-1 flex items-center rounded-full bg-white/[0.06] p-0.5", children: ["formatted", "raw"].map((v) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4127
|
+
"button",
|
|
4128
|
+
{
|
|
4129
|
+
type: "button",
|
|
4130
|
+
"aria-pressed": view === v,
|
|
4131
|
+
onClick: () => setView(v),
|
|
4132
|
+
className: cn(
|
|
4133
|
+
"h-7 rounded-full px-2.5 text-[0.75rem] transition-colors",
|
|
4134
|
+
view === v ? "bg-white/[0.12] text-white" : "text-oca-ink-subtle hover:text-white"
|
|
4135
|
+
),
|
|
4136
|
+
children: v === "formatted" ? "Formatted" : "Raw"
|
|
4137
|
+
},
|
|
4138
|
+
v
|
|
4139
|
+
)) }) : null,
|
|
4140
|
+
filename ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4141
|
+
"button",
|
|
4142
|
+
{
|
|
4143
|
+
type: "button",
|
|
4144
|
+
onClick: () => download(content, filename, mime ?? (json ? "application/json" : "text/plain")),
|
|
4145
|
+
className: BAR_BUTTON,
|
|
4146
|
+
"aria-label": `Download ${filename}`,
|
|
4147
|
+
children: [
|
|
4148
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { "aria-hidden": true, className: "size-3.5" }),
|
|
4149
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-sm:hidden", children: "Download" })
|
|
4150
|
+
]
|
|
4151
|
+
}
|
|
4152
|
+
) : null
|
|
4153
|
+
] })
|
|
4154
|
+
}
|
|
4155
|
+
);
|
|
4156
|
+
}
|
|
4157
|
+
function DropZone({
|
|
4158
|
+
onFile,
|
|
4159
|
+
onText,
|
|
4160
|
+
accept,
|
|
4161
|
+
title = "Drop a file here, or choose one",
|
|
4162
|
+
hint,
|
|
4163
|
+
privacy = "It stays in your browser. Only its hash leaves this page.",
|
|
4164
|
+
file,
|
|
4165
|
+
progress,
|
|
4166
|
+
progressLabel = "Hashing",
|
|
4167
|
+
onClear,
|
|
4168
|
+
error,
|
|
4169
|
+
disabled = false,
|
|
4170
|
+
className
|
|
4171
|
+
}) {
|
|
4172
|
+
const input = react.useRef(null);
|
|
4173
|
+
const [over, setOver] = react.useState(false);
|
|
4174
|
+
const depth = react.useRef(0);
|
|
4175
|
+
const [mode, setMode] = react.useState("file");
|
|
4176
|
+
const [text, setText] = react.useState("");
|
|
4177
|
+
const errorId = react.useId();
|
|
4178
|
+
const titleId = react.useId();
|
|
4179
|
+
const busy = progress !== null && progress !== void 0;
|
|
4180
|
+
const pct = busy ? Math.round(Math.max(0, Math.min(1, progress)) * 100) : 0;
|
|
4181
|
+
const take = (f) => {
|
|
4182
|
+
if (f && !disabled) onFile(f);
|
|
4183
|
+
};
|
|
4184
|
+
const privacyLine = privacy === null ? null : /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "flex items-start gap-2 text-[0.8125rem] leading-snug text-muted-foreground", children: [
|
|
4185
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Lock, { "aria-hidden": true, className: "mt-0.5 size-3.5 shrink-0" }),
|
|
4186
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: privacy })
|
|
4187
|
+
] });
|
|
4188
|
+
if (mode === "text" && onText) {
|
|
4189
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-3", className), children: [
|
|
4190
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4191
|
+
Textarea,
|
|
4192
|
+
{
|
|
4193
|
+
value: text,
|
|
4194
|
+
onChange: (e) => setText(e.target.value),
|
|
4195
|
+
rows: 6,
|
|
4196
|
+
"aria-label": "Text",
|
|
4197
|
+
"aria-describedby": error ? errorId : void 0,
|
|
4198
|
+
"aria-invalid": error ? true : void 0,
|
|
4199
|
+
placeholder: "Paste the text here",
|
|
4200
|
+
className: "font-mono text-base md:text-[0.875rem]"
|
|
4201
|
+
}
|
|
4202
|
+
),
|
|
4203
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
4204
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", disabled: !text.trim() || disabled, onClick: () => onText(text), children: "Use this text" }),
|
|
4205
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", variant: "ghost", onClick: () => setMode("file"), children: "Choose a file instead" })
|
|
4206
|
+
] }),
|
|
4207
|
+
error ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, role: "alert", className: "text-[0.8125rem] text-destructive", children: error }) : null,
|
|
4208
|
+
privacyLine
|
|
4209
|
+
] });
|
|
4210
|
+
}
|
|
4211
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-3", className), children: [
|
|
4212
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4213
|
+
"div",
|
|
4214
|
+
{
|
|
4215
|
+
role: "group",
|
|
4216
|
+
"aria-labelledby": titleId,
|
|
4217
|
+
"aria-describedby": error ? errorId : void 0,
|
|
4218
|
+
"aria-busy": busy || void 0,
|
|
4219
|
+
onDragEnter: (e) => {
|
|
4220
|
+
e.preventDefault();
|
|
4221
|
+
depth.current++;
|
|
4222
|
+
if (!disabled) setOver(true);
|
|
4223
|
+
},
|
|
4224
|
+
onDragOver: (e) => e.preventDefault(),
|
|
4225
|
+
onDragLeave: () => {
|
|
4226
|
+
depth.current = Math.max(0, depth.current - 1);
|
|
4227
|
+
if (depth.current === 0) setOver(false);
|
|
4228
|
+
},
|
|
4229
|
+
onDrop: (e) => {
|
|
4230
|
+
e.preventDefault();
|
|
4231
|
+
depth.current = 0;
|
|
4232
|
+
setOver(false);
|
|
4233
|
+
take(e.dataTransfer.files?.[0]);
|
|
4234
|
+
},
|
|
4235
|
+
className: cn(
|
|
4236
|
+
"relative flex flex-col gap-3 rounded-[1.25rem] border border-dashed transition-colors",
|
|
4237
|
+
file ? "px-4 py-4 sm:px-5" : "items-center px-5 py-8 text-center md:py-10",
|
|
4238
|
+
over ? "border-foreground bg-accent" : "border-oca-hairline-strong bg-card",
|
|
4239
|
+
error && "border-destructive",
|
|
4240
|
+
disabled && "opacity-55"
|
|
4241
|
+
),
|
|
4242
|
+
children: [
|
|
4243
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4244
|
+
"input",
|
|
4245
|
+
{
|
|
4246
|
+
ref: input,
|
|
4247
|
+
type: "file",
|
|
4248
|
+
accept,
|
|
4249
|
+
disabled,
|
|
4250
|
+
tabIndex: -1,
|
|
4251
|
+
"aria-hidden": true,
|
|
4252
|
+
className: "sr-only",
|
|
4253
|
+
onChange: (e) => {
|
|
4254
|
+
take(e.target.files?.[0]);
|
|
4255
|
+
e.target.value = "";
|
|
4256
|
+
}
|
|
4257
|
+
}
|
|
4258
|
+
),
|
|
4259
|
+
file ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full flex-col gap-3", children: [
|
|
4260
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
4261
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-10 shrink-0 items-center justify-center rounded-xl bg-muted text-foreground", children: busy ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { "aria-hidden": true, className: "size-5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { "aria-hidden": true, className: "size-5" }) }),
|
|
4262
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
4263
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { id: titleId, className: "truncate text-[0.9375rem] font-medium", title: file.name, children: file.name }),
|
|
4264
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.8125rem] text-muted-foreground", children: [formatBytes(file.size), file.type].filter(Boolean).join(" \xB7 ") })
|
|
4265
|
+
] }),
|
|
4266
|
+
!busy && onClear ? /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", variant: "secondary", onClick: onClear, disabled, className: "shrink-0", children: "Choose another" }) : null
|
|
4267
|
+
] }),
|
|
4268
|
+
busy ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
4269
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4270
|
+
"div",
|
|
4271
|
+
{
|
|
4272
|
+
role: "progressbar",
|
|
4273
|
+
"aria-valuemin": 0,
|
|
4274
|
+
"aria-valuemax": 100,
|
|
4275
|
+
"aria-valuenow": pct,
|
|
4276
|
+
"aria-label": typeof progressLabel === "string" ? progressLabel : "Progress",
|
|
4277
|
+
className: "h-1.5 overflow-hidden rounded-full bg-muted",
|
|
4278
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full rounded-full bg-foreground transition-[width] duration-200", style: { width: `${pct}%` } })
|
|
4279
|
+
}
|
|
4280
|
+
),
|
|
4281
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[0.8125rem] text-muted-foreground oca-tabular", children: [
|
|
4282
|
+
progressLabel,
|
|
4283
|
+
" ",
|
|
4284
|
+
pct,
|
|
4285
|
+
"%"
|
|
4286
|
+
] })
|
|
4287
|
+
] }) : null
|
|
4288
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4289
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-11 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Upload, { "aria-hidden": true, className: "size-5" }) }),
|
|
4290
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
4291
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { id: titleId, className: "text-[1rem] font-medium", children: over ? "Drop it to add it" : title }),
|
|
4292
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] text-muted-foreground", children: hint }) : null
|
|
4293
|
+
] }),
|
|
4294
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 flex flex-wrap items-center justify-center gap-2", children: [
|
|
4295
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", variant: "secondary", disabled, onClick: () => input.current?.click(), children: "Choose a file" }),
|
|
4296
|
+
onText ? /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", variant: "ghost", disabled, onClick: () => setMode("text"), children: "Paste text instead" }) : null
|
|
4297
|
+
] })
|
|
4298
|
+
] })
|
|
4299
|
+
]
|
|
4300
|
+
}
|
|
4301
|
+
),
|
|
4302
|
+
error ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, role: "alert", className: "text-[0.8125rem] text-destructive", children: error }) : null,
|
|
4303
|
+
privacyLine
|
|
4304
|
+
] });
|
|
4305
|
+
}
|
|
4306
|
+
function FormSection({
|
|
4307
|
+
n,
|
|
4308
|
+
title,
|
|
4309
|
+
hint,
|
|
4310
|
+
status,
|
|
4311
|
+
action,
|
|
4312
|
+
as: Heading = "h2",
|
|
4313
|
+
id,
|
|
4314
|
+
children,
|
|
4315
|
+
className
|
|
4316
|
+
}) {
|
|
4317
|
+
const titleId = react.useId();
|
|
4318
|
+
const tight = useDensity() === "compact";
|
|
4319
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4320
|
+
"section",
|
|
4321
|
+
{
|
|
4322
|
+
id,
|
|
4323
|
+
"aria-labelledby": titleId,
|
|
4324
|
+
"aria-current": status === "current" ? "step" : void 0,
|
|
4325
|
+
className: cn("scroll-mt-24 rounded-[1.25rem] border border-border bg-card", className),
|
|
4326
|
+
children: [
|
|
4327
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: cn("flex items-start gap-3.5", tight ? "px-5 pt-5" : "px-6 pt-6"), children: [
|
|
4328
|
+
n !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4329
|
+
"span",
|
|
4330
|
+
{
|
|
4331
|
+
"aria-hidden": true,
|
|
4332
|
+
className: cn(
|
|
4333
|
+
"mt-px flex size-7 shrink-0 items-center justify-center rounded-full border text-[0.8125rem] oca-tabular",
|
|
4334
|
+
status === "done" && "border-primary bg-primary text-primary-foreground",
|
|
4335
|
+
status === "current" && "border-brand text-oca-accent-ink",
|
|
4336
|
+
status === "blocked" && "border-destructive text-destructive",
|
|
4337
|
+
(status === "upcoming" || status === void 0) && "border-oca-hairline-strong text-muted-foreground"
|
|
4338
|
+
),
|
|
4339
|
+
children: status === "done" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-3.5", strokeWidth: 3 }) : n
|
|
4340
|
+
}
|
|
4341
|
+
) : null,
|
|
4342
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
4343
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Heading, { id: titleId, className: "text-[1.0625rem] font-medium leading-snug tracking-[-0.008em]", children: [
|
|
4344
|
+
n !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sr-only", children: [
|
|
4345
|
+
"Step ",
|
|
4346
|
+
n,
|
|
4347
|
+
": "
|
|
4348
|
+
] }) : null,
|
|
4349
|
+
title,
|
|
4350
|
+
status === "done" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: " (done)" }) : null
|
|
4351
|
+
] }),
|
|
4352
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] leading-snug text-muted-foreground", children: hint }) : null
|
|
4353
|
+
] }),
|
|
4354
|
+
action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: action }) : null
|
|
4355
|
+
] }),
|
|
4356
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col", tight ? "gap-4 p-5" : "gap-5 p-6", n !== void 0 && (tight ? "sm:pl-[3.875rem]" : "sm:pl-[4.125rem]")), children })
|
|
4357
|
+
]
|
|
4358
|
+
}
|
|
4359
|
+
);
|
|
4360
|
+
}
|
|
4361
|
+
var STATE_TONE = { good: "success", attention: "brand", bad: "danger", neutral: "neutral", quiet: "muted" };
|
|
4362
|
+
function StateBadge({
|
|
4363
|
+
tone = "neutral",
|
|
4364
|
+
children,
|
|
4365
|
+
title,
|
|
4366
|
+
className
|
|
4367
|
+
}) {
|
|
4368
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: STATE_TONE[tone], title, className, children });
|
|
4369
|
+
}
|
|
4370
|
+
function createStateBadge(states) {
|
|
4371
|
+
function ProtocolStateBadge({ state, className }) {
|
|
4372
|
+
const def = states[state];
|
|
4373
|
+
if (!def) {
|
|
4374
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
|
|
4375
|
+
console.warn(`StateBadge: no state "${state}"; known: ${Object.keys(states).join(", ")}`);
|
|
4376
|
+
}
|
|
4377
|
+
return /* @__PURE__ */ jsxRuntime.jsx(StateBadge, { className, children: String(state) });
|
|
4378
|
+
}
|
|
4379
|
+
return /* @__PURE__ */ jsxRuntime.jsx(StateBadge, { tone: def.tone, title: def.hint, className, children: def.label });
|
|
4380
|
+
}
|
|
4381
|
+
return ProtocolStateBadge;
|
|
4382
|
+
}
|
|
4383
|
+
function BlockHeight({
|
|
4384
|
+
height,
|
|
4385
|
+
label = false,
|
|
4386
|
+
link = true,
|
|
4387
|
+
network = "mainnet",
|
|
4388
|
+
className
|
|
4389
|
+
}) {
|
|
4390
|
+
const text = `${label ? "block " : ""}${formatBlockHeight(height)}`;
|
|
4391
|
+
if (!link) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("oca-tabular", className), children: text });
|
|
4392
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4393
|
+
"a",
|
|
4394
|
+
{
|
|
4395
|
+
href: explorerUrl("block", Math.trunc(height), network),
|
|
4396
|
+
target: "_blank",
|
|
4397
|
+
rel: "noreferrer",
|
|
4398
|
+
title: `Block ${formatBlockHeight(height)} on mempool.space`,
|
|
4399
|
+
className: cn("oca-tabular underline decoration-foreground/35 underline-offset-4 hover:decoration-foreground", className),
|
|
4400
|
+
children: [
|
|
4401
|
+
text,
|
|
4402
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: " (opens mempool.space in a new tab)" })
|
|
4403
|
+
]
|
|
4404
|
+
}
|
|
4405
|
+
);
|
|
4406
|
+
}
|
|
4407
|
+
var ANCHOR = {
|
|
4408
|
+
anchored: { label: "Anchored", tone: "good" },
|
|
4409
|
+
pending: { label: "Anchor pending", tone: "attention" },
|
|
4410
|
+
unverified: { label: "Not checked", tone: "quiet" },
|
|
4411
|
+
none: { label: "Not anchored", tone: "quiet" },
|
|
4412
|
+
fail: { label: "Does not check out", tone: "bad" }
|
|
4413
|
+
};
|
|
4414
|
+
function hostOf(url) {
|
|
4415
|
+
try {
|
|
4416
|
+
return new URL(url).host;
|
|
4417
|
+
} catch {
|
|
4418
|
+
return url;
|
|
4419
|
+
}
|
|
4420
|
+
}
|
|
4421
|
+
function AnchorStatus({
|
|
4422
|
+
state,
|
|
4423
|
+
blockHeight,
|
|
4424
|
+
blockTime,
|
|
4425
|
+
submittedAt,
|
|
4426
|
+
calendar,
|
|
4427
|
+
message,
|
|
4428
|
+
network = "mainnet",
|
|
4429
|
+
variant = "detail",
|
|
4430
|
+
className
|
|
4431
|
+
}) {
|
|
4432
|
+
const def = ANCHOR[state];
|
|
4433
|
+
const block = blockHeight !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(BlockHeight, { height: blockHeight, label: true, network }) : null;
|
|
4434
|
+
const line = message ?? (state === "anchored" ? block ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4435
|
+
"In ",
|
|
4436
|
+
block,
|
|
4437
|
+
blockTime !== void 0 ? ` \xB7 ${formatUtc(blockTime)}` : null
|
|
4438
|
+
] }) : "Its hash is in a Bitcoin block." : state === "pending" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4439
|
+
"Submitted",
|
|
4440
|
+
submittedAt !== void 0 ? ` ${formatUtc(submittedAt)}` : "",
|
|
4441
|
+
" to",
|
|
4442
|
+
" ",
|
|
4443
|
+
calendar ? hostOf(calendar) : "an OpenTimestamps calendar",
|
|
4444
|
+
". Waiting for a Bitcoin block."
|
|
4445
|
+
] }) : state === "unverified" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4446
|
+
"The proof names ",
|
|
4447
|
+
block ?? "a block",
|
|
4448
|
+
", but its header could not be fetched to check it."
|
|
4449
|
+
] }) : state === "fail" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4450
|
+
"The proof does not lead to ",
|
|
4451
|
+
block ?? "the block it names",
|
|
4452
|
+
"."
|
|
4453
|
+
] }) : "No timestamp yet. The signature still checks offline.");
|
|
4454
|
+
if (variant === "badge") {
|
|
4455
|
+
const plain = typeof line === "string" ? line : void 0;
|
|
4456
|
+
return /* @__PURE__ */ jsxRuntime.jsx(StateBadge, { tone: def.tone, title: plain, className, children: def.label });
|
|
4457
|
+
}
|
|
4458
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col items-start gap-1.5", className), children: [
|
|
4459
|
+
/* @__PURE__ */ jsxRuntime.jsx(StateBadge, { tone: def.tone, children: def.label }),
|
|
4460
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] leading-snug text-muted-foreground", children: line })
|
|
4461
|
+
] });
|
|
4462
|
+
}
|
|
4463
|
+
function BlockCountdown({
|
|
4464
|
+
target,
|
|
4465
|
+
tip,
|
|
4466
|
+
from,
|
|
4467
|
+
reached = "Reached",
|
|
4468
|
+
minutesPerBlock = 10,
|
|
4469
|
+
network = "mainnet",
|
|
4470
|
+
className
|
|
4471
|
+
}) {
|
|
4472
|
+
const known = typeof tip === "number";
|
|
4473
|
+
const left = known ? target - tip : null;
|
|
4474
|
+
const done = left !== null && left <= 0;
|
|
4475
|
+
const share = known && from !== void 0 && target > from ? Math.min(1, Math.max(0, (tip - from) / (target - from))) : null;
|
|
4476
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
|
|
4477
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.9375rem] leading-snug", children: !known ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4478
|
+
"At ",
|
|
4479
|
+
/* @__PURE__ */ jsxRuntime.jsx(BlockHeight, { height: target, label: true, network })
|
|
4480
|
+
] }) : done ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4481
|
+
reached,
|
|
4482
|
+
" at ",
|
|
4483
|
+
/* @__PURE__ */ jsxRuntime.jsx(BlockHeight, { height: target, label: true, network })
|
|
4484
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4485
|
+
"In ",
|
|
4486
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-tabular font-medium", children: formatBlockHeight(left) }),
|
|
4487
|
+
" block",
|
|
4488
|
+
left === 1 ? "" : "s",
|
|
4489
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
|
|
4490
|
+
", ",
|
|
4491
|
+
blocksToDuration(left, minutesPerBlock)
|
|
4492
|
+
] })
|
|
4493
|
+
] }) }),
|
|
4494
|
+
share !== null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4495
|
+
"div",
|
|
4496
|
+
{
|
|
4497
|
+
role: "progressbar",
|
|
4498
|
+
"aria-valuemin": 0,
|
|
4499
|
+
"aria-valuemax": 100,
|
|
4500
|
+
"aria-valuenow": Math.round(share * 100),
|
|
4501
|
+
"aria-label": "Blocks passed",
|
|
4502
|
+
className: "h-1.5 overflow-hidden rounded-full bg-muted",
|
|
4503
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full rounded-full bg-foreground", style: { width: `${share * 100}%` } })
|
|
4504
|
+
}
|
|
4505
|
+
) : null,
|
|
4506
|
+
known && !done ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[0.8125rem] text-muted-foreground", children: [
|
|
4507
|
+
"Target ",
|
|
4508
|
+
/* @__PURE__ */ jsxRuntime.jsx(BlockHeight, { height: target, network }),
|
|
4509
|
+
" \xB7 tip ",
|
|
4510
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-tabular", children: formatBlockHeight(tip) })
|
|
4511
|
+
] }) : null
|
|
4512
|
+
] });
|
|
4513
|
+
}
|
|
4514
|
+
function Meter({
|
|
4515
|
+
value,
|
|
4516
|
+
max,
|
|
4517
|
+
ghost,
|
|
4518
|
+
label,
|
|
4519
|
+
figure,
|
|
4520
|
+
tone = "ink",
|
|
4521
|
+
size = "md",
|
|
4522
|
+
className
|
|
4523
|
+
}) {
|
|
4524
|
+
const id = react.useId();
|
|
4525
|
+
const total = max > 0 ? max : 1;
|
|
4526
|
+
const v = Math.max(0, Math.min(1, value / total));
|
|
4527
|
+
const g = ghost ? Math.max(0, Math.min(1 - v, ghost / total)) : 0;
|
|
4528
|
+
const pct = `${Math.round(v * 100)}%`;
|
|
4529
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
|
|
4530
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline justify-between gap-4 text-[0.875rem]", children: [
|
|
4531
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { id, className: "min-w-0 truncate", children: label }),
|
|
4532
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 oca-tabular text-muted-foreground", children: figure ?? pct })
|
|
4533
|
+
] }),
|
|
4534
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4535
|
+
"div",
|
|
4536
|
+
{
|
|
4537
|
+
role: "meter",
|
|
4538
|
+
"aria-labelledby": id,
|
|
4539
|
+
"aria-valuemin": 0,
|
|
4540
|
+
"aria-valuemax": max,
|
|
4541
|
+
"aria-valuenow": value,
|
|
4542
|
+
"aria-valuetext": typeof figure === "string" ? figure : pct,
|
|
4543
|
+
className: cn("flex overflow-hidden rounded-full bg-muted", size === "sm" ? "h-1.5" : "h-2.5"),
|
|
4544
|
+
children: [
|
|
4545
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4546
|
+
"div",
|
|
4547
|
+
{
|
|
4548
|
+
className: cn("h-full shrink-0 rounded-full", tone === "brand" ? "bg-oca-orange-deep" : "bg-foreground"),
|
|
4549
|
+
style: { width: `${v * 100}%` }
|
|
4550
|
+
}
|
|
4551
|
+
),
|
|
4552
|
+
g > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4553
|
+
"div",
|
|
4554
|
+
{
|
|
4555
|
+
"aria-hidden": true,
|
|
4556
|
+
className: "-ml-1.5 h-full shrink-0 rounded-r-full pl-1.5 text-foreground/45",
|
|
4557
|
+
style: {
|
|
4558
|
+
width: `calc(${g * 100}% + 0.375rem)`,
|
|
4559
|
+
backgroundImage: "repeating-linear-gradient(-45deg, currentColor 0 2px, transparent 2px 6px)"
|
|
4560
|
+
}
|
|
4561
|
+
}
|
|
4562
|
+
) : null
|
|
4563
|
+
]
|
|
4564
|
+
}
|
|
4565
|
+
)
|
|
4566
|
+
] });
|
|
4567
|
+
}
|
|
4568
|
+
function FilterChips({
|
|
4569
|
+
options,
|
|
4570
|
+
value,
|
|
4571
|
+
onChange,
|
|
4572
|
+
label,
|
|
4573
|
+
className
|
|
4574
|
+
}) {
|
|
4575
|
+
const tight = useDensity() === "compact";
|
|
4576
|
+
const multi = Array.isArray(value);
|
|
4577
|
+
const isOn = (v) => multi ? value.includes(v) : value === v;
|
|
4578
|
+
const press = (v) => {
|
|
4579
|
+
if (multi) {
|
|
4580
|
+
const cur = value;
|
|
4581
|
+
onChange(cur.includes(v) ? cur.filter((x) => x !== v) : [...cur, v]);
|
|
4582
|
+
} else onChange(v);
|
|
4583
|
+
};
|
|
4584
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--background)", className: cn("w-full", className), children: /* @__PURE__ */ jsxRuntime.jsx("div", { role: "group", "aria-label": label, className: "flex w-max items-center gap-2 py-0.5", children: options.map((o) => {
|
|
4585
|
+
const on = isOn(o.value);
|
|
4586
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4587
|
+
"button",
|
|
4588
|
+
{
|
|
4589
|
+
type: "button",
|
|
4590
|
+
"aria-pressed": on,
|
|
4591
|
+
onClick: () => press(o.value),
|
|
4592
|
+
className: cn(
|
|
4593
|
+
"inline-flex shrink-0 items-center gap-1.5 rounded-full border px-3.5 text-[0.875rem] transition-colors",
|
|
4594
|
+
tight ? "h-8" : "h-9",
|
|
4595
|
+
on ? "border-foreground bg-foreground text-background" : "border-border bg-card text-muted-foreground hover:border-oca-hairline-strong hover:text-foreground"
|
|
4596
|
+
),
|
|
4597
|
+
children: [
|
|
4598
|
+
o.label,
|
|
4599
|
+
o.count !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-tabular", children: o.count.toLocaleString("en-US") }) : null
|
|
4600
|
+
]
|
|
4601
|
+
},
|
|
4602
|
+
o.value
|
|
4603
|
+
);
|
|
4604
|
+
}) }) });
|
|
4605
|
+
}
|
|
4606
|
+
function ToolGrid({
|
|
4607
|
+
tools,
|
|
4608
|
+
as: Heading = "h2",
|
|
4609
|
+
className
|
|
4610
|
+
}) {
|
|
4611
|
+
const tight = useDensity() === "compact";
|
|
4612
|
+
const n = tools.length;
|
|
4613
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4614
|
+
"ul",
|
|
4615
|
+
{
|
|
4616
|
+
className: cn(
|
|
4617
|
+
"grid grid-cols-1 gap-3 sm:grid-cols-2 md:gap-4",
|
|
4618
|
+
// Three or four sit in one row on a wide screen.
|
|
4619
|
+
n === 3 || n === 6 ? "lg:grid-cols-3" : n === 4 ? "xl:grid-cols-4" : null,
|
|
4620
|
+
className
|
|
4621
|
+
),
|
|
4622
|
+
children: tools.map((t) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4623
|
+
"div",
|
|
4624
|
+
{
|
|
4625
|
+
className: cn(
|
|
4626
|
+
"group relative flex h-full flex-col rounded-[1.25rem] border border-border bg-card transition-colors",
|
|
4627
|
+
tight ? "gap-3 p-5" : "gap-4 p-6",
|
|
4628
|
+
"hover:border-oca-hairline-strong has-[a:focus-visible]:ring-2 has-[a:focus-visible]:ring-ring has-[a:focus-visible]:ring-offset-2 has-[a:focus-visible]:ring-offset-background"
|
|
4629
|
+
),
|
|
4630
|
+
children: [
|
|
4631
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
4632
|
+
t.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-10 items-center justify-center rounded-xl bg-muted text-foreground [&_svg]:size-5", children: t.icon }) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
|
|
4633
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4634
|
+
lucideReact.ArrowRight,
|
|
4635
|
+
{
|
|
4636
|
+
"aria-hidden": true,
|
|
4637
|
+
className: "size-4 text-muted-foreground transition-transform duration-200 group-hover:translate-x-0.5 group-hover:text-foreground"
|
|
4638
|
+
}
|
|
4639
|
+
)
|
|
4640
|
+
] }),
|
|
4641
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
4642
|
+
/* @__PURE__ */ jsxRuntime.jsx(Heading, { className: "oca-title-sm", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4643
|
+
Link__default.default,
|
|
4644
|
+
{
|
|
4645
|
+
href: t.href,
|
|
4646
|
+
className: "outline-none after:absolute after:inset-0 after:rounded-[1.25rem] after:content-['']",
|
|
4647
|
+
children: t.label
|
|
4648
|
+
}
|
|
4649
|
+
) }),
|
|
4650
|
+
t.description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.9375rem] leading-relaxed text-muted-foreground", children: t.description }) : null
|
|
4651
|
+
] })
|
|
4652
|
+
]
|
|
4653
|
+
}
|
|
4654
|
+
) }, t.href))
|
|
4655
|
+
}
|
|
4656
|
+
);
|
|
4657
|
+
}
|
|
2623
4658
|
|
|
2624
4659
|
exports.Accent = Accent;
|
|
2625
4660
|
exports.ActivityList = ActivityList;
|
|
4661
|
+
exports.AnchorStatus = AnchorStatus;
|
|
4662
|
+
exports.ApiTable = ApiTable;
|
|
2626
4663
|
exports.AppCard = AppCard;
|
|
2627
4664
|
exports.AppGrid = AppGrid;
|
|
4665
|
+
exports.ArtifactView = ArtifactView;
|
|
4666
|
+
exports.BlockCountdown = BlockCountdown;
|
|
4667
|
+
exports.BlockHeight = BlockHeight;
|
|
4668
|
+
exports.Breadcrumbs = Breadcrumbs;
|
|
2628
4669
|
exports.BrowserFrame = BrowserFrame;
|
|
4670
|
+
exports.Callout = Callout;
|
|
4671
|
+
exports.CardGrid = CardGrid;
|
|
2629
4672
|
exports.Closing = Closing;
|
|
2630
4673
|
exports.CodeBlock = CodeBlock;
|
|
4674
|
+
exports.CodeTabs = CodeTabs;
|
|
2631
4675
|
exports.ComparisonTable = ComparisonTable;
|
|
2632
4676
|
exports.Container = Container;
|
|
2633
4677
|
exports.CopyButton = CopyButton;
|
|
2634
4678
|
exports.DataTable = DataTable;
|
|
4679
|
+
exports.Diagram = Diagram;
|
|
2635
4680
|
exports.Display = Display;
|
|
2636
4681
|
exports.DocHeader = DocHeader;
|
|
2637
4682
|
exports.DocLayout = DocLayout;
|
|
4683
|
+
exports.DocsHeading = DocsHeading;
|
|
4684
|
+
exports.DocsPager = DocsPager;
|
|
4685
|
+
exports.DropZone = DropZone;
|
|
2638
4686
|
exports.EmptyLine = EmptyLine;
|
|
2639
4687
|
exports.EmptyState = EmptyState;
|
|
2640
4688
|
exports.EndpointList = EndpointList;
|
|
@@ -2644,15 +4692,22 @@ exports.Eyebrow = Eyebrow;
|
|
|
2644
4692
|
exports.FactBlock = FactBlock;
|
|
2645
4693
|
exports.FactRows = FactRows;
|
|
2646
4694
|
exports.Faq = Faq;
|
|
4695
|
+
exports.FilterChips = FilterChips;
|
|
2647
4696
|
exports.FloatChip = FloatChip;
|
|
2648
4697
|
exports.Footnote = Footnote;
|
|
4698
|
+
exports.FormSection = FormSection;
|
|
2649
4699
|
exports.HashChip = HashChip;
|
|
4700
|
+
exports.InstallTabs = InstallTabs;
|
|
2650
4701
|
exports.KeyValueList = KeyValueList;
|
|
2651
4702
|
exports.Lead = Lead;
|
|
2652
4703
|
exports.LegalDocument = LegalDocument;
|
|
4704
|
+
exports.LinkCard = LinkCard;
|
|
2653
4705
|
exports.LoadingBlock = LoadingBlock;
|
|
4706
|
+
exports.MdxTable = MdxTable;
|
|
4707
|
+
exports.Meter = Meter;
|
|
2654
4708
|
exports.Monogram = Monogram;
|
|
2655
4709
|
exports.Notice = Notice;
|
|
4710
|
+
exports.OnThisPage = OnThisPage;
|
|
2656
4711
|
exports.PackageCard = PackageCard;
|
|
2657
4712
|
exports.PageHeader = PageHeader;
|
|
2658
4713
|
exports.PageHero = PageHero;
|
|
@@ -2667,6 +4722,8 @@ exports.Reveal = Reveal;
|
|
|
2667
4722
|
exports.Sats = Sats;
|
|
2668
4723
|
exports.SatsFigure = SatsFigure;
|
|
2669
4724
|
exports.ScrollStory = ScrollStory;
|
|
4725
|
+
exports.SearchButton = SearchButton;
|
|
4726
|
+
exports.SearchDialog = SearchDialog;
|
|
2670
4727
|
exports.Section = Section;
|
|
2671
4728
|
exports.SectionHeading = SectionHeading;
|
|
2672
4729
|
exports.SectionIntro = SectionIntro;
|
|
@@ -2675,18 +4732,26 @@ exports.SpecCard = SpecCard;
|
|
|
2675
4732
|
exports.SplitBar = SplitBar;
|
|
2676
4733
|
exports.StatCard = StatCard;
|
|
2677
4734
|
exports.StatGrid = StatGrid;
|
|
4735
|
+
exports.StateBadge = StateBadge;
|
|
4736
|
+
exports.Step = Step;
|
|
2678
4737
|
exports.StepGrid = StepGrid;
|
|
4738
|
+
exports.Steps = Steps;
|
|
2679
4739
|
exports.TextLink = TextLink;
|
|
2680
4740
|
exports.Ticker = Ticker;
|
|
4741
|
+
exports.ToolGrid = ToolGrid;
|
|
2681
4742
|
exports.TruthTable = TruthTable;
|
|
2682
4743
|
exports.UsdApprox = UsdApprox;
|
|
2683
4744
|
exports.VerifyBox = VerifyBox;
|
|
2684
4745
|
exports.VerifyReport = VerifyReport;
|
|
4746
|
+
exports.createStateBadge = createStateBadge;
|
|
4747
|
+
exports.languageName = languageName;
|
|
2685
4748
|
exports.monogramGround = monogramGround;
|
|
2686
4749
|
exports.monogramLetter = monogramLetter;
|
|
2687
4750
|
exports.satsText = satsText;
|
|
2688
4751
|
exports.sectionVariants = sectionVariants;
|
|
4752
|
+
exports.useActiveHeading = useActiveHeading;
|
|
2689
4753
|
exports.useCopy = useCopy;
|
|
4754
|
+
exports.useHeadings = useHeadings;
|
|
2690
4755
|
exports.useInView = useInView;
|
|
2691
4756
|
//# sourceMappingURL=components.js.map
|
|
2692
4757
|
//# sourceMappingURL=components.js.map
|