@godxjp/markdown 31.25.3 → 31.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,6 +47,11 @@ focusable only while it overflows, so a wide table scrolls instead of widening t
47
47
  | `rehypePlugins` | Run after the sanitiser — presentation only. |
48
48
  | `mermaid={false}` | Keep ```mermaid fences as code (or hand them to the host `pre`). |
49
49
  | `allowedElements` / `unwrapDisallowed` | Narrow a body (an activity feed: `strong`, `em`, `del`, `code`). Only removes. |
50
+ | `shortCellLength` | A table cell holding one short token (no whitespace, ≤ 24 characters by default) gets `data-short`; `Prose` keeps it on one line. `false` turns it off. |
51
+
52
+ Images: wrap the body in `<Prose imagePreview>` and every body image opens the kit preview, paging
53
+ through the others — no `img` override needed. Images in table cells keep min(natural width, 20rem),
54
+ so a narrow table scrolls instead of squashing them.
50
55
 
51
56
  ## Stored versions
52
57
 
package/dist/index.d.ts CHANGED
@@ -73,7 +73,7 @@ type PluggableList = NonNullable<Options$1["remarkPlugins"]>;
73
73
  * differently — a schema change, a new default plugin — not on every release.
74
74
  */
75
75
  declare const MARKDOWN_FORMAT = "md";
76
- declare const RENDERER_VERSION = 2;
76
+ declare const RENDERER_VERSION = 3;
77
77
  type MarkdownProps = {
78
78
  /** The Markdown source. */
79
79
  children: string;
@@ -117,6 +117,13 @@ type MarkdownProps = {
117
117
  allowElement?: Options$1["allowElement"];
118
118
  /** With an element filter: keep a removed element's children (its text) instead of dropping it. */
119
119
  unwrapDisallowed?: boolean;
120
+ /**
121
+ * A table cell whose trimmed text has no whitespace and at most this many characters — a code,
122
+ * an id, a date, 優先度 — is stamped `data-short`, and `Prose` keeps it on one line: CJK otherwise
123
+ * breaks between any two ideographs in a narrow column (gh#1150). A sentence still wraps.
124
+ * Characters are user-perceived (grapheme clusters). Default 24; `false` stamps nothing.
125
+ */
126
+ shortCellLength?: number | false;
120
127
  };
121
128
  /**
122
129
  * THE ONE RENDERER (gh#1108). GFM — tables, task lists, fenced code, autolinks, footnotes,
@@ -128,7 +135,7 @@ type MarkdownProps = {
128
135
  * Renders bare elements; the host wraps it (`<Prose>` from `@godxjp/ui/data-display`), so this
129
136
  * package carries no UI-kit dependency.
130
137
  */
131
- declare function Markdown({ children, remarkPlugins, rehypePlugins, schema, components, resolveUrl, headingId, mermaid, allowedElements, disallowedElements, allowElement, unwrapDisallowed, }: MarkdownProps): React.JSX.Element;
138
+ declare function Markdown({ children, remarkPlugins, rehypePlugins, schema, components, resolveUrl, headingId, mermaid, allowedElements, disallowedElements, allowElement, unwrapDisallowed, shortCellLength, }: MarkdownProps): React.JSX.Element;
132
139
 
133
140
  type MermaidSvgCheck = {
134
141
  ok: true;
package/dist/index.js CHANGED
@@ -244,7 +244,7 @@ function safeUrl(url, key) {
244
244
  // src/markdown.tsx
245
245
  import { jsx as jsx3 } from "react/jsx-runtime";
246
246
  var MARKDOWN_FORMAT = "md";
247
- var RENDERER_VERSION = 2;
247
+ var RENDERER_VERSION = 3;
248
248
  var URL_ATTRIBUTES = {
249
249
  a: "href",
250
250
  img: "src",
@@ -263,6 +263,30 @@ function rehypeResolveUrls(options) {
263
263
  });
264
264
  };
265
265
  }
266
+ var graphemes = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : void 0;
267
+ function textOf2(node) {
268
+ let text = "";
269
+ let hasImage = false;
270
+ visit2(node, (child) => {
271
+ if (child.type === "text") text += child.value;
272
+ else if (child.type === "element" && child.tagName === "img") hasImage = true;
273
+ });
274
+ return { text, hasImage };
275
+ }
276
+ function rehypeShortCells(options) {
277
+ return (tree) => {
278
+ const { max } = options;
279
+ if (max === false || max <= 0) return;
280
+ visit2(tree, "element", (node) => {
281
+ if (node.tagName !== "td" && node.tagName !== "th") return;
282
+ const { text, hasImage } = textOf2(node);
283
+ const token = text.trim();
284
+ if (hasImage || token === "" || /\s/.test(token)) return;
285
+ const length = graphemes ? [...graphemes.segment(token)].length : [...token].length;
286
+ if (length <= max) node.properties = { ...node.properties, dataShort: "" };
287
+ });
288
+ };
289
+ }
266
290
  function omitNode(props) {
267
291
  const { node: _node, ...rest } = props;
268
292
  return rest;
@@ -287,7 +311,8 @@ function Markdown({
287
311
  allowedElements,
288
312
  disallowedElements,
289
313
  allowElement,
290
- unwrapDisallowed
314
+ unwrapDisallowed,
315
+ shortCellLength = 24
291
316
  }) {
292
317
  const sanitizeSchema = React3.useMemo(() => extendSchema(schema), [schema]);
293
318
  const merged = React3.useMemo(() => {
@@ -313,6 +338,7 @@ function Markdown({
313
338
  [rehypeResolveUrls, { resolve: resolveUrl }],
314
339
  [rehypeHeadingIds, { resolve: headingId }],
315
340
  [rehypeSanitize, sanitizeSchema],
341
+ [rehypeShortCells, { max: shortCellLength }],
316
342
  ...rehypePlugins
317
343
  ],
318
344
  urlTransform: safeUrl,
@@ -341,8 +367,9 @@ var MARKDOWN_FIXTURES = [
341
367
  {
342
368
  name: "GFM table with alignment, in its scroll box",
343
369
  markdown: "| a | b |\n|:--|--:|\n| 1 | 2 |",
344
- // Every table sits in its own scroll box (gh#1131, renderer v2).
345
- html: '<div class="ui-prose-table-scroll" data-slot="prose-table-scroll"><table><thead><tr><th style="text-align:left">a</th><th style="text-align:right">b</th></tr></thead><tbody><tr><td style="text-align:left">1</td><td style="text-align:right">2</td></tr></tbody></table></div>'
370
+ // Every table sits in its own scroll box (gh#1131, renderer v2); a single short token per
371
+ // cell carries `data-short` (gh#1150, renderer v3).
372
+ html: '<div class="ui-prose-table-scroll" data-slot="prose-table-scroll"><table><thead><tr><th data-short="" style="text-align:left">a</th><th data-short="" style="text-align:right">b</th></tr></thead><tbody><tr><td data-short="" style="text-align:left">1</td><td data-short="" style="text-align:right">2</td></tr></tbody></table></div>'
346
373
  },
347
374
  {
348
375
  name: "task list stays read-only",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@godxjp/markdown",
3
- "version": "31.25.3",
3
+ "version": "31.26.0",
4
4
  "description": "The one Markdown renderer for GoDX apps: GFM + heading anchors, one sanitiser schema, a shared fixture corpus, and Mermaid drawn only after its SVG passes a fail-closed gate.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",