@iyulab/chat-components 0.5.0 → 0.5.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +73 -145
  2. package/dist/_virtual/{_@oxc-project_runtime@0.122.0 → _@oxc-project_runtime@0.124.0}/helpers/decorate.js +1 -1
  3. package/dist/_virtual/{_@oxc-project_runtime@0.122.0 → _@oxc-project_runtime@0.124.0}/helpers/decorateMetadata.js +1 -1
  4. package/dist/components/blocks/UCodeBlock.js +2 -2
  5. package/dist/components/blocks/UFileBlock.js +2 -2
  6. package/dist/components/blocks/UJsonBlock.js +2 -2
  7. package/dist/components/blocks/UMarkedBlock.js +2 -2
  8. package/dist/components/blocks/URefBlock.js +2 -2
  9. package/dist/components/blocks/UTableBlock.js +2 -2
  10. package/dist/components/blocks/UTextBlock.js +2 -2
  11. package/dist/components/blocks/UThinkBlock.js +2 -2
  12. package/dist/components/blocks/UToolBlock.js +2 -2
  13. package/dist/components/buttons/UAttachButton.js +2 -2
  14. package/dist/components/buttons/UCopyButton.js +2 -2
  15. package/dist/components/buttons/UVoteButton.js +2 -2
  16. package/dist/components/intents/UQuestionIntent.js +2 -2
  17. package/dist/components/message/UMessage.js +2 -2
  18. package/dist/components/prompt/UPrompt.d.ts +5 -0
  19. package/dist/components/prompt/UPrompt.js +25 -4
  20. package/dist/components/references/URefCard.js +2 -2
  21. package/dist/components/references/URefCardGroup.js +2 -2
  22. package/dist/components/references/URefTag.js +2 -2
  23. package/dist/components/views/UChartView.js +2 -2
  24. package/dist/components/views/UImagesView.js +2 -2
  25. package/dist/components/views/UMapView.js +2 -2
  26. package/dist/components/views/UVideoView.js +2 -2
  27. package/dist/components/views/UView.js +2 -2
  28. package/dist/events/SendEvent.d.ts +15 -1
  29. package/dist/events/StopEvent.d.ts +11 -1
  30. package/package.json +4 -3
  31. package/skills/iyulab-chat-components/SKILL.md +107 -0
  32. package/skills/iyulab-chat-components/references/components/attach-button.md +69 -0
  33. package/skills/iyulab-chat-components/references/components/chart-view.md +65 -0
  34. package/skills/iyulab-chat-components/references/components/code-block.md +42 -0
  35. package/skills/iyulab-chat-components/references/components/copy-button.md +46 -0
  36. package/skills/iyulab-chat-components/references/components/file-block.md +64 -0
  37. package/skills/iyulab-chat-components/references/components/images-view.md +63 -0
  38. package/skills/iyulab-chat-components/references/components/json-block.md +41 -0
  39. package/skills/iyulab-chat-components/references/components/map-view.md +54 -0
  40. package/skills/iyulab-chat-components/references/components/marked-block.md +53 -0
  41. package/skills/iyulab-chat-components/references/components/message.md +60 -0
  42. package/skills/iyulab-chat-components/references/components/prompt.md +102 -0
  43. package/skills/iyulab-chat-components/references/components/question-intent.md +75 -0
  44. package/skills/iyulab-chat-components/references/components/ref-block.md +45 -0
  45. package/skills/iyulab-chat-components/references/components/ref-card-group.md +41 -0
  46. package/skills/iyulab-chat-components/references/components/ref-card.md +48 -0
  47. package/skills/iyulab-chat-components/references/components/ref-tag.md +40 -0
  48. package/skills/iyulab-chat-components/references/components/table-block.md +63 -0
  49. package/skills/iyulab-chat-components/references/components/text-block.md +59 -0
  50. package/skills/iyulab-chat-components/references/components/think-block.md +48 -0
  51. package/skills/iyulab-chat-components/references/components/tool-block.md +57 -0
  52. package/skills/iyulab-chat-components/references/components/video-view.md +55 -0
  53. package/skills/iyulab-chat-components/references/components/view.md +51 -0
  54. package/skills/iyulab-chat-components/references/components/vote-button.md +60 -0
  55. package/skills/iyulab-chat-components/references/types.md +115 -0
  56. package/skills/iyulab-chat-components/references/usage.md +254 -0
  57. package/skills/iyulab-chat-components/references/utilities/intent-prompt-builder.md +123 -0
  58. package/skills/iyulab-chat-components/references/utilities/view-prompt-builder.md +112 -0
