@kitnai/chat 0.7.0 → 0.8.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.
Files changed (212) hide show
  1. package/README.md +9 -9
  2. package/dist/custom-elements.json +1626 -883
  3. package/dist/kitn-chat.es.js +36 -36
  4. package/dist/llms/llms-full.txt +303 -142
  5. package/dist/llms/llms.txt +18 -18
  6. package/dist/schemas/card-envelope.schema.json +14 -0
  7. package/dist/schemas/card-event.schema.json +12 -0
  8. package/dist/schemas/confirm.schema.json +65 -0
  9. package/dist/schemas/embed.schema.json +65 -0
  10. package/dist/schemas/form.result.schema.json +7 -0
  11. package/dist/schemas/form.schema.json +33 -0
  12. package/dist/schemas/link.schema.json +56 -0
  13. package/dist/schemas/task-list.result.schema.json +16 -0
  14. package/dist/schemas/task-list.schema.json +78 -0
  15. package/dist/theme.tokens.css +65 -65
  16. package/dist/tsx-B8rCNbgL.js +1 -0
  17. package/dist/typescript-RycA9KXf.js +1 -0
  18. package/frameworks/react/index.tsx +356 -189
  19. package/frameworks/react/runtime.tsx +2 -2
  20. package/llms-full.txt +303 -142
  21. package/llms.txt +18 -18
  22. package/package.json +5 -2
  23. package/src/components/artifact.stories.tsx +138 -0
  24. package/src/components/artifact.tsx +581 -0
  25. package/src/components/attachments.stories.tsx +7 -8
  26. package/src/components/attachments.tsx +2 -2
  27. package/src/components/card.tsx +110 -0
  28. package/src/components/chain-of-thought.stories.tsx +7 -8
  29. package/src/components/chat-container.stories.tsx +7 -8
  30. package/src/components/chat-container.tsx +4 -0
  31. package/src/components/checkpoint.stories.tsx +7 -8
  32. package/src/components/code-block.stories.tsx +8 -9
  33. package/src/components/component-meta.json +3411 -0
  34. package/src/components/confirm-card.stories.tsx +74 -0
  35. package/src/components/confirm-card.tsx +299 -0
  36. package/src/components/context.stories.tsx +7 -8
  37. package/src/components/conversation-item.stories.tsx +7 -8
  38. package/src/components/conversation-item.tsx +2 -2
  39. package/src/components/conversation-list.stories.tsx +7 -8
  40. package/src/components/conversation-list.tsx +1 -1
  41. package/src/components/embed.tsx +196 -0
  42. package/src/components/empty.stories.tsx +8 -9
  43. package/src/components/feedback-bar.stories.tsx +7 -8
  44. package/src/components/file-tree.stories.tsx +73 -0
  45. package/src/components/file-tree.tsx +383 -0
  46. package/src/components/file-upload.stories.tsx +7 -8
  47. package/src/components/form-widgets.tsx +461 -0
  48. package/src/components/form.tsx +796 -0
  49. package/src/components/image.stories.tsx +7 -8
  50. package/src/components/link-card.tsx +194 -0
  51. package/src/components/loader.stories.tsx +7 -8
  52. package/src/components/markdown.stories.tsx +7 -8
  53. package/src/components/message-narrow.stories.tsx +12 -13
  54. package/src/components/message-skills.stories.tsx +16 -17
  55. package/src/components/message.stories.tsx +17 -18
  56. package/src/components/model-switcher.stories.tsx +7 -8
  57. package/src/components/prompt-input.stories.tsx +8 -9
  58. package/src/components/prompt-suggestion.stories.tsx +7 -8
  59. package/src/components/prompt-suggestion.tsx +3 -3
  60. package/src/components/reasoning.stories.tsx +7 -8
  61. package/src/components/scroll-button.stories.tsx +7 -8
  62. package/src/components/slash-command.stories.tsx +8 -9
  63. package/src/components/slash-command.tsx +2 -2
  64. package/src/components/source.stories.tsx +7 -8
  65. package/src/components/source.tsx +1 -1
  66. package/src/components/task-list-card.stories.tsx +78 -0
  67. package/src/components/task-list-card.tsx +388 -0
  68. package/src/components/text-shimmer.stories.tsx +7 -8
  69. package/src/components/thinking-bar.stories.tsx +7 -8
  70. package/src/components/tool.stories.tsx +7 -8
  71. package/src/components/tool.tsx +2 -2
  72. package/src/components/voice-input.stories.tsx +7 -8
  73. package/src/elements/artifact.stories.tsx +291 -0
  74. package/src/elements/artifact.tsx +72 -0
  75. package/src/elements/{kitn-attachments.stories.tsx → attachments.stories.tsx} +11 -20
  76. package/src/elements/attachments.tsx +4 -4
  77. package/src/elements/card.stories.tsx +118 -0
  78. package/src/elements/card.tsx +40 -0
  79. package/src/elements/catalog.stories.tsx +491 -0
  80. package/src/elements/{kitn-chain-of-thought.stories.tsx → chain-of-thought.stories.tsx} +13 -22
  81. package/src/elements/chain-of-thought.tsx +3 -3
  82. package/src/elements/{kitn-chat-scope-picker.stories.tsx → chat-scope-picker.stories.tsx} +10 -19
  83. package/src/elements/chat-scope-picker.tsx +4 -4
  84. package/src/elements/{kitn-chat-workspace.stories.tsx → chat-workspace.stories.tsx} +15 -23
  85. package/src/elements/chat-workspace.tsx +2 -2
  86. package/src/elements/{kitn-chat.stories.tsx → chat.stories.tsx} +12 -20
  87. package/src/elements/chat.tsx +2 -2
  88. package/src/elements/{kitn-checkpoint.stories.tsx → checkpoint.stories.tsx} +11 -20
  89. package/src/elements/checkpoint.tsx +4 -4
  90. package/src/elements/{kitn-code-block.stories.tsx → code-block.stories.tsx} +10 -19
  91. package/src/elements/code-block.tsx +3 -3
  92. package/src/elements/compiled.css +1 -1
  93. package/src/elements/composed-shell.stories.tsx +316 -0
  94. package/src/elements/confirm-card.stories.tsx +186 -0
  95. package/src/elements/confirm-card.tsx +45 -0
  96. package/src/elements/{kitn-context-meter.stories.tsx → context-meter.stories.tsx} +10 -19
  97. package/src/elements/context-meter.tsx +3 -3
  98. package/src/elements/{kitn-conversation-list.stories.tsx → conversation-list.stories.tsx} +12 -20
  99. package/src/elements/conversation-list.tsx +2 -2
  100. package/src/elements/css.ts +1 -1
  101. package/src/elements/define.tsx +10 -10
  102. package/src/elements/element-meta.json +1379 -733
  103. package/src/elements/element-types.d.ts +251 -125
  104. package/src/elements/embed.stories.tsx +197 -0
  105. package/src/elements/embed.tsx +35 -0
  106. package/src/elements/{kitn-empty.stories.tsx → empty.stories.tsx} +12 -21
  107. package/src/elements/empty.tsx +3 -3
  108. package/src/elements/{kitn-feedback-bar.stories.tsx → feedback-bar.stories.tsx} +11 -20
  109. package/src/elements/feedback-bar.tsx +4 -4
  110. package/src/elements/file-tree.stories.tsx +133 -0
  111. package/src/elements/file-tree.tsx +52 -0
  112. package/src/elements/{kitn-file-upload.stories.tsx → file-upload.stories.tsx} +12 -21
  113. package/src/elements/file-upload.tsx +4 -4
  114. package/src/elements/form.stories.tsx +204 -0
  115. package/src/elements/form.tsx +37 -0
  116. package/src/elements/{kitn-image.stories.tsx → image.stories.tsx} +10 -19
  117. package/src/elements/image.tsx +3 -3
  118. package/src/elements/link-card.stories.tsx +193 -0
  119. package/src/elements/link-card.tsx +34 -0
  120. package/src/elements/{kitn-loader.stories.tsx → loader.stories.tsx} +11 -20
  121. package/src/elements/loader.tsx +3 -3
  122. package/src/elements/{kitn-markdown.stories.tsx → markdown.stories.tsx} +10 -19
  123. package/src/elements/markdown.tsx +3 -3
  124. package/src/elements/{kitn-message-skills.stories.tsx → message-skills.stories.tsx} +10 -19
  125. package/src/elements/message-skills.tsx +3 -3
  126. package/src/elements/{kitn-message.stories.tsx → message.stories.tsx} +12 -21
  127. package/src/elements/message.tsx +5 -5
  128. package/src/elements/{kitn-model-switcher.stories.tsx → model-switcher.stories.tsx} +10 -19
  129. package/src/elements/model-switcher.tsx +5 -5
  130. package/src/elements/{kitn-prompt-input.stories.tsx → prompt-input.stories.tsx} +14 -22
  131. package/src/elements/prompt-input.tsx +3 -3
  132. package/src/elements/{kitn-prompt-suggestions.stories.tsx → prompt-suggestions.stories.tsx} +13 -22
  133. package/src/elements/prompt-suggestions.tsx +4 -4
  134. package/src/elements/{kitn-reasoning.stories.tsx → reasoning.stories.tsx} +10 -19
  135. package/src/elements/reasoning.tsx +4 -4
  136. package/src/elements/register.ts +11 -1
  137. package/src/elements/resizable.stories.tsx +200 -0
  138. package/src/elements/resizable.tsx +264 -0
  139. package/src/elements/{kitn-response-stream.stories.tsx → response-stream.stories.tsx} +10 -19
  140. package/src/elements/response-stream.tsx +4 -4
  141. package/src/elements/{kitn-source-list.stories.tsx → source-list.stories.tsx} +11 -20
  142. package/src/elements/{kitn-source.stories.tsx → source.stories.tsx} +12 -21
  143. package/src/elements/source.tsx +5 -5
  144. package/src/elements/styles.css +140 -1
  145. package/src/elements/task-list-card.stories.tsx +194 -0
  146. package/src/elements/task-list-card.tsx +40 -0
  147. package/src/elements/{kitn-text-shimmer.stories.tsx → text-shimmer.stories.tsx} +10 -19
  148. package/src/elements/text-shimmer.tsx +3 -3
  149. package/src/elements/{kitn-thinking-bar.stories.tsx → thinking-bar.stories.tsx} +11 -20
  150. package/src/elements/thinking-bar.tsx +5 -5
  151. package/src/elements/{kitn-tool.stories.tsx → tool.stories.tsx} +10 -19
  152. package/src/elements/tool.tsx +3 -3
  153. package/src/elements/{kitn-voice-input.stories.tsx → voice-input.stories.tsx} +10 -19
  154. package/src/elements/voice-input.tsx +4 -4
  155. package/src/index.ts +94 -2
  156. package/src/primitives/card-contract.ts +60 -0
  157. package/src/primitives/card-host.tsx +35 -0
  158. package/src/primitives/card-routing.ts +79 -0
  159. package/src/primitives/card-schemas/card-envelope.schema.json +14 -0
  160. package/src/primitives/card-schemas/card-event.schema.json +12 -0
  161. package/src/primitives/card-schemas/confirm.schema.json +65 -0
  162. package/src/primitives/card-schemas/embed.schema.json +65 -0
  163. package/src/primitives/card-schemas/form.result.schema.json +7 -0
  164. package/src/primitives/card-schemas/form.schema.json +33 -0
  165. package/src/primitives/card-schemas/link.schema.json +56 -0
  166. package/src/primitives/card-schemas/task-list.result.schema.json +16 -0
  167. package/src/primitives/card-schemas/task-list.schema.json +78 -0
  168. package/src/primitives/card-validate.ts +95 -0
  169. package/src/primitives/embed-providers.ts +254 -0
  170. package/src/primitives/highlighter.ts +4 -0
  171. package/src/primitives/link-preview.ts +87 -0
  172. package/src/primitives/pdf-preview.ts +121 -0
  173. package/src/stories/chat-panel-layout.stories.tsx +2 -1
  174. package/src/stories/chat-scene.tsx +22 -21
  175. package/src/stories/checkpoint-restore.stories.tsx +10 -10
  176. package/src/stories/conversation-with-reasoning.stories.tsx +4 -4
  177. package/src/stories/conversation-with-sources.stories.tsx +7 -7
  178. package/src/stories/docs/Accessibility.mdx +2 -2
  179. package/src/stories/docs/ForAIAgents.mdx +3 -3
  180. package/src/stories/docs/GettingStarted.mdx +2 -2
  181. package/src/stories/docs/Installation.mdx +2 -2
  182. package/src/stories/docs/Integrations.mdx +29 -29
  183. package/src/stories/docs/Introduction.mdx +3 -3
  184. package/src/stories/docs/Theming.mdx +2 -2
  185. package/src/stories/docs/element-controls.ts +32 -0
  186. package/src/stories/docs/theme-editor/theme-editor.tsx +1 -0
  187. package/src/stories/examples/ChoosingComponents.mdx +94 -0
  188. package/src/stories/examples/sample-data.ts +79 -0
  189. package/src/stories/message-actions.stories.tsx +13 -13
  190. package/src/stories/pattern-centered-conversation.stories.tsx +3 -3
  191. package/src/stories/pattern-docked-widget.stories.tsx +1 -1
  192. package/src/stories/pattern-empty-state.stories.tsx +3 -3
  193. package/src/stories/prompt-input-variants.stories.tsx +13 -13
  194. package/src/stories/streaming-response.stories.tsx +3 -3
  195. package/src/stories/typography.stories.tsx +4 -4
  196. package/src/ui/avatar.stories.tsx +7 -8
  197. package/src/ui/badge.stories.tsx +7 -8
  198. package/src/ui/button.stories.tsx +8 -9
  199. package/src/ui/button.tsx +1 -0
  200. package/src/ui/collapsible.stories.tsx +6 -7
  201. package/src/ui/dropdown.stories.tsx +6 -7
  202. package/src/ui/hover-card.stories.tsx +6 -7
  203. package/src/ui/resizable.stories.tsx +74 -9
  204. package/src/ui/resizable.tsx +351 -71
  205. package/src/ui/scroll-area.stories.tsx +6 -7
  206. package/src/ui/scroll-area.tsx +3 -1
  207. package/src/ui/separator.stories.tsx +7 -8
  208. package/src/ui/skeleton.stories.tsx +7 -8
  209. package/src/ui/textarea.stories.tsx +6 -7
  210. package/src/ui/tooltip.stories.tsx +8 -9
  211. package/theme.css +65 -65
  212. package/src/stories/docs/element-spec.tsx +0 -86
