@estiva-app/ui 0.63.0 → 0.65.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/Link.d.ts +1 -1
- package/dist/RichText.d.ts +2 -1
- package/dist/RichText.d.ts.map +1 -1
- package/dist/codeColours.d.ts +18 -0
- package/dist/codeColours.d.ts.map +1 -0
- package/dist/editor.d.ts +1 -0
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +21 -0
- package/dist/editor.js.map +3 -3
- package/dist/index.js +58 -31
- package/dist/index.js.map +4 -4
- package/package.json +8 -2
- package/registry.json +33 -14
- package/src/CodeBlockColours.mdx +49 -0
- package/src/CodeBlockColours.stories.tsx +37 -0
- package/src/CodeBlockColours.test.ts +36 -0
- package/src/CodeBlockColours.ts +28 -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/RichText.stories.tsx +24 -0
- package/src/RichText.tsx +31 -17
- package/src/codeColours.ts +41 -0
- package/src/editor.ts +1 -0
- package/src/pages.test.ts +1 -0
- package/src/registry/registry.test.ts +6 -6
- package/stories/Choosing.mdx +1 -0
- package/tailwind-preset.js +7 -0
- package/tokens.css +40 -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,55 @@ 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 instance;
|
|
2428
|
+
function lowlight() {
|
|
2429
|
+
return instance ??= createLowlight(common);
|
|
2430
|
+
}
|
|
2431
|
+
function draw(node, key) {
|
|
2432
|
+
if (node.type === "text") return node.value;
|
|
2433
|
+
return createElement("span", { key, className: node.properties?.className?.join(" ") }, (node.children ?? []).map(draw));
|
|
2434
|
+
}
|
|
2435
|
+
function codeColours(text, language) {
|
|
2436
|
+
if (!language || !lowlight().registered(language)) return text;
|
|
2437
|
+
return lowlight().highlight(language, text).children.map(draw);
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2424
2440
|
// src/RichText.tsx
|
|
2425
2441
|
import { Fragment as Fragment8, jsx as jsx34, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2426
2442
|
var RICH_TEXT_CLASSES = {
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2443
|
+
/* Blocks 8px apart (Katerina, 9 October; 4 before). A list's own items stay together. */
|
|
2444
|
+
base: "flex flex-col gap-2 break-words text-text-secondary",
|
|
2445
|
+
/* 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). */
|
|
2446
|
+
headings: "[&>:is(h1,h2,h3)]:mt-1 [&>:is(h1,h2,h3):first-child]:mt-0 [&>:is(h1,h2)]:text-text-primary",
|
|
2447
|
+
/* 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). */
|
|
2448
|
+
lists: "[&_:is(ul,ol)]:pl-5 [&_li>p]:m-0 [&_li]:break-words [&_li]:marker:text-text-secondary [&_ol]:list-decimal [&_ul]:list-disc",
|
|
2449
|
+
/* The line in the muted text grey, not the border grey: a border grey was 1.3 : 1 in Leaf (Katerina, 9 October). */
|
|
2431
2450
|
// 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
|
-
|
|
2451
|
+
quote: "[&_blockquote>p]:m-0 [&_blockquote]:border-l-[3px] [&_blockquote]:border-text-muted [&_blockquote]:pl-2.5",
|
|
2452
|
+
/* Code in a sentence: the code fill and a thin border, in the heading colour (Katerina, 9 October: option B; the amber of 0.64.0 was too much). */
|
|
2453
|
+
// 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
|
|
2454
|
+
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]:border [&_:not(pre)>code]:border-border-default [&_code]:font-mono [&_code]:text-[0.85em] [&_code]:text-text-primary",
|
|
2455
|
+
/* 12px either side, 10px above and below, looser lines than the text (Katerina, 9 October; 8px all round before). */
|
|
2456
|
+
// 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
|
|
2457
|
+
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",
|
|
2458
|
+
/* Colours inside a code block, by language: the classes `codeColours` gives each word, after highlight.js's own GitHub theme (Katerina, 9 October). */
|
|
2459
|
+
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",
|
|
2460
|
+
/* A divider splits the text in two: 16px either side (Katerina, 9 October; 4 before). */
|
|
2461
|
+
divider: "[&_hr]:my-2 [&_hr]:border-border-default",
|
|
2438
2462
|
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
|
-
|
|
2463
|
+
/* 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). */
|
|
2464
|
+
marks: "[&_em]:italic [&_strong]:font-semibold [&_strong]:text-text-primary [&_u]:underline [&_u]:decoration-text-muted [&_u]:underline-offset-2",
|
|
2465
|
+
/* Lines 1.5 apart (Katerina, 9 October; 1.4 before). */
|
|
2466
|
+
default: "text-body-2 leading-normal [&>:is(h2,h3)]:text-body-2 [&>:is(h2,h3)]:font-semibold [&>h1]:text-h4",
|
|
2467
|
+
/* Blocks 6px apart; a heading keeps its 12px above and 8px below. */
|
|
2468
|
+
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
2469
|
};
|
|
2443
2470
|
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);
|
|
2471
|
+
const { base, headings, lists, quote, code, codeBlock, syntax, divider, table, marks } = RICH_TEXT_CLASSES;
|
|
2472
|
+
return cn(base, headings, lists, quote, code, codeBlock, syntax, divider, table, marks, RICH_TEXT_CLASSES[size], className);
|
|
2446
2473
|
}
|
|
2447
2474
|
var LINK_SPLIT = /(\[[^[\]\n]+\]\((?:https?:\/\/|mailto:)[^\s)]+\)|https?:\/\/[^\s]+)/g;
|
|
2448
2475
|
var WRITTEN_LINK = /^\[([^[\]\n]+)\]\(((?:https?:\/\/|mailto:)[^\s)]+)\)$/;
|
|
@@ -2469,15 +2496,15 @@ function textWithLinks(text, renderText) {
|
|
|
2469
2496
|
return part ? /* @__PURE__ */ jsx34("span", { children: renderText(part) }, i) : null;
|
|
2470
2497
|
});
|
|
2471
2498
|
}
|
|
2472
|
-
function Runs({ runs, draw }) {
|
|
2499
|
+
function Runs({ runs, draw: draw2 }) {
|
|
2473
2500
|
return /* @__PURE__ */ jsx34(Fragment8, { children: (runs ?? []).map((run, i) => {
|
|
2474
|
-
if (run.reference) return /* @__PURE__ */ jsx34("span", { children:
|
|
2501
|
+
if (run.reference) return /* @__PURE__ */ jsx34("span", { children: draw2.renderReference(run.reference, run) }, i);
|
|
2475
2502
|
if (run.marks.includes("code")) {
|
|
2476
2503
|
return /* @__PURE__ */ jsx34("code", { children: run.text }, i);
|
|
2477
2504
|
}
|
|
2478
2505
|
let node = run.text.split("\n").map((line, j) => /* @__PURE__ */ jsxs25("span", { children: [
|
|
2479
2506
|
j > 0 && /* @__PURE__ */ jsx34("br", {}),
|
|
2480
|
-
textWithLinks(line,
|
|
2507
|
+
textWithLinks(line, draw2.renderText)
|
|
2481
2508
|
] }, j));
|
|
2482
2509
|
if (run.marks.includes("underline")) node = /* @__PURE__ */ jsx34("u", { children: node });
|
|
2483
2510
|
if (run.marks.includes("italic")) node = /* @__PURE__ */ jsx34("em", { children: node });
|
|
@@ -2486,7 +2513,7 @@ function Runs({ runs, draw }) {
|
|
|
2486
2513
|
}) });
|
|
2487
2514
|
}
|
|
2488
2515
|
var named = (block) => block.typeName ?? block.type;
|
|
2489
|
-
function Table({ block, draw }) {
|
|
2516
|
+
function Table({ block, draw: draw2 }) {
|
|
2490
2517
|
const rows = (block.children ?? []).filter((row) => named(row) === "tableRow");
|
|
2491
2518
|
if (!rows.length) return null;
|
|
2492
2519
|
const cells = (row) => (row.children ?? []).map((cell, i) => {
|
|
@@ -2500,8 +2527,8 @@ function Table({ block, draw }) {
|
|
|
2500
2527
|
colSpan: colspan && colspan > 1 ? colspan : void 0,
|
|
2501
2528
|
rowSpan: rowspan && rowspan > 1 ? rowspan : void 0,
|
|
2502
2529
|
children: [
|
|
2503
|
-
(cell.children ?? []).map((child, j) => /* @__PURE__ */ jsx34(Runs, { runs: child.inline, draw }, j)),
|
|
2504
|
-
/* @__PURE__ */ jsx34(Runs, { runs: cell.inline, draw })
|
|
2530
|
+
(cell.children ?? []).map((child, j) => /* @__PURE__ */ jsx34(Runs, { runs: child.inline, draw: draw2 }, j)),
|
|
2531
|
+
/* @__PURE__ */ jsx34(Runs, { runs: cell.inline, draw: draw2 })
|
|
2505
2532
|
]
|
|
2506
2533
|
},
|
|
2507
2534
|
cell.id ?? i
|
|
@@ -2514,10 +2541,10 @@ function Table({ block, draw }) {
|
|
|
2514
2541
|
/* @__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
2542
|
] });
|
|
2516
2543
|
}
|
|
2517
|
-
function Block({ block, draw }) {
|
|
2518
|
-
const own =
|
|
2544
|
+
function Block({ block, draw: draw2 }) {
|
|
2545
|
+
const own = draw2.renderBlock?.(block);
|
|
2519
2546
|
if (own !== void 0) return own;
|
|
2520
|
-
const runs = /* @__PURE__ */ jsx34(Runs, { runs: block.inline, draw });
|
|
2547
|
+
const runs = /* @__PURE__ */ jsx34(Runs, { runs: block.inline, draw: draw2 });
|
|
2521
2548
|
switch (block.type) {
|
|
2522
2549
|
case "heading": {
|
|
2523
2550
|
if (block.level === 1) return /* @__PURE__ */ jsx34("h1", { "data-block-id": block.id, children: runs });
|
|
@@ -2528,24 +2555,24 @@ function Block({ block, draw }) {
|
|
|
2528
2555
|
return /* @__PURE__ */ jsx34("p", { "data-block-id": block.id, children: runs });
|
|
2529
2556
|
case "bulletList":
|
|
2530
2557
|
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));
|
|
2558
|
+
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
2559
|
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
2560
|
}
|
|
2534
2561
|
case "blockquote":
|
|
2535
2562
|
return /* @__PURE__ */ jsx34("blockquote", { "data-block-id": block.id, children: runs });
|
|
2536
2563
|
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("") }) });
|
|
2564
|
+
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
2565
|
case "horizontalRule":
|
|
2539
2566
|
return /* @__PURE__ */ jsx34("hr", { "data-block-id": block.id });
|
|
2540
2567
|
case "table": {
|
|
2541
|
-
const table = /* @__PURE__ */ jsx34(Table, { block, draw });
|
|
2568
|
+
const table = /* @__PURE__ */ jsx34(Table, { block, draw: draw2 });
|
|
2542
2569
|
if ((block.children ?? []).some((row) => named(row) === "tableRow")) return table;
|
|
2543
2570
|
break;
|
|
2544
2571
|
}
|
|
2545
2572
|
}
|
|
2546
2573
|
return /* @__PURE__ */ jsxs25("div", { "data-block-id": block.id, "data-block-type": named(block), children: [
|
|
2547
2574
|
runs,
|
|
2548
|
-
(block.children ?? []).map((child, i) => /* @__PURE__ */ jsx34(Block, { block: child, draw }, child.id ?? i))
|
|
2575
|
+
(block.children ?? []).map((child, i) => /* @__PURE__ */ jsx34(Block, { block: child, draw: draw2 }, child.id ?? i))
|
|
2549
2576
|
] });
|
|
2550
2577
|
}
|
|
2551
2578
|
function RichText({
|
|
@@ -2556,8 +2583,8 @@ function RichText({
|
|
|
2556
2583
|
renderBlock
|
|
2557
2584
|
}) {
|
|
2558
2585
|
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)) });
|
|
2586
|
+
const draw2 = { renderText, renderReference, renderBlock };
|
|
2587
|
+
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)) });
|
|
2561
2588
|
}
|
|
2562
2589
|
|
|
2563
2590
|
// src/KindIcon.tsx
|