@zccz14/ux 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -238,7 +238,7 @@ One prop, on purpose. There is no `math`, `mermaid`, `components`, `remarkPlugin
238
238
  - **GitHub Flavored Markdown** — tables, task lists, strikethrough, autolinks.
239
239
  , `$…$`, `\(…\)`, `\[…\]` and `math`-tagged code fences, because models emit all of them. The stylesheet and fonts are imported by the component itself, so a formula is never unstyled; the runtime (~76 KB gzipped) is fetched only by a surface whose content can actually contain a formula, and stays cached for the rest of the session. Until that chunk arrives — and always when rendering on a server — a formula shows as the source it was written as, the same state a still-streaming formula is in. Broken math degrades to one `.katex-error` span carrying the parser message.
240
240
  - **Mermaid diagrams** — a `mermaid`-tagged fence becomes an SVG, loaded on demand: a surface without a diagram never downloads mermaid. The chart follows the current theme and the surrounding text size, and re-renders when `.dark` flips. An unparseable diagram falls back to its own source block.
241
- - **Links** — absolute URLs open in a new tab with `rel="noopener noreferrer"` and an external marker; in-page anchors and relative paths stay in the app. Only `http(s)` and `mailto` survive: `javascript:`, `data:` and friends degrade to plain text.
241
+ - **Links** — absolute URLs open in a new tab with `rel="noopener noreferrer"` and an external marker; in-page anchors and relative paths stay in the app. Only `http(s)` and `mailto` survive: `javascript:`, `data:` and friends degrade to plain text. A link keeps the text colour and carries its weight in the underline: Markdown is quoted content, so it never introduces an accent of its own.
242
242
  - **Tables and code** — a wide table or a long code block scrolls inside its own box, so the transcript or article around it never grows a horizontal scrollbar.
243
243
  - **Raw HTML** — never rendered. The pipeline has no `rehype-raw`, so HTML in the source is shown as text.
244
244
 
@@ -246,6 +246,20 @@ One prop, on purpose. There is no `math`, `mermaid`, `components`, `remarkPlugin
246
246
 
247
247
  The component wraps its content in `.ux-markdown`, and that block is the family's typographic contract: every size is expressed in `em` off the inherited font size, and no measure is imposed. The same content therefore keeps identical proportions in a 14px chat bubble and a 16px article page. The host decides two things and only two — the font size of the container the content is dropped into, and the width of that container. Do not wrap the component in `prose` classes: the stylesheet is the single source of the look, and `scripts/check-styles.mjs` enforces it.
248
248
 
249
+ ### Server rendering
250
+
251
+ The component renders on a server without waiting for anything: math shows as the source it was
252
+ written as, and diagrams as their fenced block. The client swaps them in once the on-demand chunks
253
+ arrive, and the server snapshot and the first client render agree, so hydration stays silent.
254
+
255
+ If the server render goes through Vite's SSR (`ssrLoadModule`, or a framework built on it), inline
256
+ the package — otherwise Vite externalises it and hands the KaTeX stylesheet import to Node, which
257
+ cannot load `.css`:
258
+
259
+ ```ts
260
+ export default defineConfig({ ssr: { noExternal: ["@zccz14/ux"] } });
261
+ ```
262
+
249
263
  ### Why the pipeline is a runtime dependency
250
264
 
