@estiva-app/ui 0.62.1 → 0.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CodeBlockColours.d.ts +11 -0
- package/dist/CodeBlockColours.d.ts.map +1 -0
- package/dist/ComposerTriggers.d.ts +8 -2
- package/dist/ComposerTriggers.d.ts.map +1 -1
- package/dist/KindIcon.d.ts +30 -0
- package/dist/KindIcon.d.ts.map +1 -0
- package/dist/Link.d.ts +1 -1
- package/dist/PastedImages.d.ts +33 -0
- package/dist/PastedImages.d.ts.map +1 -0
- package/dist/RichText.d.ts +2 -1
- package/dist/RichText.d.ts.map +1 -1
- package/dist/codeColours.d.ts +29 -0
- package/dist/codeColours.d.ts.map +1 -0
- package/dist/editor.d.ts +2 -0
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +86 -13
- package/dist/editor.js.map +4 -4
- package/dist/eslint/index.js +1 -0
- package/dist/eslint/index.js.map +2 -2
- package/dist/eslint/no-restyled-part.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +291 -237
- package/dist/index.js.map +4 -4
- package/package.json +8 -2
- package/registry.json +179 -16
- package/src/CodeBlockColours.mdx +48 -0
- package/src/CodeBlockColours.stories.tsx +37 -0
- package/src/CodeBlockColours.ts +14 -0
- package/src/ComposerTriggers.mdx +6 -4
- package/src/ComposerTriggers.test.tsx +30 -0
- package/src/ComposerTriggers.tsx +9 -3
- package/src/KindIcon.mdx +58 -0
- package/src/KindIcon.stories.tsx +64 -0
- package/src/KindIcon.tsx +64 -0
- package/src/Link.mdx +1 -1
- package/src/Link.stories.tsx +1 -1
- package/src/Link.test.tsx +2 -2
- package/src/Link.tsx +2 -2
- package/src/PastedImages.mdx +61 -0
- package/src/PastedImages.stories.tsx +53 -0
- package/src/PastedImages.test.ts +83 -0
- package/src/PastedImages.ts +105 -0
- package/src/RichText.stories.tsx +24 -0
- package/src/RichText.tsx +31 -17
- package/src/codeColours.ts +33 -0
- package/src/editor.ts +2 -0
- package/src/eslint/no-restyled-part.ts +1 -0
- package/src/index.ts +1 -0
- package/src/pages.test.ts +5 -1
- package/src/registry/registry.test.ts +7 -7
- package/stories/Choosing.mdx +3 -0
- package/tailwind-preset.js +8 -0
- package/tokens.css +50 -0
package/dist/index.js
CHANGED
|
@@ -71,7 +71,7 @@ function cn(...inputs) {
|
|
|
71
71
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
72
72
|
var COVER_CLASSES = "after:absolute after:inset-0 after:rounded-md focus-visible:outline-none focus-visible:after:[outline-style:auto]";
|
|
73
73
|
var VARIANT_CLASSES = {
|
|
74
|
-
text: "text-
|
|
74
|
+
text: "text-text-interactive underline underline-offset-2 hover:opacity-80",
|
|
75
75
|
quiet: "hover:underline",
|
|
76
76
|
underlined: "underline underline-offset-2 hover:text-text-primary",
|
|
77
77
|
plain: ""
|
|
@@ -2421,28 +2421,52 @@ function InlineChip({ tone = "neutral", icon, href, className, children, ...prop
|
|
|
2421
2421
|
return /* @__PURE__ */ jsx33("a", { href, className: classes, ...props, onClick: inApp, children: body });
|
|
2422
2422
|
}
|
|
2423
2423
|
|
|
2424
|
+
// src/codeColours.ts
|
|
2425
|
+
import { createElement } from "react";
|
|
2426
|
+
import { common, createLowlight } from "lowlight";
|
|
2427
|
+
var lowlight = createLowlight(common);
|
|
2428
|
+
function draw(node, key) {
|
|
2429
|
+
if (node.type === "text") return node.value;
|
|
2430
|
+
return createElement("span", { key, className: node.properties?.className?.join(" ") }, (node.children ?? []).map(draw));
|
|
2431
|
+
}
|
|
2432
|
+
function codeColours(text, language) {
|
|
2433
|
+
if (!language || !lowlight.registered(language)) return text;
|
|
2434
|
+
return lowlight.highlight(language, text).children.map(draw);
|
|
2435
|
+
}
|
|
2436
|
+
|
|
2424
2437
|
// src/RichText.tsx
|
|
2425
2438
|
import { Fragment as Fragment8, jsx as jsx34, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2426
2439
|
var RICH_TEXT_CLASSES = {
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2440
|
+
/* Blocks 8px apart (Katerina, 9 October; 4 before). A list's own items stay together. */
|
|
2441
|
+
base: "flex flex-col gap-2 break-words text-text-secondary",
|
|
2442
|
+
/* A heading binds to what follows it: 12px above (4 and the 8px gap), 8px below (the gap); two headings in a row, 12px apart. The same as before the gap grew (Katerina, 9 October: headings do not change). Level 3 keeps the text's colour, one step lower: at the same size as level 2, colour is what tells them apart (Katerina, 9 October). */
|
|
2443
|
+
headings: "[&>:is(h1,h2,h3)]:mt-1 [&>:is(h1,h2,h3):first-child]:mt-0 [&>:is(h1,h2)]:text-text-primary",
|
|
2444
|
+
/* Bullets and numbers in the text's own colour, so a number can be read (Katerina, 9 October; they were the muted grey, 2.4 : 1 in Leaf). */
|
|
2445
|
+
lists: "[&_:is(ul,ol)]:pl-5 [&_li>p]:m-0 [&_li]:break-words [&_li]:marker:text-text-secondary [&_ol]:list-decimal [&_ul]:list-disc",
|
|
2446
|
+
/* The line in the muted text grey, not the border grey: a border grey was 1.3 : 1 in Leaf (Katerina, 9 October). */
|
|
2431
2447
|
// eslint-disable-next-line token-spacing/no-restricted-classes -- @estiva-escape: the quote line is Peek's, 3px, between the ramp's 2 and 4
|
|
2432
|
-
quote: "[&_blockquote>p]:m-0 [&_blockquote]:border-l-[3px] [&_blockquote]:border-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2448
|
+
quote: "[&_blockquote>p]:m-0 [&_blockquote]:border-l-[3px] [&_blockquote]:border-text-muted [&_blockquote]:pl-2.5",
|
|
2449
|
+
/* Code in a sentence is amber, its own colour (Katerina, 9 October: option I). */
|
|
2450
|
+
// eslint-disable-next-line token-values/no-restricted-classes -- @estiva-escape: code is 0.85 of the text around it, so it scales with a heading and with `small`; a named size is fixed
|
|
2451
|
+
code: "[&_:not(pre)>code]:rounded-sm [&_:not(pre)>code]:bg-bg-code [&_:not(pre)>code]:px-1 [&_:not(pre)>code]:py-0.5 [&_:not(pre)>code]:text-text-code [&_code]:font-mono [&_code]:text-[0.85em] [&_code]:text-text-primary",
|
|
2452
|
+
/* 12px either side, 10px above and below, looser lines than the text (Katerina, 9 October; 8px all round before). */
|
|
2453
|
+
// eslint-disable-next-line token-values/no-restricted-classes -- @estiva-escape: code is 0.85 of the text around it; the code inside the block is the block's own size, not 0.85 of it again
|
|
2454
|
+
codeBlock: "[&_pre>code]:text-[1em] [&_pre]:whitespace-pre-wrap [&_pre]:break-words [&_pre]:rounded-md [&_pre]:bg-bg-code [&_pre]:px-3 [&_pre]:py-2.5 [&_pre]:font-mono [&_pre]:text-[0.85em] [&_pre]:leading-relaxed [&_pre]:text-text-primary",
|
|
2455
|
+
/* Colours inside a code block, by language: the classes `codeColours` gives each word, after highlight.js's own GitHub theme (Katerina, 9 October). */
|
|
2456
|
+
syntax: "[&_:is(.hljs-keyword,.hljs-doctag,.hljs-type,.hljs-template-tag,.hljs-template-variable)]:text-syntax-keyword [&_.hljs-title]:text-syntax-function [&_:is(.hljs-number,.hljs-literal,.hljs-attr,.hljs-attribute,.hljs-meta,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id)]:text-syntax-constant [&_:is(.hljs-string,.hljs-regexp)]:text-syntax-string [&_:is(.hljs-built_in,.hljs-symbol)]:text-syntax-variable [&_.hljs-comment]:text-syntax-comment [&_:is(.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo)]:text-syntax-tag",
|
|
2457
|
+
/* A divider splits the text in two: 16px either side (Katerina, 9 October; 4 before). */
|
|
2458
|
+
divider: "[&_hr]:my-2 [&_hr]:border-border-default",
|
|
2438
2459
|
table: "[&_:is(th,td)>p]:m-0 [&_:is(th,td)]:border [&_:is(th,td)]:border-border-default [&_:is(th,td)]:px-2 [&_:is(th,td)]:py-1 [&_:is(th,td)]:text-left [&_:is(th,td)]:align-top [&_table]:w-full [&_table]:border-collapse [&_th]:bg-bg-code [&_th]:font-medium [&_th]:text-text-primary",
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2460
|
+
/* Bold in the heading colour, not only heavier. An underlined word draws a faint line, so it does not read as a link (Katerina, 9 October). */
|
|
2461
|
+
marks: "[&_em]:italic [&_strong]:font-semibold [&_strong]:text-text-primary [&_u]:underline [&_u]:decoration-text-muted [&_u]:underline-offset-2",
|
|
2462
|
+
/* Lines 1.5 apart (Katerina, 9 October; 1.4 before). */
|
|
2463
|
+
default: "text-body-2 leading-normal [&>:is(h2,h3)]:text-body-2 [&>:is(h2,h3)]:font-semibold [&>h1]:text-h4",
|
|
2464
|
+
/* Blocks 6px apart; a heading keeps its 12px above and 8px below. */
|
|
2465
|
+
small: "gap-1.5 text-caption leading-snug [&>:is(h1,h2,h3)]:mb-0.5 [&>:is(h1,h2,h3)]:mt-1.5 [&>:is(h1,h2,h3)+:is(h1,h2,h3)]:mt-1 [&>:is(h1,h2,h3):last-child]:mb-0 [&>:is(h2,h3)]:text-caption [&>:is(h2,h3)]:font-semibold [&>h1]:text-body-2 [&>h1]:font-semibold"
|
|
2442
2466
|
};
|
|
2443
2467
|
function richTextClassName(size = "default", className) {
|
|
2444
|
-
const { base, headings, lists, quote, code, codeBlock, divider, table, marks } = RICH_TEXT_CLASSES;
|
|
2445
|
-
return cn(base, headings, lists, quote, code, codeBlock, divider, table, marks, RICH_TEXT_CLASSES[size], className);
|
|
2468
|
+
const { base, headings, lists, quote, code, codeBlock, syntax, divider, table, marks } = RICH_TEXT_CLASSES;
|
|
2469
|
+
return cn(base, headings, lists, quote, code, codeBlock, syntax, divider, table, marks, RICH_TEXT_CLASSES[size], className);
|
|
2446
2470
|
}
|
|
2447
2471
|
var LINK_SPLIT = /(\[[^[\]\n]+\]\((?:https?:\/\/|mailto:)[^\s)]+\)|https?:\/\/[^\s]+)/g;
|
|
2448
2472
|
var WRITTEN_LINK = /^\[([^[\]\n]+)\]\(((?:https?:\/\/|mailto:)[^\s)]+)\)$/;
|
|
@@ -2469,15 +2493,15 @@ function textWithLinks(text, renderText) {
|
|
|
2469
2493
|
return part ? /* @__PURE__ */ jsx34("span", { children: renderText(part) }, i) : null;
|
|
2470
2494
|
});
|
|
2471
2495
|
}
|
|
2472
|
-
function Runs({ runs, draw }) {
|
|
2496
|
+
function Runs({ runs, draw: draw2 }) {
|
|
2473
2497
|
return /* @__PURE__ */ jsx34(Fragment8, { children: (runs ?? []).map((run, i) => {
|
|
2474
|
-
if (run.reference) return /* @__PURE__ */ jsx34("span", { children:
|
|
2498
|
+
if (run.reference) return /* @__PURE__ */ jsx34("span", { children: draw2.renderReference(run.reference, run) }, i);
|
|
2475
2499
|
if (run.marks.includes("code")) {
|
|
2476
2500
|
return /* @__PURE__ */ jsx34("code", { children: run.text }, i);
|
|
2477
2501
|
}
|
|
2478
2502
|
let node = run.text.split("\n").map((line, j) => /* @__PURE__ */ jsxs25("span", { children: [
|
|
2479
2503
|
j > 0 && /* @__PURE__ */ jsx34("br", {}),
|
|
2480
|
-
textWithLinks(line,
|
|
2504
|
+
textWithLinks(line, draw2.renderText)
|
|
2481
2505
|
] }, j));
|
|
2482
2506
|
if (run.marks.includes("underline")) node = /* @__PURE__ */ jsx34("u", { children: node });
|
|
2483
2507
|
if (run.marks.includes("italic")) node = /* @__PURE__ */ jsx34("em", { children: node });
|
|
@@ -2486,7 +2510,7 @@ function Runs({ runs, draw }) {
|
|
|
2486
2510
|
}) });
|
|
2487
2511
|
}
|
|
2488
2512
|
var named = (block) => block.typeName ?? block.type;
|
|
2489
|
-
function Table({ block, draw }) {
|
|
2513
|
+
function Table({ block, draw: draw2 }) {
|
|
2490
2514
|
const rows = (block.children ?? []).filter((row) => named(row) === "tableRow");
|
|
2491
2515
|
if (!rows.length) return null;
|
|
2492
2516
|
const cells = (row) => (row.children ?? []).map((cell, i) => {
|
|
@@ -2500,8 +2524,8 @@ function Table({ block, draw }) {
|
|
|
2500
2524
|
colSpan: colspan && colspan > 1 ? colspan : void 0,
|
|
2501
2525
|
rowSpan: rowspan && rowspan > 1 ? rowspan : void 0,
|
|
2502
2526
|
children: [
|
|
2503
|
-
(cell.children ?? []).map((child, j) => /* @__PURE__ */ jsx34(Runs, { runs: child.inline, draw }, j)),
|
|
2504
|
-
/* @__PURE__ */ jsx34(Runs, { runs: cell.inline, draw })
|
|
2527
|
+
(cell.children ?? []).map((child, j) => /* @__PURE__ */ jsx34(Runs, { runs: child.inline, draw: draw2 }, j)),
|
|
2528
|
+
/* @__PURE__ */ jsx34(Runs, { runs: cell.inline, draw: draw2 })
|
|
2505
2529
|
]
|
|
2506
2530
|
},
|
|
2507
2531
|
cell.id ?? i
|
|
@@ -2514,10 +2538,10 @@ function Table({ block, draw }) {
|
|
|
2514
2538
|
/* @__PURE__ */ jsx34("tbody", { children: (headerRow ? rows.slice(1) : rows).map((row, i) => /* @__PURE__ */ jsx34("tr", { "data-block-id": row.id, children: cells(row) }, row.id ?? i)) })
|
|
2515
2539
|
] });
|
|
2516
2540
|
}
|
|
2517
|
-
function Block({ block, draw }) {
|
|
2518
|
-
const own =
|
|
2541
|
+
function Block({ block, draw: draw2 }) {
|
|
2542
|
+
const own = draw2.renderBlock?.(block);
|
|
2519
2543
|
if (own !== void 0) return own;
|
|
2520
|
-
const runs = /* @__PURE__ */ jsx34(Runs, { runs: block.inline, draw });
|
|
2544
|
+
const runs = /* @__PURE__ */ jsx34(Runs, { runs: block.inline, draw: draw2 });
|
|
2521
2545
|
switch (block.type) {
|
|
2522
2546
|
case "heading": {
|
|
2523
2547
|
if (block.level === 1) return /* @__PURE__ */ jsx34("h1", { "data-block-id": block.id, children: runs });
|
|
@@ -2528,24 +2552,24 @@ function Block({ block, draw }) {
|
|
|
2528
2552
|
return /* @__PURE__ */ jsx34("p", { "data-block-id": block.id, children: runs });
|
|
2529
2553
|
case "bulletList":
|
|
2530
2554
|
case "orderedList": {
|
|
2531
|
-
const items = (block.children ?? []).map((item, i) => /* @__PURE__ */ jsx34("li", { "data-block-id": item.id, children: /* @__PURE__ */ jsx34(Runs, { runs: item.inline, draw }) }, item.id ?? i));
|
|
2555
|
+
const items = (block.children ?? []).map((item, i) => /* @__PURE__ */ jsx34("li", { "data-block-id": item.id, children: /* @__PURE__ */ jsx34(Runs, { runs: item.inline, draw: draw2 }) }, item.id ?? i));
|
|
2532
2556
|
return block.type === "bulletList" ? /* @__PURE__ */ jsx34("ul", { "data-block-id": block.id, children: items }) : /* @__PURE__ */ jsx34("ol", { "data-block-id": block.id, start: block.start, children: items });
|
|
2533
2557
|
}
|
|
2534
2558
|
case "blockquote":
|
|
2535
2559
|
return /* @__PURE__ */ jsx34("blockquote", { "data-block-id": block.id, children: runs });
|
|
2536
2560
|
case "codeBlock":
|
|
2537
|
-
return /* @__PURE__ */ jsx34("pre", { "data-block-id": block.id, "data-language": block.language, children: /* @__PURE__ */ jsx34("code", { children: (block.inline ?? []).map((run) => run.text).join("") }) });
|
|
2561
|
+
return /* @__PURE__ */ jsx34("pre", { "data-block-id": block.id, "data-language": block.language, children: /* @__PURE__ */ jsx34("code", { children: codeColours((block.inline ?? []).map((run) => run.text).join(""), block.language) }) });
|
|
2538
2562
|
case "horizontalRule":
|
|
2539
2563
|
return /* @__PURE__ */ jsx34("hr", { "data-block-id": block.id });
|
|
2540
2564
|
case "table": {
|
|
2541
|
-
const table = /* @__PURE__ */ jsx34(Table, { block, draw });
|
|
2565
|
+
const table = /* @__PURE__ */ jsx34(Table, { block, draw: draw2 });
|
|
2542
2566
|
if ((block.children ?? []).some((row) => named(row) === "tableRow")) return table;
|
|
2543
2567
|
break;
|
|
2544
2568
|
}
|
|
2545
2569
|
}
|
|
2546
2570
|
return /* @__PURE__ */ jsxs25("div", { "data-block-id": block.id, "data-block-type": named(block), children: [
|
|
2547
2571
|
runs,
|
|
2548
|
-
(block.children ?? []).map((child, i) => /* @__PURE__ */ jsx34(Block, { block: child, draw }, child.id ?? i))
|
|
2572
|
+
(block.children ?? []).map((child, i) => /* @__PURE__ */ jsx34(Block, { block: child, draw: draw2 }, child.id ?? i))
|
|
2549
2573
|
] });
|
|
2550
2574
|
}
|
|
2551
2575
|
function RichText({
|
|
@@ -2556,23 +2580,51 @@ function RichText({
|
|
|
2556
2580
|
renderBlock
|
|
2557
2581
|
}) {
|
|
2558
2582
|
if (blocks.length === 0) return null;
|
|
2559
|
-
const
|
|
2560
|
-
return /* @__PURE__ */ jsx34("div", { "data-rich-text": true, className: richTextClassName(size), children: blocks.map((block, i) => /* @__PURE__ */ jsx34(Block, { block, draw }, block.id ?? i)) });
|
|
2583
|
+
const draw2 = { renderText, renderReference, renderBlock };
|
|
2584
|
+
return /* @__PURE__ */ jsx34("div", { "data-rich-text": true, className: richTextClassName(size), children: blocks.map((block, i) => /* @__PURE__ */ jsx34(Block, { block, draw: draw2 }, block.id ?? i)) });
|
|
2585
|
+
}
|
|
2586
|
+
|
|
2587
|
+
// src/KindIcon.tsx
|
|
2588
|
+
import { IconBox, IconCircleDashed, IconFile as IconFile2, IconListDetails, IconMessage } from "@tabler/icons-react";
|
|
2589
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
2590
|
+
var ICONS = {
|
|
2591
|
+
topic: IconCircleDashed,
|
|
2592
|
+
project: IconBox,
|
|
2593
|
+
issue: IconListDetails,
|
|
2594
|
+
file: IconFile2,
|
|
2595
|
+
message: IconMessage
|
|
2596
|
+
};
|
|
2597
|
+
var KIND_MESSAGE = 9;
|
|
2598
|
+
var KIND_CHANNEL = 39e3;
|
|
2599
|
+
var KIND_BARE_FILE = 30840;
|
|
2600
|
+
var KIND_PROJECT = 30850;
|
|
2601
|
+
var KIND_ISSUE = 30851;
|
|
2602
|
+
function thingKindOf(eventKind) {
|
|
2603
|
+
if (eventKind === KIND_MESSAGE) return "message";
|
|
2604
|
+
if (eventKind === KIND_CHANNEL || eventKind === KIND_BARE_FILE) return "topic";
|
|
2605
|
+
if (eventKind === KIND_PROJECT) return "project";
|
|
2606
|
+
if (eventKind === KIND_ISSUE) return "issue";
|
|
2607
|
+
return "file";
|
|
2608
|
+
}
|
|
2609
|
+
var TONE_CLASSES = { secondary: "text-text-secondary", inherit: "" };
|
|
2610
|
+
function KindIcon({ kind, size = 16, tone = "secondary", className }) {
|
|
2611
|
+
const Icon = ICONS[kind];
|
|
2612
|
+
return /* @__PURE__ */ jsx35(Icon, { size, stroke: 1.5, className: cn("shrink-0", TONE_CLASSES[tone], className), "aria-hidden": true });
|
|
2561
2613
|
}
|
|
2562
2614
|
|
|
2563
2615
|
// src/IdentityMenu.tsx
|
|
2564
2616
|
import { useCallback as useCallback2, useRef as useRef8 } from "react";
|
|
2565
2617
|
|
|
2566
2618
|
// src/Person.tsx
|
|
2567
|
-
import { jsx as
|
|
2619
|
+
import { jsx as jsx36, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2568
2620
|
function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
2569
2621
|
return (
|
|
2570
2622
|
// gap-2: the face-to-name distance is one rule (8px) wherever a person
|
|
2571
2623
|
// appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
|
|
2572
2624
|
// row agree by construction.
|
|
2573
2625
|
/* @__PURE__ */ jsxs26("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
|
|
2574
|
-
/* @__PURE__ */
|
|
2575
|
-
/* @__PURE__ */
|
|
2626
|
+
/* @__PURE__ */ jsx36(Avatar, { name, src: picture, size }),
|
|
2627
|
+
/* @__PURE__ */ jsx36("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
|
|
2576
2628
|
] })
|
|
2577
2629
|
);
|
|
2578
2630
|
}
|
|
@@ -2580,10 +2632,10 @@ function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
|
2580
2632
|
// src/PersonTrigger.tsx
|
|
2581
2633
|
import { Button as BaseButton7 } from "@base-ui/react/button";
|
|
2582
2634
|
import { IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
|
|
2583
|
-
import { jsx as
|
|
2635
|
+
import { jsx as jsx37, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2584
2636
|
function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
|
|
2585
2637
|
if (compact) {
|
|
2586
|
-
return /* @__PURE__ */
|
|
2638
|
+
return /* @__PURE__ */ jsx37(
|
|
2587
2639
|
BaseButton7,
|
|
2588
2640
|
{
|
|
2589
2641
|
type: "button",
|
|
@@ -2592,7 +2644,7 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
2592
2644
|
"aria-label": props["aria-label"] ?? name ?? fallback,
|
|
2593
2645
|
className: cn("cursor-pointer rounded-full", className),
|
|
2594
2646
|
...props,
|
|
2595
|
-
children: /* @__PURE__ */
|
|
2647
|
+
children: /* @__PURE__ */ jsx37(Avatar, { name, src: picture, size: size ?? 36 })
|
|
2596
2648
|
}
|
|
2597
2649
|
);
|
|
2598
2650
|
}
|
|
@@ -2616,8 +2668,8 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
2616
2668
|
),
|
|
2617
2669
|
...props,
|
|
2618
2670
|
children: [
|
|
2619
|
-
/* @__PURE__ */
|
|
2620
|
-
/* @__PURE__ */
|
|
2671
|
+
/* @__PURE__ */ jsx37(Person, { name, picture, fallback, size: size ?? 22 }),
|
|
2672
|
+
/* @__PURE__ */ jsx37(IconChevronDown2, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
|
|
2621
2673
|
]
|
|
2622
2674
|
}
|
|
2623
2675
|
)
|
|
@@ -2625,10 +2677,10 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
2625
2677
|
}
|
|
2626
2678
|
|
|
2627
2679
|
// src/IdentityMenu.tsx
|
|
2628
|
-
import { Fragment as Fragment9, jsx as
|
|
2680
|
+
import { Fragment as Fragment9, jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2629
2681
|
function IdentityPanel({ className, onClose = () => {
|
|
2630
2682
|
}, ...rest }) {
|
|
2631
|
-
return /* @__PURE__ */
|
|
2683
|
+
return /* @__PURE__ */ jsx38(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx38(IdentityRows, { ...rest, onClose }) });
|
|
2632
2684
|
}
|
|
2633
2685
|
function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
|
|
2634
2686
|
const act = (action) => () => {
|
|
@@ -2638,34 +2690,34 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
|
|
|
2638
2690
|
const appRows = typeof children === "function" ? children(onClose) : children;
|
|
2639
2691
|
return /* @__PURE__ */ jsxs28(Fragment9, { children: [
|
|
2640
2692
|
/* @__PURE__ */ jsxs28(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
|
|
2641
|
-
/* @__PURE__ */
|
|
2642
|
-
/* @__PURE__ */
|
|
2693
|
+
/* @__PURE__ */ jsx38(MenuRow, { children: /* @__PURE__ */ jsx38("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx38(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
|
|
2694
|
+
/* @__PURE__ */ jsx38(Note, { children: signedIn ? "Your Estiva ID. The same person you are in every Estiva app." : "A key held by this browser only. Nobody else knows who you are." }),
|
|
2643
2695
|
me.email && /* @__PURE__ */ jsxs28(Note, { children: [
|
|
2644
2696
|
me.email,
|
|
2645
2697
|
" \xB7 known to Estiva, never published to the relay"
|
|
2646
2698
|
] })
|
|
2647
2699
|
] }),
|
|
2648
2700
|
relayUrl && /* @__PURE__ */ jsxs28(Fragment9, { children: [
|
|
2649
|
-
/* @__PURE__ */
|
|
2701
|
+
/* @__PURE__ */ jsx38(Divider, { className: "mx-0 my-2" }),
|
|
2650
2702
|
/* @__PURE__ */ jsxs28(MenuSection, { label: "Workspace", children: [
|
|
2651
|
-
/* @__PURE__ */
|
|
2652
|
-
/* @__PURE__ */
|
|
2703
|
+
/* @__PURE__ */ jsx38(MenuRow, { children: /* @__PURE__ */ jsx38("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
|
|
2704
|
+
/* @__PURE__ */ jsx38(Note, { children: "Everyone on this relay shares this workspace, in every app." })
|
|
2653
2705
|
] })
|
|
2654
2706
|
] }),
|
|
2655
2707
|
appRows && /* @__PURE__ */ jsxs28(Fragment9, { children: [
|
|
2656
|
-
/* @__PURE__ */
|
|
2708
|
+
/* @__PURE__ */ jsx38(Divider, { className: "mx-0 my-2" }),
|
|
2657
2709
|
appRows
|
|
2658
2710
|
] }),
|
|
2659
|
-
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */
|
|
2660
|
-
signedIn && idBase && /* @__PURE__ */
|
|
2711
|
+
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx38(Divider, { className: "mx-0 my-2" }) : null,
|
|
2712
|
+
signedIn && idBase && /* @__PURE__ */ jsx38(
|
|
2661
2713
|
MenuItem,
|
|
2662
2714
|
{
|
|
2663
2715
|
label: "Edit your profile in Estiva ID",
|
|
2664
2716
|
onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
|
|
2665
2717
|
}
|
|
2666
2718
|
),
|
|
2667
|
-
onCopyKey && /* @__PURE__ */
|
|
2668
|
-
idBase && onSignOut && /* @__PURE__ */
|
|
2719
|
+
onCopyKey && /* @__PURE__ */ jsx38(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
|
|
2720
|
+
idBase && onSignOut && /* @__PURE__ */ jsx38(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
|
|
2669
2721
|
] });
|
|
2670
2722
|
}
|
|
2671
2723
|
function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
|
|
@@ -2676,13 +2728,13 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
2676
2728
|
to be `relative`, because the panel was positioned against it; the panel
|
|
2677
2729
|
hangs from the trigger and portals now, so a positioning context here
|
|
2678
2730
|
would only be a lie about what this box does. */
|
|
2679
|
-
/* @__PURE__ */
|
|
2731
|
+
/* @__PURE__ */ jsx38("div", { className, children: /* @__PURE__ */ jsx38(
|
|
2680
2732
|
Menu,
|
|
2681
2733
|
{
|
|
2682
2734
|
align: "right",
|
|
2683
2735
|
actionsRef: actions,
|
|
2684
2736
|
className: "w-72",
|
|
2685
|
-
trigger: /* @__PURE__ */
|
|
2737
|
+
trigger: /* @__PURE__ */ jsx38(
|
|
2686
2738
|
PersonTrigger,
|
|
2687
2739
|
{
|
|
2688
2740
|
name: me.name,
|
|
@@ -2693,7 +2745,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
2693
2745
|
"aria-label": compact ? "Account menu" : void 0
|
|
2694
2746
|
}
|
|
2695
2747
|
),
|
|
2696
|
-
children: /* @__PURE__ */
|
|
2748
|
+
children: /* @__PURE__ */ jsx38(
|
|
2697
2749
|
IdentityRows,
|
|
2698
2750
|
{
|
|
2699
2751
|
me,
|
|
@@ -2711,14 +2763,14 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
2711
2763
|
);
|
|
2712
2764
|
}
|
|
2713
2765
|
function Note({ children }) {
|
|
2714
|
-
return /* @__PURE__ */
|
|
2766
|
+
return /* @__PURE__ */ jsx38("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
|
|
2715
2767
|
}
|
|
2716
2768
|
|
|
2717
2769
|
// src/FilePicker.tsx
|
|
2718
2770
|
import { forwardRef } from "react";
|
|
2719
|
-
import { jsx as
|
|
2771
|
+
import { jsx as jsx39 } from "react/jsx-runtime";
|
|
2720
2772
|
var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
|
|
2721
|
-
return /* @__PURE__ */
|
|
2773
|
+
return /* @__PURE__ */ jsx39(
|
|
2722
2774
|
"input",
|
|
2723
2775
|
{
|
|
2724
2776
|
ref,
|
|
@@ -2739,7 +2791,7 @@ var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
|
|
|
2739
2791
|
// src/Select.tsx
|
|
2740
2792
|
import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown3 } from "@tabler/icons-react";
|
|
2741
2793
|
import { Select as BaseSelect } from "@base-ui/react/select";
|
|
2742
|
-
import { jsx as
|
|
2794
|
+
import { jsx as jsx40, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2743
2795
|
var GAP4 = 4;
|
|
2744
2796
|
var VIEWPORT_PAD4 = 8;
|
|
2745
2797
|
function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, disabledReason, className, ...aria }) {
|
|
@@ -2781,13 +2833,13 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2781
2833
|
),
|
|
2782
2834
|
children: [
|
|
2783
2835
|
/* @__PURE__ */ jsxs29("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
|
|
2784
|
-
selected?.leading && /* @__PURE__ */
|
|
2785
|
-
/* @__PURE__ */
|
|
2836
|
+
selected?.leading && /* @__PURE__ */ jsx40("span", { className: "flex shrink-0 items-center", children: selected.leading }),
|
|
2837
|
+
/* @__PURE__ */ jsx40(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
|
|
2786
2838
|
] }),
|
|
2787
|
-
/* @__PURE__ */
|
|
2839
|
+
/* @__PURE__ */ jsx40(
|
|
2788
2840
|
BaseSelect.Icon,
|
|
2789
2841
|
{
|
|
2790
|
-
render: /* @__PURE__ */
|
|
2842
|
+
render: /* @__PURE__ */ jsx40(IconChevronDown3, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2791
2843
|
}
|
|
2792
2844
|
)
|
|
2793
2845
|
]
|
|
@@ -2806,8 +2858,8 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2806
2858
|
disabled: disabled && !held,
|
|
2807
2859
|
modal: false,
|
|
2808
2860
|
children: [
|
|
2809
|
-
held ? /* @__PURE__ */
|
|
2810
|
-
/* @__PURE__ */
|
|
2861
|
+
held ? /* @__PURE__ */ jsx40(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
|
|
2862
|
+
/* @__PURE__ */ jsx40(BaseSelect.Portal, { children: /* @__PURE__ */ jsx40(
|
|
2811
2863
|
BaseSelect.Positioner,
|
|
2812
2864
|
{
|
|
2813
2865
|
side: "bottom",
|
|
@@ -2816,25 +2868,25 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2816
2868
|
collisionPadding: VIEWPORT_PAD4,
|
|
2817
2869
|
alignItemWithTrigger: false,
|
|
2818
2870
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
2819
|
-
children: /* @__PURE__ */
|
|
2871
|
+
children: /* @__PURE__ */ jsx40(
|
|
2820
2872
|
BaseSelect.Popup,
|
|
2821
2873
|
{
|
|
2822
|
-
render: /* @__PURE__ */
|
|
2874
|
+
render: /* @__PURE__ */ jsx40(MenuPanel, {}),
|
|
2823
2875
|
className: "min-w-[var(--anchor-width)] p-0",
|
|
2824
|
-
children: /* @__PURE__ */
|
|
2876
|
+
children: /* @__PURE__ */ jsx40(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col gap-0.5 p-2", children: options.map((option) => /* @__PURE__ */ jsxs29(
|
|
2825
2877
|
BaseSelect.Item,
|
|
2826
2878
|
{
|
|
2827
2879
|
value: option.value,
|
|
2828
2880
|
className: cn(menuItemClassName({ size: "default" }), "justify-between data-[selected]:font-medium"),
|
|
2829
2881
|
children: [
|
|
2830
2882
|
/* @__PURE__ */ jsxs29("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
2831
|
-
option.leading && /* @__PURE__ */
|
|
2832
|
-
/* @__PURE__ */
|
|
2883
|
+
option.leading && /* @__PURE__ */ jsx40("span", { className: "flex shrink-0 items-center", children: option.leading }),
|
|
2884
|
+
/* @__PURE__ */ jsx40(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
|
|
2833
2885
|
] }),
|
|
2834
|
-
/* @__PURE__ */
|
|
2886
|
+
/* @__PURE__ */ jsx40(
|
|
2835
2887
|
BaseSelect.ItemIndicator,
|
|
2836
2888
|
{
|
|
2837
|
-
render: /* @__PURE__ */
|
|
2889
|
+
render: /* @__PURE__ */ jsx40(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2838
2890
|
}
|
|
2839
2891
|
)
|
|
2840
2892
|
]
|
|
@@ -2853,9 +2905,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2853
2905
|
// src/TextInput.tsx
|
|
2854
2906
|
import { forwardRef as forwardRef2 } from "react";
|
|
2855
2907
|
import { Input } from "@base-ui/react/input";
|
|
2856
|
-
import { jsx as
|
|
2908
|
+
import { jsx as jsx41 } from "react/jsx-runtime";
|
|
2857
2909
|
var TextInput = forwardRef2(function TextInput2({ className, type = "text", size = "default", ...props }, ref) {
|
|
2858
|
-
return /* @__PURE__ */
|
|
2910
|
+
return /* @__PURE__ */ jsx41(
|
|
2859
2911
|
Input,
|
|
2860
2912
|
{
|
|
2861
2913
|
ref,
|
|
@@ -2881,13 +2933,13 @@ var TextInput = forwardRef2(function TextInput2({ className, type = "text", size
|
|
|
2881
2933
|
// src/Textarea.tsx
|
|
2882
2934
|
import { forwardRef as forwardRef3 } from "react";
|
|
2883
2935
|
import { Field as BaseField3 } from "@base-ui/react/field";
|
|
2884
|
-
import { jsx as
|
|
2936
|
+
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
2885
2937
|
var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
|
|
2886
|
-
return /* @__PURE__ */
|
|
2938
|
+
return /* @__PURE__ */ jsx42(
|
|
2887
2939
|
BaseField3.Control,
|
|
2888
2940
|
{
|
|
2889
2941
|
ref,
|
|
2890
|
-
render: /* @__PURE__ */
|
|
2942
|
+
render: /* @__PURE__ */ jsx42("textarea", {}),
|
|
2891
2943
|
className: cn(
|
|
2892
2944
|
// The border strengthens on hover, as Select's and ChipInput's do (Katerina, 16 September:
|
|
2893
2945
|
// "aren't there hover states in text input and text area?"). Focus comes after hover in
|
|
@@ -2907,7 +2959,7 @@ var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
|
|
|
2907
2959
|
|
|
2908
2960
|
// src/ConfirmDialog.tsx
|
|
2909
2961
|
import { useState as useState6 } from "react";
|
|
2910
|
-
import { Fragment as Fragment10, jsx as
|
|
2962
|
+
import { Fragment as Fragment10, jsx as jsx43, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2911
2963
|
function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
|
|
2912
2964
|
const [busy, setBusy] = useState6(false);
|
|
2913
2965
|
const confirm = async () => {
|
|
@@ -2919,17 +2971,17 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
2919
2971
|
setBusy(false);
|
|
2920
2972
|
}
|
|
2921
2973
|
};
|
|
2922
|
-
return /* @__PURE__ */
|
|
2974
|
+
return /* @__PURE__ */ jsx43(
|
|
2923
2975
|
DialogShell,
|
|
2924
2976
|
{
|
|
2925
2977
|
alert: true,
|
|
2926
2978
|
title,
|
|
2927
2979
|
onClose,
|
|
2928
2980
|
footer: /* @__PURE__ */ jsxs30(Fragment10, { children: [
|
|
2929
|
-
/* @__PURE__ */
|
|
2930
|
-
/* @__PURE__ */
|
|
2981
|
+
/* @__PURE__ */ jsx43(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
|
|
2982
|
+
/* @__PURE__ */ jsx43(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
|
|
2931
2983
|
] }),
|
|
2932
|
-
children: /* @__PURE__ */
|
|
2984
|
+
children: /* @__PURE__ */ jsx43("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
|
|
2933
2985
|
}
|
|
2934
2986
|
);
|
|
2935
2987
|
}
|
|
@@ -2938,7 +2990,7 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
2938
2990
|
import { useEffect as useEffect5, useRef as useRef9, useState as useState7 } from "react";
|
|
2939
2991
|
import { Field as BaseField4 } from "@base-ui/react/field";
|
|
2940
2992
|
import { Input as Input2 } from "@base-ui/react/input";
|
|
2941
|
-
import { jsx as
|
|
2993
|
+
import { jsx as jsx44 } from "react/jsx-runtime";
|
|
2942
2994
|
function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
|
|
2943
2995
|
const [editing, setEditing] = useState7(false);
|
|
2944
2996
|
const [draft, setDraft] = useState7(value);
|
|
@@ -2996,7 +3048,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2996
3048
|
written and never read. Read-only, this is a line of text: whatever
|
|
2997
3049
|
names the region around it (a `Field`, a `Property`) names this too.
|
|
2998
3050
|
*/
|
|
2999
|
-
/* @__PURE__ */
|
|
3051
|
+
/* @__PURE__ */ jsx44(
|
|
3000
3052
|
"div",
|
|
3001
3053
|
{
|
|
3002
3054
|
className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
|
|
@@ -3006,11 +3058,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
3006
3058
|
);
|
|
3007
3059
|
}
|
|
3008
3060
|
if (editing) {
|
|
3009
|
-
return multiline ? /* @__PURE__ */
|
|
3061
|
+
return multiline ? /* @__PURE__ */ jsx44(
|
|
3010
3062
|
BaseField4.Control,
|
|
3011
3063
|
{
|
|
3012
3064
|
ref: fieldRef,
|
|
3013
|
-
render: /* @__PURE__ */
|
|
3065
|
+
render: /* @__PURE__ */ jsx44("textarea", { rows: 4 }),
|
|
3014
3066
|
"aria-label": label,
|
|
3015
3067
|
value: draft,
|
|
3016
3068
|
disabled: busy,
|
|
@@ -3019,7 +3071,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
3019
3071
|
onBlur: () => void commit(),
|
|
3020
3072
|
className: fieldClass
|
|
3021
3073
|
}
|
|
3022
|
-
) : /* @__PURE__ */
|
|
3074
|
+
) : /* @__PURE__ */ jsx44(
|
|
3023
3075
|
Input2,
|
|
3024
3076
|
{
|
|
3025
3077
|
ref: fieldRef,
|
|
@@ -3033,7 +3085,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
3033
3085
|
}
|
|
3034
3086
|
);
|
|
3035
3087
|
}
|
|
3036
|
-
return /* @__PURE__ */
|
|
3088
|
+
return /* @__PURE__ */ jsx44(
|
|
3037
3089
|
"button",
|
|
3038
3090
|
{
|
|
3039
3091
|
type: "button",
|
|
@@ -3053,7 +3105,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
3053
3105
|
// src/ErrorBoundary.tsx
|
|
3054
3106
|
import { Component } from "react";
|
|
3055
3107
|
import { IconAlertTriangle as IconAlertTriangle2 } from "@tabler/icons-react";
|
|
3056
|
-
import { jsx as
|
|
3108
|
+
import { jsx as jsx45 } from "react/jsx-runtime";
|
|
3057
3109
|
var ErrorBoundary = class extends Component {
|
|
3058
3110
|
state = { hasError: false };
|
|
3059
3111
|
static getDerivedStateFromError() {
|
|
@@ -3064,22 +3116,22 @@ var ErrorBoundary = class extends Component {
|
|
|
3064
3116
|
}
|
|
3065
3117
|
render() {
|
|
3066
3118
|
if (!this.state.hasError) return this.props.children;
|
|
3067
|
-
const message = /* @__PURE__ */
|
|
3119
|
+
const message = /* @__PURE__ */ jsx45(
|
|
3068
3120
|
EmptyState,
|
|
3069
3121
|
{
|
|
3070
|
-
icon: /* @__PURE__ */
|
|
3122
|
+
icon: /* @__PURE__ */ jsx45(IconAlertTriangle2, { size: 16, stroke: 1.5 }),
|
|
3071
3123
|
message: `Something went wrong${this.props.label ? ` in the ${this.props.label}` : ""}. Your data is safe \u2014 try again.`,
|
|
3072
3124
|
action: { label: "Try again", onClick: () => this.setState({ hasError: false }) }
|
|
3073
3125
|
}
|
|
3074
3126
|
);
|
|
3075
3127
|
if (this.props.frame) return this.props.frame(message);
|
|
3076
|
-
return this.props.fallbackClassName ? /* @__PURE__ */
|
|
3128
|
+
return this.props.fallbackClassName ? /* @__PURE__ */ jsx45("div", { className: this.props.fallbackClassName, children: message }) : message;
|
|
3077
3129
|
}
|
|
3078
3130
|
};
|
|
3079
3131
|
|
|
3080
3132
|
// src/ProgressBar.tsx
|
|
3081
3133
|
import { Progress } from "@base-ui/react/progress";
|
|
3082
|
-
import { jsx as
|
|
3134
|
+
import { jsx as jsx46 } from "react/jsx-runtime";
|
|
3083
3135
|
var TRACK_CLASSES = {
|
|
3084
3136
|
default: "h-1.5 w-full overflow-hidden rounded-full bg-bg-inset",
|
|
3085
3137
|
// 4px, Katerina's ruling of 14 September; Peek's own bar is 3px until it takes this one.
|
|
@@ -3092,13 +3144,13 @@ var INDICATOR_CLASSES = {
|
|
|
3092
3144
|
function ProgressBar({ value, max, label, variant = "default", className }) {
|
|
3093
3145
|
return (
|
|
3094
3146
|
// `max={0}` needs no guard: Base UI reads the 0/0 share as an empty bar.
|
|
3095
|
-
/* @__PURE__ */
|
|
3147
|
+
/* @__PURE__ */ jsx46(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx46(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx46(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
|
|
3096
3148
|
);
|
|
3097
3149
|
}
|
|
3098
3150
|
|
|
3099
3151
|
// src/Breadcrumb.tsx
|
|
3100
3152
|
import { Fragment as Fragment11, useCallback as useCallback3, useLayoutEffect as useLayoutEffect4, useRef as useRef10, useState as useState8 } from "react";
|
|
3101
|
-
import { jsx as
|
|
3153
|
+
import { jsx as jsx47, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
3102
3154
|
function Breadcrumb({ items, className }) {
|
|
3103
3155
|
const navRef = useRef10(null);
|
|
3104
3156
|
const labelRefs = useRef10([]);
|
|
@@ -3118,7 +3170,7 @@ function Breadcrumb({ items, className }) {
|
|
|
3118
3170
|
observer.observe(nav);
|
|
3119
3171
|
return () => observer.disconnect();
|
|
3120
3172
|
}, [measure, items]);
|
|
3121
|
-
return /* @__PURE__ */
|
|
3173
|
+
return /* @__PURE__ */ jsx47("nav", { ref: navRef, "aria-label": "Breadcrumb", className: cn("flex min-w-0 items-center gap-1.5 text-body-2", className), children: items.map((item, index) => {
|
|
3122
3174
|
const last = index === items.length - 1;
|
|
3123
3175
|
const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
|
|
3124
3176
|
const text = cn(
|
|
@@ -3139,16 +3191,16 @@ function Breadcrumb({ items, className }) {
|
|
|
3139
3191
|
// on a box around it, which the link takes them from, rather than
|
|
3140
3192
|
// pushed into it (UIG-9); the link is still the one element that
|
|
3141
3193
|
// truncates and is measured.
|
|
3142
|
-
/* @__PURE__ */
|
|
3143
|
-
) : /* @__PURE__ */
|
|
3194
|
+
/* @__PURE__ */ jsx47("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx47(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
|
|
3195
|
+
) : /* @__PURE__ */ jsx47("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
|
|
3144
3196
|
return /* @__PURE__ */ jsxs31(Fragment11, { children: [
|
|
3145
|
-
index > 0 && /* @__PURE__ */
|
|
3146
|
-
item.icon && /* @__PURE__ */
|
|
3197
|
+
index > 0 && /* @__PURE__ */ jsx47("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
|
|
3198
|
+
item.icon && /* @__PURE__ */ jsx47("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
|
|
3147
3199
|
truncated.has(index) ? (
|
|
3148
3200
|
// `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
|
|
3149
3201
|
// must keep truncating inside it, or wrapping it would widen the
|
|
3150
3202
|
// trail and the tooltip would never be needed again.
|
|
3151
|
-
/* @__PURE__ */
|
|
3203
|
+
/* @__PURE__ */ jsx47(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
|
|
3152
3204
|
) : crumb
|
|
3153
3205
|
] }, `${item.label}-${index}`);
|
|
3154
3206
|
}) });
|
|
@@ -3160,13 +3212,13 @@ import { Collapsible } from "@base-ui/react/collapsible";
|
|
|
3160
3212
|
import { IconAlertSquareRounded, IconChevronRight as IconChevronRight2, IconDotsVertical } from "@tabler/icons-react";
|
|
3161
3213
|
|
|
3162
3214
|
// src/UnreadDot.tsx
|
|
3163
|
-
import { jsx as
|
|
3215
|
+
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
3164
3216
|
function UnreadDot({ className }) {
|
|
3165
|
-
return /* @__PURE__ */
|
|
3217
|
+
return /* @__PURE__ */ jsx48("div", { className: cn("flex h-6 w-6 shrink-0 items-center justify-center", className), "data-unread": true, children: /* @__PURE__ */ jsx48("div", { className: "h-1.5 w-1.5 rounded-full bg-accent-primary" }) });
|
|
3166
3218
|
}
|
|
3167
3219
|
|
|
3168
3220
|
// src/NavItem.tsx
|
|
3169
|
-
import { jsx as
|
|
3221
|
+
import { jsx as jsx49, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
3170
3222
|
function NavItem({
|
|
3171
3223
|
label,
|
|
3172
3224
|
href,
|
|
@@ -3197,7 +3249,7 @@ function NavItem({
|
|
|
3197
3249
|
onOpenChange?.(next);
|
|
3198
3250
|
};
|
|
3199
3251
|
const besides = menu != null || hasRows;
|
|
3200
|
-
const mark = unread ? urgent ? /* @__PURE__ */
|
|
3252
|
+
const mark = unread ? urgent ? /* @__PURE__ */ jsx49(UrgentMark, {}) : /* @__PURE__ */ jsx49(UnreadDot, {}) : null;
|
|
3201
3253
|
const stepsAside = menu != null && "transition-opacity group-hover/nav:opacity-0 group-has-[:focus-visible]/nav:opacity-0 group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:opacity-0 [@media(hover:none)]:opacity-0";
|
|
3202
3254
|
const row = /* @__PURE__ */ jsxs32(
|
|
3203
3255
|
"a",
|
|
@@ -3221,7 +3273,7 @@ function NavItem({
|
|
|
3221
3273
|
...props,
|
|
3222
3274
|
onClick: inApp,
|
|
3223
3275
|
children: [
|
|
3224
|
-
(icon || hasRows) && /* @__PURE__ */
|
|
3276
|
+
(icon || hasRows) && /* @__PURE__ */ jsx49(
|
|
3225
3277
|
"span",
|
|
3226
3278
|
{
|
|
3227
3279
|
className: cn(
|
|
@@ -3232,10 +3284,10 @@ function NavItem({
|
|
|
3232
3284
|
children: icon
|
|
3233
3285
|
}
|
|
3234
3286
|
),
|
|
3235
|
-
/* @__PURE__ */
|
|
3287
|
+
/* @__PURE__ */ jsx49("span", { className: cn("flex-1 truncate", unread && "font-medium"), children: label }),
|
|
3236
3288
|
hint != null && // Takes room only while it shows, so the label gives way to it.
|
|
3237
|
-
/* @__PURE__ */
|
|
3238
|
-
count ? /* @__PURE__ */
|
|
3289
|
+
/* @__PURE__ */ jsx49("span", { className: "hidden shrink-0 items-center group-hover/nav:flex group-has-[:focus-visible]/nav:flex", children: hint }),
|
|
3290
|
+
count ? /* @__PURE__ */ jsx49(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx49(
|
|
3239
3291
|
"span",
|
|
3240
3292
|
{
|
|
3241
3293
|
className: cn(
|
|
@@ -3251,7 +3303,7 @@ function NavItem({
|
|
|
3251
3303
|
// `-mr-1`: the 24px slot's dot then sits on the axis of a count and
|
|
3252
3304
|
// of the ⋮ (8px from the edge to the 16px box), one column with a
|
|
3253
3305
|
// folder heading's dot and ⋮ (Katerina, 5 October).
|
|
3254
|
-
/* @__PURE__ */
|
|
3306
|
+
/* @__PURE__ */ jsx49("span", { className: cn("-mr-1 flex shrink-0", stepsAside), children: mark })
|
|
3255
3307
|
) : menu != null && !count ? (
|
|
3256
3308
|
// Nothing at the right, but a menu: no room is kept at rest, so the
|
|
3257
3309
|
// label has the row's whole width; while the ⋮ shows, its 24px slot
|
|
@@ -3259,7 +3311,7 @@ function NavItem({
|
|
|
3259
3311
|
// `-mr-1`: the ⋮ sits at `right-1`, 4px into the row's padding, so the
|
|
3260
3312
|
// slot does too — at the padding's edge it kept 4px the ⋮ never
|
|
3261
3313
|
// covers, and the label stopped 12px short of the button, not 8.
|
|
3262
|
-
/* @__PURE__ */
|
|
3314
|
+
/* @__PURE__ */ jsx49("span", { "aria-hidden": "true", className: "-mr-1 hidden w-6 shrink-0 group-hover/nav:block group-has-[:focus-visible]/nav:block group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:block [@media(hover:none)]:block" })
|
|
3263
3315
|
) : null
|
|
3264
3316
|
]
|
|
3265
3317
|
}
|
|
@@ -3270,7 +3322,7 @@ function NavItem({
|
|
|
3270
3322
|
row,
|
|
3271
3323
|
hasRows && // `left-1`: the 24px button's 16px arrow then sits where the icon
|
|
3272
3324
|
// sits (the row's px-2), so the icon turns into the arrow in place.
|
|
3273
|
-
/* @__PURE__ */
|
|
3325
|
+
/* @__PURE__ */ jsx49("div", { className: "absolute inset-y-0 left-1 flex items-center opacity-0 transition-opacity group-hover/nav:opacity-100 group-has-[:focus-visible]/nav:opacity-100", children: /* @__PURE__ */ jsx49(
|
|
3274
3326
|
IconButton,
|
|
3275
3327
|
{
|
|
3276
3328
|
tooltip: open ? "Collapse" : "Expand",
|
|
@@ -3278,7 +3330,7 @@ function NavItem({
|
|
|
3278
3330
|
"aria-expanded": open,
|
|
3279
3331
|
"aria-controls": panelId,
|
|
3280
3332
|
onClick: () => setOpen(!open),
|
|
3281
|
-
children: /* @__PURE__ */
|
|
3333
|
+
children: /* @__PURE__ */ jsx49(IconChevronRight2, { size: 16, stroke: 1.5, className: cn("transition-transform duration-150", open && "rotate-90") })
|
|
3282
3334
|
}
|
|
3283
3335
|
) }),
|
|
3284
3336
|
menu != null && // `right-1`: the 24px button's 16px icon ends 8px from the row's
|
|
@@ -3289,11 +3341,11 @@ function NavItem({
|
|
|
3289
3341
|
// right of the slot's centre.
|
|
3290
3342
|
// On a screen with no hover it always shows: nothing there can point
|
|
3291
3343
|
// at the row, and the menu has no other way in.
|
|
3292
|
-
/* @__PURE__ */
|
|
3344
|
+
/* @__PURE__ */ jsx49("div", { "data-nav-menu": true, className: cn("absolute inset-y-0 right-1 flex items-center", "opacity-0 transition-opacity group-hover/nav:opacity-100 group-has-[:focus-visible]/nav:opacity-100 has-[[aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100"), children: /* @__PURE__ */ jsx49(
|
|
3293
3345
|
Menu,
|
|
3294
3346
|
{
|
|
3295
3347
|
align: "right",
|
|
3296
|
-
trigger: /* @__PURE__ */
|
|
3348
|
+
trigger: /* @__PURE__ */ jsx49(IconButton, { tooltip: "More options", "aria-label": name, children: /* @__PURE__ */ jsx49(IconDotsVertical, { size: 16, stroke: 1.5 }) }),
|
|
3297
3349
|
children: menu
|
|
3298
3350
|
}
|
|
3299
3351
|
) })
|
|
@@ -3301,19 +3353,19 @@ function NavItem({
|
|
|
3301
3353
|
if (!hasRows) return line;
|
|
3302
3354
|
return /* @__PURE__ */ jsxs32(Collapsible.Root, { open, onOpenChange: setOpen, className: "flex shrink-0 flex-col", children: [
|
|
3303
3355
|
line,
|
|
3304
|
-
/* @__PURE__ */
|
|
3356
|
+
/* @__PURE__ */ jsx49(
|
|
3305
3357
|
Collapsible.Panel,
|
|
3306
3358
|
{
|
|
3307
3359
|
id: panelId,
|
|
3308
3360
|
hiddenUntilFound: true,
|
|
3309
3361
|
className: COLLAPSIBLE_PANEL_CLASSES,
|
|
3310
|
-
children: /* @__PURE__ */
|
|
3362
|
+
children: /* @__PURE__ */ jsx49("div", { className: "flex flex-col gap-0.5 pt-0.5 pl-6", children })
|
|
3311
3363
|
}
|
|
3312
3364
|
)
|
|
3313
3365
|
] });
|
|
3314
3366
|
}
|
|
3315
3367
|
function UrgentMark() {
|
|
3316
|
-
return /* @__PURE__ */
|
|
3368
|
+
return /* @__PURE__ */ jsx49("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center", "data-urgent": true, children: /* @__PURE__ */ jsx49("div", { className: "flex items-center rounded-full bg-warning-muted p-0.5 signal:shadow-glow-warning", children: /* @__PURE__ */ jsx49(IconAlertSquareRounded, { size: 12, stroke: 2.5, className: "text-warning-default" }) }) });
|
|
3317
3369
|
}
|
|
3318
3370
|
|
|
3319
3371
|
// src/NavTree.tsx
|
|
@@ -3326,14 +3378,14 @@ import { Collapsible as Collapsible2 } from "@base-ui/react/collapsible";
|
|
|
3326
3378
|
// src/SectionHeader.tsx
|
|
3327
3379
|
import { IconChevronRight as IconChevronRight3, IconDotsVertical as IconDotsVertical2 } from "@tabler/icons-react";
|
|
3328
3380
|
import { useRender } from "@base-ui/react/use-render";
|
|
3329
|
-
import { Fragment as Fragment12, jsx as
|
|
3381
|
+
import { Fragment as Fragment12, jsx as jsx50, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
3330
3382
|
function SectionHeader({ title, chevron = false, icon, isExpanded = true, onToggle, trailing, count, actions, menu, menuLabel, showActions = "hover", hover = "fill", look = "heading", render, className }) {
|
|
3331
3383
|
const row = look === "row";
|
|
3332
3384
|
const acts = actions && actions.length > 0 || menu != null;
|
|
3333
3385
|
const trailingClasses = !acts ? "has-[[data-unread]]:-mr-1" : showActions === "hover" && "has-[[data-unread]]:pointer-events-none has-[[data-unread]]:absolute has-[[data-unread]]:inset-y-0 has-[[data-unread]]:right-1 has-[[data-unread]]:w-6 has-[[data-unread]]:justify-center has-[[data-unread]]:transition-opacity group-hover:has-[[data-unread]]:opacity-0 group-has-[:focus-visible]:has-[[data-unread]]:opacity-0 group-has-[[data-section-menu]_[aria-expanded=true]]:has-[[data-unread]]:opacity-0 [@media(hover:none)]:has-[[data-unread]]:opacity-0";
|
|
3334
3386
|
const reveal = showActions === "hover" && "opacity-0 transition-opacity group-hover:opacity-100 group-has-[:focus-visible]:opacity-100 has-[[aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100";
|
|
3335
3387
|
const titleElement = useRender({
|
|
3336
|
-
render: render ?? (chevron ? /* @__PURE__ */
|
|
3388
|
+
render: render ?? (chevron ? /* @__PURE__ */ jsx50("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx50("span", {})),
|
|
3337
3389
|
props: {
|
|
3338
3390
|
// `text-left`: a button centres its text. `h-full` and `flex-1`: the
|
|
3339
3391
|
// whole row up to the actions is the hit target, as it was when the
|
|
@@ -3342,8 +3394,8 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
|
|
|
3342
3394
|
className: cn("flex h-full min-w-0 flex-1 items-center text-left", row || chevron || icon != null ? "gap-2" : "gap-1"),
|
|
3343
3395
|
children: /* @__PURE__ */ jsxs33(Fragment12, { children: [
|
|
3344
3396
|
icon != null ? /* @__PURE__ */ jsxs33("span", { className: "relative flex size-4 shrink-0 items-center justify-center text-text-secondary", children: [
|
|
3345
|
-
/* @__PURE__ */
|
|
3346
|
-
chevron && /* @__PURE__ */
|
|
3397
|
+
/* @__PURE__ */ jsx50("span", { className: cn("flex", chevron && "transition-opacity group-hover:opacity-0 group-has-[:focus-visible]:opacity-0"), children: icon }),
|
|
3398
|
+
chevron && /* @__PURE__ */ jsx50(
|
|
3347
3399
|
IconChevronRight3,
|
|
3348
3400
|
{
|
|
3349
3401
|
size: 16,
|
|
@@ -3351,7 +3403,7 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
|
|
|
3351
3403
|
className: cn("absolute opacity-0 transition-[opacity,transform] duration-150 group-hover:opacity-100 group-has-[:focus-visible]:opacity-100", isExpanded && "rotate-90")
|
|
3352
3404
|
}
|
|
3353
3405
|
)
|
|
3354
|
-
] }) : chevron && /* @__PURE__ */
|
|
3406
|
+
] }) : chevron && /* @__PURE__ */ jsx50(
|
|
3355
3407
|
IconChevronRight3,
|
|
3356
3408
|
{
|
|
3357
3409
|
size: 16,
|
|
@@ -3359,11 +3411,11 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
|
|
|
3359
3411
|
className: cn("shrink-0 transition-transform duration-150", !row && "text-text-secondary", isExpanded && "rotate-90")
|
|
3360
3412
|
}
|
|
3361
3413
|
),
|
|
3362
|
-
look === "quiet" ? /* @__PURE__ */
|
|
3414
|
+
look === "quiet" ? /* @__PURE__ */ jsx50("span", { className: "min-w-0 truncate text-caption text-text-muted", children: title }) : row ? (
|
|
3363
3415
|
// A row's words: NavItem's size and colour, brightening under the pointer with the row.
|
|
3364
|
-
/* @__PURE__ */
|
|
3365
|
-
) : /* @__PURE__ */
|
|
3366
|
-
count != null && /* @__PURE__ */
|
|
3416
|
+
/* @__PURE__ */ jsx50("span", { className: "min-w-0 flex-1 truncate text-body-2", children: title })
|
|
3417
|
+
) : /* @__PURE__ */ jsx50(SectionLabel, { folds: chevron, children: title }),
|
|
3418
|
+
count != null && /* @__PURE__ */ jsx50("span", { className: cn("ml-1 shrink-0", COUNT_TEXT_CLASSES), children: count })
|
|
3367
3419
|
] })
|
|
3368
3420
|
}
|
|
3369
3421
|
});
|
|
@@ -3388,18 +3440,18 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
|
|
|
3388
3440
|
),
|
|
3389
3441
|
children: [
|
|
3390
3442
|
titleElement,
|
|
3391
|
-
trailing != null && /* @__PURE__ */
|
|
3392
|
-
acts && /* @__PURE__ */
|
|
3443
|
+
trailing != null && /* @__PURE__ */ jsx50("div", { className: cn("flex shrink-0 items-center", trailingClasses), children: trailing }),
|
|
3444
|
+
acts && /* @__PURE__ */ jsx50(
|
|
3393
3445
|
"div",
|
|
3394
3446
|
{
|
|
3395
3447
|
className: "-mr-1 flex shrink-0 items-center",
|
|
3396
3448
|
children: /* @__PURE__ */ jsxs33("div", { className: cn("flex items-center gap-1", reveal), children: [
|
|
3397
|
-
actions?.map((action) => /* @__PURE__ */
|
|
3398
|
-
menu != null && /* @__PURE__ */
|
|
3449
|
+
actions?.map((action) => /* @__PURE__ */ jsx50(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip)),
|
|
3450
|
+
menu != null && /* @__PURE__ */ jsx50("div", { "data-section-menu": true, className: "flex items-center", children: /* @__PURE__ */ jsx50(
|
|
3399
3451
|
Menu,
|
|
3400
3452
|
{
|
|
3401
3453
|
align: "right",
|
|
3402
|
-
trigger: /* @__PURE__ */
|
|
3454
|
+
trigger: /* @__PURE__ */ jsx50(IconButton, { tooltip: "More options", "aria-label": menuLabel ?? `More options for ${title}`, children: /* @__PURE__ */ jsx50(IconDotsVertical2, { size: 16, stroke: 1.5 }) }),
|
|
3403
3455
|
children: menu
|
|
3404
3456
|
}
|
|
3405
3457
|
) })
|
|
@@ -3412,7 +3464,7 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
|
|
|
3412
3464
|
}
|
|
3413
3465
|
|
|
3414
3466
|
// src/CollapsibleSection.tsx
|
|
3415
|
-
import { jsx as
|
|
3467
|
+
import { jsx as jsx51, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
3416
3468
|
var OPEN = "open";
|
|
3417
3469
|
var CLOSED = "closed";
|
|
3418
3470
|
function readStored(key) {
|
|
@@ -3440,30 +3492,30 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
|
|
|
3440
3492
|
onOpenChange?.(next);
|
|
3441
3493
|
};
|
|
3442
3494
|
return /* @__PURE__ */ jsxs34(Collapsible2.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
|
|
3443
|
-
/* @__PURE__ */
|
|
3444
|
-
/* @__PURE__ */
|
|
3495
|
+
/* @__PURE__ */ jsx51(SectionHeader, { title, chevron: true, icon, isExpanded: open, trailing, actions, menu, menuLabel, showActions, look, className: "shrink-0", render: /* @__PURE__ */ jsx51(Collapsible2.Trigger, {}) }),
|
|
3496
|
+
/* @__PURE__ */ jsx51(
|
|
3445
3497
|
Collapsible2.Panel,
|
|
3446
3498
|
{
|
|
3447
3499
|
hiddenUntilFound: true,
|
|
3448
3500
|
className: COLLAPSIBLE_PANEL_CLASSES,
|
|
3449
|
-
children: /* @__PURE__ */
|
|
3501
|
+
children: /* @__PURE__ */ jsx51("div", { className: cn("flex flex-col pt-0.5", (look === "row" || indent) && "pl-6", contentClassName), children })
|
|
3450
3502
|
}
|
|
3451
3503
|
)
|
|
3452
3504
|
] });
|
|
3453
3505
|
}
|
|
3454
3506
|
|
|
3455
3507
|
// src/NavTree.tsx
|
|
3456
|
-
import { Fragment as Fragment13, jsx as
|
|
3508
|
+
import { Fragment as Fragment13, jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
3457
3509
|
var NAV_TREE_INTENT_MS = 150;
|
|
3458
3510
|
function holds(nodes, id) {
|
|
3459
3511
|
return !!nodes && id !== void 0 && nodes.some((node) => node.id === id || holds(node.children ?? null, id));
|
|
3460
3512
|
}
|
|
3461
3513
|
function Line({ message }) {
|
|
3462
|
-
return /* @__PURE__ */
|
|
3514
|
+
return /* @__PURE__ */ jsx52("div", { className: "px-2 py-1", children: /* @__PURE__ */ jsx52(EmptyState, { scope: "section", message }) });
|
|
3463
3515
|
}
|
|
3464
3516
|
function Row({ node, selected, onSelect }) {
|
|
3465
|
-
const under = node.childrenMessage !== void 0 ? /* @__PURE__ */
|
|
3466
|
-
return /* @__PURE__ */
|
|
3517
|
+
const under = node.childrenMessage !== void 0 ? /* @__PURE__ */ jsx52(Line, { message: node.childrenMessage }) : node.children?.length ? node.children.map((child) => /* @__PURE__ */ jsx52(Row, { node: child, selected, onSelect }, child.id)) : node.children === null || node.hasChildren && node.children === void 0 ? /* @__PURE__ */ jsx52(SkeletonList, { rows: 2 }) : void 0;
|
|
3518
|
+
return /* @__PURE__ */ jsx52(
|
|
3467
3519
|
NavItem,
|
|
3468
3520
|
{
|
|
3469
3521
|
href: node.href,
|
|
@@ -3485,7 +3537,7 @@ function Row({ node, selected, onSelect }) {
|
|
|
3485
3537
|
);
|
|
3486
3538
|
}
|
|
3487
3539
|
function Group({ group, selected, onSelect, storageKey }) {
|
|
3488
|
-
return /* @__PURE__ */
|
|
3540
|
+
return /* @__PURE__ */ jsx52(
|
|
3489
3541
|
NavTreeSection,
|
|
3490
3542
|
{
|
|
3491
3543
|
id: group.id,
|
|
@@ -3501,7 +3553,7 @@ function Group({ group, selected, onSelect, storageKey }) {
|
|
|
3501
3553
|
onOpenChange: group.onOpenChange,
|
|
3502
3554
|
storageKey: storageKey ? `${storageKey}.${group.id}` : void 0,
|
|
3503
3555
|
onIntent: group.onIntent,
|
|
3504
|
-
children: group.nodes?.map((node) => /* @__PURE__ */
|
|
3556
|
+
children: group.nodes?.map((node) => /* @__PURE__ */ jsx52(Row, { node, selected, onSelect }, node.id))
|
|
3505
3557
|
}
|
|
3506
3558
|
);
|
|
3507
3559
|
}
|
|
@@ -3509,7 +3561,7 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
|
|
|
3509
3561
|
const timer = useRef11(void 0);
|
|
3510
3562
|
useEffect6(() => () => clearTimeout(timer.current), []);
|
|
3511
3563
|
const intent = onIntent;
|
|
3512
|
-
return /* @__PURE__ */
|
|
3564
|
+
return /* @__PURE__ */ jsx52(
|
|
3513
3565
|
"div",
|
|
3514
3566
|
{
|
|
3515
3567
|
className: "shrink-0 [&+&]:mt-1",
|
|
@@ -3520,7 +3572,7 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
|
|
|
3520
3572
|
} : void 0,
|
|
3521
3573
|
onPointerLeave: intent ? () => clearTimeout(timer.current) : void 0,
|
|
3522
3574
|
onFocus: intent,
|
|
3523
|
-
children: /* @__PURE__ */
|
|
3575
|
+
children: /* @__PURE__ */ jsx52(
|
|
3524
3576
|
CollapsibleSection,
|
|
3525
3577
|
{
|
|
3526
3578
|
title,
|
|
@@ -3535,7 +3587,7 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
|
|
|
3535
3587
|
icon,
|
|
3536
3588
|
className: "shrink-0",
|
|
3537
3589
|
contentClassName: "gap-0.5",
|
|
3538
|
-
children: message !== void 0 ? /* @__PURE__ */
|
|
3590
|
+
children: message !== void 0 ? /* @__PURE__ */ jsx52(Line, { message }) : loading ? /* @__PURE__ */ jsx52(SkeletonList, { rows: 3 }) : children
|
|
3539
3591
|
}
|
|
3540
3592
|
)
|
|
3541
3593
|
}
|
|
@@ -3543,18 +3595,18 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
|
|
|
3543
3595
|
}
|
|
3544
3596
|
function NavTree({ title, titleActions, groups, children, selected, onSelect, emptyMessage = "", storageKey }) {
|
|
3545
3597
|
return /* @__PURE__ */ jsxs35(Fragment13, { children: [
|
|
3546
|
-
title && /* @__PURE__ */
|
|
3547
|
-
groups === void 0 ? children : groups === null ? /* @__PURE__ */
|
|
3598
|
+
title && /* @__PURE__ */ jsx52(SectionHeader, { title, look: "quiet", showActions: "always", actions: titleActions, className: "mt-4 shrink-0" }),
|
|
3599
|
+
groups === void 0 ? children : groups === null ? /* @__PURE__ */ jsx52(SkeletonList, { rows: 5 }) : groups.length === 0 ? (
|
|
3548
3600
|
// No words, no line: an app that says nothing when it has no groups.
|
|
3549
|
-
emptyMessage ? /* @__PURE__ */
|
|
3550
|
-
) : groups.map((group) => /* @__PURE__ */
|
|
3601
|
+
emptyMessage ? /* @__PURE__ */ jsx52(Line, { message: emptyMessage }) : null
|
|
3602
|
+
) : groups.map((group) => /* @__PURE__ */ jsx52(Group, { group, selected, onSelect, storageKey }, group.id))
|
|
3551
3603
|
] });
|
|
3552
3604
|
}
|
|
3553
3605
|
|
|
3554
3606
|
// src/Popover.tsx
|
|
3555
3607
|
import { useMemo as useMemo4 } from "react";
|
|
3556
3608
|
import { Popover as BasePopover } from "@base-ui/react/popover";
|
|
3557
|
-
import { jsx as
|
|
3609
|
+
import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3558
3610
|
var GAP5 = 4;
|
|
3559
3611
|
var VIEWPORT_PAD5 = 8;
|
|
3560
3612
|
function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className, contentClassName, maxHeight }) {
|
|
@@ -3571,8 +3623,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
3571
3623
|
actionsRef,
|
|
3572
3624
|
modal: false,
|
|
3573
3625
|
children: [
|
|
3574
|
-
trigger && /* @__PURE__ */
|
|
3575
|
-
/* @__PURE__ */
|
|
3626
|
+
trigger && /* @__PURE__ */ jsx53(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
|
|
3627
|
+
/* @__PURE__ */ jsx53(BasePopover.Portal, { children: /* @__PURE__ */ jsx53(
|
|
3576
3628
|
BasePopover.Positioner,
|
|
3577
3629
|
{
|
|
3578
3630
|
anchor: anchorTarget,
|
|
@@ -3581,20 +3633,20 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
3581
3633
|
sideOffset: GAP5,
|
|
3582
3634
|
collisionPadding: VIEWPORT_PAD5,
|
|
3583
3635
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
3584
|
-
children: /* @__PURE__ */
|
|
3636
|
+
children: /* @__PURE__ */ jsx53(
|
|
3585
3637
|
BasePopover.Popup,
|
|
3586
3638
|
{
|
|
3587
3639
|
"aria-label": ariaLabel,
|
|
3588
3640
|
initialFocus: trigger ? void 0 : false,
|
|
3589
3641
|
finalFocus,
|
|
3590
3642
|
className: cn("min-w-[180px] outline-none p-0", className),
|
|
3591
|
-
render: /* @__PURE__ */
|
|
3592
|
-
children: /* @__PURE__ */
|
|
3643
|
+
render: /* @__PURE__ */ jsx53(MenuPanel, {}),
|
|
3644
|
+
children: /* @__PURE__ */ jsx53(
|
|
3593
3645
|
ScrollArea,
|
|
3594
3646
|
{
|
|
3595
3647
|
viewportClassName: maxHeight ?? "max-h-[var(--available-height)]",
|
|
3596
3648
|
contentClassName: cn("flex flex-col p-2", contentClassName),
|
|
3597
|
-
children: /* @__PURE__ */
|
|
3649
|
+
children: /* @__PURE__ */ jsx53(DividerInPanel.Provider, { value: true, children })
|
|
3598
3650
|
}
|
|
3599
3651
|
)
|
|
3600
3652
|
}
|
|
@@ -3608,7 +3660,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
3608
3660
|
|
|
3609
3661
|
// src/SuggestionMenu.tsx
|
|
3610
3662
|
import { useCallback as useCallback4, useEffect as useEffect7, useId as useId3, useImperativeHandle, useMemo as useMemo5, useRef as useRef12, useState as useState11 } from "react";
|
|
3611
|
-
import { jsx as
|
|
3663
|
+
import { jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3612
3664
|
function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sections, itemKey, row, onSelect, handle }) {
|
|
3613
3665
|
const shown = useMemo5(() => sections.filter((section) => section.items.length > 0), [sections]);
|
|
3614
3666
|
const items = useMemo5(() => shown.flatMap((section) => section.items), [shown]);
|
|
@@ -3673,7 +3725,7 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
|
|
|
3673
3725
|
const { label, description, leading, shortcut, hint, size } = row(item);
|
|
3674
3726
|
return (
|
|
3675
3727
|
// A row of a list the editor drives from its caret: focus stays in the text, so the row is no Tab stop.
|
|
3676
|
-
/* @__PURE__ */
|
|
3728
|
+
/* @__PURE__ */ jsx54(
|
|
3677
3729
|
MenuItem,
|
|
3678
3730
|
{
|
|
3679
3731
|
role: "option",
|
|
@@ -3700,9 +3752,9 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
|
|
|
3700
3752
|
};
|
|
3701
3753
|
return (
|
|
3702
3754
|
// finalFocus={false}: focus never left the text, and a list that closes because focus moved elsewhere must not pull it back (71a4577b).
|
|
3703
|
-
/* @__PURE__ */
|
|
3704
|
-
i > 0 && /* @__PURE__ */
|
|
3705
|
-
section.label ? /* @__PURE__ */
|
|
3755
|
+
/* @__PURE__ */ jsx54(Popover, { anchor: rect, open: rect !== null, side: "top", align: "left", className: width, maxHeight, ariaLabel, finalFocus: false, children: /* @__PURE__ */ jsx54("div", { ref: keepFocus, id: listboxId, role: "listbox", "aria-label": ariaLabel, className: "flex flex-col gap-0.5", children: shown.map((section, i) => /* @__PURE__ */ jsxs37("div", { className: "contents", children: [
|
|
3756
|
+
i > 0 && /* @__PURE__ */ jsx54(MenuSeparator, {}),
|
|
3757
|
+
section.label ? /* @__PURE__ */ jsx54("div", { role: "group", "aria-label": section.label, children: /* @__PURE__ */ jsx54(MenuSection, { label: section.label, className: section.className, children: section.items.map(drawRow) }) }) : section.items.map(drawRow)
|
|
3706
3758
|
] }, section.label ?? i)) }) })
|
|
3707
3759
|
);
|
|
3708
3760
|
}
|
|
@@ -3710,7 +3762,7 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
|
|
|
3710
3762
|
// src/ShowMore.tsx
|
|
3711
3763
|
import { useLayoutEffect as useLayoutEffect5, useRef as useRef13, useState as useState12 } from "react";
|
|
3712
3764
|
import { IconChevronDown as IconChevronDown4, IconChevronUp } from "@tabler/icons-react";
|
|
3713
|
-
import { jsx as
|
|
3765
|
+
import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3714
3766
|
var FADE_CLASSES = { surface: "from-bg-surface", inset: "from-bg-inset" };
|
|
3715
3767
|
function ShowMore({ children, maxHeight = 96, surface = "surface", action, className }) {
|
|
3716
3768
|
const box = useRef13(null);
|
|
@@ -3730,22 +3782,22 @@ function ShowMore({ children, maxHeight = 96, surface = "surface", action, class
|
|
|
3730
3782
|
return /* @__PURE__ */ jsxs38("div", { className: cn("flex flex-col items-start", className), children: [
|
|
3731
3783
|
/* @__PURE__ */ jsxs38("div", { ref: box, className: cn("relative w-full", cut && "overflow-hidden"), style: cut ? { maxHeight } : void 0, onFocus: cut ? () => setOpen(true) : void 0, children: [
|
|
3732
3784
|
children,
|
|
3733
|
-
cut && /* @__PURE__ */
|
|
3785
|
+
cut && /* @__PURE__ */ jsx55("div", { "aria-hidden": true, className: cn("pointer-events-none absolute inset-x-0 bottom-0 h-10 bg-gradient-to-t to-transparent", FADE_CLASSES[surface]) })
|
|
3734
3786
|
] }),
|
|
3735
3787
|
action ? /* @__PURE__ */ jsxs38("div", { className: cn("mt-1 flex w-full items-center gap-2", overflows ? "justify-between" : "justify-end"), children: [
|
|
3736
|
-
overflows && /* @__PURE__ */
|
|
3737
|
-
/* @__PURE__ */
|
|
3738
|
-
] }) : overflows && /* @__PURE__ */
|
|
3788
|
+
overflows && /* @__PURE__ */ jsx55(Toggle, { open, onToggle: () => setOpen((o) => !o) }),
|
|
3789
|
+
/* @__PURE__ */ jsx55("div", { className: "-mr-2 flex shrink-0", children: action })
|
|
3790
|
+
] }) : overflows && /* @__PURE__ */ jsx55(Toggle, { open, onToggle: () => setOpen((o) => !o), className: "mt-1" })
|
|
3739
3791
|
] });
|
|
3740
3792
|
}
|
|
3741
3793
|
function Toggle({ open, onToggle, className }) {
|
|
3742
3794
|
const Icon = open ? IconChevronUp : IconChevronDown4;
|
|
3743
|
-
return /* @__PURE__ */
|
|
3795
|
+
return /* @__PURE__ */ jsx55(
|
|
3744
3796
|
Button,
|
|
3745
3797
|
{
|
|
3746
3798
|
variant: "outlined",
|
|
3747
3799
|
size: "small",
|
|
3748
|
-
leadingIcon: /* @__PURE__ */
|
|
3800
|
+
leadingIcon: /* @__PURE__ */ jsx55(Icon, { stroke: 1.5, className: "size-3.5" }),
|
|
3749
3801
|
className,
|
|
3750
3802
|
"aria-expanded": open,
|
|
3751
3803
|
onClick: onToggle,
|
|
@@ -3756,9 +3808,9 @@ function Toggle({ open, onToggle, className }) {
|
|
|
3756
3808
|
|
|
3757
3809
|
// src/Toolbar.tsx
|
|
3758
3810
|
import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
|
|
3759
|
-
import { jsx as
|
|
3811
|
+
import { jsx as jsx56 } from "react/jsx-runtime";
|
|
3760
3812
|
function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
|
|
3761
|
-
const strip = /* @__PURE__ */
|
|
3813
|
+
const strip = /* @__PURE__ */ jsx56(
|
|
3762
3814
|
BaseToolbar.Root,
|
|
3763
3815
|
{
|
|
3764
3816
|
"aria-label": ariaLabel,
|
|
@@ -3769,27 +3821,27 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
|
|
|
3769
3821
|
}
|
|
3770
3822
|
);
|
|
3771
3823
|
if (!surface) return strip;
|
|
3772
|
-
return /* @__PURE__ */
|
|
3824
|
+
return /* @__PURE__ */ jsx56(MenuPanel, { className: "w-fit p-1", children: strip });
|
|
3773
3825
|
}
|
|
3774
3826
|
function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
|
|
3775
|
-
return /* @__PURE__ */
|
|
3827
|
+
return /* @__PURE__ */ jsx56(
|
|
3776
3828
|
BaseToolbar.Button,
|
|
3777
3829
|
{
|
|
3778
3830
|
ref,
|
|
3779
3831
|
disabled: disabled || !!disabledReason,
|
|
3780
3832
|
focusableWhenDisabled: true,
|
|
3781
|
-
render: /* @__PURE__ */
|
|
3833
|
+
render: /* @__PURE__ */ jsx56(IconButton, { disabled, disabledReason, ...props })
|
|
3782
3834
|
}
|
|
3783
3835
|
);
|
|
3784
3836
|
}
|
|
3785
3837
|
function ToolbarLink({ ref, href, ...props }) {
|
|
3786
|
-
return /* @__PURE__ */
|
|
3838
|
+
return /* @__PURE__ */ jsx56(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx56(IconButton, { href, ...props }) });
|
|
3787
3839
|
}
|
|
3788
3840
|
function ToolbarInput({ size, ...props }) {
|
|
3789
|
-
return /* @__PURE__ */
|
|
3841
|
+
return /* @__PURE__ */ jsx56(BaseToolbar.Input, { render: /* @__PURE__ */ jsx56(TextInput, { size }), ...props });
|
|
3790
3842
|
}
|
|
3791
3843
|
function ToolbarSeparator({ className }) {
|
|
3792
|
-
return /* @__PURE__ */
|
|
3844
|
+
return /* @__PURE__ */ jsx56(
|
|
3793
3845
|
BaseToolbar.Separator,
|
|
3794
3846
|
{
|
|
3795
3847
|
orientation: "vertical",
|
|
@@ -3799,9 +3851,9 @@ function ToolbarSeparator({ className }) {
|
|
|
3799
3851
|
}
|
|
3800
3852
|
|
|
3801
3853
|
// src/ReactionPicker.tsx
|
|
3802
|
-
import { jsx as
|
|
3854
|
+
import { jsx as jsx57 } from "react/jsx-runtime";
|
|
3803
3855
|
function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
|
|
3804
|
-
return /* @__PURE__ */
|
|
3856
|
+
return /* @__PURE__ */ jsx57(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
|
|
3805
3857
|
/*
|
|
3806
3858
|
A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
|
|
3807
3859
|
would become the toolbar's item and the button inside it would never
|
|
@@ -3811,14 +3863,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
3811
3863
|
The tooltip names it for a pointer, `aria-label` for everything else,
|
|
3812
3864
|
and both say the meaning rather than the glyph.
|
|
3813
3865
|
*/
|
|
3814
|
-
/* @__PURE__ */
|
|
3866
|
+
/* @__PURE__ */ jsx57(
|
|
3815
3867
|
ToolbarButton,
|
|
3816
3868
|
{
|
|
3817
3869
|
"aria-label": option.label,
|
|
3818
3870
|
tooltip: option.label,
|
|
3819
3871
|
onClick: () => onSelect(option.emoji),
|
|
3820
3872
|
className: "size-7",
|
|
3821
|
-
children: /* @__PURE__ */
|
|
3873
|
+
children: /* @__PURE__ */ jsx57("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
|
|
3822
3874
|
},
|
|
3823
3875
|
option.emoji
|
|
3824
3876
|
)
|
|
@@ -3827,23 +3879,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
3827
3879
|
|
|
3828
3880
|
// src/PreviewCard.tsx
|
|
3829
3881
|
import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
|
|
3830
|
-
import { jsx as
|
|
3882
|
+
import { jsx as jsx58, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3831
3883
|
var GAP6 = 12;
|
|
3832
3884
|
var VIEWPORT_PAD6 = 8;
|
|
3833
3885
|
var OPEN_DELAY2 = 350;
|
|
3834
3886
|
var CLOSE_DELAY = 200;
|
|
3835
3887
|
function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, contentClassName, wrapperClassName }) {
|
|
3836
3888
|
return /* @__PURE__ */ jsxs39(BasePreviewCard.Root, { children: [
|
|
3837
|
-
/* @__PURE__ */
|
|
3889
|
+
/* @__PURE__ */ jsx58(
|
|
3838
3890
|
BasePreviewCard.Trigger,
|
|
3839
3891
|
{
|
|
3840
3892
|
delay,
|
|
3841
3893
|
closeDelay,
|
|
3842
|
-
render: /* @__PURE__ */
|
|
3894
|
+
render: /* @__PURE__ */ jsx58("span", { className: cn("inline-flex", wrapperClassName) }),
|
|
3843
3895
|
children
|
|
3844
3896
|
}
|
|
3845
3897
|
),
|
|
3846
|
-
/* @__PURE__ */
|
|
3898
|
+
/* @__PURE__ */ jsx58(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx58(
|
|
3847
3899
|
BasePreviewCard.Positioner,
|
|
3848
3900
|
{
|
|
3849
3901
|
side,
|
|
@@ -3851,12 +3903,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
3851
3903
|
sideOffset: GAP6,
|
|
3852
3904
|
collisionPadding: VIEWPORT_PAD6,
|
|
3853
3905
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
3854
|
-
children: /* @__PURE__ */
|
|
3906
|
+
children: /* @__PURE__ */ jsx58(
|
|
3855
3907
|
BasePreviewCard.Popup,
|
|
3856
3908
|
{
|
|
3857
3909
|
className: cn("w-[360px] p-0 outline-none", className),
|
|
3858
|
-
render: /* @__PURE__ */
|
|
3859
|
-
children: /* @__PURE__ */
|
|
3910
|
+
render: /* @__PURE__ */ jsx58(MenuPanel, {}),
|
|
3911
|
+
children: /* @__PURE__ */ jsx58(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
|
|
3860
3912
|
}
|
|
3861
3913
|
)
|
|
3862
3914
|
}
|
|
@@ -3865,13 +3917,13 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
3865
3917
|
}
|
|
3866
3918
|
|
|
3867
3919
|
// src/Rail.tsx
|
|
3868
|
-
import { jsx as
|
|
3920
|
+
import { jsx as jsx59 } from "react/jsx-runtime";
|
|
3869
3921
|
function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
|
|
3870
|
-
return /* @__PURE__ */
|
|
3922
|
+
return /* @__PURE__ */ jsx59("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
|
|
3871
3923
|
}
|
|
3872
3924
|
|
|
3873
3925
|
// src/RailItem.tsx
|
|
3874
|
-
import { jsx as
|
|
3926
|
+
import { jsx as jsx60, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
3875
3927
|
function RailItem({ href, icon, label, active = false, className, onClick, ...props }) {
|
|
3876
3928
|
const inApp = useInAppClick(href, onClick);
|
|
3877
3929
|
return /* @__PURE__ */ jsxs40(
|
|
@@ -3883,14 +3935,14 @@ function RailItem({ href, icon, label, active = false, className, onClick, ...pr
|
|
|
3883
3935
|
...props,
|
|
3884
3936
|
onClick: inApp,
|
|
3885
3937
|
children: [
|
|
3886
|
-
/* @__PURE__ */
|
|
3938
|
+
/* @__PURE__ */ jsx60(
|
|
3887
3939
|
"div",
|
|
3888
3940
|
{
|
|
3889
3941
|
className: cn(
|
|
3890
3942
|
"flex items-center justify-center rounded-lg p-2 transition-colors",
|
|
3891
3943
|
active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
|
|
3892
3944
|
),
|
|
3893
|
-
children: /* @__PURE__ */
|
|
3945
|
+
children: /* @__PURE__ */ jsx60(
|
|
3894
3946
|
"span",
|
|
3895
3947
|
{
|
|
3896
3948
|
className: cn(
|
|
@@ -3902,14 +3954,14 @@ function RailItem({ href, icon, label, active = false, className, onClick, ...pr
|
|
|
3902
3954
|
)
|
|
3903
3955
|
}
|
|
3904
3956
|
),
|
|
3905
|
-
/* @__PURE__ */
|
|
3957
|
+
/* @__PURE__ */ jsx60("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
|
|
3906
3958
|
]
|
|
3907
3959
|
}
|
|
3908
3960
|
);
|
|
3909
3961
|
}
|
|
3910
3962
|
|
|
3911
3963
|
// src/Property.tsx
|
|
3912
|
-
import { jsx as
|
|
3964
|
+
import { jsx as jsx61, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
3913
3965
|
var VALUE_CLASSES = "contents";
|
|
3914
3966
|
function Property({ label, layout = "row", children, className }) {
|
|
3915
3967
|
if (layout === "stacked") {
|
|
@@ -3918,20 +3970,20 @@ function Property({ label, layout = "row", children, className }) {
|
|
|
3918
3970
|
// Peek's topic-details sections already sit at 12px, Ship's rail was
|
|
3919
3971
|
// 6px, and unifying means the bigger, calmer one.
|
|
3920
3972
|
/* @__PURE__ */ jsxs41("dl", { className: cn("flex flex-col gap-3", className), children: [
|
|
3921
|
-
/* @__PURE__ */
|
|
3922
|
-
/* @__PURE__ */
|
|
3973
|
+
/* @__PURE__ */ jsx61("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
|
|
3974
|
+
/* @__PURE__ */ jsx61("dd", { className: VALUE_CLASSES, children })
|
|
3923
3975
|
] })
|
|
3924
3976
|
);
|
|
3925
3977
|
}
|
|
3926
3978
|
return /* @__PURE__ */ jsxs41("dl", { className: cn("flex items-center gap-2", className), children: [
|
|
3927
|
-
/* @__PURE__ */
|
|
3928
|
-
/* @__PURE__ */
|
|
3979
|
+
/* @__PURE__ */ jsx61("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
|
|
3980
|
+
/* @__PURE__ */ jsx61("dd", { className: VALUE_CLASSES, children })
|
|
3929
3981
|
] });
|
|
3930
3982
|
}
|
|
3931
3983
|
|
|
3932
3984
|
// src/Reaction.tsx
|
|
3933
3985
|
import { Toggle as Toggle2 } from "@base-ui/react/toggle";
|
|
3934
|
-
import { jsx as
|
|
3986
|
+
import { jsx as jsx62, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
3935
3987
|
function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
3936
3988
|
return (
|
|
3937
3989
|
// @estiva-escape(no-copied-look): W1 (Katerina, 24 September: leave alone): a reaction pill shares four words with a field's box by coincidence
|
|
@@ -3957,8 +4009,8 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
|
3957
4009
|
),
|
|
3958
4010
|
...props,
|
|
3959
4011
|
children: [
|
|
3960
|
-
/* @__PURE__ */
|
|
3961
|
-
/* @__PURE__ */
|
|
4012
|
+
/* @__PURE__ */ jsx62("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
|
|
4013
|
+
/* @__PURE__ */ jsx62("span", { className: CHIP_TEXT_CLASSES, children: count })
|
|
3962
4014
|
]
|
|
3963
4015
|
}
|
|
3964
4016
|
)
|
|
@@ -3968,7 +4020,7 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
|
3968
4020
|
// src/SearchInput.tsx
|
|
3969
4021
|
import "react";
|
|
3970
4022
|
import { Input as Input3 } from "@base-ui/react/input";
|
|
3971
|
-
import { jsx as
|
|
4023
|
+
import { jsx as jsx63, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
3972
4024
|
function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
|
|
3973
4025
|
return /* @__PURE__ */ jsxs43(
|
|
3974
4026
|
"div",
|
|
@@ -3982,7 +4034,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
3982
4034
|
className
|
|
3983
4035
|
),
|
|
3984
4036
|
children: [
|
|
3985
|
-
/* @__PURE__ */
|
|
4037
|
+
/* @__PURE__ */ jsx63(
|
|
3986
4038
|
Input3,
|
|
3987
4039
|
{
|
|
3988
4040
|
className: cn("flex-1 min-w-0 text-input-value", BARE_INPUT_CLASSES),
|
|
@@ -3990,40 +4042,40 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
3990
4042
|
...props
|
|
3991
4043
|
}
|
|
3992
4044
|
),
|
|
3993
|
-
shortcut && /* @__PURE__ */
|
|
4045
|
+
shortcut && /* @__PURE__ */ jsx63(Kbd, { children: shortcut })
|
|
3994
4046
|
]
|
|
3995
4047
|
}
|
|
3996
4048
|
);
|
|
3997
4049
|
}
|
|
3998
4050
|
|
|
3999
4051
|
// src/Panel.tsx
|
|
4000
|
-
import { jsx as
|
|
4052
|
+
import { jsx as jsx64, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
4001
4053
|
function Frame({ title, chevron = false, actions, children, footer, bodyClassName, bodyRef, onBodyScroll, className, broken = false }) {
|
|
4002
4054
|
return /* @__PURE__ */ jsxs44("div", { className: cn("flex h-full min-h-0 flex-1 flex-col", className), children: [
|
|
4003
|
-
/* @__PURE__ */
|
|
4055
|
+
/* @__PURE__ */ jsx64(ContainerHeader, { title, chevron, actions }),
|
|
4004
4056
|
broken ? (
|
|
4005
4057
|
// The message takes the room the body had and centres itself in it.
|
|
4006
|
-
/* @__PURE__ */
|
|
4007
|
-
) : /* @__PURE__ */
|
|
4008
|
-
!broken && footer && /* @__PURE__ */
|
|
4058
|
+
/* @__PURE__ */ jsx64("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
|
|
4059
|
+
) : /* @__PURE__ */ jsx64(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
|
|
4060
|
+
!broken && footer && /* @__PURE__ */ jsx64("div", { className: "shrink-0", children: footer })
|
|
4009
4061
|
] });
|
|
4010
4062
|
}
|
|
4011
4063
|
function Panel(props) {
|
|
4012
|
-
return /* @__PURE__ */
|
|
4064
|
+
return /* @__PURE__ */ jsx64(
|
|
4013
4065
|
ErrorBoundary,
|
|
4014
4066
|
{
|
|
4015
4067
|
label: "panel",
|
|
4016
4068
|
frame: (message) => (
|
|
4017
4069
|
// Only the name comes back with the message: the actions and the footer may be what threw.
|
|
4018
|
-
/* @__PURE__ */
|
|
4070
|
+
/* @__PURE__ */ jsx64(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
|
|
4019
4071
|
),
|
|
4020
|
-
children: /* @__PURE__ */
|
|
4072
|
+
children: /* @__PURE__ */ jsx64(Frame, { ...props })
|
|
4021
4073
|
}
|
|
4022
4074
|
);
|
|
4023
4075
|
}
|
|
4024
4076
|
|
|
4025
4077
|
// src/ListColumn.tsx
|
|
4026
|
-
import { jsx as
|
|
4078
|
+
import { jsx as jsx65, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
4027
4079
|
function Column({ title, chevron = false, titleMenu, actions, above, collapsed = false, children, className, broken = false }) {
|
|
4028
4080
|
return /* @__PURE__ */ jsxs45(
|
|
4029
4081
|
"div",
|
|
@@ -4036,35 +4088,35 @@ function Column({ title, chevron = false, titleMenu, actions, above, collapsed =
|
|
|
4036
4088
|
),
|
|
4037
4089
|
"data-collapsed": collapsed || void 0,
|
|
4038
4090
|
children: [
|
|
4039
|
-
/* @__PURE__ */
|
|
4091
|
+
/* @__PURE__ */ jsx65(ContainerHeader, { title, chevron, titleMenu, actions }),
|
|
4040
4092
|
above,
|
|
4041
4093
|
broken ? (
|
|
4042
4094
|
// The message takes the room the list had and centres itself in it (Katerina, 19 September).
|
|
4043
|
-
/* @__PURE__ */
|
|
4044
|
-
) : /* @__PURE__ */
|
|
4095
|
+
/* @__PURE__ */ jsx65("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
|
|
4096
|
+
) : /* @__PURE__ */ jsx65(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
|
|
4045
4097
|
]
|
|
4046
4098
|
}
|
|
4047
4099
|
);
|
|
4048
4100
|
}
|
|
4049
4101
|
function ListColumn(props) {
|
|
4050
|
-
return /* @__PURE__ */
|
|
4102
|
+
return /* @__PURE__ */ jsx65(
|
|
4051
4103
|
ErrorBoundary,
|
|
4052
4104
|
{
|
|
4053
4105
|
label: "list panel",
|
|
4054
4106
|
frame: (message) => (
|
|
4055
4107
|
// Only the name comes back with the message: the actions and the row above may be what threw.
|
|
4056
|
-
/* @__PURE__ */
|
|
4108
|
+
/* @__PURE__ */ jsx65(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
|
|
4057
4109
|
),
|
|
4058
|
-
children: /* @__PURE__ */
|
|
4110
|
+
children: /* @__PURE__ */ jsx65(Column, { ...props })
|
|
4059
4111
|
}
|
|
4060
4112
|
);
|
|
4061
4113
|
}
|
|
4062
4114
|
|
|
4063
4115
|
// src/Tabs.tsx
|
|
4064
4116
|
import { Tabs as BaseTabs } from "@base-ui/react/tabs";
|
|
4065
|
-
import { Fragment as Fragment14, jsx as
|
|
4117
|
+
import { Fragment as Fragment14, jsx as jsx66, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
4066
4118
|
function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
|
|
4067
|
-
return /* @__PURE__ */
|
|
4119
|
+
return /* @__PURE__ */ jsx66(
|
|
4068
4120
|
BaseTabs.Root,
|
|
4069
4121
|
{
|
|
4070
4122
|
value: active,
|
|
@@ -4072,7 +4124,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
4072
4124
|
if (details.reason === "none") onChange(value);
|
|
4073
4125
|
},
|
|
4074
4126
|
className,
|
|
4075
|
-
children: /* @__PURE__ */
|
|
4127
|
+
children: /* @__PURE__ */ jsx66(
|
|
4076
4128
|
BaseTabs.List,
|
|
4077
4129
|
{
|
|
4078
4130
|
activateOnFocus: true,
|
|
@@ -4094,11 +4146,11 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
4094
4146
|
tab.icon,
|
|
4095
4147
|
/* @__PURE__ */ jsxs46("span", { className: "flex items-baseline", children: [
|
|
4096
4148
|
tab.label,
|
|
4097
|
-
tab.count !== void 0 ? /* @__PURE__ */
|
|
4149
|
+
tab.count !== void 0 ? /* @__PURE__ */ jsx66("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
|
|
4098
4150
|
] }),
|
|
4099
4151
|
tab.unread ? /* @__PURE__ */ jsxs46(Fragment14, { children: [
|
|
4100
|
-
/* @__PURE__ */
|
|
4101
|
-
/* @__PURE__ */
|
|
4152
|
+
/* @__PURE__ */ jsx66(UnreadDot, { className: "h-auto w-auto" }),
|
|
4153
|
+
/* @__PURE__ */ jsx66("span", { className: "sr-only", children: "new" })
|
|
4102
4154
|
] }) : null
|
|
4103
4155
|
]
|
|
4104
4156
|
},
|
|
@@ -4114,7 +4166,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
4114
4166
|
import { createContext as createContext7, useContext as useContext7, useMemo as useMemo6 } from "react";
|
|
4115
4167
|
import { Toast as BaseToast } from "@base-ui/react/toast";
|
|
4116
4168
|
import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
|
|
4117
|
-
import { jsx as
|
|
4169
|
+
import { jsx as jsx67, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
4118
4170
|
var SURFACE_STYLES = {
|
|
4119
4171
|
success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
|
|
4120
4172
|
brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
|
|
@@ -4122,7 +4174,7 @@ var SURFACE_STYLES = {
|
|
|
4122
4174
|
warning: "bg-warning-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
|
|
4123
4175
|
error: "bg-error-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md"
|
|
4124
4176
|
};
|
|
4125
|
-
var
|
|
4177
|
+
var ICONS2 = {
|
|
4126
4178
|
success: IconCircleCheck,
|
|
4127
4179
|
brand: IconCircleCheck,
|
|
4128
4180
|
neutral: IconCircleCheck,
|
|
@@ -4149,17 +4201,17 @@ var pillClassName = (type, hasAction, className) => cn(
|
|
|
4149
4201
|
className
|
|
4150
4202
|
);
|
|
4151
4203
|
function LeadingIcon({ type }) {
|
|
4152
|
-
const Icon =
|
|
4153
|
-
return /* @__PURE__ */
|
|
4204
|
+
const Icon = ICONS2[type];
|
|
4205
|
+
return /* @__PURE__ */ jsx67(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
|
|
4154
4206
|
}
|
|
4155
4207
|
function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
|
|
4156
4208
|
const hasAction = !!(actionLabel && onAction);
|
|
4157
4209
|
return /* @__PURE__ */ jsxs47("div", { className: pillClassName(type, hasAction, className), children: [
|
|
4158
4210
|
/* @__PURE__ */ jsxs47("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
4159
|
-
leadingIcon && /* @__PURE__ */
|
|
4160
|
-
/* @__PURE__ */
|
|
4211
|
+
leadingIcon && /* @__PURE__ */ jsx67(LeadingIcon, { type }),
|
|
4212
|
+
/* @__PURE__ */ jsx67("span", { className: LABEL_CLASSES, children: label })
|
|
4161
4213
|
] }),
|
|
4162
|
-
hasAction && /* @__PURE__ */
|
|
4214
|
+
hasAction && /* @__PURE__ */ jsx67(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
|
|
4163
4215
|
] });
|
|
4164
4216
|
}
|
|
4165
4217
|
var ToastContext = createContext7(null);
|
|
@@ -4180,9 +4232,9 @@ function ToastProvider({ children }) {
|
|
|
4180
4232
|
}),
|
|
4181
4233
|
[manager]
|
|
4182
4234
|
);
|
|
4183
|
-
return /* @__PURE__ */
|
|
4235
|
+
return /* @__PURE__ */ jsx67(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs47(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
|
|
4184
4236
|
children,
|
|
4185
|
-
/* @__PURE__ */
|
|
4237
|
+
/* @__PURE__ */ jsx67(BaseToast.Portal, { children: /* @__PURE__ */ jsx67(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx67(ToastList, {}) }) })
|
|
4186
4238
|
] }) });
|
|
4187
4239
|
}
|
|
4188
4240
|
function ToastList() {
|
|
@@ -4198,17 +4250,17 @@ function ToastList() {
|
|
|
4198
4250
|
className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
|
|
4199
4251
|
children: [
|
|
4200
4252
|
/* @__PURE__ */ jsxs47("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
4201
|
-
leadingIcon && /* @__PURE__ */
|
|
4202
|
-
/* @__PURE__ */
|
|
4253
|
+
leadingIcon && /* @__PURE__ */ jsx67(LeadingIcon, { type }),
|
|
4254
|
+
/* @__PURE__ */ jsx67(BaseToast.Title, { render: /* @__PURE__ */ jsx67("span", {}), className: LABEL_CLASSES })
|
|
4203
4255
|
] }),
|
|
4204
|
-
actionLabel && /* @__PURE__ */
|
|
4256
|
+
actionLabel && /* @__PURE__ */ jsx67(
|
|
4205
4257
|
BaseToast.Action,
|
|
4206
4258
|
{
|
|
4207
4259
|
onClick: () => {
|
|
4208
4260
|
onAction?.();
|
|
4209
4261
|
close(toast.id);
|
|
4210
4262
|
},
|
|
4211
|
-
render: /* @__PURE__ */
|
|
4263
|
+
render: /* @__PURE__ */ jsx67(Button, { variant: "outlined", size: "small", children: actionLabel })
|
|
4212
4264
|
}
|
|
4213
4265
|
)
|
|
4214
4266
|
]
|
|
@@ -4264,6 +4316,7 @@ export {
|
|
|
4264
4316
|
InlineChip,
|
|
4265
4317
|
InputChip,
|
|
4266
4318
|
Kbd,
|
|
4319
|
+
KindIcon,
|
|
4267
4320
|
Lightbox,
|
|
4268
4321
|
Link,
|
|
4269
4322
|
ListColumn,
|
|
@@ -4325,6 +4378,7 @@ export {
|
|
|
4325
4378
|
isApplePlatform,
|
|
4326
4379
|
richTextClassName,
|
|
4327
4380
|
shortcutLabel,
|
|
4381
|
+
thingKindOf,
|
|
4328
4382
|
useToast
|
|
4329
4383
|
};
|
|
4330
4384
|
//# sourceMappingURL=index.js.map
|