@kitnai/chat 0.6.0 → 0.7.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/dist/custom-elements.json +125 -73
- package/dist/kitn-chat.es.js +1 -1
- package/dist/llms/llms-full.txt +24 -24
- package/frameworks/react/index.tsx +46 -24
- package/llms-full.txt +24 -24
- package/package.json +1 -1
- package/src/elements/chat-workspace.tsx +28 -2
- package/src/elements/chat.tsx +22 -1
- package/src/elements/compiled.css +1 -1
- package/src/elements/conversation-list.tsx +10 -1
- package/src/elements/element-meta.json +2003 -0
- package/src/elements/kitn-attachments.stories.tsx +9 -0
- package/src/elements/kitn-chain-of-thought.stories.tsx +9 -0
- package/src/elements/kitn-chat-scope-picker.stories.tsx +9 -0
- package/src/elements/kitn-chat-workspace.stories.tsx +64 -14
- package/src/elements/kitn-chat.stories.tsx +58 -5
- package/src/elements/kitn-checkpoint.stories.tsx +9 -0
- package/src/elements/kitn-code-block.stories.tsx +9 -0
- package/src/elements/kitn-context-meter.stories.tsx +9 -0
- package/src/elements/kitn-conversation-list.stories.tsx +31 -10
- package/src/elements/kitn-empty.stories.tsx +9 -0
- package/src/elements/kitn-feedback-bar.stories.tsx +9 -0
- package/src/elements/kitn-file-upload.stories.tsx +9 -0
- package/src/elements/kitn-image.stories.tsx +9 -0
- package/src/elements/kitn-loader.stories.tsx +9 -0
- package/src/elements/kitn-markdown.stories.tsx +9 -0
- package/src/elements/kitn-message-skills.stories.tsx +9 -0
- package/src/elements/kitn-message.stories.tsx +9 -0
- package/src/elements/kitn-model-switcher.stories.tsx +9 -0
- package/src/elements/kitn-prompt-input.stories.tsx +35 -5
- package/src/elements/kitn-prompt-suggestions.stories.tsx +9 -0
- package/src/elements/kitn-reasoning.stories.tsx +9 -0
- package/src/elements/kitn-response-stream.stories.tsx +9 -0
- package/src/elements/kitn-source-list.stories.tsx +9 -0
- package/src/elements/kitn-source.stories.tsx +9 -0
- package/src/elements/kitn-text-shimmer.stories.tsx +9 -0
- package/src/elements/kitn-thinking-bar.stories.tsx +9 -0
- package/src/elements/kitn-tool.stories.tsx +9 -0
- package/src/elements/kitn-voice-input.stories.tsx +9 -0
- package/src/elements/prompt-input.tsx +2 -2
- package/src/stories/docs/element-controls.ts +28 -0
- package/src/stories/docs/element-spec.tsx +86 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
2
2
|
import { onMount } from 'solid-js';
|
|
3
3
|
import './register'; // side effect: registers the custom elements
|
|
4
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
5
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
4
6
|
|
|
5
7
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
6
8
|
declare module 'solid-js' {
|
|
@@ -49,6 +51,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
|
49
51
|
const meta = {
|
|
50
52
|
title: 'Web Components/kitn-message-skills',
|
|
51
53
|
tags: ['autodocs'],
|
|
54
|
+
argTypes: argTypesFor('kitn-message-skills'),
|
|
52
55
|
parameters: {
|
|
53
56
|
layout: 'fullscreen',
|
|
54
57
|
docs: {
|
|
@@ -67,6 +70,12 @@ const meta = {
|
|
|
67
70
|
export default meta;
|
|
68
71
|
type Story = StoryObj;
|
|
69
72
|
|
|
73
|
+
/** Full generated API reference — properties, events, tokens, and composed-from. */
|
|
74
|
+
export const API: Story = {
|
|
75
|
+
render: () => <ElementSpec tag="kitn-message-skills" />,
|
|
76
|
+
parameters: { layout: 'padded' },
|
|
77
|
+
};
|
|
78
|
+
|
|
70
79
|
/** Two active-skill badges. */
|
|
71
80
|
export const Default: Story = {
|
|
72
81
|
render: () => <MessageSkillsElement skills={sampleSkills} />,
|
|
@@ -2,6 +2,8 @@ import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
|
2
2
|
import { onMount } from 'solid-js';
|
|
3
3
|
import './register'; // side effect: registers the custom elements
|
|
4
4
|
import type { ChatMessage } from './chat-types';
|
|
5
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
6
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
5
7
|
|
|
6
8
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
7
9
|
declare module 'solid-js' {
|
|
@@ -75,6 +77,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
|
75
77
|
const meta = {
|
|
76
78
|
title: 'Web Components/kitn-message',
|
|
77
79
|
tags: ['autodocs'],
|
|
80
|
+
argTypes: argTypesFor('kitn-message'),
|
|
78
81
|
parameters: {
|
|
79
82
|
layout: 'fullscreen',
|
|
80
83
|
docs: {
|
|
@@ -93,6 +96,12 @@ const meta = {
|
|
|
93
96
|
export default meta;
|
|
94
97
|
type Story = StoryObj;
|
|
95
98
|
|
|
99
|
+
/** Full generated API reference — properties, events, tokens, and composed-from. */
|
|
100
|
+
export const API: Story = {
|
|
101
|
+
render: () => <ElementSpec tag="kitn-message" />,
|
|
102
|
+
parameters: { layout: 'padded' },
|
|
103
|
+
};
|
|
104
|
+
|
|
96
105
|
/** A rich assistant message: markdown, reasoning, a tool call, an attachment, and actions. */
|
|
97
106
|
export const Assistant: Story = {
|
|
98
107
|
render: () => <MessageElement message={assistantMessage} />,
|
|
@@ -2,6 +2,8 @@ import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
|
2
2
|
import { onMount } from 'solid-js';
|
|
3
3
|
import './register'; // side effect: registers the custom elements
|
|
4
4
|
import type { ModelOption } from '../types';
|
|
5
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
6
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
5
7
|
|
|
6
8
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
7
9
|
declare module 'solid-js' {
|
|
@@ -55,6 +57,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
|
55
57
|
const meta = {
|
|
56
58
|
title: 'Web Components/kitn-model-switcher',
|
|
57
59
|
tags: ['autodocs'],
|
|
60
|
+
argTypes: argTypesFor('kitn-model-switcher'),
|
|
58
61
|
parameters: {
|
|
59
62
|
layout: 'fullscreen',
|
|
60
63
|
docs: {
|
|
@@ -73,6 +76,12 @@ const meta = {
|
|
|
73
76
|
export default meta;
|
|
74
77
|
type Story = StoryObj;
|
|
75
78
|
|
|
79
|
+
/** Full generated API reference — properties, events, tokens, and composed-from. */
|
|
80
|
+
export const API: Story = {
|
|
81
|
+
render: () => <ElementSpec tag="kitn-model-switcher" />,
|
|
82
|
+
parameters: { layout: 'padded' },
|
|
83
|
+
};
|
|
84
|
+
|
|
76
85
|
/** A three-model picker; selecting updates the trigger label. */
|
|
77
86
|
export const Default: Story = {
|
|
78
87
|
render: () => <SwitcherElement models={models} current="opus" />,
|
|
@@ -2,6 +2,8 @@ import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
|
2
2
|
import { onMount } from 'solid-js';
|
|
3
3
|
import './register'; // side effect: registers <kitn-chat>, <kitn-conversation-list>, <kitn-prompt-input>
|
|
4
4
|
import type { AttachmentData } from '../components/attachments';
|
|
5
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
6
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
5
7
|
|
|
6
8
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
7
9
|
declare module 'solid-js' {
|
|
@@ -41,15 +43,27 @@ interface PromptInputEl extends HTMLElement {
|
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
/** Live demo of the actual `<kitn-prompt-input>` custom element (Shadow DOM and all). */
|
|
44
|
-
function PromptInputElement(props
|
|
46
|
+
function PromptInputElement(props: { search?: boolean; voice?: boolean; attachments?: AttachmentData[]; args?: Record<string, unknown> }) {
|
|
45
47
|
let el: PromptInputEl | undefined;
|
|
46
48
|
onMount(() => {
|
|
47
49
|
if (!el) return;
|
|
50
|
+
// Default fixed data
|
|
48
51
|
el.placeholder = 'Ask anything...';
|
|
49
52
|
el.suggestions = sampleSuggestions;
|
|
50
|
-
if (props
|
|
51
|
-
if (props
|
|
52
|
-
if (props
|
|
53
|
+
if (props.search) el.setAttribute('search', '');
|
|
54
|
+
if (props.voice) el.setAttribute('voice', '');
|
|
55
|
+
if (props.attachments) el.attachments = props.attachments;
|
|
56
|
+
// Scalar args from Controls
|
|
57
|
+
const args = props.args;
|
|
58
|
+
if (args) {
|
|
59
|
+
const scalarNames = [
|
|
60
|
+
'value', 'placeholder', 'disabled', 'loading', 'suggestionMode',
|
|
61
|
+
'slashCompact', 'search', 'voice',
|
|
62
|
+
];
|
|
63
|
+
for (const name of scalarNames) {
|
|
64
|
+
if (name in args) (el as unknown as Record<string, unknown>)[name] = args[name];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
53
67
|
el.addEventListener('search', () => console.log('search clicked'));
|
|
54
68
|
el.addEventListener('voice', () => console.log('voice clicked'));
|
|
55
69
|
});
|
|
@@ -108,6 +122,7 @@ function Composer() {
|
|
|
108
122
|
const meta = {
|
|
109
123
|
title: 'Web Components/kitn-prompt-input',
|
|
110
124
|
tags: ['autodocs'],
|
|
125
|
+
argTypes: argTypesFor('kitn-prompt-input'),
|
|
111
126
|
parameters: {
|
|
112
127
|
layout: 'fullscreen',
|
|
113
128
|
docs: {
|
|
@@ -129,7 +144,16 @@ type Story = StoryObj;
|
|
|
129
144
|
|
|
130
145
|
/** The element used the plain-HTML / any-framework way. */
|
|
131
146
|
export const Default: Story = {
|
|
132
|
-
|
|
147
|
+
args: {
|
|
148
|
+
placeholder: 'Send a message...',
|
|
149
|
+
disabled: false,
|
|
150
|
+
loading: false,
|
|
151
|
+
suggestionMode: 'submit',
|
|
152
|
+
slashCompact: false,
|
|
153
|
+
search: false,
|
|
154
|
+
voice: false,
|
|
155
|
+
},
|
|
156
|
+
render: (args: Record<string, unknown>) => <PromptInputElement args={args} />,
|
|
133
157
|
parameters: { docs: { source: { code: HTML_SNIPPET, language: 'html' } } },
|
|
134
158
|
};
|
|
135
159
|
|
|
@@ -179,3 +203,9 @@ export const WithAttachments: Story = {
|
|
|
179
203
|
render: () => <PromptInputElement voice attachments={sampleAttachments} />,
|
|
180
204
|
parameters: { docs: { source: { code: ATTACHMENTS_SNIPPET, language: 'html' } } },
|
|
181
205
|
};
|
|
206
|
+
|
|
207
|
+
/** Full generated API reference — properties, events, tokens, and the SolidJS components this element is composed from. */
|
|
208
|
+
export const API: Story = {
|
|
209
|
+
render: () => <ElementSpec tag="kitn-prompt-input" />,
|
|
210
|
+
parameters: { layout: 'padded' },
|
|
211
|
+
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
2
2
|
import { onMount } from 'solid-js';
|
|
3
3
|
import './register'; // side effect: registers the custom elements
|
|
4
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
5
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
4
6
|
|
|
5
7
|
type Item = string | { label: string; value?: string };
|
|
6
8
|
|
|
@@ -62,6 +64,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
|
62
64
|
const meta = {
|
|
63
65
|
title: 'Web Components/kitn-prompt-suggestions',
|
|
64
66
|
tags: ['autodocs'],
|
|
67
|
+
argTypes: argTypesFor('kitn-prompt-suggestions'),
|
|
65
68
|
parameters: {
|
|
66
69
|
layout: 'fullscreen',
|
|
67
70
|
docs: {
|
|
@@ -80,6 +83,12 @@ const meta = {
|
|
|
80
83
|
export default meta;
|
|
81
84
|
type Story = StoryObj;
|
|
82
85
|
|
|
86
|
+
/** Full generated API reference — properties, events, tokens, and composed-from. */
|
|
87
|
+
export const API: Story = {
|
|
88
|
+
render: () => <ElementSpec tag="kitn-prompt-suggestions" />,
|
|
89
|
+
parameters: { layout: 'padded' },
|
|
90
|
+
};
|
|
91
|
+
|
|
83
92
|
/** Default outline pills, wrapping in a row. */
|
|
84
93
|
export const Default: Story = {
|
|
85
94
|
render: () => <SuggestionsElement suggestions={suggestions} variant="outline" />,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
2
2
|
import { onMount } from 'solid-js';
|
|
3
3
|
import './register'; // side effect: registers the custom elements
|
|
4
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
5
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
4
6
|
|
|
5
7
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
6
8
|
declare module 'solid-js' {
|
|
@@ -46,6 +48,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
|
46
48
|
const meta = {
|
|
47
49
|
title: 'Web Components/kitn-reasoning',
|
|
48
50
|
tags: ['autodocs'],
|
|
51
|
+
argTypes: argTypesFor('kitn-reasoning'),
|
|
49
52
|
parameters: {
|
|
50
53
|
layout: 'fullscreen',
|
|
51
54
|
docs: {
|
|
@@ -64,6 +67,12 @@ const meta = {
|
|
|
64
67
|
export default meta;
|
|
65
68
|
type Story = StoryObj;
|
|
66
69
|
|
|
70
|
+
/** Full generated API reference — properties, events, tokens, and composed-from. */
|
|
71
|
+
export const API: Story = {
|
|
72
|
+
render: () => <ElementSpec tag="kitn-reasoning" />,
|
|
73
|
+
parameters: { layout: 'padded' },
|
|
74
|
+
};
|
|
75
|
+
|
|
67
76
|
/** A collapsed reasoning block (the trigger toggles it). */
|
|
68
77
|
export const Default: Story = {
|
|
69
78
|
render: () => <ReasoningElement text={sampleText} />,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
2
2
|
import { onMount } from 'solid-js';
|
|
3
3
|
import './register'; // side effect: registers the custom elements
|
|
4
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
5
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
4
6
|
|
|
5
7
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
6
8
|
declare module 'solid-js' {
|
|
@@ -49,6 +51,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
|
49
51
|
const meta = {
|
|
50
52
|
title: 'Web Components/kitn-response-stream',
|
|
51
53
|
tags: ['autodocs'],
|
|
54
|
+
argTypes: argTypesFor('kitn-response-stream'),
|
|
52
55
|
parameters: {
|
|
53
56
|
layout: 'fullscreen',
|
|
54
57
|
docs: {
|
|
@@ -67,6 +70,12 @@ const meta = {
|
|
|
67
70
|
export default meta;
|
|
68
71
|
type Story = StoryObj;
|
|
69
72
|
|
|
73
|
+
/** Full generated API reference — properties, events, tokens, and composed-from. */
|
|
74
|
+
export const API: Story = {
|
|
75
|
+
render: () => <ElementSpec tag="kitn-response-stream" />,
|
|
76
|
+
parameters: { layout: 'padded' },
|
|
77
|
+
};
|
|
78
|
+
|
|
70
79
|
/** Typewriter reveal (the default). */
|
|
71
80
|
export const Typewriter: Story = {
|
|
72
81
|
render: () => <StreamElement text={STREAM_TEXT} mode="typewriter" speed={20} />,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
2
2
|
import { onMount } from 'solid-js';
|
|
3
3
|
import './register'; // side effect: registers the custom elements
|
|
4
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
5
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
4
6
|
|
|
5
7
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
6
8
|
declare module 'solid-js' {
|
|
@@ -52,6 +54,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
|
52
54
|
const meta = {
|
|
53
55
|
title: 'Web Components/kitn-source-list',
|
|
54
56
|
tags: ['autodocs'],
|
|
57
|
+
argTypes: argTypesFor('kitn-source-list'),
|
|
55
58
|
parameters: {
|
|
56
59
|
layout: 'fullscreen',
|
|
57
60
|
docs: {
|
|
@@ -70,6 +73,12 @@ const meta = {
|
|
|
70
73
|
export default meta;
|
|
71
74
|
type Story = StoryObj;
|
|
72
75
|
|
|
76
|
+
/** Full generated API reference — properties, events, tokens, and composed-from. */
|
|
77
|
+
export const API: Story = {
|
|
78
|
+
render: () => <ElementSpec tag="kitn-source-list" />,
|
|
79
|
+
parameters: { layout: 'padded' },
|
|
80
|
+
};
|
|
81
|
+
|
|
73
82
|
/** Two citations rendered as a wrapped list with favicons. */
|
|
74
83
|
export const Default: Story = {
|
|
75
84
|
render: () => <SourceListElement />,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
2
2
|
import { onMount } from 'solid-js';
|
|
3
3
|
import './register'; // side effect: registers the custom elements
|
|
4
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
5
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
4
6
|
|
|
5
7
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
6
8
|
declare module 'solid-js' {
|
|
@@ -48,6 +50,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
|
48
50
|
const meta = {
|
|
49
51
|
title: 'Web Components/kitn-source',
|
|
50
52
|
tags: ['autodocs'],
|
|
53
|
+
argTypes: argTypesFor('kitn-source'),
|
|
51
54
|
parameters: {
|
|
52
55
|
layout: 'fullscreen',
|
|
53
56
|
docs: {
|
|
@@ -66,6 +69,12 @@ const meta = {
|
|
|
66
69
|
export default meta;
|
|
67
70
|
type Story = StoryObj;
|
|
68
71
|
|
|
72
|
+
/** Full generated API reference — properties, events, tokens, and composed-from. */
|
|
73
|
+
export const API: Story = {
|
|
74
|
+
render: () => <ElementSpec tag="kitn-source" />,
|
|
75
|
+
parameters: { layout: 'padded' },
|
|
76
|
+
};
|
|
77
|
+
|
|
69
78
|
/** A citation with a custom label, hover headline/description, and favicon. */
|
|
70
79
|
export const Default: Story = {
|
|
71
80
|
render: () => (
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
2
2
|
import './register'; // side effect: registers the custom elements
|
|
3
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
4
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
3
5
|
|
|
4
6
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
5
7
|
declare module 'solid-js' {
|
|
@@ -25,6 +27,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
|
25
27
|
const meta = {
|
|
26
28
|
title: 'Web Components/kitn-text-shimmer',
|
|
27
29
|
tags: ['autodocs'],
|
|
30
|
+
argTypes: argTypesFor('kitn-text-shimmer'),
|
|
28
31
|
parameters: {
|
|
29
32
|
layout: 'fullscreen',
|
|
30
33
|
docs: {
|
|
@@ -43,6 +46,12 @@ const meta = {
|
|
|
43
46
|
export default meta;
|
|
44
47
|
type Story = StoryObj;
|
|
45
48
|
|
|
49
|
+
/** Full generated API reference — properties, events, tokens, and composed-from. */
|
|
50
|
+
export const API: Story = {
|
|
51
|
+
render: () => <ElementSpec tag="kitn-text-shimmer" />,
|
|
52
|
+
parameters: { layout: 'padded' },
|
|
53
|
+
};
|
|
54
|
+
|
|
46
55
|
/** Default shimmer. */
|
|
47
56
|
export const Default: Story = {
|
|
48
57
|
render: () => (
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
2
2
|
import './register'; // side effect: registers the custom elements
|
|
3
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
4
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
3
5
|
|
|
4
6
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
5
7
|
declare module 'solid-js' {
|
|
@@ -29,6 +31,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
|
29
31
|
const meta = {
|
|
30
32
|
title: 'Web Components/kitn-thinking-bar',
|
|
31
33
|
tags: ['autodocs'],
|
|
34
|
+
argTypes: argTypesFor('kitn-thinking-bar'),
|
|
32
35
|
parameters: {
|
|
33
36
|
layout: 'fullscreen',
|
|
34
37
|
docs: {
|
|
@@ -47,6 +50,12 @@ const meta = {
|
|
|
47
50
|
export default meta;
|
|
48
51
|
type Story = StoryObj;
|
|
49
52
|
|
|
53
|
+
/** Full generated API reference — properties, events, tokens, and composed-from. */
|
|
54
|
+
export const API: Story = {
|
|
55
|
+
render: () => <ElementSpec tag="kitn-thinking-bar" />,
|
|
56
|
+
parameters: { layout: 'padded' },
|
|
57
|
+
};
|
|
58
|
+
|
|
50
59
|
/** A plain thinking indicator. */
|
|
51
60
|
export const Default: Story = {
|
|
52
61
|
render: () => (
|
|
@@ -2,6 +2,8 @@ import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
|
2
2
|
import { onMount } from 'solid-js';
|
|
3
3
|
import './register'; // side effect: registers the custom elements
|
|
4
4
|
import type { ToolPart } from '../components/tool';
|
|
5
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
6
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
5
7
|
|
|
6
8
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
7
9
|
declare module 'solid-js' {
|
|
@@ -58,6 +60,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
|
58
60
|
const meta = {
|
|
59
61
|
title: 'Web Components/kitn-tool',
|
|
60
62
|
tags: ['autodocs'],
|
|
63
|
+
argTypes: argTypesFor('kitn-tool'),
|
|
61
64
|
parameters: {
|
|
62
65
|
layout: 'fullscreen',
|
|
63
66
|
docs: {
|
|
@@ -76,6 +79,12 @@ const meta = {
|
|
|
76
79
|
export default meta;
|
|
77
80
|
type Story = StoryObj;
|
|
78
81
|
|
|
82
|
+
/** Full generated API reference — properties, events, tokens, and composed-from. */
|
|
83
|
+
export const API: Story = {
|
|
84
|
+
render: () => <ElementSpec tag="kitn-tool" />,
|
|
85
|
+
parameters: { layout: 'padded' },
|
|
86
|
+
};
|
|
87
|
+
|
|
79
88
|
/** A completed call with input and output, started expanded. */
|
|
80
89
|
export const Completed: Story = {
|
|
81
90
|
render: () => <ToolElement tool={completedTool} open />,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
2
2
|
import { onMount } from 'solid-js';
|
|
3
3
|
import './register'; // side effect: registers the custom elements
|
|
4
|
+
import { ElementSpec } from '../stories/docs/element-spec';
|
|
5
|
+
import { argTypesFor } from '../stories/docs/element-controls';
|
|
4
6
|
|
|
5
7
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
6
8
|
declare module 'solid-js' {
|
|
@@ -57,6 +59,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
|
57
59
|
const meta = {
|
|
58
60
|
title: 'Web Components/kitn-voice-input',
|
|
59
61
|
tags: ['autodocs'],
|
|
62
|
+
argTypes: argTypesFor('kitn-voice-input'),
|
|
60
63
|
parameters: {
|
|
61
64
|
layout: 'fullscreen',
|
|
62
65
|
docs: {
|
|
@@ -75,6 +78,12 @@ const meta = {
|
|
|
75
78
|
export default meta;
|
|
76
79
|
type Story = StoryObj;
|
|
77
80
|
|
|
81
|
+
/** Full generated API reference — properties, events, tokens, and composed-from. */
|
|
82
|
+
export const API: Story = {
|
|
83
|
+
render: () => <ElementSpec tag="kitn-voice-input" />,
|
|
84
|
+
parameters: { layout: 'padded' },
|
|
85
|
+
};
|
|
86
|
+
|
|
78
87
|
/** A working mic button wired to a stub transcriber. */
|
|
79
88
|
export const Default: Story = {
|
|
80
89
|
render: () => <VoiceElement />,
|
|
@@ -51,9 +51,9 @@ interface Events {
|
|
|
51
51
|
/** A slash command was chosen from the palette. */
|
|
52
52
|
slashselect: { command: SlashCommandItem };
|
|
53
53
|
/** The Search (Globe) toolbar button was clicked. */
|
|
54
|
-
search:
|
|
54
|
+
search: Record<string, never>;
|
|
55
55
|
/** The Voice (Mic) toolbar button was clicked. */
|
|
56
|
-
voice:
|
|
56
|
+
voice: Record<string, never>;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
defineKitnElement<Props, Events>('kitn-prompt-input', {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import meta from '../../elements/element-meta.json';
|
|
2
|
+
|
|
3
|
+
type Prop = { name: string; type: string; default?: string; scalar: boolean };
|
|
4
|
+
type ElementMeta = { tag: string; props: Prop[] };
|
|
5
|
+
const all = meta as unknown as ElementMeta[];
|
|
6
|
+
|
|
7
|
+
const enumValues = (type: string): string[] | null => {
|
|
8
|
+
// string-literal unions like "'light' | 'dark' | 'auto'"
|
|
9
|
+
const parts = type.split('|').map((s) => s.trim());
|
|
10
|
+
if (parts.length > 1 && parts.every((p) => /^'[^']*'$/.test(p))) return parts.map((p) => p.slice(1, -1));
|
|
11
|
+
return null;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/** Storybook argTypes for an element's scalar props (theme select, booleans, text, number). */
|
|
15
|
+
export function argTypesFor(tag: string): Record<string, unknown> {
|
|
16
|
+
const el = all.find((e) => e.tag === tag);
|
|
17
|
+
if (!el) return {};
|
|
18
|
+
const out: Record<string, unknown> = {};
|
|
19
|
+
for (const p of el.props) {
|
|
20
|
+
if (!p.scalar) continue;
|
|
21
|
+
const values = enumValues(p.type);
|
|
22
|
+
if (values) out[p.name] = { control: 'select', options: values };
|
|
23
|
+
else if (/boolean/.test(p.type)) out[p.name] = { control: 'boolean' };
|
|
24
|
+
else if (/number/.test(p.type)) out[p.name] = { control: 'number' };
|
|
25
|
+
else out[p.name] = { control: 'text' };
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { For, Show } from 'solid-js';
|
|
2
|
+
import meta from '../../elements/element-meta.json';
|
|
3
|
+
|
|
4
|
+
type Prop = { name: string; type: string; default?: string; scalar: boolean; description: string };
|
|
5
|
+
type Event = { name: string; detail: string | null; description: string };
|
|
6
|
+
type Composed = { name: string; group: string; storyId?: string };
|
|
7
|
+
type ElementMeta = { tag: string; className: string; props: Prop[]; events: Event[]; composedFrom: Composed[]; tokens: string[] };
|
|
8
|
+
|
|
9
|
+
const all = meta as unknown as ElementMeta[];
|
|
10
|
+
|
|
11
|
+
const th = 'text-left font-semibold px-2 py-1.5 border-b border-border text-foreground';
|
|
12
|
+
const td = 'px-2 py-1.5 border-b border-border align-top text-muted-foreground';
|
|
13
|
+
const code = 'font-mono text-[0.85em] text-code-foreground';
|
|
14
|
+
|
|
15
|
+
export function ElementSpec(props: { tag: string }) {
|
|
16
|
+
const el = () => all.find((e) => e.tag === props.tag);
|
|
17
|
+
return (
|
|
18
|
+
<Show when={el()} fallback={<p>Unknown element: {props.tag}</p>}>
|
|
19
|
+
{(e) => (
|
|
20
|
+
<div class="text-sm space-y-6">
|
|
21
|
+
<section>
|
|
22
|
+
<h3 class="text-title font-semibold text-foreground mb-2">Properties</h3>
|
|
23
|
+
<table class="w-full border-collapse">
|
|
24
|
+
<thead><tr><th class={th}>Property</th><th class={th}>Attribute</th><th class={th}>Type / values</th><th class={th}>Default</th></tr></thead>
|
|
25
|
+
<tbody>
|
|
26
|
+
<For each={e().props}>{(p) => (
|
|
27
|
+
<tr>
|
|
28
|
+
<td class={td}><span class={code}>{p.name}</span></td>
|
|
29
|
+
<td class={td}>{p.scalar ? <span class={code}>{kebab(p.name)}</span> : <span class="opacity-50">— (property only)</span>}</td>
|
|
30
|
+
<td class={td}><span class={code}>{p.type}</span></td>
|
|
31
|
+
<td class={td}>{p.default ? <span class={code}>{p.default}</span> : '—'}</td>
|
|
32
|
+
</tr>
|
|
33
|
+
)}</For>
|
|
34
|
+
</tbody>
|
|
35
|
+
</table>
|
|
36
|
+
</section>
|
|
37
|
+
|
|
38
|
+
<Show when={e().events.length}>
|
|
39
|
+
<section>
|
|
40
|
+
<h3 class="text-title font-semibold text-foreground mb-2">Events</h3>
|
|
41
|
+
<p class="text-muted-foreground mb-2 text-xs">Non-bubbling <span class={code}>CustomEvent</span>s on the element; the payload is on <span class={code}>event.detail</span>.</p>
|
|
42
|
+
<table class="w-full border-collapse">
|
|
43
|
+
<thead><tr><th class={th}>Event</th><th class={th}>detail</th><th class={th}>Description</th></tr></thead>
|
|
44
|
+
<tbody>
|
|
45
|
+
<For each={e().events}>{(ev) => (
|
|
46
|
+
<tr>
|
|
47
|
+
<td class={td}><span class={code}>{ev.name}</span></td>
|
|
48
|
+
<td class={td}><span class={code}>{detailText(ev.detail)}</span></td>
|
|
49
|
+
<td class={td}>{ev.description}</td>
|
|
50
|
+
</tr>
|
|
51
|
+
)}</For>
|
|
52
|
+
</tbody>
|
|
53
|
+
</table>
|
|
54
|
+
</section>
|
|
55
|
+
</Show>
|
|
56
|
+
|
|
57
|
+
<Show when={e().composedFrom.length}>
|
|
58
|
+
<section>
|
|
59
|
+
<h3 class="text-title font-semibold text-foreground mb-2">Composed from</h3>
|
|
60
|
+
<p class="text-muted-foreground mb-2 text-xs">This element wraps these SolidJS components:</p>
|
|
61
|
+
<div class="flex flex-wrap gap-2">
|
|
62
|
+
<For each={e().composedFrom}>{(c) => (
|
|
63
|
+
<a class="rounded-md bg-muted px-2 py-1 text-xs text-foreground hover:bg-accent no-underline" href={`?path=/docs/${c.storyId}`}>
|
|
64
|
+
{c.group}/{c.name}
|
|
65
|
+
</a>
|
|
66
|
+
)}</For>
|
|
67
|
+
</div>
|
|
68
|
+
</section>
|
|
69
|
+
</Show>
|
|
70
|
+
|
|
71
|
+
<section>
|
|
72
|
+
<h3 class="text-title font-semibold text-foreground mb-2">Theming</h3>
|
|
73
|
+
<p class="text-muted-foreground text-xs">
|
|
74
|
+
Themed by the global design tokens — override any <span class={code}>--color-*</span> token to rebrand (see the <a href="?path=/docs/theming-token-reference--docs" class="text-primary">Token Reference</a>).
|
|
75
|
+
<Show when={e().tokens.length}>{' '}This element also reads:{' '}<For each={e().tokens}>{(t, i) => <><span class={code}>{t}</span>{i() < e().tokens.length - 1 ? ', ' : ''}</>}</For>.</Show>
|
|
76
|
+
</p>
|
|
77
|
+
</section>
|
|
78
|
+
</div>
|
|
79
|
+
)}
|
|
80
|
+
</Show>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function kebab(name: string) { return name.replace(/([A-Z])/g, '-$1').toLowerCase(); }
|
|
85
|
+
// Payloadless events (no detail, or an empty `Record<string, never>`) render as a dash.
|
|
86
|
+
function detailText(detail: string | null) { return !detail || detail === 'Record<string, never>' ? '—' : detail; }
|