251
265
  `react-markdown`, `remark-gfm`, `remark-math-extended`, `rehype-katex`, `katex` and `mermaid` are `dependencies`, not peers, so an app wires nothing. An app that never renders Markdown tree-shakes the whole chain away, and two pieces are deliberately kept out of the main bundle even for apps that do: Mermaid (loaded by the first diagram, so a surface without one never downloads it) and the math runtime (KaTeX's ~76 KB gzipped JavaScript, loaded by the first surface whose content may contain a formula). What stays static is KaTeX's stylesheet — about 3.6 KB gzipped, with fonts the browser only fetches once a formula is on screen — because a formula must never render unstyled. `scripts/check-package.mjs` fails the build if the manifest ever claims `sideEffects: false`, which would let a bundler drop that stylesheet and render every formula as bare LaTeX with no error to notice.
@@ -259,7 +273,7 @@ The component wraps its content in `.ux-markdown`, and that block is the family'
259
273
 
260
274
  ## Styling
261
275
 
262
- Import `@zccz14/ux/styles.css` once. It consumes the app's shadcn theme tokens and falls back to its own values, so the shell stays readable even when a token is missing: `--background`, `--foreground`, `--border`, `--accent`, `--muted`, `--ring`, `--sidebar`, `--sidebar-foreground`, `--sidebar-accent`, `--sidebar-accent-foreground`, `--sidebar-border`, `--sidebar-ring`. The Markdown layer reads `--muted`, `--muted-foreground`, `--primary` and `--destructive` through the same `--ux-*` layer (`--ux-muted`, `--ux-muted-foreground`, `--ux-primary`, `--ux-destructive`).
276
+ Import `@zccz14/ux/styles.css` once. It consumes the app's shadcn theme tokens and falls back to its own values, so the shell stays readable even when a token is missing: `--background`, `--foreground`, `--border`, `--accent`, `--muted`, `--ring`, `--sidebar`, `--sidebar-foreground`, `--sidebar-accent`, `--sidebar-accent-foreground`, `--sidebar-border`, `--sidebar-ring`. The Markdown layer reads `--muted`, `--muted-foreground` and `--destructive` through the same `--ux-*` layer (`--ux-muted`, `--ux-muted-foreground`, `--ux-destructive`).
263
277
 
264
278
  Those tokens are read through a `--ux-*` layer declared twice — a light set on `:root` and a dark set on `.dark` — so every fallback has a dark counterpart. A missing `--sidebar` therefore renders dark in dark mode instead of a light sidebar. The shell also sets `color-scheme` per mode, so native scrollbars and controls follow the theme without help from a theme provider.
265
279
 
package/dist/styles.css CHANGED
@@ -15,7 +15,6 @@
15
15
  --ux-accent: var(--accent, var(--muted, #f1f5f9));
16
16
  --ux-muted: var(--muted, #f1f5f9);
17
17
  --ux-muted-foreground: var(--muted-foreground, #64748b);
18
- --ux-primary: var(--primary, #2563eb);
19
18
  --ux-destructive: var(--destructive, #dc2626);
20
19
  --ux-ring: var(--ring, #2563eb);
21
20
  --ux-sidebar: var(--sidebar, #fafafa);
@@ -33,7 +32,6 @@
33
32
  --ux-accent: var(--accent, var(--muted, #303030));
34
33
  --ux-muted: var(--muted, #262626);
35
34
  --ux-muted-foreground: var(--muted-foreground, #a3a3a3);
36
- --ux-primary: var(--primary, #60a5fa);
37
35
  --ux-destructive: var(--destructive, #f87171);
38
36
  --ux-ring: var(--ring, #d4d4d4);
39
37
  --ux-sidebar: var(--sidebar, #161616);
@@ -593,8 +591,13 @@
593
591
  border-top: 1px solid var(--ux-border);
594
592
  }
595
593
 
594
+ /*
595
+ * A link keeps the text colour and carries its weight in the underline. Markdown is quoted
596
+ * content — model output, a manual, an article — so it never introduces an accent colour of its
597
+ * own; the family's coloured elements are actions, not text.
598
+ */
596
599
  .ux-markdown a {
597
- color: var(--ux-primary);
600
+ color: inherit;
598
601
  text-decoration: underline;
599
602
  text-underline-offset: 0.2em;
600
603
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zccz14/ux",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "description": "Unified app shell and Markdown renderer for the NTNL app family: one animated icon sidebar, a fixed-size logo that doubles as the page favicon, the Linkit-integrated AppHeader, and the single Markdown surface every app renders through.",
5
5
  "license": "MIT",
6
6
  "repository": {