@g9tm/aiassistant-svelte 1.0.0 → 1.1.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.
@@ -1,49 +1,52 @@
1
- <script lang="ts">
2
- // The panel in six layouts (sheet, side, fullscreen, inline, card, compact) or "auto" by the container's width; the
3
- // layout can change live without losing the conversation. Escape closes; Alt+A (by key position, so it works with a
4
- // Persian keyboard) toggles. Dialogs inside sit above the panel.
5
- import type { Snippet } from "svelte";
6
- import { pickLayout, type Layout, type LayoutThresholds } from "@g9tm/aiassistant";
7
- import { cls, sty, useUi } from "../context.js";
8
- import AssistantChat from "./AssistantChat.svelte";
9
-
10
- let { open = $bindable(true), layout = "auto", thresholds = undefined, title = undefined, header = undefined, onclose = undefined }: {
11
- open?: boolean; layout?: Layout; thresholds?: LayoutThresholds | undefined; title?: string | undefined; header?: Snippet | undefined; onclose?: (() => void) | undefined;
12
- } = $props();
13
- const ui = useUi();
14
- const t = ui.texts.t;
15
- let width = $state(1024);
16
- let opener: Element | null = null;
17
- const current = $derived(pickLayout(layout, width, thresholds));
18
-
19
- function close(): void {
20
- open = false;
21
- onclose?.();
22
- if (opener instanceof HTMLElement) opener.focus(); // focus goes back to what opened it
23
- }
24
-
25
- function onkey(e: KeyboardEvent): void {
26
- if (e.altKey && e.code === "KeyA") {
27
- e.preventDefault();
28
- if (!open) opener = document.activeElement;
29
- open = !open;
30
- } else if (e.key === "Escape" && open && current !== "inline" && current !== "card") close();
31
- }
32
- </script>
33
-
34
- <svelte:window onkeydown={onkey} />
35
-
36
- <div class="g9a-measure" bind:clientWidth={width}></div>
37
- {#if open || current === "inline" || current === "card"}
38
- <section class={cls(ui, "panel")} style={sty(ui, "panel") ?? ""} data-layout={current} role={current === "sheet" || current === "fullscreen" ? "dialog" : "region"}
39
- aria-label={title ?? t("assistant.name")} style:z-index={current === "inline" || current === "card" ? undefined : ui.layer - 1}>
40
- {#if current !== "compact"}
41
- <header class={cls(ui, "panel.header")}>
42
- {#if header}{@render header()}{:else}<strong>{title ?? t("assistant.name")}</strong>{/if}
43
- <button type="button" onclick={() => ui.assistant.fresh()}>{t("panel.new")}</button>
44
- {#if current !== "inline" && current !== "card"}<button type="button" aria-label={t("panel.close")} onclick={close}>×</button>{/if}
45
- </header>
46
- {/if}
47
- <div class={cls(ui, "panel.body")}><AssistantChat /></div>
48
- </section>
49
- {/if}
1
+ <script lang="ts">
2
+ // The panel in six layouts (sheet, side, fullscreen, inline, card, compact) or "auto" by the container's width; the
3
+ // layout can change live without losing the conversation. Escape closes; Alt+A (by key position, so it works with a
4
+ // Persian keyboard) toggles. Dialogs inside sit above the panel.
5
+ import type { Snippet } from "svelte";
6
+ import { pickLayout, type Layout, type LayoutThresholds } from "@g9tm/aiassistant";
7
+ import { cls, override, sty, useUi } from "../context.js";
8
+ import PdfButton from "../parts/PdfButton.svelte";
9
+ import AssistantChat from "./AssistantChat.svelte";
10
+
11
+ let { open = $bindable(true), layout = "auto", thresholds = undefined, title = undefined, header = undefined, onclose = undefined }: {
12
+ open?: boolean; layout?: Layout; thresholds?: LayoutThresholds | undefined; title?: string | undefined; header?: Snippet | undefined; onclose?: (() => void) | undefined;
13
+ } = $props();
14
+ const ui = useUi();
15
+ const t = ui.texts.t;
16
+ let width = $state(1024);
17
+ let opener: Element | null = null;
18
+ const current = $derived(pickLayout(layout, width, thresholds));
19
+ const Pdf = $derived(override(ui, "PdfButton") ?? PdfButton);
20
+
21
+ function close(): void {
22
+ open = false;
23
+ onclose?.();
24
+ if (opener instanceof HTMLElement) opener.focus(); // focus goes back to what opened it
25
+ }
26
+
27
+ function onkey(e: KeyboardEvent): void {
28
+ if (e.altKey && e.code === "KeyA") {
29
+ e.preventDefault();
30
+ if (!open) opener = document.activeElement;
31
+ open = !open;
32
+ } else if (e.key === "Escape" && open && current !== "inline" && current !== "card") close();
33
+ }
34
+ </script>
35
+
36
+ <svelte:window onkeydown={onkey} />
37
+
38
+ <div class="g9a-measure" bind:clientWidth={width}></div>
39
+ {#if open || current === "inline" || current === "card"}
40
+ <section class={cls(ui, "panel")} style={sty(ui, "panel") ?? ""} data-layout={current} role={current === "sheet" || current === "fullscreen" ? "dialog" : "region"}
41
+ aria-label={title ?? t("assistant.name")} style:z-index={current === "inline" || current === "card" ? undefined : ui.layer - 1}>
42
+ {#if current !== "compact"}
43
+ <header class={cls(ui, "panel.header")}>
44
+ {#if header}{@render header()}{:else}<strong>{title ?? t("assistant.name")}</strong>{/if}
45
+ <button type="button" onclick={() => ui.assistant.fresh()}>{t("panel.new")}</button>
46
+ <Pdf />
47
+ {#if current !== "inline" && current !== "card"}<button type="button" aria-label={t("panel.close")} onclick={close}>×</button>{/if}
48
+ </header>
49
+ {/if}
50
+ <div class={cls(ui, "panel.body")}><AssistantChat /></div>
51
+ </section>
52
+ {/if}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@g9tm/aiassistant-svelte",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Svelte 5 components for the G9 AI assistant, fully customisable (layouts, tokens, per-part classes, overrides, parts).",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -31,7 +31,7 @@
31
31
  "access": "public"
32
32
  },
33
33
  "dependencies": {
34
- "@g9tm/aiassistant": "1.0.0"
34
+ "@g9tm/aiassistant": "1.1.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@sveltejs/package": "2.5.8",