# ChatWindow

`ChatWindow` owns a launcher and a conversation dialog that can switch between floating and modal fullscreen layouts.

## Usage

Load `@dg/ui/styles.css` once in the root layout.

```svelte
<script>
  import { ChatWindow, ChatPanel, ChatThread, ChatMessage, ChatComposer } from "@dg/ui";
  let draft = $state("");
  let lastSent = $state("");
</script>

<ChatWindow id="support-chat" title="Support">
  <ChatPanel>
    <ChatThread><ChatMessage text="How can I help?" /></ChatThread>
    <ChatComposer
      id="support-question"
      bind:value={draft}
      onsend={(text) => {
        lastSent = text;
        draft = "";
      }}
    />
  </ChatPanel>
</ChatWindow>
<p class="feedback" aria-live="polite">{lastSent}</p>
```

## Notes

- The expand, collapse and close controls use built-in names in the `Page` language.
- Native HTML attributes, DOM callbacks, class and style are forwarded to the dialog; it owns its ID, accessible name and cancel behavior.
- Forwarding uses native attribute types; unknown props are not supported. Pass class as a string.
- Floating mode uses `--floating-shadow` and `--floating-layer`; fullscreen uses the native modal top layer without a shadow.
- Use bind:this for methods. Fullscreen is a modal layout, not the browser Fullscreen API. The parent supplies messages, draft state and any backend calls.
- Methods require a mounted instance through bind:this. Closing preserves draft and child state; the app owns persistence across unmounts and reloads. Fullscreen centers the panel and restores focus to the resize control after switching.

## Parameters

| Name       | Type      | Default     | Description                                                                              |
| ---------- | --------- | ----------- | ---------------------------------------------------------------------------------------- |
| `id`       | `string`  | `Required`  | Unique dialog ID; also connects its launcher and title.                                  |
| `title`    | `string`  | `undefined` | Window title and launcher label. Defaults to the built-in assistant name.                |
| `subtitle` | `string`  | `""`        | Optional supporting text in the window header.                                           |
| `badge`    | `string`  | `""`        | Optional short badge in the header and launcher.                                         |
| `symbol`   | `string`  | `"✳"`       | Decorative launcher symbol.                                                              |
| `children` | `Snippet` | `undefined` | Window content, usually `ChatPanel`. Children remain mounted while the window is closed. |

## Methods

| Name                 | Description                                                                                      |
| -------------------- | ------------------------------------------------------------------------------------------------ |
| `open()`             | Open the floating window and focus its first textarea or input. Returns a Promise.               |
| `close()`            | Close either layout, release scroll locking and restore launcher focus. Returns a Promise.       |
| `toggleFullscreen()` | Open if necessary, then switch between floating and modal fullscreen layouts. Returns a Promise. |

## Accessibility

Supply a unique id. Opening focuses the first input; closing restores launcher focus. Escape closes either mode. Fullscreen uses showModal and locks document scrolling on the root element, like `Dialog`; floating mode leaves the page interactive. `ChatWindow` keeps its own dialog lifecycle because its floating mode is nonmodal, which `Dialog` does not support. Children remain mounted while closed, but unmounting `ChatWindow` destroys them.
