# Frameworks

The kai-* web components run in any framework — React adds a typed adapter, SolidJS adds native components.

The `kai-*` web components drop into React, Vue, Angular, Svelte, or plain HTML with a single import — no per-framework package, no wrappers. React adds a typed adapter; in a Solid app you can import the native components directly.

## Pick an entry point

| Entry | Use it for |
|---|---|
| `@kitn.ai/ui/elements` | Any framework — registers every `kai-*` element |
| `@kitn.ai/ui/react` | React — typed wrappers with camelCase props and event handlers |
| `@kitn.ai/ui/solid` | SolidJS — native Solid components for full compositional control |
| `@kitn.ai/ui` | The shared layer every framework uses — types, state and card helpers |

## Any framework: the web components

Import `@kitn.ai/ui/elements` once for its side effect. It registers every `kai-*` element; after that they work like built-in HTML.

```ts

```

Registration is **async**. If your framework sets array or object properties as it mounts (Vue, Angular, Svelte all do), mount behind the `elementsReady` promise the same entry exports. A property written before the element upgrades is lost.

```ts

elementsReady.then(() => mountYourApp());
```

Then use them in your templates:

<Tabs>
  <TabItem label="HTML">
    ```html
    <kai-chat style="display:block; height:100%;"></kai-chat>

    <script type="module">

      await customElements.whenDefined('kai-chat');

      const chat = document.querySelector('kai-chat');
      chat.messages = [{ id: '1', role: 'assistant', parts: [{ type: 'text', text: 'Hello!' }] }];
      chat.addEventListener('kai-submit', (e) => console.log(e.detail));
    </script>
    ```
  </TabItem>
  <TabItem label="Vue">
    ```vue
    <script setup>

    const messages = ref([{ id: '1', role: 'assistant', parts: [{ type: 'text', text: 'Hello!' }] }]);
    </script>

    <template>
      <kai-chat
        :messages.prop="messages"
        @kai-submit="onSubmit"
      />
    </template>
    ```
  </TabItem>
  <TabItem label="Svelte">
    ```svelte
    <script>

    let messages = [{ id: '1', role: 'assistant', parts: [{ type: 'text', text: 'Hello!' }] }];
    </script>

    <kai-chat
      {messages}
      on:kai-submit={onSubmit}
    ></kai-chat>
    ```
  </TabItem>
  <TabItem label="Angular">
    ```ts
    // main.ts

    elementsReady.then(() => bootstrapApplication(AppComponent, appConfig));
    ```

    ```ts
    // the component using kai-* tags
    @Component({ /* … */ schemas: [CUSTOM_ELEMENTS_SCHEMA] })
    export class AppComponent {}
    ```

    ```html
    <!-- template -->
    <kai-chat
      [messages]="messages"
      (kai-submit)="onSubmit($event)"
    ></kai-chat>
    ```
  </TabItem>
</Tabs>

## Properties vs. attributes

The one thing to get right: Arrays and objects must be set in JavaScript, not as HTML attributes — an attribute is always a string, so writing `messages` or `models` as an attribute silently does nothing.

```js
const chat = document.querySelector('kai-chat');

// Right: set the array in JavaScript.
chat.messages = [{ id: '1', role: 'assistant', parts: [{ type: 'text', text: 'Hello!' }] }];

// Wrong: an attribute is a string, so the element never gets the array.
// <kai-chat messages="[...]"></kai-chat>
```

Scalars — `placeholder`, `loading`, `theme`, `prose-size` — work fine as attributes. Each framework's binding picks the right path for you: Vue uses `:prop.prop`, Angular uses `[prop]`, Svelte binds objects directly.

## Events

Every `kai-*` element dispatches `CustomEvent`s with a `detail` payload, named with a `kai-` prefix (`kai-submit`, `kai-model-change`, `kai-remove`, …).

```js
chat.addEventListener('kai-submit', (e) => {
  const { value } = e.detail;
  // send value to your model API
});
```

The events don't bubble — listen on the element itself.

## React adapter

`@kitn.ai/ui/react` exports a typed component for every element. Props take arrays and objects directly (no `.prop` modifier), and events arrive as camelCase handler props that receive the `CustomEvent`.

```tsx

export function MyChatApp() {
  return (
    <Chat
      messages={messages}
      onSubmit={(e) => console.log(e.detail.value)}
      onModelChange={(e) => console.log(e.detail)}
    />
  );
}
```

> **tip:** 
The React adapter ships full types for every prop and event, including the `ChatMessage` shape for `messages` and the `detail` type on each event.

## SolidJS native components

Writing Solid? Skip the element wrapper and compose the kit's native components from `@kitn.ai/ui/solid`. That entry is the complete Solid catalog, compiled as its own bundle so the other frameworks never pay for it. It tree-shakes to exactly what you import and mixes freely with your own primitives.

```tsx

  Button,
  ChatConfig,
  ChatContainer,
  ChatContainerContent,
  Message,
  MessageContent,
  PromptInput,
  PromptInputTextarea,
  PromptInputActions,
} from '@kitn.ai/ui/solid';

export function App() {
  const [input, setInput] = createSignal('');

  return (
    <ChatConfig>
      <ChatContainer style={{ height: '100dvh' }}>
        <ChatContainerContent>
          <Message>
            <MessageContent markdown>Hello! How can I help?</MessageContent>
          </Message>
        </ChatContainerContent>
      </ChatContainer>
      <PromptInput
        value={input()}
        onValueChange={setInput}
        onSubmit={() => {
          handleSubmit(input());
          setInput('');
        }}
      >
        
        <PromptInputActions>
          <Button size="sm" disabled={!input()}>Send</Button>
        </PromptInputActions>
      </PromptInput>
    </ChatConfig>
  );
}
```

Solid usage also needs `solid-js` as a peer dependency:

```bash
npm install solid-js
```

Unlike the elements, the native components are Tailwind v4 classes, so this path also needs Tailwind in the app plus an `@source` line pointing at the package. Rendering a real thread means `MessageBody` over each message's ordered `parts`, or `Thread` for the whole list at once. Both are covered in the [SolidJS guide](/guides/frameworks/solid/).

## Per-framework guides

Full setup, binding patterns, and examples for each environment:

- [HTML](/guides/frameworks/html/)
- [React](/guides/frameworks/react/)
- [Vue](/guides/frameworks/vue/)
- [Svelte](/guides/frameworks/svelte/)
- [Angular](/guides/frameworks/angular/)
- [SolidJS](/guides/frameworks/solid/)