@@ -1,8 +1,7 @@
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
+ import { argTypesFor, specDescription } from '../stories/docs/element-controls';
6
5
 
7
6
  interface Step {
8
7
  label: string;
@@ -14,7 +13,7 @@ declare module 'solid-js' {
14
13
  // eslint-disable-next-line @typescript-eslint/no-namespace
15
14
  namespace JSX {
16
15
  interface IntrinsicElements {
17
- 'kitn-chain-of-thought': JSX.HTMLAttributes<HTMLElement>;
16
+ 'kc-chain-of-thought': JSX.HTMLAttributes<HTMLElement>;
18
17
  }
19
18
  }
20
19
  }
@@ -25,19 +24,19 @@ const steps: Step[] = [
25
24
  { label: 'Build & verify' },
26
25
  ];
27
26
 
28
- /** Render `<kitn-chain-of-thought>` with the `steps` set as a JS property. */
27
+ /** Render `<kc-chain-of-thought>` with the `steps` set as a JS property. */
29
28
  function CotElement(props: { steps: Step[] }) {
30
29
  let el: (HTMLElement & { steps?: Step[] }) | undefined;
31
30
  onMount(() => {
32
31
  if (el) el.steps = props.steps;
33
32
  });
34
33
  return (
35
- <kitn-chain-of-thought ref={(e) => (el = e as HTMLElement)} style={{ display: 'block', padding: '24px', 'max-width': '560px' }} />
34
+ <kc-chain-of-thought ref={(e) => (el = e as HTMLElement)} style={{ display: 'block', padding: '24px', 'max-width': '560px' }} />
36
35
  );
37
36
  }
38
37
 
39
38
  const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
40
- <kitn-chain-of-thought id="cot"></kitn-chain-of-thought>
39
+ <kc-chain-of-thought id="cot"></kc-chain-of-thought>
41
40
 
42
41
  <script type="module">
43
42
  import '@kitnai/chat/elements'; // registers the custom elements
@@ -50,20 +49,18 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
50
49
  </script>`;
51
50
 
52
51
  const meta = {
53
- title: 'Web Components/kitn-chain-of-thought',
52
+ title: 'Web Components/kc-chain-of-thought',
54
53
  tags: ['autodocs'],
55
- argTypes: argTypesFor('kitn-chain-of-thought'),
54
+ argTypes: argTypesFor('kc-chain-of-thought'),
56
55
  parameters: {
57
56
  layout: 'fullscreen',
58
57
  docs: {
59
- description: {
60
- component: [
61
- '`<kitn-chain-of-thought>` is the framework-agnostic **web component** for step-by-step reasoning a connected list of steps, each with optional collapsible detail — isolated in **Shadow DOM**. The compound primitive collapses to a single `steps` data model (Route 1).',
62
- '**When to use:** surfacing an agent\'s plan or reasoning trace in a non-Solid app. In SolidJS, compose the `ChainOfThought` primitives for finer control.',
63
- "**How to use:** register once with `import '@kitnai/chat/elements'`, then set the `steps` **property** an array of `{ label, content? }`. Steps with `content` become expandable.",
64
- 'See the **Code** tab for HTML usage.',
65
- ].join('\n\n'),
66
- },
58
+ description: specDescription('kc-chain-of-thought', [
59
+ '`<kc-chain-of-thought>` is the framework-agnostic **web component** for step-by-step reasoning — a connected list of steps, each with optional collapsible detail — isolated in **Shadow DOM**. The compound primitive collapses to a single `steps` data model (Route 1).',
60
+ '**When to use:** surfacing an agent\'s plan or reasoning trace in a non-Solid app. In SolidJS, compose the `ChainOfThought` primitives for finer control.',
61
+ "**How to use:** register once with `import '@kitnai/chat/elements'`, then set the `steps` **property** an array of `{ label, content? }`. Steps with `content` become expandable.",
62
+ 'See the **Code** tab for HTML usage.',
63
+ ]),
67
64
  },
68
65
  },
69
66
  } satisfies Meta;
@@ -71,12 +68,6 @@ const meta = {
71
68
  export default meta;
72
69
  type Story = StoryObj;
73
70
 
74
- /** Full generated API reference — properties, events, tokens, and composed-from. */
75
- export const API: Story = {
76
- render: () => <ElementSpec tag="kitn-chain-of-thought" />,
77
- parameters: { layout: 'padded' },
78
- };
79
-
80
71
  /** A three-step reasoning trace; the last step has no detail. */
81
72
  export const Default: Story = {
82
73
  render: () => <CotElement steps={steps} />,
@@ -1,5 +1,5 @@
1
1
  import { For, Show } from 'solid-js';
2
- import { defineKitnElement } from './define';
2
+ import { defineWebComponent } from './define';
3
3
  import {
4
4
  ChainOfThought,
5
5
  ChainOfThoughtStep,
@@ -22,10 +22,10 @@ interface Props extends Record<string, unknown> {
22
22
  }
23
23
 
24
24
  /**
25
- * `<kitn-chain-of-thought>` — step-by-step reasoning with connectors and
25
+ * `<kc-chain-of-thought>` — step-by-step reasoning with connectors and
26
26
  * per-step collapsible detail. Data via the `steps` property.
27
27
  */
28
- defineKitnElement<Props>('kitn-chain-of-thought', {
28
+ defineWebComponent<Props>('kc-chain-of-thought', {
29
29
  steps: [],
30
30
  }, (props) => (
31
31
  <ChainOfThought>
@@ -1,22 +1,21 @@
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
+ import { argTypesFor, specDescription } from '../stories/docs/element-controls';
6
5
 
7
6
  // The web components are custom DOM elements, so declare the tags for JSX.
8
7
  declare module 'solid-js' {
9
8
  // eslint-disable-next-line @typescript-eslint/no-namespace
10
9
  namespace JSX {
11
10
  interface IntrinsicElements {
12
- 'kitn-chat-scope-picker': JSX.HTMLAttributes<HTMLElement> & {
11
+ 'kc-scope-picker': JSX.HTMLAttributes<HTMLElement> & {
13
12
  'current-label'?: string;
14
13
  };
15
14
  }
16
15
  }
17
16
  }
18
17
 
19
- /** Render `<kitn-chat-scope-picker>` with author/tag options set as properties. */
18
+ /** Render `<kc-scope-picker>` with author/tag options set as properties. */
20
19
  function ScopePickerElement(props: { authors: string[]; tags: string[] }) {
21
20
  let el: (HTMLElement & { availableAuthors?: string[]; availableTags?: string[] }) | undefined;
22
21
  onMount(() => {
@@ -29,12 +28,12 @@ function ScopePickerElement(props: { authors: string[]; tags: string[] }) {
29
28
  });
30
29
  });
31
30
  return (
32
- <kitn-chat-scope-picker ref={(e) => (el = e as HTMLElement)} style={{ display: 'inline-block', padding: '40px' }} />
31
+ <kc-scope-picker ref={(e) => (el = e as HTMLElement)} style={{ display: 'inline-block', padding: '40px' }} />
33
32
  );
34
33
  }
35
34
 
36
35
  const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
37
- <kitn-chat-scope-picker id="scope"></kitn-chat-scope-picker>
36
+ <kc-scope-picker id="scope"></kc-scope-picker>
38
37
 
39
38
  <script type="module">
40
39
  import '@kitnai/chat/elements'; // registers the custom elements
@@ -47,20 +46,18 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
47
46
  </script>`;
48
47
 
49
48
  const meta = {
50
- title: 'Web Components/kitn-chat-scope-picker',
49
+ title: 'Web Components/kc-scope-picker',
51
50
  tags: ['autodocs'],
52
- argTypes: argTypesFor('kitn-chat-scope-picker'),
51
+ argTypes: argTypesFor('kc-scope-picker'),
53
52
  parameters: {
54
53
  layout: 'fullscreen',
55
54
  docs: {
56
- description: {
57
- component: [
58
- '`<kitn-chat-scope-picker>` is the framework-agnostic **web component** for scoping a chat by author or tag — a dropdown that emits the chosen filters — isolated in **Shadow DOM**.',
55
+ description: specDescription('kc-scope-picker', [
56
+ '`<kc-scope-picker>` is the framework-agnostic **web component** for scoping a chat by author or tag — a dropdown that emits the chosen filters — isolated in **Shadow DOM**.',
59
57
  '**When to use:** letting users narrow a conversation/search to a subset of content. In SolidJS, use the `ChatScopePicker` primitive.',
60
58
  "**How to use:** register once with `import '@kitnai/chat/elements'`, set the `availableAuthors` / `availableTags` **properties** (and optionally `current-label`), and listen for the `scopechange` **CustomEvent** (`undefined` filters = \"All Content\").",
61
59
  'See the **Code** tab for HTML usage.',
62
- ].join('\n\n'),
63
- },
60
+ ]),
64
61
  },
65
62
  },
66
63
  } satisfies Meta;
@@ -68,12 +65,6 @@ const meta = {
68
65
  export default meta;
69
66
  type Story = StoryObj;
70
67
 
71
- /** Full generated API reference — properties, events, tokens, and composed-from. */
72
- export const API: Story = {
73
- render: () => <ElementSpec tag="kitn-chat-scope-picker" />,
74
- parameters: { layout: 'padded' },
75
- };
76
-
77
68
  /** Authors and tags available as scope filters. */
78
69
  export const Default: Story = {
79
70
  render: () => <ScopePickerElement authors={['Rob', 'Alex']} tags={['design', 'api']} />,
@@ -1,4 +1,4 @@
1
- import { defineKitnElement } from './define';
1
+ import { defineWebComponent } from './define';
2
2
  import { ChatScopePicker } from '../components/chat-scope-picker';
3
3
  import type { SearchFilters } from '../types';
4
4
 
@@ -11,18 +11,18 @@ interface Props extends Record<string, unknown> {
11
11
  currentLabel?: string;
12
12
  }
13
13
 
14
- /** Events fired by `<kitn-chat-scope-picker>`. */
14
+ /** Events fired by `<kc-scope-picker>`. */
15
15
  interface Events {
16
16
  /** A scope was chosen (`undefined` filters = "All Content"). */
17
17
  scopechange: { filters: SearchFilters | undefined };
18
18
  }
19
19
 
20
20
  /**
21
- * `<kitn-chat-scope-picker>` — a dropdown to scope a chat by author or tag.
21
+ * `<kc-scope-picker>` — a dropdown to scope a chat by author or tag.
22
22
  * Options via `available-authors`/`available-tags` properties; emits
23
23
  * `scopechange`.
24
24
  */
25
- defineKitnElement<Props, Events>('kitn-chat-scope-picker', {
25
+ defineWebComponent<Props, Events>('kc-scope-picker', {
26
26
  availableAuthors: [],
27
27
  availableTags: [],
28
28
  currentLabel: 'All Content',
@@ -1,17 +1,16 @@
1
1
  import type { Meta, StoryObj } from 'storybook-solidjs-vite';
2
2
  import { onMount } from 'solid-js';
3
- import './register'; // side effect: registers all kitn custom elements including <kitn-chat-workspace>
3
+ import './register'; // side effect: registers all kitn custom elements including <kc-workspace>
4
4
  import type { ConversationGroup, ConversationSummary, ModelOption } from '../types';
5
5
  import type { ChatMessage } from './chat-types';
6
- import { ElementSpec } from '../stories/docs/element-spec';
7
- import { argTypesFor } from '../stories/docs/element-controls';
6
+ import { argTypesFor, specDescription } from '../stories/docs/element-controls';
8
7
 
9
8
  // The web components are custom DOM elements, so declare the tags for JSX.
10
9
  declare module 'solid-js' {
11
10
  // eslint-disable-next-line @typescript-eslint/no-namespace
12
11
  namespace JSX {
13
12
  interface IntrinsicElements {
14
- 'kitn-chat-workspace': JSX.HTMLAttributes<HTMLElement>;
13
+ 'kc-workspace': JSX.HTMLAttributes<HTMLElement>;
15
14
  }
16
15
  }
17
16
  }
@@ -52,7 +51,7 @@ const sampleMessages: ChatMessage[] = [
52
51
  id: 'm2',
53
52
  role: 'assistant',
54
53
  content:
55
- 'Use `<kitn-chat-workspace>` — set `conversations`, `messages`, and `models` as properties and listen for `conversationselect` + `submit`.',
54
+ 'Use `<kc-workspace>` — set `conversations`, `messages`, and `models` as properties and listen for `conversationselect` + `submit`.',
56
55
  actions: ['copy', 'like'],
57
56
  },
58
57
  ];
@@ -82,7 +81,7 @@ type WorkspaceEl = HTMLElement & {
82
81
  value?: string;
83
82
  };
84
83
 
85
- /** Live demo of the actual `<kitn-chat-workspace>` custom element (Shadow DOM and all). */
84
+ /** Live demo of the actual `<kc-workspace>` custom element (Shadow DOM and all). */
86
85
  function WorkspaceElement(props: { args?: Record<string, unknown> }) {
87
86
  let el: WorkspaceEl | undefined;
88
87
  onMount(() => {
@@ -114,7 +113,7 @@ function WorkspaceElement(props: { args?: Record<string, unknown> }) {
114
113
  });
115
114
  return (
116
115
  <div style={{ height: '720px', width: '100%' }}>
117
- <kitn-chat-workspace
116
+ <kc-workspace
118
117
  ref={(e) => (el = e as WorkspaceEl)}
119
118
  style={{ display: 'block', height: '100%' }}
120
119
  />
@@ -123,7 +122,7 @@ function WorkspaceElement(props: { args?: Record<string, unknown> }) {
123
122
  }
124
123
 
125
124
  const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
126
- <kitn-chat-workspace id="workspace" style="display:block; height:100vh;"></kitn-chat-workspace>
125
+ <kc-workspace id="workspace" style="display:block; height:100vh;"></kc-workspace>
127
126
 
128
127
  <script type="module">
129
128
  import '@kitnai/chat/elements'; // registers the custom elements
@@ -138,7 +137,7 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
138
137
  ];
139
138
  workspace.messages = [
140
139
  { id: 'm1', role: 'user', content: 'How do I drop the whole chat app in with one tag?' },
141
- { id: 'm2', role: 'assistant', content: 'Use <kitn-chat-workspace> — set conversations, messages, and models as properties.' },
140
+ { id: 'm2', role: 'assistant', content: 'Use <kc-workspace> — set conversations, messages, and models as properties.' },
142
141
  ];
143
142
  workspace.models = [
144
143
  { id: 'claude-4', name: 'Claude 4 Opus', provider: 'Anthropic' },
@@ -171,7 +170,7 @@ function Workspace() {
171
170
  ];
172
171
  const messages: ChatMessage[] = [
173
172
  { id: 'm1', role: 'user', content: 'How do I drop the whole chat app in with one tag?' },
174
- { id: 'm2', role: 'assistant', content: 'Use <kitn-chat-workspace> — set conversations, messages, and models as properties.' },
173
+ { id: 'm2', role: 'assistant', content: 'Use <kc-workspace> — set conversations, messages, and models as properties.' },
175
174
  ];
176
175
  onMount(() => {
177
176
  el.conversations = conversations;
@@ -182,7 +181,7 @@ function Workspace() {
182
181
  el.addEventListener('sidebartoggle', (e) => console.log('sidebar collapsed:', e.detail.collapsed));
183
182
  });
184
183
  return (
185
- <kitn-chat-workspace
184
+ <kc-workspace
186
185
  ref={el}
187
186
  style={{ display: 'block', height: '100vh' }}
188
187
  />
@@ -190,21 +189,19 @@ function Workspace() {
190
189
  }`;
191
190
 
192
191
  const meta = {
193
- title: 'Web Components/kitn-chat-workspace',
192
+ title: 'Web Components/kc-workspace',
194
193
  tags: ['autodocs'],
195
- argTypes: argTypesFor('kitn-chat-workspace'),
194
+ argTypes: argTypesFor('kc-workspace'),
196
195
  parameters: {
197
196
  layout: 'fullscreen',
198
197
  docs: {
199
- description: {
200
- component: [
201
- '`<kitn-chat-workspace>` is the full chat shell as a single **web component** — a resizable split layout with a collapsible conversation list on the left and a full message thread on the right, all isolated in **Shadow DOM**. SolidJS is bundled in, so the host needs nothing.',
198
+ description: specDescription('kc-workspace', [
199
+ '`<kc-workspace>` is the full chat shell as a single **web component** — a resizable split layout with a collapsible conversation list on the left and a full message thread on the right, all isolated in **Shadow DOM**. SolidJS is bundled in, so the host needs nothing.',
202
200
  '**When to use:** dropping an entire chat application shell into a non-Solid app (React, Vue, Svelte, plain HTML), or anywhere you want zero style conflicts and a ready-made list+chat layout. If you *are* in SolidJS and want fine-grained control, compose the `ConversationList` and `ChatThread` primitives directly.',
203
201
  '**How to use:** register once with `import \'@kitnai/chat/elements\'`, set rich data as JS **properties** (`el.conversations = [...]`, `el.messages = [...]`, `el.models = [...]`), and listen for **CustomEvents** (`conversationselect`, `submit`, `sidebartoggle`, `newchat`) directly on the element.',
204
202
  '**Placement:** as a full-page surface or large panel. Give it an explicit height (e.g. `height: 100vh`). The sidebar is drag-resizable and can be collapsed via the toggle button in its header.',
205
203
  'See the **Code** tab below for the HTML usage; the *SolidJS* story shows the same element inside a Solid component.',
206
- ].join('\n\n'),
207
- },
204
+ ]),
208
205
  },
209
206
  },
210
207
  } satisfies Meta;
@@ -238,8 +235,3 @@ export const InSolidJS: Story = {
238
235
  parameters: { docs: { source: { code: SOLID_SNIPPET, language: 'tsx' } } },
239
236
  };
240
237
 
241
- /** Full generated API reference — properties, events, tokens, and the SolidJS components this element is composed from. */
242
- export const API: Story = {
243
- render: () => <ElementSpec tag="kitn-chat-workspace" />,
244
- parameters: { layout: 'padded' },
245
- };
@@ -1,5 +1,5 @@
1
1
  import { createSignal, Show } from 'solid-js';
2
- import { defineKitnElement } from './define';
2
+ import { defineWebComponent } from './define';
3
3
  import { ChatThread, type ChatThreadContextUsage } from '../components/chat-thread';
4
4
  import { ConversationList } from '../components/conversation-list';
5
5
  import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from '../ui/resizable';
@@ -73,7 +73,7 @@ interface Events {
73
73
  suggestionclick: { value: string };
74
74
  }
75
75
 
76
- defineKitnElement<Props, Events>('kitn-chat-workspace', {
76
+ defineWebComponent<Props, Events>('kc-workspace', {
77
77
  groups: [], conversations: [], activeId: undefined, messages: [],
78
78
  value: undefined, placeholder: 'Send a message...', loading: false,
79
79
  suggestions: undefined, suggestionMode: 'submit', proseSize: 'sm',
@@ -1,16 +1,15 @@
1
1
  import type { Meta, StoryObj } from 'storybook-solidjs-vite';
2
2
  import { onMount } from 'solid-js';
3
- import './register'; // side effect: registers <kitn-chat>, <kitn-conversation-list>, <kitn-prompt-input>
3
+ import './register'; // side effect: registers <kc-chat>, <kc-conversations>, <kc-prompt-input>
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
+ import { argTypesFor, specDescription } from '../stories/docs/element-controls';
7
6
 
8
7
  // The web components are custom DOM elements, so declare the tags for JSX.
9
8
  declare module 'solid-js' {
10
9
  // eslint-disable-next-line @typescript-eslint/no-namespace
11
10
  namespace JSX {
12
11
  interface IntrinsicElements {
13
- 'kitn-chat': JSX.HTMLAttributes<HTMLElement>;
12
+ 'kc-chat': JSX.HTMLAttributes<HTMLElement>;
14
13
  }
15
14
  }
16
15
  }
@@ -43,7 +42,7 @@ type ChatEl = HTMLElement & {
43
42
  slashCompact?: boolean;
44
43
  };
45
44
 
46
- /** Live demo of the actual `<kitn-chat>` custom element (Shadow DOM and all). */
45
+ /** Live demo of the actual `<kc-chat>` custom element (Shadow DOM and all). */
47
46
  function ChatElement(props: { args?: Record<string, unknown> }) {
48
47
  let el: ChatEl | undefined;
49
48
  onMount(() => {
@@ -64,11 +63,11 @@ function ChatElement(props: { args?: Record<string, unknown> }) {
64
63
  }
65
64
  }
66
65
  });
67
- return <kitn-chat ref={(e) => (el = e as ChatEl)} style={{ display: 'block', height: '560px' }} />;
66
+ return <kc-chat ref={(e) => (el = e as ChatEl)} style={{ display: 'block', height: '560px' }} />;
68
67
  }
69
68
 
70
69
  const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
71
- <kitn-chat id="chat" style="display:block; height:100vh;"></kitn-chat>
70
+ <kc-chat id="chat" style="display:block; height:100vh;"></kc-chat>
72
71
 
73
72
  <script type="module">
74
73
  import '@kitnai/chat/elements'; // registers the custom elements
@@ -95,7 +94,7 @@ function Chat() {
95
94
  ];
96
95
  onMount(() => { el.messages = messages; });
97
96
  return (
98
- <kitn-chat
97
+ <kc-chat
99
98
  ref={el}
100
99
  style={{ display: 'block', height: '100vh' }}
101
100
  on:submit={(e) => console.log('user sent:', e.detail.value)}
@@ -104,21 +103,19 @@ function Chat() {
104
103
  }`;
105
104
 
106
105
  const meta = {
107
- title: 'Web Components/kitn-chat',
106
+ title: 'Web Components/kc-chat',
108
107
  tags: ['autodocs'],
109
- argTypes: argTypesFor('kitn-chat'),
108
+ argTypes: argTypesFor('kc-chat'),
110
109
  parameters: {
111
110
  layout: 'fullscreen',
112
111
  docs: {
113
- description: {
114
- component: [
115
- '`<kitn-chat>` is the framework-agnostic **web component** version of the chat UI — a complete message thread plus prompt input, isolated in **Shadow DOM** so the host page\'s CSS can\'t leak in and the kit\'s styles can\'t leak out. SolidJS is bundled in, so the host needs nothing.',
112
+ description: specDescription('kc-chat', [
113
+ '`<kc-chat>` is the framework-agnostic **web component** version of the chat UI — a complete message thread plus prompt input, isolated in **Shadow DOM** so the host page\'s CSS can\'t leak in and the kit\'s styles can\'t leak out. SolidJS is bundled in, so the host needs nothing.',
116
114
  '**When to use:** dropping a full chat into a non-Solid app (React, Vue, Svelte, plain HTML), or anywhere you want zero style conflicts. If you *are* in SolidJS and want fine-grained control, compose the primitives (`ChatContainer`, `Message`, `PromptInput`) instead.',
117
115
  '**How to use:** register once with `import \'@kitnai/chat/elements\'`, set rich data as JS **properties** (`el.messages = [...]`), and listen for **CustomEvents** (`submit`, `messageaction`, `valuechange`) directly on the element.',
118
116
  '**Placement:** as a top-level panel or full-page surface. Give it an explicit height (e.g. `height: 100vh`).',
119
117
  'See the **Code** tab below for the HTML usage; the *SolidJS* story shows the same element inside a Solid component.',
120
- ].join('\n\n'),
121
- },
118
+ ]),
122
119
  },
123
120
  },
124
121
  } satisfies Meta;
@@ -151,8 +148,3 @@ export const InSolidJS: Story = {
151
148
  parameters: { docs: { source: { code: SOLID_SNIPPET, language: 'tsx' } } },
152
149
  };
153
150
 
154
- /** Full generated API reference — properties, events, tokens, and the SolidJS components this element is composed from. */
155
- export const API: Story = {
156
- render: () => <ElementSpec tag="kitn-chat" />,
157
- parameters: { layout: 'padded' },
158
- };
@@ -1,4 +1,4 @@
1
- import { defineKitnElement } from './define';
1
+ import { defineWebComponent } from './define';
2
2
  import { ChatThread, type ChatThreadProps, type ChatThreadContextUsage } from '../components/chat-thread';
3
3
  import type { AttachmentData } from '../components/attachments';
4
4
  import type { SlashCommandItem } from '../components/slash-command';
@@ -29,7 +29,7 @@ interface Events {
29
29
  voice: Record<string, never>;
30
30
  }
31
31
 
32
- defineKitnElement<Props, Events>('kitn-chat', {
32
+ defineWebComponent<Props, Events>('kc-chat', {
33
33
  messages: [], value: undefined, placeholder: 'Send a message...', loading: false,
34
34
  suggestions: undefined, suggestionMode: 'submit', proseSize: 'sm',
35
35
  codeTheme: 'github-dark-dimmed', codeHighlight: true, chatTitle: undefined,
@@ -1,20 +1,19 @@
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
+ import { argTypesFor, specDescription } from '../stories/docs/element-controls';
6
5
 
7
6
  // The web components are custom DOM elements, so declare the tags for JSX.
8
7
  declare module 'solid-js' {
9
8
  // eslint-disable-next-line @typescript-eslint/no-namespace
10
9
  namespace JSX {
11
10
  interface IntrinsicElements {
12
- 'kitn-checkpoint': JSX.HTMLAttributes<HTMLElement>;
11
+ 'kc-checkpoint': JSX.HTMLAttributes<HTMLElement>;
13
12
  }
14
13
  }
15
14
  }
16
15
 
17
- /** Render the actual `<kitn-checkpoint>` custom element configured by attributes. */
16
+ /** Render the actual `<kc-checkpoint>` custom element configured by attributes. */
18
17
  function CheckpointElement(props: { label?: string; tooltip?: string; variant?: string; size?: string }) {
19
18
  let el: HTMLElement | undefined;
20
19
  onMount(() => {
@@ -25,35 +24,33 @@ function CheckpointElement(props: { label?: string; tooltip?: string; variant?:
25
24
  if (props.size) el.setAttribute('size', props.size);
26
25
  el.addEventListener('select', () => console.log('checkpoint selected'));
27
26
  });
28
- return <kitn-checkpoint ref={(e) => (el = e as HTMLElement)} style={{ display: 'inline-block', padding: '16px' }} />;
27
+ return <kc-checkpoint ref={(e) => (el = e as HTMLElement)} style={{ display: 'inline-block', padding: '16px' }} />;
29
28
  }
30
29
 
31
30
  const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
32
- <kitn-checkpoint label="Restore" tooltip="Restore this checkpoint" variant="outline" size="sm"></kitn-checkpoint>
31
+ <kc-checkpoint label="Restore" tooltip="Restore this checkpoint" variant="outline" size="sm"></kc-checkpoint>
33
32
 
34
33
  <script type="module">
35
34
  import '@kitnai/chat/elements'; // registers the custom elements
36
35
 
37
- const cp = document.querySelector('kitn-checkpoint');
36
+ const cp = document.querySelector('kc-checkpoint');
38
37
  // events are CustomEvents on the element (they do not bubble)
39
38
  cp.addEventListener('select', () => console.log('restore checkpoint'));
40
39
  </script>`;
41
40
 
42
41
  const meta = {
43
- title: 'Web Components/kitn-checkpoint',
42
+ title: 'Web Components/kc-checkpoint',
44
43
  tags: ['autodocs'],
45
- argTypes: argTypesFor('kitn-checkpoint'),
44
+ argTypes: argTypesFor('kc-checkpoint'),
46
45
  parameters: {
47
46
  layout: 'fullscreen',
48
47
  docs: {
49
- description: {
50
- component: [
51
- '`<kitn-checkpoint>` is the framework-agnostic **web component** for a bookmark/checkpoint button (with an optional tooltip and label), isolated in **Shadow DOM**.',
48
+ description: specDescription('kc-checkpoint', [
49
+ '`<kc-checkpoint>` is the framework-agnostic **web component** for a bookmark/checkpoint button (with an optional tooltip and label), isolated in **Shadow DOM**.',
52
50
  '**When to use:** marking a restore point in a conversation in a non-Solid app. In SolidJS, compose the `Checkpoint` primitives.',
53
51
  "**How to use:** register once with `import '@kitnai/chat/elements'`, set `label`, `tooltip`, `variant` (`ghost` | `default` | `outline`), and `size` via attributes, and listen for the `select` **CustomEvent** on click.",
54
52
  'See the **Code** tab for HTML usage.',
55
- ].join('\n\n'),
56
- },
53
+ ]),
57
54
  },
58
55
  },
59
56
  } satisfies Meta;
@@ -61,12 +58,6 @@ const meta = {
61
58
  export default meta;
62
59
  type Story = StoryObj;
63
60
 
64
- /** Full generated API reference — properties, events, tokens, and composed-from. */
65
- export const API: Story = {
66
- render: () => <ElementSpec tag="kitn-checkpoint" />,
67
- parameters: { layout: 'padded' },
68
- };
69
-
70
61
  /** A labeled checkpoint button. (Add a `tooltip` attribute for a hover hint — see the Code tab.) */
71
62
  export const Labeled: Story = {
72
63
  render: () => <CheckpointElement label="Restore" variant="outline" />,
@@ -1,5 +1,5 @@
1
1
  import { Show } from 'solid-js';
2
- import { defineKitnElement } from './define';
2
+ import { defineWebComponent } from './define';
3
3
  import { Checkpoint, CheckpointIcon, CheckpointTrigger } from '../components/checkpoint';
4
4
 
5
5
  interface Props extends Record<string, unknown> {
@@ -13,17 +13,17 @@ interface Props extends Record<string, unknown> {
13
13
  size?: 'sm' | 'md' | 'lg' | 'icon' | 'icon-sm';
14
14
  }
15
15
 
16
- /** Events fired by `<kitn-checkpoint>`. */
16
+ /** Events fired by `<kc-checkpoint>`. */
17
17
  interface Events {
18
18
  /** The checkpoint was clicked. */
19
19
  select: void;
20
20
  }
21
21
 
22
22
  /**
23
- * `<kitn-checkpoint>` — a bookmark/checkpoint button (optional tooltip + label).
23
+ * `<kc-checkpoint>` — a bookmark/checkpoint button (optional tooltip + label).
24
24
  * Emits `select`.
25
25
  */
26
- defineKitnElement<Props, Events>('kitn-checkpoint', {
26
+ defineWebComponent<Props, Events>('kc-checkpoint', {
27
27
  label: undefined,
28
28
  tooltip: undefined,
29
29
  variant: 'ghost',
@@ -1,15 +1,14 @@
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
+ import { argTypesFor, specDescription } from '../stories/docs/element-controls';
6
5
 
7
6
  // The web components are custom DOM elements, so declare the tags for JSX.
8
7
  declare module 'solid-js' {
9
8
  // eslint-disable-next-line @typescript-eslint/no-namespace
10
9
  namespace JSX {
11
10
  interface IntrinsicElements {
12
- 'kitn-code-block': JSX.HTMLAttributes<HTMLElement>;
11
+ 'kc-code-block': JSX.HTMLAttributes<HTMLElement>;
13
12
  }
14
13
  }
15
14
  }
@@ -24,7 +23,7 @@ const pythonCode = `def fib(n):
24
23
  a, b = b, a + b
25
24
  return a`;
26
25
 
27
- /** Render the actual `<kitn-code-block>` custom element with a `code` property. */
26
+ /** Render the actual `<kc-code-block>` custom element with a `code` property. */
28
27
  function CodeBlockElement(props: { code: string; language?: string }) {
29
28
  let el: (HTMLElement & { code?: string }) | undefined;
30
29
  onMount(() => {
@@ -34,7 +33,7 @@ function CodeBlockElement(props: { code: string; language?: string }) {
34
33
  }
35
34
  });
36
35
  return (
37
- <kitn-code-block
36
+ <kc-code-block
38
37
  ref={(e) => (el = e as HTMLElement)}
39
38
  style={{ display: 'block', padding: '16px', 'max-width': '720px' }}
40
39
  />
@@ -42,7 +41,7 @@ function CodeBlockElement(props: { code: string; language?: string }) {
42
41
  }
43
42
 
44
43
  const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
45
- <kitn-code-block id="code" language="ts" code-theme="github-dark-dimmed"></kitn-code-block>
44
+ <kc-code-block id="code" language="ts" code-theme="github-dark-dimmed"></kc-code-block>
46
45
 
47
46
  <script type="module">
48
47
  import '@kitnai/chat/elements'; // registers the custom elements
@@ -52,20 +51,18 @@ const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
52
51
  </script>`;
53
52
 
54
53
  const meta = {
55
- title: 'Web Components/kitn-code-block',
54
+ title: 'Web Components/kc-code-block',
56
55
  tags: ['autodocs'],
57
- argTypes: argTypesFor('kitn-code-block'),
56
+ argTypes: argTypesFor('kc-code-block'),
58
57
  parameters: {
59
58
  layout: 'fullscreen',
60
59
  docs: {
61
- description: {
62
- component: [
63
- '`<kitn-code-block>` is the framework-agnostic **web component** for a single syntax-highlighted code block, complete with a copy button, isolated in **Shadow DOM**.',
60
+ description: specDescription('kc-code-block', [
61
+ '`<kc-code-block>` is the framework-agnostic **web component** for a single syntax-highlighted code block, complete with a copy button, isolated in **Shadow DOM**.',
64
62
  '**When to use:** dropping a highlighted snippet into a non-Solid app. In SolidJS, compose `CodeBlock` + `CodeBlockCode` directly.',
65
63
  "**How to use:** register once with `import '@kitnai/chat/elements'`, set the source via the `code` **property** (`el.code = '...'`), and pick a grammar with the `language` attribute (defaults to `tsx`). Tune highlighting with `code-theme` / `code-highlight`.",
66
64
  'See the **Code** tab for HTML usage.',
67
- ].join('\n\n'),
68
- },
65
+ ]),
69
66
  },
70
67
  },
71
68
  } satisfies Meta;
@@ -73,12 +70,6 @@ const meta = {
73
70
  export default meta;
74
71
  type Story = StoryObj;
75
72
 
76
- /** Full generated API reference — properties, events, tokens, and composed-from. */
77
- export const API: Story = {
78
- render: () => <ElementSpec tag="kitn-code-block" />,
79
- parameters: { layout: 'padded' },
80
- };
81
-
82
73
  /** A TypeScript snippet (the default `tsx` grammar). */
83
74
  export const TypeScript: Story = {
84
75
  render: () => <CodeBlockElement code={sampleCode} language="ts" />,