@djangocfg/ui-tools 2.1.298 → 2.1.300
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 +126 -2
- package/dist/{DocsLayout-74WIW7L3.mjs → DocsLayout-MWRKNFXR.mjs} +3 -3
- package/dist/{DocsLayout-74WIW7L3.mjs.map → DocsLayout-MWRKNFXR.mjs.map} +1 -1
- package/dist/{DocsLayout-IA55EXRN.cjs → DocsLayout-NWJUF42A.cjs} +48 -48
- package/dist/{DocsLayout-IA55EXRN.cjs.map → DocsLayout-NWJUF42A.cjs.map} +1 -1
- package/dist/{chunk-2BBXP3DH.mjs → chunk-CKD7GNE5.mjs} +220 -187
- package/dist/chunk-CKD7GNE5.mjs.map +1 -0
- package/dist/{chunk-Q6FNLXLZ.cjs → chunk-SEXWBCLX.cjs} +256 -222
- package/dist/chunk-SEXWBCLX.cjs.map +1 -0
- package/dist/index.cjs +13 -9
- package/dist/index.d.cts +82 -59
- package/dist/index.d.ts +82 -59
- package/dist/index.mjs +4 -4
- package/package.json +6 -6
- package/src/components/markdown/MarkdownMessage/CodeBlock.tsx +69 -0
- package/src/components/markdown/MarkdownMessage/CollapseToggle.tsx +60 -0
- package/src/components/markdown/MarkdownMessage/MarkdownMessage.story.tsx +171 -0
- package/src/components/markdown/MarkdownMessage/MarkdownMessage.tsx +202 -0
- package/src/components/markdown/MarkdownMessage/components.tsx +154 -0
- package/src/components/markdown/MarkdownMessage/index.ts +13 -0
- package/src/components/markdown/MarkdownMessage/linkRules.ts +83 -0
- package/src/components/markdown/MarkdownMessage/plainText.ts +50 -0
- package/src/components/markdown/MarkdownMessage/sanitize.ts +78 -0
- package/src/components/markdown/MarkdownMessage/types.ts +104 -0
- package/src/components/markdown/index.ts +6 -1
- package/dist/chunk-2BBXP3DH.mjs.map +0 -1
- package/dist/chunk-Q6FNLXLZ.cjs.map +0 -1
- package/src/components/markdown/MarkdownMessage.tsx +0 -721
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ This package contains heavy components that are loaded lazily to keep your initi
|
|
|
28
28
|
| `@djangocfg/ui-tools` | Heavy tools with lazy loading |
|
|
29
29
|
| `@djangocfg/ui-nextjs` | Next.js apps (extends ui-core) |
|
|
30
30
|
|
|
31
|
-
## Tools (
|
|
31
|
+
## Tools (15)
|
|
32
32
|
|
|
33
33
|
| Tool | Bundle Size | Description |
|
|
34
34
|
|------|-------------|-------------|
|
|
@@ -42,6 +42,7 @@ This package contains heavy components that are loaded lazily to keep your initi
|
|
|
42
42
|
| `LottiePlayer` | ~200KB | Lottie animation player |
|
|
43
43
|
| `AudioPlayer` | ~200KB | Audio player with WaveSurfer.js |
|
|
44
44
|
| `VideoPlayer` | ~150KB | Professional video player with Vidstack |
|
|
45
|
+
| `MarkdownMessage` | ~120KB | Read-only chat-tuned markdown renderer (GFM, syntax highlighting, mermaid, declarative `linkRules` for custom URL schemes) |
|
|
45
46
|
| `JsonTree` | ~100KB | JSON visualization with modes (full/compact/inline) |
|
|
46
47
|
| `Gallery` | ~50KB | Image/video gallery with carousel, grid, lightbox |
|
|
47
48
|
| `ImageViewer` | ~50KB | Image viewer with zoom/pan/rotate/flip and gallery navigation |
|
|
@@ -558,11 +559,134 @@ const schema = {
|
|
|
558
559
|
/>
|
|
559
560
|
```
|
|
560
561
|
|
|
562
|
+
## Markdown Message
|
|
563
|
+
|
|
564
|
+
Read-only markdown renderer tuned for chat / agent transcripts. Built
|
|
565
|
+
on `react-markdown` + `remark-gfm` + `rehype-sanitize`, with a few
|
|
566
|
+
chat-specific affordances on top:
|
|
567
|
+
|
|
568
|
+
- Syntax-highlighted code blocks with a hover-revealed Copy button
|
|
569
|
+
(delegates to `PrettyCode` from this package).
|
|
570
|
+
- Mermaid diagram rendering for ` ```mermaid ` fences.
|
|
571
|
+
- Plain-text fast path: when content has no markdown syntax we skip
|
|
572
|
+
ReactMarkdown entirely and just render the string with
|
|
573
|
+
`whitespace: pre-line`. Cheaper, identical visual.
|
|
574
|
+
- Optional collapsible "Read more..." for long messages.
|
|
575
|
+
- User vs assistant styling modes (`isUser` prop).
|
|
576
|
+
- **`linkRules` API** — declarative handling of custom URL schemes
|
|
577
|
+
(e.g. `cmdop://machine/<uuid>` → render as a chip; `obsidian://`
|
|
578
|
+
→ open in a viewer). One prop replaces the per-consumer
|
|
579
|
+
custom-`a`/sanitize/urlTransform boilerplate.
|
|
580
|
+
|
|
581
|
+
```tsx
|
|
582
|
+
import { MarkdownMessage } from '@djangocfg/ui-tools';
|
|
583
|
+
|
|
584
|
+
<MarkdownMessage
|
|
585
|
+
content="# Hello\n\nThis is **bold** text and `inline code`."
|
|
586
|
+
isCompact={false}
|
|
587
|
+
/>
|
|
588
|
+
|
|
589
|
+
// Chat user message — primary-tinted bubble styling
|
|
590
|
+
<MarkdownMessage content={msg} isUser />
|
|
591
|
+
|
|
592
|
+
// Long content with "Read more..."
|
|
593
|
+
<MarkdownMessage
|
|
594
|
+
content={longText}
|
|
595
|
+
collapsible
|
|
596
|
+
maxLength={300}
|
|
597
|
+
maxLines={5}
|
|
598
|
+
/>
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### Custom URL schemes — `linkRules`
|
|
602
|
+
|
|
603
|
+
For any chat that emits its own URL schemes — `cmdop://machine/<uuid>`
|
|
604
|
+
mention chips, `obsidian://open?path=…` deep-links, custom file
|
|
605
|
+
viewers — the recommended approach is `linkRules`:
|
|
606
|
+
|
|
607
|
+
```tsx
|
|
608
|
+
import { MarkdownMessage, type LinkRule } from '@djangocfg/ui-tools';
|
|
609
|
+
|
|
610
|
+
const machineMention: LinkRule = {
|
|
611
|
+
name: 'machine-mention',
|
|
612
|
+
protocols: ['cmdop'],
|
|
613
|
+
|
|
614
|
+
// Optional: rewrite the source markdown before render. Useful when
|
|
615
|
+
// your composer adds a decorative `@` outside the link
|
|
616
|
+
// (`@[label](href)`) — the chip itself reads as the mention
|
|
617
|
+
// indicator, so rendering "@<chip>" looks like "@@label".
|
|
618
|
+
preprocess: (source) =>
|
|
619
|
+
source.replace(
|
|
620
|
+
/(^|[^A-Za-z0-9_])@(\[[^\]]+\]\(cmdop:\/\/machine\/[^)\s]+\))/g,
|
|
621
|
+
'$1$2',
|
|
622
|
+
),
|
|
623
|
+
|
|
624
|
+
// Predicate against the resolved href.
|
|
625
|
+
match: (href) => href.startsWith('cmdop://machine/'),
|
|
626
|
+
|
|
627
|
+
// Render whatever you want. `children` is the link's React label.
|
|
628
|
+
render: ({ href, children, isUser }) => {
|
|
629
|
+
const id = href.slice('cmdop://machine/'.length);
|
|
630
|
+
return <MentionChip id={id} isUser={isUser}>{children}</MentionChip>;
|
|
631
|
+
},
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
<MarkdownMessage
|
|
635
|
+
content="Talk to @[Vps-audi](cmdop://machine/abc-123) about deployment."
|
|
636
|
+
linkRules={[machineMention]}
|
|
637
|
+
/>
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
#### Why `linkRules` and not just `customComponents.a`
|
|
641
|
+
|
|
642
|
+
Three concerns have to be aligned for a custom URL scheme to make it
|
|
643
|
+
intact to your renderer, and `customComponents` alone covers only one
|
|
644
|
+
of them:
|
|
645
|
+
|
|
646
|
+
| Concern | What goes wrong without help |
|
|
647
|
+
|---|---|
|
|
648
|
+
| **Sanitize whitelist** | `rehype-sanitize` strips href values for any protocol it doesn't recognise — your renderer receives `href={undefined}`. |
|
|
649
|
+
| **`urlTransform`** | `react-markdown`'s default `urlTransform` runs *before* sanitize and blanks unrecognised schemes the same way — sanitize whitelist is moot if this layer already nuked the href. |
|
|
650
|
+
| **Source preprocess** | Your composer might emit a shape like `@[label](cmdop://...)`; the leading `@` lives outside the link and needs to be stripped before render or the chip ends up next to a literal `@`. |
|
|
651
|
+
|
|
652
|
+
`linkRules` collapses all three into a single declaration:
|
|
653
|
+
- `protocols` is unioned into the sanitize schema.
|
|
654
|
+
- The same protocol opts in the `urlTransform`.
|
|
655
|
+
- `preprocess` runs ahead of render.
|
|
656
|
+
- `match` + `render` replace the per-rule `<a>`.
|
|
657
|
+
|
|
658
|
+
You can still pass `customComponents` and `extraHrefProtocols`
|
|
659
|
+
alongside; rules win on URLs they `match`, everything else falls
|
|
660
|
+
through to your `customComponents.a` (or the built-in chat anchor).
|
|
661
|
+
|
|
662
|
+
### Anatomy
|
|
663
|
+
|
|
664
|
+
The component lives at `src/components/markdown/MarkdownMessage/`:
|
|
665
|
+
|
|
666
|
+
```
|
|
667
|
+
MarkdownMessage/
|
|
668
|
+
├── MarkdownMessage.tsx # composition only
|
|
669
|
+
├── types.ts # MarkdownMessageProps + LinkRule
|
|
670
|
+
├── sanitize.ts # buildSchema + buildUrlTransform
|
|
671
|
+
├── components.tsx # createMarkdownComponents (h/p/ul/a/pre/...)
|
|
672
|
+
├── CodeBlock.tsx # code block with copy button + fallback
|
|
673
|
+
├── CollapseToggle.tsx # "Read more..." button
|
|
674
|
+
├── linkRules.ts # rule application helpers
|
|
675
|
+
├── plainText.ts # hasMarkdownSyntax + extractTextFromChildren
|
|
676
|
+
└── index.ts # public re-exports
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
Decomposed in 2.1.299 to keep concerns flat and reviewable. Public
|
|
680
|
+
contract (`MarkdownMessage`, `MarkdownMessageProps`, `LinkRule`,
|
|
681
|
+
`extractTextFromChildren`) re-exported from
|
|
682
|
+
`@djangocfg/ui-tools` directly.
|
|
683
|
+
|
|
561
684
|
## Components
|
|
562
685
|
|
|
563
686
|
| Component | Description |
|
|
564
687
|
|-----------|-------------|
|
|
565
|
-
| `
|
|
688
|
+
| `MarkdownMessage` | Read-only markdown renderer with custom-URL-scheme support via `linkRules` (see above) |
|
|
689
|
+
| `Markdown` | Generic markdown renderer with GFM support |
|
|
566
690
|
|
|
567
691
|
## Stores
|
|
568
692
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deduplicateEndpoints, dereferenceSchema, resolveBaseUrl, usePlaygroundContext, toMarkdown, toCompactJson, toRawJson, formatBytes, MarkdownMessage, CODE_SAMPLE_TARGETS, buildHarRequest, resolveAbsolute, renderSnippet, PrettyCode_default, relativePath, endpointToMarkdown, isValidJson, findApiKeyById, parseRequestHeaders, UrlBuilder, sampleSchemaJson, joinUrl } from './chunk-
|
|
1
|
+
import { deduplicateEndpoints, dereferenceSchema, resolveBaseUrl, usePlaygroundContext, toMarkdown, toCompactJson, toRawJson, formatBytes, MarkdownMessage, CODE_SAMPLE_TARGETS, buildHarRequest, resolveAbsolute, renderSnippet, PrettyCode_default, relativePath, endpointToMarkdown, isValidJson, findApiKeyById, parseRequestHeaders, UrlBuilder, sampleSchemaJson, joinUrl } from './chunk-CKD7GNE5.mjs';
|
|
2
2
|
import { JsonTree_default } from './chunk-LFWQ36LJ.mjs';
|
|
3
3
|
import './chunk-SSUOENAZ.mjs';
|
|
4
4
|
import { __name } from './chunk-CGILA3WO.mjs';
|
|
@@ -3459,5 +3459,5 @@ var DocsLayout = /* @__PURE__ */ __name(() => {
|
|
|
3459
3459
|
}, "DocsLayout");
|
|
3460
3460
|
|
|
3461
3461
|
export { DocsLayout };
|
|
3462
|
-
//# sourceMappingURL=DocsLayout-
|
|
3463
|
-
//# sourceMappingURL=DocsLayout-
|
|
3462
|
+
//# sourceMappingURL=DocsLayout-MWRKNFXR.mjs.map
|
|
3463
|
+
//# sourceMappingURL=DocsLayout-MWRKNFXR.mjs.map
|