@@ -0,0 +1,102 @@
1
+ # u-prompt
2
+
3
+ ```ts
4
+ import '@iyulab/chat-components/dist/components/prompt/UPrompt.js';
5
+ ```
6
+
7
+ **Tag:** `u-prompt`
8
+
9
+ Chat input component. Combines a text input area, file attachment previews, and an integrated send/stop button.
10
+
11
+ ```html
12
+ <!-- Basic usage -->
13
+ <u-prompt placeholder="Type a message..."></u-prompt>
14
+
15
+ <!-- Loading (streaming) state -->
16
+ <u-prompt loading></u-prompt>
17
+
18
+ <!-- With file attach button -->
19
+ <u-prompt>
20
+ <u-attach-button slot="left-actions" multiple accept="image/*,application/pdf">
21
+ Attach
22
+ </u-attach-button>
23
+ </u-prompt>
24
+ ```
25
+
26
+ ```ts
27
+ const prompt = document.querySelector('u-prompt');
28
+
29
+ // Send event
30
+ prompt.addEventListener('send', () => {
31
+ console.log('value:', prompt.value);
32
+ console.log('files:', prompt.files);
33
+ });
34
+
35
+ // Stop event (fired when send button is clicked while loading=true)
36
+ prompt.addEventListener('stop', () => {
37
+ console.log('stopped');
38
+ });
39
+
40
+ // Wire up file attach button
41
+ prompt.addEventListener('attach', (e) => {
42
+ const { files } = e.detail;
43
+ prompt.files = [
44
+ ...(prompt.files ?? []),
45
+ ...files.map(f => ({
46
+ type: 'file' as const,
47
+ name: f.name,
48
+ size: f.size,
49
+ mimeType: f.type,
50
+ status: 'idle' as const,
51
+ }))
52
+ ];
53
+ });
54
+
55
+ // Programmatic submit
56
+ prompt.submit();
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Slots
62
+
63
+ | Name | Description |
64
+ |------|-------------|
65
+ | `header` | Area above the input |
66
+ | `left-actions` | Left side of the control bar (e.g. attach button) |
67
+ | `right-actions` | Right side of the control bar |
68
+ | `footer` | Area below the input |
69
+
70
+ ## Properties
71
+
72
+ | Property | Type | Default | Reflect | Description |
73
+ |----------|------|---------|---------|-------------|
74
+ | `loading` | `boolean` | `false` | ✓ | Loading state. Send button becomes a stop button |
75
+ | `value` | `string` | `undefined` | — | Text input value |
76
+ | `files` | `FileBlockItem[]` | `undefined` | — | Attached file list |
77
+ | `placeholder` | `string` | `undefined` | — | Input placeholder text |
78
+ | `minRows` | `number` | `1` | — | Minimum textarea rows |
79
+ | `maxRows` | `number` | `10` | — | Maximum textarea rows (scrolls beyond) |
80
+
81
+ ## Methods
82
+
83
+ | Method | Description |
84
+ |--------|-------------|
85
+ | `submit()` | Programmatically submit. Fires `stop` if loading, otherwise fires `send` (only when value or files present) |
86
+
87
+ ## Events
88
+
89
+ | Event | Detail | Description |
90
+ |-------|--------|-------------|
91
+ | `send` | `unknown` | Fired on Enter or send button click |
92
+ | `stop` | `unknown` | Fired on send button click while loading |
93
+ | `remove` | `RemoveEventDetail` | Fired when an attached file's remove button is clicked |
94
+
95
+ ## CSS Parts
96
+
97
+ | Part | Description |
98
+ |------|-------------|
99
+ | `input` | Text input area (`u-text-block`) |
100
+ | `files` | File attachment preview area |
101
+ | `control` | Bottom control row (actions + send button) |
102
+ | `send-btn` | Send / stop button |
@@ -0,0 +1,75 @@
1
+ # u-question-intent
2
+
3
+ ```ts
4
+ import '@iyulab/chat-components/dist/components/intents/UQuestionIntent.js';
5
+ ```
6
+
7
+ **Tag:** `u-question-intent`
8
+
9
+ Renders a question with clickable choice buttons generated by the LLM. Fires a `choice` event when the user selects an option.
10
+
11
+ `u-marked-block` strips `intent-json` code blocks from the rendered output, so you must parse them manually using `IntentPromptBuilder` and create this component yourself.
12
+
13
+ ```html
14
+ <!-- Basic usage -->
15
+ <u-question-intent
16
+ question="What topic are you interested in?"
17
+ .choices=${["Artificial Intelligence", "Blockchain", "Cloud Computing"]}
18
+ ></u-question-intent>
19
+
20
+ <!-- Choices only, no question text -->
21
+ <u-question-intent
22
+ .choices=${["Yes, continue", "No, stop"]}
23
+ ></u-question-intent>
24
+ ```
25
+
26
+ ```ts
27
+ const intent = document.querySelector('u-question-intent');
28
+
29
+ intent.addEventListener('choice', (e) => {
30
+ const { value } = e.detail; // selected choice text
31
+ console.log('Selected:', value);
32
+
33
+ // Auto-fill and submit the prompt
34
+ prompt.value = value;
35
+ prompt.submit();
36
+ });
37
+ ```
38
+
39
+ Parsing from an LLM response with `IntentPromptBuilder`:
40
+
41
+ ```ts
42
+ import { IntentPromptBuilder, PresetIntent } from '@iyulab/chat-components';
43
+
44
+ // Setup
45
+ IntentPromptBuilder.instance.use(PresetIntent.Questions);
46
+
47
+ // Parse LLM response
48
+ const [cleanText, intents] = IntentPromptBuilder.instance.parse(llmResponse);
49
+
50
+ for (const intent of intents) {
51
+ if (intent.type === 'question') {
52
+ const el = document.createElement('u-question-intent');
53
+ el.question = intent.properties?.question;
54
+ el.choices = intent.properties?.choices ?? [];
55
+ messageContainer.appendChild(el);
56
+ }
57
+ }
58
+
59
+ markedBlock.value = cleanText;
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Properties
65
+
66
+ | Property | Type | Default | Description |
67
+ |----------|------|---------|-------------|
68
+ | `question` | `string` | `undefined` | Question text shown above choices. Hidden if not set |
69
+ | `choices` | `string[]` | `[]` | Clickable choices (1–5 recommended). Renders nothing if empty |
70
+
71
+ ## Events
72
+
73
+ | Event | Detail | Description |
74
+ |-------|--------|-------------|
75
+ | `choice` | `{ value: string }` | Fired when a choice button is clicked |
@@ -0,0 +1,45 @@
1
+ # u-ref-block
2
+
3
+ ```ts
4
+ import '@iyulab/chat-components/dist/components/blocks/URefBlock.js';
5
+ ```
6
+
7
+ **Tag:** `u-ref-block`
8
+
9
+ Displays a group of reference sources as a collapsible block with a `u-ref-card` grid layout.
10
+
11
+ ```html
12
+ <!-- Basic usage -->
13
+ <u-ref-block
14
+ title="References"
15
+ .sources=${[
16
+ { type: 'web', url: 'https://example.com', title: 'Example Page', snippet: 'Summary...' },
17
+ { type: 'document', title: 'Internal Report', snippet: 'Excerpt...', tags: ['report'] }
18
+ ]}
19
+ ></u-ref-block>
20
+
21
+ <!-- Expanded by default -->
22
+ <u-ref-block .collapsed=${false} .sources=${sources}></u-ref-block>
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Properties
28
+
29
+ | Property | Type | Default | Reflect | Description |
30
+ |----------|------|---------|---------|-------------|
31
+ | `title` | `string` | `''` | — | Header title (falls back to 'References') |
32
+ | `collapsed` | `boolean` | `true` | ✓ | Collapsed state. Toggle by clicking the header |
33
+ | `sources` | `ReferenceSource[]` | `undefined` | — | List of reference sources |
34
+
35
+ ## ReferenceSource Type
36
+
37
+ ```ts
38
+ interface ReferenceSource {
39
+ type: 'web' | 'document';
40
+ url?: string; // Link URL
41
+ title?: string; // Card title
42
+ snippet?: string; // Excerpt text
43
+ tags?: string[]; // Tag list
44
+ }
45
+ ```
@@ -0,0 +1,41 @@
1
+ # u-ref-card-group
2
+
3
+ ```ts
4
+ import '@iyulab/chat-components/dist/components/references/URefCardGroup.js';
5
+ ```
6
+
7
+ **Tag:** `u-ref-card-group`
8
+
9
+ Groups multiple `u-ref-card` elements into a paginated slider. Previous/next navigation and a page indicator appear automatically when there are 2 or more cards.
10
+
11
+ Used automatically by `u-marked-block` when processing citation data.
12
+
13
+ ```html
14
+ <u-ref-card-group>
15
+ <u-ref-card type="web" url="https://example.com/1" title="First Source"></u-ref-card>
16
+ <u-ref-card type="web" url="https://example.com/2" title="Second Source"></u-ref-card>
17
+ <u-ref-card type="document" title="Internal Doc"></u-ref-card>
18
+ </u-ref-card-group>
19
+ ```
20
+
21
+ ```ts
22
+ const group = document.querySelector('u-ref-card-group');
23
+
24
+ // Navigate to a specific card
25
+ group.switch(1); // go to second card
26
+ group.switch(-1); // wraps to last card
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Slots
32
+
33
+ | Name | Description |
34
+ |------|-------------|
35
+ | *(default)* | `u-ref-card` elements |
36
+
37
+ ## Methods
38
+
39
+ | Method | Description |
40
+ |--------|-------------|
41
+ | `switch(index)` | Navigate to the card at `index`. Wraps around on out-of-bounds values |
@@ -0,0 +1,48 @@
1
+ # u-ref-card
2
+
3
+ ```ts
4
+ import '@iyulab/chat-components/dist/components/references/URefCard.js';
5
+ ```
6
+
7
+ **Tag:** `u-ref-card`
8
+
9
+ Displays a single reference source as a card. Supports `web` and `document` types. For web sources, automatically fetches a favicon via the Google Favicon API.
10
+
11
+ Extends `UDataElement`, so data can also be injected via a `<script type="application/json">` slot.
12
+
13
+ ```html
14
+ <!-- Web source -->
15
+ <u-ref-card
16
+ type="web"
17
+ url="https://example.com/article"
18
+ title="Article Title"
19
+ snippet="Short content summary..."
20
+ .tags=${["tech", "AI"]}
21
+ ></u-ref-card>
22
+
23
+ <!-- Document source -->
24
+ <u-ref-card
25
+ type="document"
26
+ title="Internal Document"
27
+ snippet="Document excerpt..."
28
+ ></u-ref-card>
29
+
30
+ <!-- JSON slot injection -->
31
+ <u-ref-card>
32
+ <script type="application/json">
33
+ { "type": "web", "url": "https://example.com", "title": "Example", "snippet": "Description" }
34
+ </script>
35
+ </u-ref-card>
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Properties
41
+
42
+ | Property | Type | Default | Reflect | Description |
43
+ |----------|------|---------|---------|-------------|
44
+ | `type` | `'web'\|'document'` | `'web'` | ✓ | Card type. Determines badge icon |
45
+ | `url` | `string` | `undefined` | — | External link URL. Click is suppressed if not set |
46
+ | `title` | `string` | `''` | — | Card title (falls back to domain name for web type) |
47
+ | `snippet` | `string` | `undefined` | — | Excerpt text |
48
+ | `tags` | `string[]` | `undefined` | — | Tag list. Pass as JSON array string via HTML attribute |
@@ -0,0 +1,40 @@
1
+ # u-ref-tag
2
+
3
+ ```ts
4
+ import '@iyulab/chat-components/dist/components/references/URefTag.js';
5
+ ```
6
+
7
+ **Tag:** `u-ref-tag`
8
+
9
+ Inline citation tag inserted within markdown body text. Opens an external link on click and shows source details in a tooltip.
10
+
11
+ Typically inserted automatically by `u-marked-block` when `refs` data is provided.
12
+
13
+ ```html
14
+ <!-- Inline citation -->
15
+ <u-ref-tag href="https://example.com">
16
+ [1]
17
+ <div slot="tooltip">Example Domain — source description...</div>
18
+ </u-ref-tag>
19
+
20
+ <!-- No href (local document) -->
21
+ <u-ref-tag>
22
+ [2]
23
+ <div slot="tooltip">Internal document title</div>
24
+ </u-ref-tag>
25
+ ```
26
+
27
+ ---
28
+
29
+ ## Slots
30
+
31
+ | Name | Description |
32
+ |------|-------------|
33
+ | *(default)* | Citation label text (e.g. `[1]`, `(Smith, 2023)`) |
34
+ | `tooltip` | Tooltip content (source details) |
35
+
36
+ ## Properties
37
+
38
+ | Property | Type | Default | Description |
39
+ |----------|------|---------|-------------|
40
+ | `href` | `string` | `undefined` | External link URL. Click is suppressed if not set |
@@ -0,0 +1,63 @@
1
+ # u-table-block
2
+
3
+ ```ts
4
+ import '@iyulab/chat-components/dist/components/blocks/UTableBlock.js';
5
+ ```
6
+
7
+ **Tag:** `u-table-block`
8
+
9
+ Renders tabular data with column sorting, search filtering, and CSV/XLS download. Automatically rendered inside `u-marked-block` for markdown tables.
10
+
11
+ Extends `UDataElement`, so data can also be injected via a `<script type="application/json">` slot.
12
+
13
+ ```html
14
+ <!-- Direct data binding -->
15
+ <u-table-block
16
+ .headers=${[
17
+ { text: 'Name', align: 'left' },
18
+ { text: 'Age', align: 'center' },
19
+ { text: 'Score', align: 'right' }
20
+ ]}
21
+ .rows=${[
22
+ [{ text: 'Alice', align: 'left' }, { text: '30', align: 'center' }, { text: '95', align: 'right' }],
23
+ [{ text: 'Bob', align: 'left' }, { text: '25', align: 'center' }, { text: '88', align: 'right' }]
24
+ ]}
25
+ ></u-table-block>
26
+
27
+ <!-- JSON slot injection -->
28
+ <u-table-block>
29
+ <script type="application/json">
30
+ {
31
+ "headers": [{ "text": "Name", "align": "left" }],
32
+ "rows": [[{ "text": "Alice", "align": "left" }]]
33
+ }
34
+ </script>
35
+ </u-table-block>
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Properties
41
+
42
+ | Property | Type | Default | Description |
43
+ |----------|------|---------|-------------|
44
+ | `headers` | `TableCell[]` | `[]` | Header cells, each with `text` and `align` |
45
+ | `rows` | `TableCell[][]` | `[]` | Row data; each row is an array of `TableCell` |
46
+
47
+ ## TableCell Type
48
+
49
+ ```ts
50
+ interface TableCell {
51
+ text: string;
52
+ align: 'left' | 'center' | 'right' | null;
53
+ }
54
+ ```
55
+
56
+ ## Features
57
+
58
+ | Feature | Description |
59
+ |---------|-------------|
60
+ | Column sort | Click a header to sort asc/desc |
61
+ | Search filter | Search bar filters rows (debounced) |
62
+ | CSV download | Downloads current filtered/sorted data as CSV |
63
+ | XLS download | Downloads as Excel file |
@@ -0,0 +1,59 @@
1
+ # u-text-block
2
+
3
+ ```ts
4
+ import '@iyulab/chat-components/dist/components/blocks/UTextBlock.js';
5
+ ```
6
+
7
+ **Tag:** `u-text-block`
8
+
9
+ Displays plain text or acts as an editable textarea. Used inside `u-prompt` as the input area.
10
+
11
+ ```html
12
+ <!-- Read-only text display -->
13
+ <u-text-block .value=${"Hello!"}></u-text-block>
14
+
15
+ <!-- Editable textarea -->
16
+ <u-text-block
17
+ editable
18
+ placeholder="Type a message..."
19
+ .minRows=${3}
20
+ .maxRows=${10}
21
+ .value=${inputValue}
22
+ @input=${handleInput}
23
+ ></u-text-block>
24
+ ```
25
+
26
+ ```ts
27
+ const block = document.querySelector('u-text-block');
28
+
29
+ block.addEventListener('input', () => {
30
+ console.log(block.value);
31
+ });
32
+
33
+ block.focus();
34
+ ```
35
+
36
+ ---
37
+
38
+ ## Properties
39
+
40
+ | Property | Type | Default | Reflect | Description |
41
+ |----------|------|---------|---------|-------------|
42
+ | `value` | `string` | `undefined` | — | Text content |
43
+ | `editable` | `boolean` | `false` | ✓ | Enables the textarea and focuses it on activation |
44
+ | `placeholder` | `string` | `undefined` | — | Placeholder shown in edit mode |
45
+ | `minRows` | `number` | `1` | — | Minimum visible rows |
46
+ | `maxRows` | `number` | `undefined` | — | Maximum rows before scrolling |
47
+ | `spellcheck` | `boolean` | `false` | — | Enables browser spell-check |
48
+
49
+ ## Methods
50
+
51
+ | Method | Description |
52
+ |--------|-------------|
53
+ | `focus(options?)` | Focuses the inner textarea |
54
+
55
+ ## Events
56
+
57
+ | Event | Description |
58
+ |-------|-------------|
59
+ | `input` | Fired on text change (re-dispatches the original `InputEvent`) |
@@ -0,0 +1,48 @@
1
+ # u-think-block
2
+
3
+ ```ts
4
+ import '@iyulab/chat-components/dist/components/blocks/UThinkBlock.js';
5
+ ```
6
+
7
+ **Tag:** `u-think-block`
8
+
9
+ Displays LLM reasoning (thinking) content. Shows "Thinking..." while loading and switches to "Thought" on completion. Content can be collapsed or expanded via a header click.
10
+
11
+ ```html
12
+ <!-- Reasoning in progress -->
13
+ <u-think-block loading .value=${"Analyzing..."}></u-think-block>
14
+
15
+ <!-- Completed (default: collapsed) -->
16
+ <u-think-block .value=${"Full reasoning content here."}></u-think-block>
17
+
18
+ <!-- Expanded with auto-scroll during streaming -->
19
+ <u-think-block
20
+ auto-scroll
21
+ .collapsed=${false}
22
+ .value=${streamingThought}
23
+ ></u-think-block>
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Properties
29
+
30
+ | Property | Type | Default | Reflect | Description |
31
+ |----------|------|---------|---------|-------------|
32
+ | `value` | `string` | `undefined` | — | Reasoning text (rendered as markdown) |
33
+ | `loading` | `boolean` | `false` | ✓ | Loading state. Shows spinner, displays "Thinking..." label |
34
+ | `collapsed` | `boolean` | `true` | ✓ | Collapsed state. Toggle by clicking the header |
35
+ | `autoScroll` | `boolean` | `false` | — | (`auto-scroll`) Scrolls to bottom on each `value` update. Disables on user scroll interaction |
36
+
37
+ ## Methods
38
+
39
+ | Method | Returns | Description |
40
+ |--------|---------|-------------|
41
+ | `scrollToBottom()` | `boolean` | Smoothly scrolls the body to the bottom. Returns `true` if body element exists |
42
+
43
+ ## CSS Parts
44
+
45
+ | Part | Description |
46
+ |------|-------------|
47
+ | `header` | Header row (icon + title + collapse toggle) |
48
+ | `body` | Scrollable content area |
@@ -0,0 +1,57 @@
1
+ # u-tool-block
2
+
3
+ ```ts
4
+ import '@iyulab/chat-components/dist/components/blocks/UToolBlock.js';
5
+ ```
6
+
7
+ **Tag:** `u-tool-block`
8
+
9
+ Displays a tool call's input and output as collapsible JSON trees. Used to show LLM tool usage inline in a message.
10
+
11
+ ```html
12
+ <!-- Tool call in progress -->
13
+ <u-tool-block loading title="search_web"></u-tool-block>
14
+
15
+ <!-- Completed tool call -->
16
+ <u-tool-block
17
+ title="search_web"
18
+ .input=${{ query: "weather today" }}
19
+ .output=${{ results: ["Sunny, 25°C"] }}
20
+ ></u-tool-block>
21
+
22
+ <!-- Expanded by default -->
23
+ <u-tool-block
24
+ title="code_execution"
25
+ .collapsed=${false}
26
+ .input=${{ code: "print('hello')" }}
27
+ .output=${{ stdout: "hello\n" }}
28
+ ></u-tool-block>
29
+ ```
30
+
31
+ Pass JSON via HTML attribute (uses `jsonAttrConverter`):
32
+
33
+ ```html
34
+ <u-tool-block
35
+ title="calculator"
36
+ input='{"expression": "2 + 2"}'
37
+ output='{"result": 4}'
38
+ ></u-tool-block>
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Properties
44
+
45
+ | Property | Type | Default | Reflect | Description |
46
+ |----------|------|---------|---------|-------------|
47
+ | `title` | `string` | `''` | — | Tool name shown in the header (falls back to 'Tool Usage') |
48
+ | `loading` | `boolean` | `false` | ✓ | Loading state. Shows spinner in header |
49
+ | `collapsed` | `boolean` | `true` | ✓ | Collapsed state. Toggle by clicking the header |
50
+ | `input` | `JsonNode` | `undefined` | — | Tool input JSON |
51
+ | `output` | `JsonNode` | `undefined` | — | Tool output JSON |
52
+
53
+ ## CSS Parts
54
+
55
+ | Part | Description |
56
+ |------|-------------|
57
+ | `body` | Input / output display area |
@@ -0,0 +1,55 @@
1
+ # u-video-view
2
+
3
+ ```ts
4
+ import '@iyulab/chat-components/dist/components/views/UVideoView.js';
5
+ ```
6
+
7
+ **Tag:** `u-video-view`
8
+
9
+ Embeds a video from YouTube, Vimeo, or a direct file URL. Automatically detects the platform from the URL and selects the appropriate player.
10
+
11
+ ```html
12
+ <!-- YouTube -->
13
+ <u-video-view src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"></u-video-view>
14
+
15
+ <!-- Vimeo -->
16
+ <u-video-view src="https://vimeo.com/123456789"></u-video-view>
17
+
18
+ <!-- Direct video file -->
19
+ <u-video-view
20
+ src="https://example.com/video.mp4"
21
+ poster="https://example.com/thumbnail.jpg"
22
+ ratio="4:3"
23
+ ></u-video-view>
24
+ ```
25
+
26
+ LLM output example (`view-json` code block):
27
+
28
+ ````
29
+ ```view-json
30
+ {
31
+ "tag": "u-video-view",
32
+ "properties": {
33
+ "src": "https://www.youtube.com/watch?v=VIDEO_ID"
34
+ }
35
+ }
36
+ ```
37
+ ````
38
+
39
+ ---
40
+
41
+ ## Properties
42
+
43
+ | Property | Type | Default | Description |
44
+ |----------|------|---------|-------------|
45
+ | `src` | `string` | `undefined` | Video URL: YouTube, Vimeo, or direct file |
46
+ | `poster` | `string` | `undefined` | Poster image URL for direct video files |
47
+ | `ratio` | `'16:9'\|'4:3'\|'1:1'` | `'16:9'` | Aspect ratio |
48
+
49
+ ## Supported Platforms
50
+
51
+ | Platform | URL Pattern | Embed Method |
52
+ |----------|-------------|--------------|
53
+ | YouTube | `youtube.com`, `youtu.be` | `youtube.com/embed/{id}` iframe |
54
+ | Vimeo | `vimeo.com` | `player.vimeo.com/video/{id}` iframe |
55
+ | Other | any URL | Native `<video>` element |
@@ -0,0 +1,51 @@
1
+ # u-view
2
+
3
+ ```ts
4
+ import '@iyulab/chat-components/dist/components/views/UView.js';
5
+ ```
6
+
7
+ **Tag:** `u-view`
8
+
9
+ Dynamic custom element renderer. Creates the element specified by `tag`, binds `properties` to it, and handles loading and error states. Used internally by `u-marked-block` to render `view-json` code blocks.
10
+
11
+ ```html
12
+ <!-- Render u-chart-view dynamically -->
13
+ <u-view
14
+ tag="u-chart-view"
15
+ .properties=${{
16
+ type: 'bar',
17
+ data: { labels: ['A', 'B'], datasets: [{ data: [10, 20] }] }
18
+ }}
19
+ ></u-view>
20
+
21
+ <!-- Loading state (skeleton placeholder) -->
22
+ <u-view tag="u-chart-view" loading></u-view>
23
+ ```
24
+
25
+ How `u-marked-block` processes a `view-json` block:
26
+
27
+ ````
28
+ ```view-json
29
+ {
30
+ "tag": "u-images-view",
31
+ "properties": { "items": [{ "src": "https://..." }] }
32
+ }
33
+ ```
34
+ ````
35
+
36
+ This is converted to `<u-view tag="u-images-view" ...>` via `UView.buildHTML()`.
37
+
38
+ ---
39
+
40
+ ## Properties
41
+
42
+ | Property | Type | Default | Reflect | Description |
43
+ |----------|------|---------|---------|-------------|
44
+ | `tag` | `string` | `undefined` | — | Custom element tag to render. Must already be registered |
45
+ | `properties` | `Record<string, unknown>` | `undefined` | — | Properties to bind to the rendered element |
46
+ | `loading` | `boolean` | `false` | ✓ | Shows a skeleton placeholder instead of the element |
47
+ | `blacklist` | `string[]` | `['innerHTML', 'outerHTML', ...]` | — | Property names blocked from binding for XSS prevention |
48
+
49
+ ## Security
50
+
51
+ The following property names are blocked by default to prevent XSS: `innerHTML`, `outerHTML`, `textContent`, `innerText`, `outerText`, `srcdoc`. Extend `blacklist` to add more restrictions.