@kitn.ai/ui 0.14.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.
- package/LICENSE +21 -0
- package/README.md +394 -0
- package/dist/bash-InADTalH.js +1 -0
- package/dist/core-AYMC6_lb.js +12 -0
- package/dist/css-M7EaDHN_.js +1 -0
- package/dist/custom-elements.json +4739 -0
- package/dist/engine-javascript-vq0WuIJl.js +141 -0
- package/dist/github-dark-dimmed-DUshB20C.js +1 -0
- package/dist/github-light-JYsPkUQd.js +1 -0
- package/dist/host-embed.d.ts +33 -0
- package/dist/html-CPZ3oZQ7.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/javascript-C25yR2R2.js +1 -0
- package/dist/json-DxJze_jm.js +1 -0
- package/dist/kitn-chat-provider.d.ts +2 -0
- package/dist/kitn-chat-provider.es.js +240 -0
- package/dist/kitn-chat.es.js +77 -0
- package/dist/llms/llms-full.txt +1018 -0
- package/dist/llms/llms.txt +104 -0
- package/dist/origin.d.ts +5 -0
- package/dist/provider-runtime.d.ts +27 -0
- package/dist/schemas/card-envelope.schema.json +14 -0
- package/dist/schemas/card-event.schema.json +12 -0
- package/dist/schemas/choice.schema.json +70 -0
- package/dist/schemas/confirm.schema.json +65 -0
- package/dist/schemas/embed.schema.json +65 -0
- package/dist/schemas/form.result.schema.json +7 -0
- package/dist/schemas/form.schema.json +33 -0
- package/dist/schemas/link.schema.json +56 -0
- package/dist/schemas/tasks.result.schema.json +16 -0
- package/dist/schemas/tasks.schema.json +78 -0
- package/dist/svelte--5p79yCD.js +1 -0
- package/dist/theme.tokens.css +176 -0
- package/dist/tsx-B8rCNbgL.js +1 -0
- package/dist/typescript-RycA9KXf.js +1 -0
- package/dist/validate.d.ts +4 -0
- package/dist/version.d.ts +4 -0
- package/dist/vue-BmIZj4XD.js +1 -0
- package/dist/wire.d.ts +53 -0
- package/frameworks/react/index.tsx +948 -0
- package/frameworks/react/runtime.tsx +94 -0
- package/llms-full.txt +1018 -0
- package/llms.txt +104 -0
- package/package.json +141 -0
- package/src/components/artifact.stories.tsx +138 -0
- package/src/components/artifact.tsx +743 -0
- package/src/components/attachments.stories.tsx +303 -0
- package/src/components/attachments.test.tsx +64 -0
- package/src/components/attachments.tsx +399 -0
- package/src/components/card-fallback.tsx +28 -0
- package/src/components/card-renderer.tsx +52 -0
- package/src/components/card.tsx +110 -0
- package/src/components/chain-of-thought.stories.tsx +211 -0
- package/src/components/chain-of-thought.tsx +139 -0
- package/src/components/chat-container.stories.tsx +187 -0
- package/src/components/chat-container.tsx +82 -0
- package/src/components/chat-scope-picker.tsx +47 -0
- package/src/components/chat-thread.test.tsx +58 -0
- package/src/components/chat-thread.tsx +249 -0
- package/src/components/checkpoint.stories.tsx +102 -0
- package/src/components/checkpoint.tsx +88 -0
- package/src/components/choice-card.tsx +569 -0
- package/src/components/code-block.stories.tsx +150 -0
- package/src/components/code-block.tsx +105 -0
- package/src/components/component-meta.json +3735 -0
- package/src/components/confirm-card.stories.tsx +74 -0
- package/src/components/confirm-card.tsx +315 -0
- package/src/components/context.stories.tsx +229 -0
- package/src/components/context.test.tsx +133 -0
- package/src/components/context.tsx +363 -0
- package/src/components/conversation-item.stories.tsx +125 -0
- package/src/components/conversation-item.tsx +16 -0
- package/src/components/conversation-list.stories.tsx +133 -0
- package/src/components/conversation-list.tsx +101 -0
- package/src/components/default-input.test.tsx +111 -0
- package/src/components/embed.tsx +196 -0
- package/src/components/empty.stories.tsx +434 -0
- package/src/components/empty.tsx +166 -0
- package/src/components/feedback-bar.stories.tsx +138 -0
- package/src/components/feedback-bar.test.tsx +103 -0
- package/src/components/feedback-bar.tsx +166 -0
- package/src/components/file-tree.stories.tsx +73 -0
- package/src/components/file-tree.tsx +383 -0
- package/src/components/file-upload.stories.tsx +156 -0
- package/src/components/file-upload.tsx +161 -0
- package/src/components/form-widgets.tsx +461 -0
- package/src/components/form.tsx +873 -0
- package/src/components/image.stories.tsx +89 -0
- package/src/components/image.tsx +67 -0
- package/src/components/link-preview.tsx +194 -0
- package/src/components/loader.stories.tsx +181 -0
- package/src/components/loader.tsx +333 -0
- package/src/components/markdown.stories.tsx +180 -0
- package/src/components/markdown.tsx +81 -0
- package/src/components/message-action-bar.test.tsx +128 -0
- package/src/components/message-narrow.stories.tsx +329 -0
- package/src/components/message-skills.stories.tsx +211 -0
- package/src/components/message-skills.tsx +36 -0
- package/src/components/message.stories.tsx +281 -0
- package/src/components/message.tsx +227 -0
- package/src/components/model-switcher.stories.tsx +123 -0
- package/src/components/model-switcher.test.tsx +65 -0
- package/src/components/model-switcher.tsx +87 -0
- package/src/components/prompt-input.stories.tsx +222 -0
- package/src/components/prompt-input.tsx +211 -0
- package/src/components/prompt-suggestion.stories.tsx +142 -0
- package/src/components/prompt-suggestion.tsx +115 -0
- package/src/components/reasoning.stories.tsx +140 -0
- package/src/components/reasoning.tsx +156 -0
- package/src/components/resizable.test.tsx +226 -0
- package/src/components/response-stream.tsx +103 -0
- package/src/components/scroll-button.stories.tsx +100 -0
- package/src/components/scroll-button.tsx +34 -0
- package/src/components/slash-command.stories.tsx +163 -0
- package/src/components/slash-command.tsx +232 -0
- package/src/components/source-list.test.tsx +152 -0
- package/src/components/source.stories.tsx +124 -0
- package/src/components/source.tsx +129 -0
- package/src/components/tasks-card.stories.tsx +78 -0
- package/src/components/tasks-card.tsx +432 -0
- package/src/components/text-shimmer.stories.tsx +87 -0
- package/src/components/text-shimmer.tsx +37 -0
- package/src/components/thinking-bar.stories.tsx +87 -0
- package/src/components/thinking-bar.tsx +50 -0
- package/src/components/tool.stories.tsx +153 -0
- package/src/components/tool.tsx +184 -0
- package/src/components/use-card-resolution.ts +28 -0
- package/src/components/voice-input.stories.tsx +83 -0
- package/src/components/voice-input.tsx +107 -0
- package/src/elements/artifact.stories.tsx +506 -0
- package/src/elements/artifact.tsx +137 -0
- package/src/elements/attachments.stories.tsx +190 -0
- package/src/elements/attachments.tsx +136 -0
- package/src/elements/card.stories.tsx +113 -0
- package/src/elements/card.tsx +40 -0
- package/src/elements/cards.stories.tsx +59 -0
- package/src/elements/cards.tsx +97 -0
- package/src/elements/catalog.stories.tsx +491 -0
- package/src/elements/chain-of-thought.declarative.test.tsx +153 -0
- package/src/elements/chain-of-thought.stories.tsx +113 -0
- package/src/elements/chain-of-thought.tsx +92 -0
- package/src/elements/chat-scope-picker.stories.tsx +73 -0
- package/src/elements/chat-scope-picker.tsx +36 -0
- package/src/elements/chat-types.ts +42 -0
- package/src/elements/chat-workspace.stories.tsx +288 -0
- package/src/elements/chat-workspace.tsx +161 -0
- package/src/elements/chat.stories.tsx +151 -0
- package/src/elements/chat.tsx +80 -0
- package/src/elements/checkpoint.stories.tsx +72 -0
- package/src/elements/checkpoint.tsx +47 -0
- package/src/elements/choice.stories.tsx +240 -0
- package/src/elements/choice.tsx +48 -0
- package/src/elements/code-block.stories.tsx +83 -0
- package/src/elements/code-block.tsx +42 -0
- package/src/elements/compiled.css +2 -0
- package/src/elements/composed-shell.stories.tsx +316 -0
- package/src/elements/confirm-card.stories.tsx +227 -0
- package/src/elements/confirm-card.tsx +51 -0
- package/src/elements/context-meter.stories.tsx +151 -0
- package/src/elements/context-meter.tsx +121 -0
- package/src/elements/conversation-list.declarative.test.tsx +137 -0
- package/src/elements/conversation-list.stories.tsx +243 -0
- package/src/elements/conversation-list.tsx +80 -0
- package/src/elements/css.ts +5 -0
- package/src/elements/default-input.tsx +247 -0
- package/src/elements/define.tsx +171 -0
- package/src/elements/element-meta.json +3314 -0
- package/src/elements/element-types.d.ts +710 -0
- package/src/elements/embed.stories.tsx +213 -0
- package/src/elements/embed.tsx +35 -0
- package/src/elements/empty.stories.tsx +111 -0
- package/src/elements/empty.tsx +29 -0
- package/src/elements/feedback-bar.stories.tsx +114 -0
- package/src/elements/feedback-bar.tsx +61 -0
- package/src/elements/file-tree.stories.tsx +134 -0
- package/src/elements/file-tree.tsx +52 -0
- package/src/elements/file-upload.stories.tsx +82 -0
- package/src/elements/file-upload.tsx +44 -0
- package/src/elements/form.stories.tsx +248 -0
- package/src/elements/form.tsx +43 -0
- package/src/elements/framework-usage.json +563 -0
- package/src/elements/image.stories.tsx +71 -0
- package/src/elements/image.tsx +32 -0
- package/src/elements/link-preview.stories.tsx +209 -0
- package/src/elements/link-preview.tsx +34 -0
- package/src/elements/loader.stories.tsx +88 -0
- package/src/elements/loader.tsx +25 -0
- package/src/elements/markdown.stories.tsx +76 -0
- package/src/elements/markdown.tsx +38 -0
- package/src/elements/message-skills.declarative.test.tsx +104 -0
- package/src/elements/message-skills.stories.tsx +114 -0
- package/src/elements/message-skills.tsx +85 -0
- package/src/elements/message.stories.tsx +218 -0
- package/src/elements/message.tsx +162 -0
- package/src/elements/model-switcher.declarative.test.tsx +130 -0
- package/src/elements/model-switcher.stories.tsx +198 -0
- package/src/elements/model-switcher.tsx +93 -0
- package/src/elements/popover.stories.tsx +80 -0
- package/src/elements/popover.tsx +59 -0
- package/src/elements/prompt-input-slash-command.test.tsx +128 -0
- package/src/elements/prompt-input-stoppable.test.tsx +88 -0
- package/src/elements/prompt-input-toolbar-actions.test.tsx +120 -0
- package/src/elements/prompt-input.stories.tsx +331 -0
- package/src/elements/prompt-input.tsx +185 -0
- package/src/elements/prompt-suggestions.declarative.test.tsx +164 -0
- package/src/elements/prompt-suggestions.stories.tsx +213 -0
- package/src/elements/prompt-suggestions.tsx +94 -0
- package/src/elements/reasoning.stories.tsx +77 -0
- package/src/elements/reasoning.tsx +50 -0
- package/src/elements/register.ts +56 -0
- package/src/elements/remote.stories.tsx +314 -0
- package/src/elements/remote.tsx +221 -0
- package/src/elements/resizable.d.ts +27 -0
- package/src/elements/resizable.stories.tsx +426 -0
- package/src/elements/resizable.tsx +553 -0
- package/src/elements/response-stream.stories.tsx +79 -0
- package/src/elements/response-stream.tsx +40 -0
- package/src/elements/scroll-button.stories.tsx +202 -0
- package/src/elements/scroll-button.test.tsx +148 -0
- package/src/elements/scroll-button.tsx +126 -0
- package/src/elements/source-list.stories.tsx +143 -0
- package/src/elements/source.stories.tsx +88 -0
- package/src/elements/source.tsx +120 -0
- package/src/elements/styles.css +199 -0
- package/src/elements/switch.stories.tsx +56 -0
- package/src/elements/switch.tsx +43 -0
- package/src/elements/tasks.stories.tsx +237 -0
- package/src/elements/tasks.tsx +46 -0
- package/src/elements/text-shimmer.stories.tsx +64 -0
- package/src/elements/text-shimmer.tsx +28 -0
- package/src/elements/thinking-bar.stories.tsx +72 -0
- package/src/elements/thinking-bar.tsx +34 -0
- package/src/elements/tool.stories.tsx +89 -0
- package/src/elements/tool.tsx +23 -0
- package/src/elements/voice-input.stories.tsx +88 -0
- package/src/elements/voice-input.tsx +41 -0
- package/src/index.ts +253 -0
- package/src/primitives/card-contract.ts +71 -0
- package/src/primitives/card-host.tsx +35 -0
- package/src/primitives/card-registry.tsx +67 -0
- package/src/primitives/card-resolution.ts +36 -0
- package/src/primitives/card-routing.ts +79 -0
- package/src/primitives/card-schemas/card-envelope.schema.json +14 -0
- package/src/primitives/card-schemas/card-event.schema.json +12 -0
- package/src/primitives/card-schemas/choice.schema.json +70 -0
- package/src/primitives/card-schemas/confirm.schema.json +65 -0
- package/src/primitives/card-schemas/embed.schema.json +65 -0
- package/src/primitives/card-schemas/form.result.schema.json +7 -0
- package/src/primitives/card-schemas/form.schema.json +33 -0
- package/src/primitives/card-schemas/link.schema.json +56 -0
- package/src/primitives/card-schemas/tasks.result.schema.json +16 -0
- package/src/primitives/card-schemas/tasks.schema.json +78 -0
- package/src/primitives/card-validate.ts +95 -0
- package/src/primitives/chat-config.tsx +76 -0
- package/src/primitives/controllable.test.ts +47 -0
- package/src/primitives/controllable.ts +21 -0
- package/src/primitives/embed-providers.ts +254 -0
- package/src/primitives/highlighter.ts +157 -0
- package/src/primitives/link-preview.ts +87 -0
- package/src/primitives/pdf-preview.ts +121 -0
- package/src/primitives/use-auto-resize.ts +31 -0
- package/src/primitives/use-resize-observer.ts +12 -0
- package/src/primitives/use-stick-to-bottom.ts +43 -0
- package/src/primitives/use-text-stream.ts +112 -0
- package/src/primitives/use-voice-recorder.ts +50 -0
- package/src/remote/host-embed.ts +345 -0
- package/src/remote/index.ts +2 -0
- package/src/remote/origin.ts +30 -0
- package/src/remote/provider-runtime.ts +259 -0
- package/src/remote/provider.ts +2 -0
- package/src/remote/validate.ts +22 -0
- package/src/remote/version.ts +12 -0
- package/src/remote/wire.ts +48 -0
- package/src/stories/chat-panel-layout.stories.tsx +145 -0
- package/src/stories/chat-scene.tsx +571 -0
- package/src/stories/checkpoint-restore.stories.tsx +256 -0
- package/src/stories/context-usage.stories.tsx +212 -0
- package/src/stories/conversation-with-reasoning.stories.tsx +182 -0
- package/src/stories/conversation-with-sources.stories.tsx +471 -0
- package/src/stories/docs/Accessibility.mdx +119 -0
- package/src/stories/docs/ChildElements.mdx +269 -0
- package/src/stories/docs/ForAIAgents.mdx +162 -0
- package/src/stories/docs/GettingStarted.mdx +65 -0
- package/src/stories/docs/Installation.mdx +83 -0
- package/src/stories/docs/Introduction.mdx +50 -0
- package/src/stories/docs/SolidJsAdvanced.mdx +17 -0
- package/src/stories/docs/Theming.mdx +85 -0
- package/src/stories/docs/element-controls.ts +121 -0
- package/src/stories/docs/frameworks/Angular.mdx +245 -0
- package/src/stories/docs/frameworks/Html.mdx +227 -0
- package/src/stories/docs/frameworks/Overview.mdx +47 -0
- package/src/stories/docs/frameworks/React.mdx +227 -0
- package/src/stories/docs/frameworks/Solid.mdx +173 -0
- package/src/stories/docs/frameworks/Svelte.mdx +194 -0
- package/src/stories/docs/frameworks/Vue.mdx +238 -0
- package/src/stories/docs/generative-ui-overview.mdx +186 -0
- package/src/stories/docs/recipes/SpeechToText.mdx +7 -0
- package/src/stories/docs/recipes/Streaming.mdx +68 -0
- package/src/stories/docs/recipes/TextToSpeech.mdx +35 -0
- package/src/stories/docs/theme-editor/canvas.tsx +32 -0
- package/src/stories/docs/theme-editor/inspector.tsx +66 -0
- package/src/stories/docs/theme-editor/presets.test.ts +32 -0
- package/src/stories/docs/theme-editor/presets.ts +64 -0
- package/src/stories/docs/theme-editor/theme-css.test.ts +19 -0
- package/src/stories/docs/theme-editor/theme-css.ts +15 -0
- package/src/stories/docs/theme-editor/theme-editor.tsx +146 -0
- package/src/stories/docs/theme-tokens.tsx +174 -0
- package/src/stories/examples/ChoosingComponents.mdx +106 -0
- package/src/stories/examples/sample-data.ts +79 -0
- package/src/stories/examples/usage/checkpoint-restore.ts +156 -0
- package/src/stories/examples/usage/context-usage.ts +591 -0
- package/src/stories/examples/usage/conversation-with-reasoning.ts +224 -0
- package/src/stories/examples/usage/conversation-with-sources.ts +589 -0
- package/src/stories/examples/usage/empty-state.ts +144 -0
- package/src/stories/examples/usage/full-chat-app.ts +277 -0
- package/src/stories/examples/usage/index.ts +63 -0
- package/src/stories/examples/usage/message-actions.ts +704 -0
- package/src/stories/examples/usage/pattern-centered-conversation.ts +446 -0
- package/src/stories/examples/usage/pattern-chat-panel-layout.ts +442 -0
- package/src/stories/examples/usage/pattern-docked-widget.ts +479 -0
- package/src/stories/examples/usage/prompt-input-variants.ts +1356 -0
- package/src/stories/examples/usage/streaming-response.ts +687 -0
- package/src/stories/examples/usage/types.ts +33 -0
- package/src/stories/full-chat.stories.tsx +18 -0
- package/src/stories/message-actions.stories.tsx +230 -0
- package/src/stories/pattern-centered-conversation.stories.tsx +93 -0
- package/src/stories/pattern-docked-widget.stories.tsx +93 -0
- package/src/stories/pattern-empty-state.stories.tsx +76 -0
- package/src/stories/prompt-input-variants.stories.tsx +456 -0
- package/src/stories/streaming-response.stories.tsx +438 -0
- package/src/stories/theme-editor.stories.tsx +16 -0
- package/src/stories/token-reference.stories.tsx +18 -0
- package/src/stories/typography.stories.tsx +78 -0
- package/src/types.ts +47 -0
- package/src/ui/action-icons.ts +52 -0
- package/src/ui/avatar.stories.tsx +103 -0
- package/src/ui/avatar.tsx +23 -0
- package/src/ui/badge.stories.tsx +86 -0
- package/src/ui/badge.tsx +21 -0
- package/src/ui/button.stories.tsx +145 -0
- package/src/ui/button.tsx +38 -0
- package/src/ui/collapsible.stories.tsx +69 -0
- package/src/ui/collapsible.tsx +125 -0
- package/src/ui/dropdown.stories.tsx +59 -0
- package/src/ui/dropdown.tsx +196 -0
- package/src/ui/hover-card.stories.tsx +77 -0
- package/src/ui/hover-card.test.tsx +30 -0
- package/src/ui/hover-card.tsx +172 -0
- package/src/ui/overlay.stories.tsx +115 -0
- package/src/ui/overlay.tsx +158 -0
- package/src/ui/popover.stories.tsx +81 -0
- package/src/ui/popover.test.tsx +99 -0
- package/src/ui/popover.tsx +92 -0
- package/src/ui/resizable.stories.tsx +236 -0
- package/src/ui/resizable.tsx +576 -0
- package/src/ui/scroll-area.stories.tsx +50 -0
- package/src/ui/scroll-area.tsx +15 -0
- package/src/ui/separator.stories.tsx +81 -0
- package/src/ui/separator.tsx +10 -0
- package/src/ui/skeleton.stories.tsx +337 -0
- package/src/ui/skeleton.tsx +16 -0
- package/src/ui/switch.stories.tsx +51 -0
- package/src/ui/switch.test.tsx +59 -0
- package/src/ui/switch.tsx +62 -0
- package/src/ui/textarea.stories.tsx +76 -0
- package/src/ui/textarea.tsx +21 -0
- package/src/ui/tooltip.stories.tsx +74 -0
- package/src/ui/tooltip.tsx +68 -0
- package/src/utils/cn.ts +24 -0
- package/theme.css +187 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { ExampleUsage, StoryUsage } from './types';
|
|
2
|
+
|
|
3
|
+
/** New Chat — a centered greeting (icon + title + description), starter suggestion chips, and a composer. */
|
|
4
|
+
const newChat: StoryUsage = {
|
|
5
|
+
intro:
|
|
6
|
+
"The new-chat zero state. `<kai-empty>` renders the centered greeting from two scalar props — `emptyTitle` (DOM attribute `empty-title`, since `title` is a global HTML attribute) and `description`. The icon, the starter suggestion chips, and the composer below aren't part of `<kai-empty>` — compose those with the SolidJS `Empty` + `PromptSuggestion` + `PromptInput` primitives (see the Solid tab).",
|
|
7
|
+
snippets: {
|
|
8
|
+
html: `<!-- Register the elements once (CDN or bundler) -->
|
|
9
|
+
<script type="module">
|
|
10
|
+
import 'https://cdn.jsdelivr.net/npm/@kitn.ai/ui/dist/kitn-chat.es.js';
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<!-- Scalars are plain attributes. Note the kebab-case empty-title. -->
|
|
14
|
+
<kai-empty
|
|
15
|
+
empty-title="How can I help today?"
|
|
16
|
+
description="Ask anything, or start from one of these."
|
|
17
|
+
></kai-empty>
|
|
18
|
+
|
|
19
|
+
<!-- The icon, suggestion chips, and composer are not part of <kai-empty>;
|
|
20
|
+
compose them yourself (see the Solid tab). -->`,
|
|
21
|
+
|
|
22
|
+
react: `import { Empty } from '@kitn.ai/ui/react';
|
|
23
|
+
|
|
24
|
+
export function NewChat() {
|
|
25
|
+
// Icon, suggestion chips, and composer aren't props on <Empty> —
|
|
26
|
+
// compose them yourself (see the Solid tab).
|
|
27
|
+
return (
|
|
28
|
+
<Empty
|
|
29
|
+
emptyTitle="How can I help today?"
|
|
30
|
+
description="Ask anything, or start from one of these."
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
}`,
|
|
34
|
+
|
|
35
|
+
vue: `<script setup>
|
|
36
|
+
import '@kitn.ai/ui/elements'; // register once (e.g. in main.ts)
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<template>
|
|
40
|
+
<!-- Scalars as plain attributes; empty-title is kebab-case. -->
|
|
41
|
+
<kai-empty
|
|
42
|
+
empty-title="How can I help today?"
|
|
43
|
+
description="Ask anything, or start from one of these."
|
|
44
|
+
/>
|
|
45
|
+
<!-- Icon, suggestions, and composer are composed separately. -->
|
|
46
|
+
</template>`,
|
|
47
|
+
|
|
48
|
+
svelte: `<script>
|
|
49
|
+
import '@kitn.ai/ui/elements'; // register once
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<!-- Scalars as attributes; empty-title is kebab-case. -->
|
|
53
|
+
<kai-empty
|
|
54
|
+
empty-title="How can I help today?"
|
|
55
|
+
description="Ask anything, or start from one of these."
|
|
56
|
+
></kai-empty>
|
|
57
|
+
<!-- Icon, suggestions, and composer are composed separately. -->`,
|
|
58
|
+
|
|
59
|
+
angular: `// main.ts: import '@kitn.ai/ui/elements' before bootstrapApplication,
|
|
60
|
+
// and add CUSTOM_ELEMENTS_SCHEMA to the component.
|
|
61
|
+
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
62
|
+
|
|
63
|
+
@Component({
|
|
64
|
+
selector: 'app-new-chat',
|
|
65
|
+
standalone: true,
|
|
66
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
67
|
+
// empty-title is kebab-case; both props are scalar strings.
|
|
68
|
+
template: \`
|
|
69
|
+
<kai-empty
|
|
70
|
+
empty-title="How can I help today?"
|
|
71
|
+
description="Ask anything, or start from one of these."
|
|
72
|
+
></kai-empty>
|
|
73
|
+
\`,
|
|
74
|
+
})
|
|
75
|
+
export class NewChatComponent {}`,
|
|
76
|
+
|
|
77
|
+
solid: `import { createSignal } from 'solid-js';
|
|
78
|
+
import {
|
|
79
|
+
ChatConfig, Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent,
|
|
80
|
+
PromptSuggestion, PromptInput, PromptInputTextarea, PromptInputActions, Button,
|
|
81
|
+
} from '@kitn.ai/ui';
|
|
82
|
+
import { Sparkles, Plus, Globe, ArrowUp } from 'lucide-solid';
|
|
83
|
+
|
|
84
|
+
const SUGGESTIONS = [
|
|
85
|
+
'Summarize a document',
|
|
86
|
+
'Draft a product update',
|
|
87
|
+
'Explain a code snippet',
|
|
88
|
+
'Plan my week',
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
export function NewChat() {
|
|
92
|
+
const [input, setInput] = createSignal('');
|
|
93
|
+
return (
|
|
94
|
+
<ChatConfig proseSize="base">
|
|
95
|
+
<Empty class="flex-1">
|
|
96
|
+
<EmptyHeader>
|
|
97
|
+
<EmptyMedia variant="icon"><Sparkles class="size-6" /></EmptyMedia>
|
|
98
|
+
<EmptyTitle>How can I help today?</EmptyTitle>
|
|
99
|
+
<EmptyDescription>Ask anything, or start from one of these.</EmptyDescription>
|
|
100
|
+
</EmptyHeader>
|
|
101
|
+
<EmptyContent>
|
|
102
|
+
<div class="flex max-w-md flex-wrap justify-center gap-2">
|
|
103
|
+
{SUGGESTIONS.map((s) => (
|
|
104
|
+
<PromptSuggestion onClick={() => setInput(s)}>{s}</PromptSuggestion>
|
|
105
|
+
))}
|
|
106
|
+
</div>
|
|
107
|
+
</EmptyContent>
|
|
108
|
+
</Empty>
|
|
109
|
+
|
|
110
|
+
{/* Composer fills from a clicked suggestion. */}
|
|
111
|
+
<PromptInput value={input()} onValueChange={setInput} onSubmit={() => setInput('')}>
|
|
112
|
+
<PromptInputTextarea placeholder="Ask anything…" />
|
|
113
|
+
<PromptInputActions class="flex items-center justify-between gap-2">
|
|
114
|
+
<div class="flex items-center gap-2">
|
|
115
|
+
<Button variant="outline" size="icon-sm" class="rounded-full" aria-label="Add"><Plus class="size-4" /></Button>
|
|
116
|
+
<Button variant="outline" size="sm" class="rounded-full gap-1" aria-label="Search the web"><Globe class="size-4" />Search</Button>
|
|
117
|
+
</div>
|
|
118
|
+
<Button size="icon-sm" class="rounded-full" disabled={!input().trim()} aria-label="Send message">
|
|
119
|
+
<ArrowUp class="size-4" />
|
|
120
|
+
</Button>
|
|
121
|
+
</PromptInputActions>
|
|
122
|
+
</PromptInput>
|
|
123
|
+
</ChatConfig>
|
|
124
|
+
);
|
|
125
|
+
}`,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Pattern: Empty State — the new-chat zero state. `<kai-empty>` covers the
|
|
131
|
+
* centered greeting (`emptyTitle` + `description`); the icon, starter
|
|
132
|
+
* suggestion chips, and composer are SolidJS primitive composition. Per-story:
|
|
133
|
+
* the Usage tab shows the snippet for the story you're on; the example-level
|
|
134
|
+
* fields below are the fallback.
|
|
135
|
+
*/
|
|
136
|
+
const emptyState: ExampleUsage = {
|
|
137
|
+
title: 'Patterns/Empty State',
|
|
138
|
+
...newChat, // example-level fallback = the primary "New Chat" story
|
|
139
|
+
stories: {
|
|
140
|
+
'New Chat': newChat,
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export default emptyState;
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import type { ExampleUsage, StoryUsage } from './types';
|
|
2
|
+
|
|
3
|
+
// A small thread reused across the snippets — user + assistant, with actions,
|
|
4
|
+
// reasoning, and a tool call on the second assistant message.
|
|
5
|
+
const MESSAGES = `[
|
|
6
|
+
{ id: 'u1', role: 'user', content: 'Can you explain how SolidJS reactivity differs from React hooks?' },
|
|
7
|
+
{
|
|
8
|
+
id: 'a1',
|
|
9
|
+
role: 'assistant',
|
|
10
|
+
content: 'SolidJS uses fine-grained signals: components run once and only the DOM nodes that read a signal update.',
|
|
11
|
+
actions: ['copy', 'like', 'dislike', 'regenerate'],
|
|
12
|
+
},
|
|
13
|
+
{ id: 'u2', role: 'user', content: 'Can you benchmark SolidJS vs React for 10,000 items?' },
|
|
14
|
+
{
|
|
15
|
+
id: 'a2',
|
|
16
|
+
role: 'assistant',
|
|
17
|
+
content: 'Here are the benchmark results — SolidJS renders ~7x faster and updates ~42x faster.',
|
|
18
|
+
actions: ['copy', 'like', 'dislike', 'regenerate'],
|
|
19
|
+
reasoning: { label: 'Thought for 4 seconds', text: 'Render the same 10,000 items in both frameworks for a fair comparison.' },
|
|
20
|
+
tools: [
|
|
21
|
+
{
|
|
22
|
+
type: 'run_benchmark',
|
|
23
|
+
state: 'output-available',
|
|
24
|
+
input: { framework: ['solid', 'react'], itemCount: 10000 },
|
|
25
|
+
output: { solid: { avgRenderMs: 12.4 }, react: { avgRenderMs: 89.2 } },
|
|
26
|
+
toolCallId: 'call_abc123',
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
]`;
|
|
31
|
+
|
|
32
|
+
const MODELS = `[
|
|
33
|
+
{ id: 'claude-4', name: 'Claude 4 Opus', provider: 'Anthropic' },
|
|
34
|
+
{ id: 'gpt-4o', name: 'GPT-4o', provider: 'OpenAI' },
|
|
35
|
+
]`;
|
|
36
|
+
|
|
37
|
+
const CONTEXT = `{ usedTokens: 12400, maxTokens: 200000, inputTokens: 8200, outputTokens: 4200, estimatedCost: 0.042 }`;
|
|
38
|
+
|
|
39
|
+
const SUGGESTIONS = `['How does SolidJS handle context?', 'Show me a store example']`;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Default — the entire chat experience in one element. `<kai-chat>` renders the
|
|
43
|
+
* message thread (markdown, reasoning, tool calls, per-message action bars), a
|
|
44
|
+
* header with the `models` switcher + `context` token meter, the `suggestions`
|
|
45
|
+
* chips, and the prompt input. The demo's resizable sidebar + conversation list
|
|
46
|
+
* are separate chrome that lives *outside* the element.
|
|
47
|
+
*/
|
|
48
|
+
const fullChat: StoryUsage = {
|
|
49
|
+
intro:
|
|
50
|
+
'Drop in the whole chat experience with one element. `<kai-chat>` renders the thread (markdown, reasoning, tool calls, action bars), an optional header model switcher + `context` token meter, `suggestions` chips, and the prompt input — set `messages` as a property and handle `submit` / `messageaction` / `modelchange`. The resizable conversation sidebar in the demo is separate chrome `<kai-chat>` does not include. (The live demo composes the SolidJS `ChatContainer`, `Message`, `PromptInput`, and `ConversationList` primitives directly.)',
|
|
51
|
+
snippets: {
|
|
52
|
+
html: `<!-- Register the elements once (CDN or bundler) -->
|
|
53
|
+
<script type="module">
|
|
54
|
+
import 'https://cdn.jsdelivr.net/npm/@kitn.ai/ui/dist/kitn-chat.es.js';
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<kai-chat
|
|
58
|
+
id="chat"
|
|
59
|
+
chat-title="SolidJS reactivity vs React hooks"
|
|
60
|
+
current-model="claude-4"
|
|
61
|
+
prose-size="base"
|
|
62
|
+
placeholder="Ask anything..."
|
|
63
|
+
></kai-chat>
|
|
64
|
+
|
|
65
|
+
<script type="module">
|
|
66
|
+
const chat = document.getElementById('chat');
|
|
67
|
+
|
|
68
|
+
// Object/array props are set as PROPERTIES, not attributes.
|
|
69
|
+
chat.messages = ${MESSAGES};
|
|
70
|
+
chat.models = ${MODELS};
|
|
71
|
+
chat.context = ${CONTEXT};
|
|
72
|
+
chat.suggestions = ${SUGGESTIONS};
|
|
73
|
+
|
|
74
|
+
chat.addEventListener('kai-submit', (e) => {
|
|
75
|
+
const { value, attachments } = e.detail; // append the user message / call your backend
|
|
76
|
+
console.log('send', value, attachments);
|
|
77
|
+
});
|
|
78
|
+
chat.addEventListener('kai-message-action', (e) => {
|
|
79
|
+
const { messageId, action } = e.detail; // 'copy' | 'like' | 'dislike' | 'regenerate' | 'edit'
|
|
80
|
+
console.log(messageId, action);
|
|
81
|
+
});
|
|
82
|
+
chat.addEventListener('kai-model-change', (e) => console.log(e.detail.modelId));
|
|
83
|
+
</script>`,
|
|
84
|
+
|
|
85
|
+
react: `import { Chat } from '@kitn.ai/ui/react';
|
|
86
|
+
|
|
87
|
+
export function ChatApp() {
|
|
88
|
+
return (
|
|
89
|
+
<Chat
|
|
90
|
+
chatTitle="SolidJS reactivity vs React hooks"
|
|
91
|
+
proseSize="base"
|
|
92
|
+
placeholder="Ask anything..."
|
|
93
|
+
currentModel="claude-4"
|
|
94
|
+
models={${MODELS}}
|
|
95
|
+
context={${CONTEXT}}
|
|
96
|
+
suggestions={${SUGGESTIONS}}
|
|
97
|
+
messages={${MESSAGES}}
|
|
98
|
+
onSubmit={(e) => console.log('send', e.detail.value, e.detail.attachments)}
|
|
99
|
+
onMessageAction={(e) => console.log(e.detail.messageId, e.detail.action)}
|
|
100
|
+
onModelChange={(e) => console.log(e.detail.modelId)}
|
|
101
|
+
/>
|
|
102
|
+
);
|
|
103
|
+
}`,
|
|
104
|
+
|
|
105
|
+
vue: `<script setup>
|
|
106
|
+
import '@kitn.ai/ui/elements'; // register once (e.g. in main.ts)
|
|
107
|
+
|
|
108
|
+
// Object/array props use the .prop modifier in the template.
|
|
109
|
+
const messages = ${MESSAGES};
|
|
110
|
+
const models = ${MODELS};
|
|
111
|
+
const context = ${CONTEXT};
|
|
112
|
+
const suggestions = ${SUGGESTIONS};
|
|
113
|
+
|
|
114
|
+
function onSubmit(e) { console.log('send', e.detail.value, e.detail.attachments); }
|
|
115
|
+
function onAction(e) { console.log(e.detail.messageId, e.detail.action); }
|
|
116
|
+
</script>
|
|
117
|
+
|
|
118
|
+
<template>
|
|
119
|
+
<kai-chat
|
|
120
|
+
chat-title="SolidJS reactivity vs React hooks"
|
|
121
|
+
prose-size="base"
|
|
122
|
+
placeholder="Ask anything..."
|
|
123
|
+
current-model="claude-4"
|
|
124
|
+
:messages.prop="messages"
|
|
125
|
+
:models.prop="models"
|
|
126
|
+
:context.prop="context"
|
|
127
|
+
:suggestions.prop="suggestions"
|
|
128
|
+
@kai-submit="onSubmit"
|
|
129
|
+
@kai-message-action="onAction"
|
|
130
|
+
@kai-model-change="(e) => console.log(e.detail.modelId)"
|
|
131
|
+
/>
|
|
132
|
+
</template>`,
|
|
133
|
+
|
|
134
|
+
svelte: `<script>
|
|
135
|
+
import '@kitn.ai/ui/elements';
|
|
136
|
+
|
|
137
|
+
let el;
|
|
138
|
+
// Object/array props are set as properties via bind:this.
|
|
139
|
+
const messages = ${MESSAGES};
|
|
140
|
+
const models = ${MODELS};
|
|
141
|
+
const context = ${CONTEXT};
|
|
142
|
+
const suggestions = ${SUGGESTIONS};
|
|
143
|
+
$: if (el) {
|
|
144
|
+
el.messages = messages;
|
|
145
|
+
el.models = models;
|
|
146
|
+
el.context = context;
|
|
147
|
+
el.suggestions = suggestions;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function onSubmit(e) { console.log('send', e.detail.value, e.detail.attachments); }
|
|
151
|
+
function onAction(e) { console.log(e.detail.messageId, e.detail.action); }
|
|
152
|
+
</script>
|
|
153
|
+
|
|
154
|
+
<kai-chat
|
|
155
|
+
bind:this={el}
|
|
156
|
+
chat-title="SolidJS reactivity vs React hooks"
|
|
157
|
+
prose-size="base"
|
|
158
|
+
placeholder="Ask anything..."
|
|
159
|
+
current-model="claude-4"
|
|
160
|
+
on:kai-submit={onSubmit}
|
|
161
|
+
on:kai-message-action={onAction}
|
|
162
|
+
on:kai-model-change={(e) => console.log(e.detail.modelId)}
|
|
163
|
+
/>`,
|
|
164
|
+
|
|
165
|
+
angular: `// main.ts: import '@kitn.ai/ui/elements' before bootstrapApplication,
|
|
166
|
+
// and add CUSTOM_ELEMENTS_SCHEMA to the component.
|
|
167
|
+
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
168
|
+
|
|
169
|
+
@Component({
|
|
170
|
+
selector: 'app-chat',
|
|
171
|
+
standalone: true,
|
|
172
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
173
|
+
template: \`
|
|
174
|
+
<kai-chat
|
|
175
|
+
chat-title="SolidJS reactivity vs React hooks"
|
|
176
|
+
prose-size="base"
|
|
177
|
+
placeholder="Ask anything..."
|
|
178
|
+
current-model="claude-4"
|
|
179
|
+
[messages]="messages"
|
|
180
|
+
[models]="models"
|
|
181
|
+
[context]="context"
|
|
182
|
+
[suggestions]="suggestions"
|
|
183
|
+
(kai-submit)="onSubmit($event)"
|
|
184
|
+
(kai-message-action)="onAction($event)"
|
|
185
|
+
(kai-model-change)="onModel($event)"
|
|
186
|
+
></kai-chat>
|
|
187
|
+
\`,
|
|
188
|
+
})
|
|
189
|
+
export class ChatComponent {
|
|
190
|
+
messages = ${MESSAGES};
|
|
191
|
+
models = ${MODELS};
|
|
192
|
+
context = ${CONTEXT};
|
|
193
|
+
suggestions = ${SUGGESTIONS};
|
|
194
|
+
onSubmit(e: CustomEvent<{ value: string; attachments: unknown[] }>) {
|
|
195
|
+
console.log('send', e.detail.value, e.detail.attachments);
|
|
196
|
+
}
|
|
197
|
+
onAction(e: CustomEvent<{ messageId: string; action: string }>) {
|
|
198
|
+
console.log(e.detail.messageId, e.detail.action);
|
|
199
|
+
}
|
|
200
|
+
onModel(e: CustomEvent<{ modelId: string }>) { console.log(e.detail.modelId); }
|
|
201
|
+
}`,
|
|
202
|
+
|
|
203
|
+
solid: `import { createSignal, For } from 'solid-js';
|
|
204
|
+
import {
|
|
205
|
+
ChatContainer, ChatContainerContent, ChatContainerScrollAnchor,
|
|
206
|
+
Message, MessageContent, MessageActions,
|
|
207
|
+
PromptInput, PromptInputTextarea, PromptInputActions,
|
|
208
|
+
ConversationList, ModelSwitcher, PromptSuggestion, ScrollButton, Button,
|
|
209
|
+
} from '@kitn.ai/ui';
|
|
210
|
+
import { Copy, ThumbsUp, ThumbsDown, RefreshCw, ArrowUp } from 'lucide-solid';
|
|
211
|
+
|
|
212
|
+
export function ChatApp() {
|
|
213
|
+
const [value, setValue] = createSignal('');
|
|
214
|
+
const [modelId, setModelId] = createSignal('claude-4');
|
|
215
|
+
|
|
216
|
+
return (
|
|
217
|
+
<div class="flex h-screen w-full bg-background">
|
|
218
|
+
{/* Sidebar — separate chrome from the thread */}
|
|
219
|
+
<ConversationList groups={groups} conversations={conversations} activeId="1" onSelect={() => {}} onNewChat={() => {}} />
|
|
220
|
+
|
|
221
|
+
<main class="flex flex-1 flex-col overflow-hidden">
|
|
222
|
+
<header class="flex h-14 items-center justify-between border-b border-border px-5">
|
|
223
|
+
<div class="text-sm font-semibold">SolidJS reactivity vs React hooks</div>
|
|
224
|
+
<ModelSwitcher models={models} currentModelId={modelId()} onModelChange={setModelId} />
|
|
225
|
+
</header>
|
|
226
|
+
|
|
227
|
+
<ChatContainer class="flex-1">
|
|
228
|
+
<ChatContainerContent class="px-5 pt-4">
|
|
229
|
+
<Message class="group items-start">
|
|
230
|
+
<MessageContent markdown class="prose">{assistantReply}</MessageContent>
|
|
231
|
+
<MessageActions class="opacity-0 group-hover:opacity-100 transition-opacity">
|
|
232
|
+
<Button variant="ghost" size="icon-sm" aria-label="Copy"><Copy class="size-3.5" /></Button>
|
|
233
|
+
<Button variant="ghost" size="icon-sm" aria-label="Good response"><ThumbsUp class="size-3.5" /></Button>
|
|
234
|
+
<Button variant="ghost" size="icon-sm" aria-label="Bad response"><ThumbsDown class="size-3.5" /></Button>
|
|
235
|
+
<Button variant="ghost" size="icon-sm" aria-label="Regenerate"><RefreshCw class="size-3.5" /></Button>
|
|
236
|
+
</MessageActions>
|
|
237
|
+
</Message>
|
|
238
|
+
<ChatContainerScrollAnchor />
|
|
239
|
+
</ChatContainerContent>
|
|
240
|
+
<ScrollButton />
|
|
241
|
+
</ChatContainer>
|
|
242
|
+
|
|
243
|
+
<div class="px-5 pb-5">
|
|
244
|
+
<div class="flex gap-2 pb-3">
|
|
245
|
+
<For each={['How does SolidJS handle context?', 'Show me a store example']}>
|
|
246
|
+
{(s) => <PromptSuggestion onClick={() => setValue(s)}>{s}</PromptSuggestion>}
|
|
247
|
+
</For>
|
|
248
|
+
</div>
|
|
249
|
+
<PromptInput value={value()} onValueChange={setValue} onSubmit={() => setValue('')}>
|
|
250
|
+
<PromptInputTextarea placeholder="Ask anything..." />
|
|
251
|
+
<PromptInputActions class="justify-end">
|
|
252
|
+
<Button size="icon-sm" disabled={!value().trim()} aria-label="Send message"><ArrowUp class="size-4" /></Button>
|
|
253
|
+
</PromptInputActions>
|
|
254
|
+
</PromptInput>
|
|
255
|
+
</div>
|
|
256
|
+
</main>
|
|
257
|
+
</div>
|
|
258
|
+
);
|
|
259
|
+
}`,
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Example: Full Chat App — the complete experience. As an embedder you reach for
|
|
265
|
+
* the single `<kai-chat>` element; the live demo composes the granular SolidJS
|
|
266
|
+
* primitives for full control. Per-story: the Usage tab shows the snippet for the
|
|
267
|
+
* story you're on; the example-level fields below are the fallback.
|
|
268
|
+
*/
|
|
269
|
+
const fullChatApp: ExampleUsage = {
|
|
270
|
+
title: 'Examples/Full Chat App',
|
|
271
|
+
...fullChat, // example-level fallback = the "Default" story
|
|
272
|
+
stories: {
|
|
273
|
+
Default: fullChat,
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
export default fullChatApp;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { ExampleUsage } from './types';
|
|
2
|
+
import messageActions from './message-actions';
|
|
3
|
+
import streamingResponse from './streaming-response';
|
|
4
|
+
import conversationWithReasoning from './conversation-with-reasoning';
|
|
5
|
+
import conversationWithSources from './conversation-with-sources';
|
|
6
|
+
import promptInputVariants from './prompt-input-variants';
|
|
7
|
+
import contextUsage from './context-usage';
|
|
8
|
+
import checkpointRestore from './checkpoint-restore';
|
|
9
|
+
import fullChatApp from './full-chat-app';
|
|
10
|
+
import emptyState from './empty-state';
|
|
11
|
+
import centeredConversation from './pattern-centered-conversation';
|
|
12
|
+
import chatPanelLayout from './pattern-chat-panel-layout';
|
|
13
|
+
import dockedWidget from './pattern-docked-widget';
|
|
14
|
+
|
|
15
|
+
export type { ExampleUsage, FrameworkKey } from './types';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Every Example/Pattern that has hand-authored "how to build this" code.
|
|
19
|
+
* Add a module here and it lights up its Code tab automatically.
|
|
20
|
+
*
|
|
21
|
+
* Element-centric examples first, then the 4 layout Patterns — each pattern
|
|
22
|
+
* module carries a `title` that exactly matches its Storybook group title so
|
|
23
|
+
* the Usage tab appears automatically via `exampleUsageStoryIdPrefixes`.
|
|
24
|
+
*/
|
|
25
|
+
export const exampleUsageList: ExampleUsage[] = [
|
|
26
|
+
messageActions,
|
|
27
|
+
streamingResponse,
|
|
28
|
+
conversationWithReasoning,
|
|
29
|
+
conversationWithSources,
|
|
30
|
+
promptInputVariants,
|
|
31
|
+
contextUsage,
|
|
32
|
+
checkpointRestore,
|
|
33
|
+
fullChatApp,
|
|
34
|
+
// Patterns — layout recipes showing how to compose the building blocks
|
|
35
|
+
emptyState,
|
|
36
|
+
centeredConversation,
|
|
37
|
+
chatPanelLayout,
|
|
38
|
+
dockedWidget,
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
/** Lookup by Storybook group title, e.g. `'Examples/Message Actions'`. */
|
|
42
|
+
export const exampleUsageByTitle = new Map(exampleUsageList.map((u) => [u.title, u]));
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Storybook's `sanitize` (from `@storybook/csf`), inlined so the manager addon
|
|
46
|
+
* has no extra dependency. Turns a title into its story-id stem, e.g.
|
|
47
|
+
* `'Examples/Message Actions'` → `'examples-message-actions'`.
|
|
48
|
+
*/
|
|
49
|
+
const sanitize = (s: string): string =>
|
|
50
|
+
s
|
|
51
|
+
.toLowerCase()
|
|
52
|
+
.replace(/[ ’–—―′¿'`~!@#$%^&*()_|+\-=?;:'",.<>{}[\]\\/]/g, '-')
|
|
53
|
+
.replace(/-+/g, '-')
|
|
54
|
+
.replace(/^-+/, '')
|
|
55
|
+
.replace(/-+$/, '');
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Story-id prefixes (`<stem>--`) for entries that have a Code tab. `manager.ts`
|
|
59
|
+
* uses these to show the tab only where we've authored code.
|
|
60
|
+
*/
|
|
61
|
+
export const exampleUsageStoryIdPrefixes: string[] = exampleUsageList.map(
|
|
62
|
+
(u) => `${sanitize(u.title)}--`,
|
|
63
|
+
);
|