@lotics/ui 41.3.0 → 41.4.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/MIGRATION.md +17 -0
- package/docs/catalog.md +3 -1
- package/package.json +1 -1
- package/src/markdown.web.tsx +56 -2
package/MIGRATION.md
CHANGED
|
@@ -4,6 +4,23 @@ Breaking changes, newest first — normally per major, plus the rare minor that
|
|
|
4
4
|
anyway (recorded under its exact version). The current contract lives in `AGENTS.md` + `docs/`;
|
|
5
5
|
this file exists only to move an app from one release to the next.
|
|
6
6
|
|
|
7
|
+
## 41.4.0 — embedded markdown is demoted in the OUTLINE, not only on the type ladder
|
|
8
|
+
|
|
9
|
+
`<Markdown variant="embedded">` sized its headings down and left them as the tags the author
|
|
10
|
+
wrote, so an `h2` inside a record value still landed in heading navigation as a PEER of the
|
|
11
|
+
page's own sections. Measured on a record surface, the outline read:
|
|
12
|
+
|
|
13
|
+
> Activity · "Tóm tắt cuộc họp (AI) — …" · "Bài học …" · Details · Next action
|
|
14
|
+
|
|
15
|
+
— a model's call-summary title between two real sections, contributed from inside ONE row of a
|
|
16
|
+
feed that can hold twenty more. Nothing visual finds this, and fixing the size is what makes it
|
|
17
|
+
invisible: the defect stops looking wrong at the moment it stops being measurable.
|
|
18
|
+
|
|
19
|
+
Embedded headings now render `h4`/`h5`/`h6` (h1→h4, h2→h5, h3 and deeper→h6). They stay
|
|
20
|
+
headings, so a reader can still navigate inside a long summary; they simply can no longer reach
|
|
21
|
+
a section's level. **Nothing to migrate** — document-scale markdown is untouched, and the
|
|
22
|
+
embedded type scale is unchanged.
|
|
23
|
+
|
|
7
24
|
## 41.3.0 — `Timeline` rows, embedded markdown, and a disclosure that is not a link
|
|
8
25
|
|
|
9
26
|
Nothing here removes an API or breaks a type. Two of the changes alter what your rows render on
|
package/docs/catalog.md
CHANGED
|
@@ -413,7 +413,9 @@ source (`src/<module>.tsx`/`.ts`) is the API reference.
|
|
|
413
413
|
field on a record, a summary in a feed row. Reach for `"embedded"` whenever the
|
|
414
414
|
text was not written by whoever built the screen, which is now the common case
|
|
415
415
|
because the writer is routinely a model; at document scale an `h1` it emits is
|
|
416
|
-
the same rung as your `SectionHeadingTitle`.
|
|
416
|
+
the same rung as your `SectionHeadingTitle`. Embedded demotes the heading LEVEL as well as
|
|
417
|
+
the scale (h1→h4, h2→h5, h3+→h6): sizing alone leaves a model's `##` announcing as a PEER of
|
|
418
|
+
your own sections in heading navigation, which no visual check can see.
|
|
417
419
|
- **`markdown_types`** — `MarkdownProps`; types only.
|
|
418
420
|
- **`markdown.css`** — import once for the web markdown styling.
|
|
419
421
|
- **`format_date`** — `formatDate` / `parseDate` / `toISODate` + `DateFormatStyle`.
|
package/package.json
CHANGED
package/src/markdown.web.tsx
CHANGED
|
@@ -8,10 +8,14 @@ import { colors } from "./colors";
|
|
|
8
8
|
import type { MarkdownProps } from "./markdown_types";
|
|
9
9
|
|
|
10
10
|
export function Markdown({ children, variant = "document" }: MarkdownProps) {
|
|
11
|
+
const embedded = variant === "embedded";
|
|
11
12
|
return (
|
|
12
13
|
<View>
|
|
13
|
-
<div className={
|
|
14
|
-
<ReactMarkdown
|
|
14
|
+
<div className={embedded ? "ui-markdown ui-markdown-embedded" : "ui-markdown"}>
|
|
15
|
+
<ReactMarkdown
|
|
16
|
+
remarkPlugins={[remarkGfmSafe]}
|
|
17
|
+
components={embedded ? embeddedComponents : markdownComponents}
|
|
18
|
+
>
|
|
15
19
|
{children}
|
|
16
20
|
</ReactMarkdown>
|
|
17
21
|
</div>
|
|
@@ -24,6 +28,56 @@ const markdownComponents = {
|
|
|
24
28
|
table: CopyableTable,
|
|
25
29
|
};
|
|
26
30
|
|
|
31
|
+
/**
|
|
32
|
+
* EMBEDDED MARKDOWN IS DEMOTED IN THE OUTLINE, not only on the type ladder.
|
|
33
|
+
*
|
|
34
|
+
* Sizing the headings down fixes what a screen SHOWS and nothing about what it
|
|
35
|
+
* ANNOUNCES: an `h2` the author of the text happened to write is still an `h2`,
|
|
36
|
+
* so it lands in heading navigation as a PEER of the page's own sections.
|
|
37
|
+
* Measured on a record surface, the outline read
|
|
38
|
+
*
|
|
39
|
+
* Activity · "Tóm tắt cuộc họp (AI) — …" · "Bài học …" · Details · Next action
|
|
40
|
+
*
|
|
41
|
+
* — a model's call-summary title sitting between two real sections, from inside
|
|
42
|
+
* one row of a feed that can hold twenty more. No visual probe finds this, and
|
|
43
|
+
* fixing the size is what makes it invisible: the defect stops looking wrong at
|
|
44
|
+
* the exact moment it stops being measurable.
|
|
45
|
+
*
|
|
46
|
+
* The page's sections are `h2` (`SectionHeading`), and embedded markdown is a
|
|
47
|
+
* VALUE inside one — inside a row, usually — so it starts at `h4`: deep enough
|
|
48
|
+
* that it can never be a section's peer, shallow enough to keep its own
|
|
49
|
+
* hierarchy. It stays a heading rather than becoming a `<div>`, because a long
|
|
50
|
+
* summary genuinely has parts and a reader navigating INSIDE it should still
|
|
51
|
+
* find them.
|
|
52
|
+
*/
|
|
53
|
+
const EMBEDDED_HEADING_LEVEL: Record<string, "h4" | "h5" | "h6"> = {
|
|
54
|
+
h1: "h4",
|
|
55
|
+
h2: "h5",
|
|
56
|
+
h3: "h6",
|
|
57
|
+
h4: "h6",
|
|
58
|
+
h5: "h6",
|
|
59
|
+
h6: "h6",
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
type HeadingProps = React.ComponentPropsWithoutRef<"h4"> & { node?: unknown };
|
|
63
|
+
|
|
64
|
+
function embeddedHeading(from: keyof typeof EMBEDDED_HEADING_LEVEL) {
|
|
65
|
+
const Tag = EMBEDDED_HEADING_LEVEL[from];
|
|
66
|
+
return function EmbeddedHeading({ node: _node, children, ...rest }: HeadingProps) {
|
|
67
|
+
return <Tag {...rest}>{children}</Tag>;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const embeddedComponents = {
|
|
72
|
+
...markdownComponents,
|
|
73
|
+
h1: embeddedHeading("h1"),
|
|
74
|
+
h2: embeddedHeading("h2"),
|
|
75
|
+
h3: embeddedHeading("h3"),
|
|
76
|
+
h4: embeddedHeading("h4"),
|
|
77
|
+
h5: embeddedHeading("h5"),
|
|
78
|
+
h6: embeddedHeading("h6"),
|
|
79
|
+
};
|
|
80
|
+
|
|
27
81
|
function CopyableTable(props: React.ComponentPropsWithoutRef<"table"> & { node?: unknown }) {
|
|
28
82
|
const { node: _node, children, ...rest } = props;
|
|
29
83
|
const tableRef = useRef<HTMLTableElement>(null);
|