@kitnai/chat 0.6.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.
- package/README.md +9 -9
- package/dist/custom-elements.json +1676 -881
- package/dist/kitn-chat.es.js +36 -36
- package/dist/llms/llms-full.txt +316 -155
- package/dist/llms/llms.txt +18 -18
- package/dist/schemas/card-envelope.schema.json +14 -0
- package/dist/schemas/card-event.schema.json +12 -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/task-list.result.schema.json +16 -0
- package/dist/schemas/task-list.schema.json +78 -0
- package/dist/theme.tokens.css +65 -65
- package/dist/tsx-B8rCNbgL.js +1 -0
- package/dist/typescript-RycA9KXf.js +1 -0
- package/frameworks/react/index.tsx +382 -193
- package/frameworks/react/runtime.tsx +2 -2
- package/llms-full.txt +316 -155
- package/llms.txt +18 -18
- package/package.json +5 -2
- package/src/components/artifact.stories.tsx +138 -0
- package/src/components/artifact.tsx +581 -0
- package/src/components/attachments.stories.tsx +7 -8
- package/src/components/attachments.tsx +2 -2
- package/src/components/card.tsx +110 -0
- package/src/components/chain-of-thought.stories.tsx +7 -8
- package/src/components/chat-container.stories.tsx +7 -8
- package/src/components/chat-container.tsx +4 -0
- package/src/components/checkpoint.stories.tsx +7 -8
- package/src/components/code-block.stories.tsx +8 -9
- package/src/components/component-meta.json +3411 -0
- package/src/components/confirm-card.stories.tsx +74 -0
- package/src/components/confirm-card.tsx +299 -0
- package/src/components/context.stories.tsx +7 -8
- package/src/components/conversation-item.stories.tsx +7 -8
- package/src/components/conversation-item.tsx +2 -2
- package/src/components/conversation-list.stories.tsx +7 -8
- package/src/components/conversation-list.tsx +1 -1
- package/src/components/embed.tsx +196 -0
- package/src/components/empty.stories.tsx +8 -9
- package/src/components/feedback-bar.stories.tsx +7 -8
- package/src/components/file-tree.stories.tsx +73 -0
- package/src/components/file-tree.tsx +383 -0
- package/src/components/file-upload.stories.tsx +7 -8
- package/src/components/form-widgets.tsx +461 -0
- package/src/components/form.tsx +796 -0
- package/src/components/image.stories.tsx +7 -8
- package/src/components/link-card.tsx +194 -0
- package/src/components/loader.stories.tsx +7 -8
- package/src/components/markdown.stories.tsx +7 -8
- package/src/components/message-narrow.stories.tsx +12 -13
- package/src/components/message-skills.stories.tsx +16 -17
- package/src/components/message.stories.tsx +17 -18
- package/src/components/model-switcher.stories.tsx +7 -8
- package/src/components/prompt-input.stories.tsx +8 -9
- package/src/components/prompt-suggestion.stories.tsx +7 -8
- package/src/components/prompt-suggestion.tsx +3 -3
- package/src/components/reasoning.stories.tsx +7 -8
- package/src/components/scroll-button.stories.tsx +7 -8
- package/src/components/slash-command.stories.tsx +8 -9
- package/src/components/slash-command.tsx +2 -2
- package/src/components/source.stories.tsx +7 -8
- package/src/components/source.tsx +1 -1
- package/src/components/task-list-card.stories.tsx +78 -0
- package/src/components/task-list-card.tsx +388 -0
- package/src/components/text-shimmer.stories.tsx +7 -8
- package/src/components/thinking-bar.stories.tsx +7 -8
- package/src/components/tool.stories.tsx +7 -8
- package/src/components/tool.tsx +2 -2
- package/src/components/voice-input.stories.tsx +7 -8
- package/src/elements/artifact.stories.tsx +291 -0
- package/src/elements/artifact.tsx +72 -0
- package/src/elements/{kitn-attachments.stories.tsx → attachments.stories.tsx} +11 -11
- package/src/elements/attachments.tsx +4 -4
- package/src/elements/card.stories.tsx +118 -0
- package/src/elements/card.tsx +40 -0
- package/src/elements/catalog.stories.tsx +491 -0
- package/src/elements/{kitn-chain-of-thought.stories.tsx → chain-of-thought.stories.tsx} +13 -13
- package/src/elements/chain-of-thought.tsx +3 -3
- package/src/elements/{kitn-chat-scope-picker.stories.tsx → chat-scope-picker.stories.tsx} +10 -10
- package/src/elements/chat-scope-picker.tsx +4 -4
- package/src/elements/{kitn-chat-workspace.stories.tsx → chat-workspace.stories.tsx} +71 -29
- package/src/elements/chat-workspace.tsx +29 -3
- package/src/elements/{kitn-chat.stories.tsx → chat.stories.tsx} +61 -16
- package/src/elements/chat.tsx +23 -2
- package/src/elements/{kitn-checkpoint.stories.tsx → checkpoint.stories.tsx} +11 -11
- package/src/elements/checkpoint.tsx +4 -4
- package/src/elements/{kitn-code-block.stories.tsx → code-block.stories.tsx} +10 -10
- package/src/elements/code-block.tsx +3 -3
- package/src/elements/compiled.css +1 -1
- package/src/elements/composed-shell.stories.tsx +316 -0
- package/src/elements/confirm-card.stories.tsx +186 -0
- package/src/elements/confirm-card.tsx +45 -0
- package/src/elements/{kitn-context-meter.stories.tsx → context-meter.stories.tsx} +10 -10
- package/src/elements/context-meter.tsx +3 -3
- package/src/elements/{kitn-conversation-list.stories.tsx → conversation-list.stories.tsx} +35 -22
- package/src/elements/conversation-list.tsx +11 -2
- package/src/elements/css.ts +1 -1
- package/src/elements/define.tsx +10 -10
- package/src/elements/element-meta.json +2649 -0
- package/src/elements/element-types.d.ts +251 -125
- package/src/elements/embed.stories.tsx +197 -0
- package/src/elements/embed.tsx +35 -0
- package/src/elements/{kitn-empty.stories.tsx → empty.stories.tsx} +12 -12
- package/src/elements/empty.tsx +3 -3
- package/src/elements/{kitn-feedback-bar.stories.tsx → feedback-bar.stories.tsx} +11 -11
- package/src/elements/feedback-bar.tsx +4 -4
- package/src/elements/file-tree.stories.tsx +133 -0
- package/src/elements/file-tree.tsx +52 -0
- package/src/elements/{kitn-file-upload.stories.tsx → file-upload.stories.tsx} +12 -12
- package/src/elements/file-upload.tsx +4 -4
- package/src/elements/form.stories.tsx +204 -0
- package/src/elements/form.tsx +37 -0
- package/src/elements/{kitn-image.stories.tsx → image.stories.tsx} +10 -10
- package/src/elements/image.tsx +3 -3
- package/src/elements/link-card.stories.tsx +193 -0
- package/src/elements/link-card.tsx +34 -0
- package/src/elements/{kitn-loader.stories.tsx → loader.stories.tsx} +11 -11
- package/src/elements/loader.tsx +3 -3
- package/src/elements/{kitn-markdown.stories.tsx → markdown.stories.tsx} +10 -10
- package/src/elements/markdown.tsx +3 -3
- package/src/elements/{kitn-message-skills.stories.tsx → message-skills.stories.tsx} +10 -10
- package/src/elements/message-skills.tsx +3 -3
- package/src/elements/{kitn-message.stories.tsx → message.stories.tsx} +12 -12
- package/src/elements/message.tsx +5 -5
- package/src/elements/{kitn-model-switcher.stories.tsx → model-switcher.stories.tsx} +10 -10
- package/src/elements/model-switcher.tsx +5 -5
- package/src/elements/{kitn-prompt-input.stories.tsx → prompt-input.stories.tsx} +41 -19
- package/src/elements/prompt-input.tsx +5 -5
- package/src/elements/{kitn-prompt-suggestions.stories.tsx → prompt-suggestions.stories.tsx} +13 -13
- package/src/elements/prompt-suggestions.tsx +4 -4
- package/src/elements/{kitn-reasoning.stories.tsx → reasoning.stories.tsx} +10 -10
- package/src/elements/reasoning.tsx +4 -4
- package/src/elements/register.ts +11 -1
- package/src/elements/resizable.stories.tsx +200 -0
- package/src/elements/resizable.tsx +264 -0
- package/src/elements/{kitn-response-stream.stories.tsx → response-stream.stories.tsx} +10 -10
- package/src/elements/response-stream.tsx +4 -4
- package/src/elements/{kitn-source-list.stories.tsx → source-list.stories.tsx} +11 -11
- package/src/elements/{kitn-source.stories.tsx → source.stories.tsx} +12 -12
- package/src/elements/source.tsx +5 -5
- package/src/elements/styles.css +140 -1
- package/src/elements/task-list-card.stories.tsx +194 -0
- package/src/elements/task-list-card.tsx +40 -0
- package/src/elements/{kitn-text-shimmer.stories.tsx → text-shimmer.stories.tsx} +10 -10
- package/src/elements/text-shimmer.tsx +3 -3
- package/src/elements/{kitn-thinking-bar.stories.tsx → thinking-bar.stories.tsx} +11 -11
- package/src/elements/thinking-bar.tsx +5 -5
- package/src/elements/{kitn-tool.stories.tsx → tool.stories.tsx} +10 -10
- package/src/elements/tool.tsx +3 -3
- package/src/elements/{kitn-voice-input.stories.tsx → voice-input.stories.tsx} +10 -10
- package/src/elements/voice-input.tsx +4 -4
- package/src/index.ts +94 -2
- package/src/primitives/card-contract.ts +60 -0
- package/src/primitives/card-host.tsx +35 -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/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/task-list.result.schema.json +16 -0
- package/src/primitives/card-schemas/task-list.schema.json +78 -0
- package/src/primitives/card-validate.ts +95 -0
- package/src/primitives/embed-providers.ts +254 -0
- package/src/primitives/highlighter.ts +4 -0
- package/src/primitives/link-preview.ts +87 -0
- package/src/primitives/pdf-preview.ts +121 -0
- package/src/stories/chat-panel-layout.stories.tsx +2 -1
- package/src/stories/chat-scene.tsx +22 -21
- package/src/stories/checkpoint-restore.stories.tsx +10 -10
- package/src/stories/conversation-with-reasoning.stories.tsx +4 -4
- package/src/stories/conversation-with-sources.stories.tsx +7 -7
- package/src/stories/docs/Accessibility.mdx +2 -2
- package/src/stories/docs/ForAIAgents.mdx +3 -3
- package/src/stories/docs/GettingStarted.mdx +2 -2
- package/src/stories/docs/Installation.mdx +2 -2
- package/src/stories/docs/Integrations.mdx +29 -29
- package/src/stories/docs/Introduction.mdx +3 -3
- package/src/stories/docs/Theming.mdx +2 -2
- package/src/stories/docs/element-controls.ts +60 -0
- package/src/stories/docs/theme-editor/theme-editor.tsx +1 -0
- package/src/stories/examples/ChoosingComponents.mdx +94 -0
- package/src/stories/examples/sample-data.ts +79 -0
- package/src/stories/message-actions.stories.tsx +13 -13
- package/src/stories/pattern-centered-conversation.stories.tsx +3 -3
- package/src/stories/pattern-docked-widget.stories.tsx +1 -1
- package/src/stories/pattern-empty-state.stories.tsx +3 -3
- package/src/stories/prompt-input-variants.stories.tsx +13 -13
- package/src/stories/streaming-response.stories.tsx +3 -3
- package/src/stories/typography.stories.tsx +4 -4
- package/src/ui/avatar.stories.tsx +7 -8
- package/src/ui/badge.stories.tsx +7 -8
- package/src/ui/button.stories.tsx +8 -9
- package/src/ui/button.tsx +1 -0
- package/src/ui/collapsible.stories.tsx +6 -7
- package/src/ui/dropdown.stories.tsx +6 -7
- package/src/ui/hover-card.stories.tsx +6 -7
- package/src/ui/resizable.stories.tsx +74 -9
- package/src/ui/resizable.tsx +351 -71
- package/src/ui/scroll-area.stories.tsx +6 -7
- package/src/ui/scroll-area.tsx +3 -1
- package/src/ui/separator.stories.tsx +7 -8
- package/src/ui/skeleton.stories.tsx +7 -8
- package/src/ui/textarea.stories.tsx +6 -7
- package/src/ui/tooltip.stories.tsx +8 -9
- package/theme.css +65 -65
|
@@ -1,14 +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 <
|
|
3
|
+
import './register'; // side effect: registers <kc-chat>, <kc-conversations>, <kc-prompt-input>
|
|
4
4
|
import type { ConversationGroup, ConversationSummary } from '../types';
|
|
5
|
+
import { argTypesFor, specDescription } from '../stories/docs/element-controls';
|
|
5
6
|
|
|
6
7
|
// The web components are custom DOM elements, so declare the tags for JSX.
|
|
7
8
|
declare module 'solid-js' {
|
|
8
9
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
9
10
|
namespace JSX {
|
|
10
11
|
interface IntrinsicElements {
|
|
11
|
-
'
|
|
12
|
+
'kc-conversations': JSX.HTMLAttributes<HTMLElement>;
|
|
12
13
|
}
|
|
13
14
|
}
|
|
14
15
|
}
|
|
@@ -56,32 +57,41 @@ const sampleConversations: ConversationSummary[] = [
|
|
|
56
57
|
},
|
|
57
58
|
];
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
60
|
+
type ConversationListEl = HTMLElement & {
|
|
61
|
+
groups?: ConversationGroup[];
|
|
62
|
+
conversations?: ConversationSummary[];
|
|
63
|
+
activeId?: string;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/** Live demo of the actual `<kc-conversations>` custom element (Shadow DOM and all). */
|
|
67
|
+
function ConversationListElement(props: { args?: Record<string, unknown> }) {
|
|
68
|
+
let el: ConversationListEl | undefined;
|
|
68
69
|
onMount(() => {
|
|
69
70
|
if (el) {
|
|
71
|
+
// Fixed array data
|
|
70
72
|
el.groups = sampleGroups;
|
|
71
73
|
el.conversations = sampleConversations;
|
|
72
74
|
el.activeId = 'c-1';
|
|
75
|
+
// Scalar args from Controls
|
|
76
|
+
const args = props.args;
|
|
77
|
+
if (args) {
|
|
78
|
+
const scalarNames = ['activeId'];
|
|
79
|
+
for (const name of scalarNames) {
|
|
80
|
+
if (name in args) (el as unknown as Record<string, unknown>)[name] = args[name];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
73
83
|
}
|
|
74
84
|
});
|
|
75
85
|
return (
|
|
76
|
-
<
|
|
77
|
-
ref={(e) => (el = e as
|
|
86
|
+
<kc-conversations
|
|
87
|
+
ref={(e) => (el = e as ConversationListEl)}
|
|
78
88
|
style={{ display: 'block', width: '300px', height: '560px' }}
|
|
79
89
|
/>
|
|
80
90
|
);
|
|
81
91
|
}
|
|
82
92
|
|
|
83
93
|
const HTML_SNIPPET = `<!-- Works in any framework or plain HTML -->
|
|
84
|
-
<
|
|
94
|
+
<kc-conversations id="list" style="display:block; width:300px; height:100vh;"></kc-conversations>
|
|
85
95
|
|
|
86
96
|
<script type="module">
|
|
87
97
|
import '@kitnai/chat/elements'; // registers the custom elements
|
|
@@ -131,7 +141,7 @@ function Sidebar() {
|
|
|
131
141
|
el.activeId = 'c-1';
|
|
132
142
|
});
|
|
133
143
|
return (
|
|
134
|
-
<
|
|
144
|
+
<kc-conversations
|
|
135
145
|
ref={el}
|
|
136
146
|
style={{ display: 'block', width: '300px', height: '100vh' }}
|
|
137
147
|
on:select={(e) => console.log('opened:', e.detail.id)}
|
|
@@ -142,20 +152,19 @@ function Sidebar() {
|
|
|
142
152
|
}`;
|
|
143
153
|
|
|
144
154
|
const meta = {
|
|
145
|
-
title: 'Web Components/
|
|
155
|
+
title: 'Web Components/kc-conversations',
|
|
146
156
|
tags: ['autodocs'],
|
|
157
|
+
argTypes: argTypesFor('kc-conversations'),
|
|
147
158
|
parameters: {
|
|
148
159
|
layout: 'fullscreen',
|
|
149
160
|
docs: {
|
|
150
|
-
description:
|
|
151
|
-
|
|
152
|
-
'`<kitn-conversation-list>` is the framework-agnostic **web component** version of the chat sidebar — a searchable, grouped list of conversations with a "new chat" button, 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.',
|
|
161
|
+
description: specDescription('kc-conversations', [
|
|
162
|
+
'`<kc-conversations>` is the framework-agnostic **web component** version of the chat sidebar — a searchable, grouped list of conversations with a "new chat" button, 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.',
|
|
153
163
|
'**When to use:** adding a conversation switcher to 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 `ConversationList` primitive instead.',
|
|
154
164
|
'**How to use:** register once with `import \'@kitnai/chat/elements\'`, set rich data as JS **properties** (`el.groups = [...]`, `el.conversations = [...]`, `el.activeId = \'c-1\'`), and listen for **CustomEvents** (`select`, `newchat`, `togglesidebar`) directly on the element.',
|
|
155
165
|
'**Placement:** as a fixed-width side panel next to the chat surface. Give it an explicit width and height (e.g. `width: 300px; height: 100vh`).',
|
|
156
166
|
'See the **Code** tab below for the HTML usage; the *SolidJS* story shows the same element inside a Solid component.',
|
|
157
|
-
]
|
|
158
|
-
},
|
|
167
|
+
]),
|
|
159
168
|
},
|
|
160
169
|
},
|
|
161
170
|
} satisfies Meta;
|
|
@@ -165,7 +174,10 @@ type Story = StoryObj;
|
|
|
165
174
|
|
|
166
175
|
/** The element used the plain-HTML / any-framework way. */
|
|
167
176
|
export const Default: Story = {
|
|
168
|
-
|
|
177
|
+
args: {
|
|
178
|
+
activeId: 'c-1',
|
|
179
|
+
},
|
|
180
|
+
render: (args: Record<string, unknown>) => <ConversationListElement args={args} />,
|
|
169
181
|
parameters: { docs: { source: { code: HTML_SNIPPET, language: 'html' } } },
|
|
170
182
|
};
|
|
171
183
|
|
|
@@ -175,3 +187,4 @@ export const InSolidJS: Story = {
|
|
|
175
187
|
render: () => <ConversationListElement />,
|
|
176
188
|
parameters: { docs: { source: { code: SOLID_SNIPPET, language: 'tsx' } } },
|
|
177
189
|
};
|
|
190
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defineWebComponent } from './define';
|
|
2
2
|
import { ConversationList } from '../components/conversation-list';
|
|
3
3
|
import type { ConversationGroup, ConversationSummary } from '../types';
|
|
4
4
|
|
|
@@ -14,7 +14,16 @@ interface Props extends Record<string, unknown> {
|
|
|
14
14
|
activeId?: string;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
interface Events {
|
|
18
|
+
/** A conversation was selected. */
|
|
19
|
+
select: { id: string };
|
|
20
|
+
/** The "New chat" button was clicked. */
|
|
21
|
+
newchat: Record<string, never>;
|
|
22
|
+
/** The sidebar toggle was clicked. */
|
|
23
|
+
togglesidebar: Record<string, never>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
defineWebComponent<Props, Events>('kc-conversations', {
|
|
18
27
|
groups: [],
|
|
19
28
|
conversations: [],
|
|
20
29
|
activeId: undefined,
|
package/src/elements/css.ts
CHANGED
package/src/elements/define.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { customElement } from 'solid-element';
|
|
2
2
|
import { ChatConfig } from '../primitives/chat-config';
|
|
3
|
-
import {
|
|
3
|
+
import { ELEMENT_CSS } from './css';
|
|
4
4
|
import { createSignal, onCleanup, onMount, Show, type JSX } from 'solid-js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -17,7 +17,7 @@ function getSharedSheet(): CSSStyleSheet | null {
|
|
|
17
17
|
try {
|
|
18
18
|
if (typeof CSSStyleSheet === 'undefined') throw new Error('no CSSStyleSheet');
|
|
19
19
|
const sheet = new CSSStyleSheet();
|
|
20
|
-
sheet.replaceSync(
|
|
20
|
+
sheet.replaceSync(ELEMENT_CSS);
|
|
21
21
|
sharedSheet = sheet;
|
|
22
22
|
} catch {
|
|
23
23
|
sharedSheet = null;
|
|
@@ -47,7 +47,7 @@ function createDarkMode(getTheme: () => string | undefined) {
|
|
|
47
47
|
* `{ eventName: detailType }` — which types `dispatch` so a facade can only fire
|
|
48
48
|
* its declared events with the right `detail` shape.
|
|
49
49
|
*/
|
|
50
|
-
export interface
|
|
50
|
+
export interface WebComponentContext<E = Record<string, unknown>> {
|
|
51
51
|
/** The custom-element host node. */
|
|
52
52
|
element: HTMLElement;
|
|
53
53
|
/** Fire a non-bubbling, non-composed CustomEvent off the host. Consumers
|
|
@@ -74,13 +74,13 @@ function toAttr(name: string): string {
|
|
|
74
74
|
return name.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
/** Underlying flag resolution; see `
|
|
77
|
+
/** Underlying flag resolution; see `WebComponentContext.flag`. */
|
|
78
78
|
function resolveFlag(element: HTMLElement, value: unknown, attribute: string): boolean {
|
|
79
79
|
if (value === true) return true;
|
|
80
80
|
return element.hasAttribute(attribute) && element.getAttribute(attribute) !== 'false';
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
type FacadeComponent<P, E> = (props: P, ctx:
|
|
83
|
+
type FacadeComponent<P, E> = (props: P, ctx: WebComponentContext<E>) => JSX.Element;
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
86
|
* Register a Solid facade as a Shadow-DOM custom element.
|
|
@@ -94,7 +94,7 @@ type FacadeComponent<P, E> = (props: P, ctx: KitnElementContext<E>) => JSX.Eleme
|
|
|
94
94
|
* the element, so bubbling/composed would only cause consumer collisions).
|
|
95
95
|
* - Idempotent: redefining an already-registered tag is a no-op.
|
|
96
96
|
*/
|
|
97
|
-
export function
|
|
97
|
+
export function defineWebComponent<P extends Record<string, unknown>, E = Record<string, unknown>>(
|
|
98
98
|
tag: string,
|
|
99
99
|
propDefaults: P,
|
|
100
100
|
Facade: FacadeComponent<P, E>,
|
|
@@ -111,7 +111,7 @@ export function defineKitnElement<P extends Record<string, unknown>, E = Record<
|
|
|
111
111
|
for (const key of Object.keys(propDefaults)) {
|
|
112
112
|
if (RESERVED.includes(key)) {
|
|
113
113
|
throw new Error(
|
|
114
|
-
`
|
|
114
|
+
`defineWebComponent(${tag}): prop "${key}" collides with a global HTMLElement ` +
|
|
115
115
|
`attribute and will break the element constructor. Rename it (e.g. ` +
|
|
116
116
|
`"bar-title" → barTitle, a source title → headline).`,
|
|
117
117
|
);
|
|
@@ -131,10 +131,10 @@ export function defineKitnElement<P extends Record<string, unknown>, E = Record<
|
|
|
131
131
|
const dispatch = ((type: string, detail?: unknown) =>
|
|
132
132
|
element.dispatchEvent(
|
|
133
133
|
new CustomEvent(type, { detail, bubbles: false, composed: false }),
|
|
134
|
-
)) as
|
|
134
|
+
)) as WebComponentContext<E>['dispatch'];
|
|
135
135
|
|
|
136
136
|
// Reads `props[name]` (reactive) and falls back to attribute presence so
|
|
137
|
-
// bare boolean attributes behave like normal HTML. See
|
|
137
|
+
// bare boolean attributes behave like normal HTML. See WebComponentContext.
|
|
138
138
|
const flag = (name: string) =>
|
|
139
139
|
resolveFlag(element, (props as Record<string, unknown>)[name], toAttr(name));
|
|
140
140
|
|
|
@@ -153,7 +153,7 @@ export function defineKitnElement<P extends Record<string, unknown>, E = Record<
|
|
|
153
153
|
return (
|
|
154
154
|
<>
|
|
155
155
|
<Show when={!sheet}>
|
|
156
|
-
<style>{
|
|
156
|
+
<style>{ELEMENT_CSS}</style>
|
|
157
157
|
</Show>
|
|
158
158
|
{/* display:contents — no layout box; carries the .dark token scope and
|
|
159
159
|
re-roots the inherited `color` to the active mode's foreground, so text
|