@schlenkr/quassel 0.5.6 → 0.7.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/ChatInputToolbar.d.ts +6 -10
- package/ComposerPrimaryAction.d.ts +13 -0
- package/QuasselProvider.d.ts +1 -0
- package/README.md +44 -18
- package/RecordingAura.d.ts +4 -0
- package/chat.css +312 -212
- package/index.d.ts +1 -1
- package/index.js +430 -174
- package/index.js.map +4 -4
- package/options.d.ts +12 -4
- package/package.json +1 -1
- package/texts.d.ts +5 -0
package/ChatInputToolbar.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReactNode, Ref } from "react";
|
|
2
2
|
import { ChatTexts } from "./texts";
|
|
3
3
|
import type { ChatAttachmentInput } from "./events";
|
|
4
|
-
import type { SendShortcut } from "./options";
|
|
4
|
+
import type { ChatMicrophone, SendShortcut } from "./options";
|
|
5
5
|
/** A toolbar button, declarative: icon, text or both - plus click handler. */
|
|
6
6
|
export interface ToolbarAction {
|
|
7
7
|
icon?: ReactNode;
|
|
@@ -21,20 +21,14 @@ export interface ChatInputHandle {
|
|
|
21
21
|
allowEmpty?: boolean;
|
|
22
22
|
}) => Promise<void>;
|
|
23
23
|
}
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
* declaratively through `actions` or freely through the left/right slots; while work is running
|
|
27
|
-
* the stop button stays visible, and typing shows the send button next to it, which then
|
|
28
|
-
* interjects. `rows` sets the initial height; with `maxRows` the textarea grows with its content
|
|
29
|
-
* up to that number of rows and scrolls after that. `inline` starts with one row and grows the same way.
|
|
30
|
-
*/
|
|
31
|
-
export declare function ChatInputToolbar({ onSend, onStop, running, disabled, sendDisabled, layout, detailsContainer, onErrorChange, inputAriaControls, rows, maxRows, actions, toolbarLeft, toolbarRight, texts, handleRef, attachments: attachmentsEnabled, attachmentCapabilities, attachmentCapabilitiesError, onAttachmentsChange, initialValue, onDraftChange, sendShortcut, autoFocus, onAutoFocusSettled, }: {
|
|
24
|
+
/** A composer with attachments, host slots and steering into a running turn. */
|
|
25
|
+
export declare function ChatInputToolbar({ onSend, onStop, running, disabled, sendDisabled, layout, detailsContainer, onErrorChange, inputAriaControls, rows, maxRows, actions, toolbarLeft, toolbarRight, microphone, replaceInput, texts, handleRef, attachments: attachmentsEnabled, attachmentCapabilities, attachmentCapabilitiesError, onAttachmentsChange, initialValue, onDraftChange, sendShortcut, autoFocus, onAutoFocusSettled, }: {
|
|
32
26
|
onSend: (text: string, attachments?: ChatAttachmentInput[]) => void | Promise<void>;
|
|
33
27
|
onStop?: () => void;
|
|
34
28
|
running?: boolean;
|
|
35
29
|
disabled?: boolean;
|
|
36
30
|
sendDisabled?: boolean;
|
|
37
|
-
layout?: "card" | "toolbar" | "inline";
|
|
31
|
+
layout?: "card" | "toolbar" | "inline" | "pill";
|
|
38
32
|
detailsContainer?: HTMLElement | null;
|
|
39
33
|
onErrorChange?: (error: string | undefined) => void;
|
|
40
34
|
inputAriaControls?: string;
|
|
@@ -43,6 +37,8 @@ export declare function ChatInputToolbar({ onSend, onStop, running, disabled, se
|
|
|
43
37
|
actions?: ToolbarAction[];
|
|
44
38
|
toolbarLeft?: ReactNode;
|
|
45
39
|
toolbarRight?: ReactNode;
|
|
40
|
+
microphone?: ChatMicrophone;
|
|
41
|
+
replaceInput?: ReactNode;
|
|
46
42
|
texts?: Partial<ChatTexts>;
|
|
47
43
|
handleRef?: Ref<ChatInputHandle>;
|
|
48
44
|
/** false = no attaching: neither button nor dropping or pasting files. */
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ChatMicrophone } from "./options";
|
|
2
|
+
import type { ChatTexts } from "./texts";
|
|
3
|
+
export declare function ComposerPrimaryAction({ hasContent, running, sending, disabled, sendDisabled, microphone, texts, onSend, onStop }: {
|
|
4
|
+
hasContent: boolean;
|
|
5
|
+
running: boolean;
|
|
6
|
+
sending: boolean;
|
|
7
|
+
disabled: boolean;
|
|
8
|
+
sendDisabled: boolean;
|
|
9
|
+
microphone?: ChatMicrophone;
|
|
10
|
+
texts: Required<ChatTexts>;
|
|
11
|
+
onSend: () => void;
|
|
12
|
+
onStop?: () => void;
|
|
13
|
+
}): import("react").JSX.Element;
|
package/QuasselProvider.d.ts
CHANGED
package/README.md
CHANGED
|
@@ -43,13 +43,14 @@ variables too.
|
|
|
43
43
|
- Streaming-safe Markdown (tables, code with copy button, lists) via Streamdown.
|
|
44
44
|
- Steering: typing while a turn runs sends into it; stop, retry and failed-send recovery built in.
|
|
45
45
|
- Attachments by button, drag and drop or paste, with previews and size limits.
|
|
46
|
+
- Optional pill composer: one animated action for microphone, send, steering and stop, with host-controlled recording and transcription.
|
|
46
47
|
- Condensed conversation: all user inputs and the latest answer between them, independently of tool/thinking detail.
|
|
47
48
|
- Timestamps, day separators, message actions, configurable bubbles and appearance.
|
|
48
49
|
- Screen reader friendly: the transcript is not a live region; finished replies and new
|
|
49
50
|
actions are announced once, with the host in control of the wording.
|
|
50
51
|
- Complete English and German UI labels through `englishTexts` / `germanTexts`; `texts` can override any label (English by default).
|
|
51
52
|
- Grouped steps show their error count even while collapsed.
|
|
52
|
-
-
|
|
53
|
+
- One text size per host, a fixed small size and shared Markdown typography (see below).
|
|
53
54
|
|
|
54
55
|
## Install
|
|
55
56
|
|
|
@@ -91,30 +92,55 @@ export function Chat({ send, stop }: { send: (text: string) => Promise<void>; st
|
|
|
91
92
|
|
|
92
93
|
Any backend that emits the `@schlenkr/quassel/events` stream works with the same components.
|
|
93
94
|
|
|
94
|
-
##
|
|
95
|
+
## Pill composer
|
|
95
96
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
1px gap between rows; tool rows have 1px of vertical padding on each side.
|
|
97
|
+
Use `layout="pill"` for a larger, rounded composer with one 48px primary action. Host buttons
|
|
98
|
+
go into `toolbarLeft` and `toolbarRight`; attachments stay just before the primary action.
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
```tsx
|
|
101
|
+
<ChatInputToolbar
|
|
102
|
+
layout="pill"
|
|
103
|
+
maxRows={5}
|
|
104
|
+
running={running}
|
|
105
|
+
onSend={send}
|
|
106
|
+
onStop={stop}
|
|
107
|
+
microphone={microphone}
|
|
108
|
+
replaceInput={microphone.state === "recording" ? <LiveWaveform /> : undefined}
|
|
109
|
+
toolbarLeft={<ConversationControls />}
|
|
110
|
+
/>
|
|
111
|
+
```
|
|
103
112
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
113
|
+
Empty input shows the microphone, text or attachments show send, and an empty running turn
|
|
114
|
+
shows stop. Typing while running sends into that turn. Without `microphone`, empty input shows
|
|
115
|
+
a disabled send button. The host owns audio, press-and-hold or click-to-latch behavior, and
|
|
116
|
+
transcription through the typed `ChatMicrophone` API. Recording has a live color and an aura
|
|
117
|
+
driven by `level` (0-1); preparing and transcribing show a spinner. The aura renders outside
|
|
118
|
+
clipping ancestors and animations respect reduced motion. Card, inline and toolbar keep their defaults.
|
|
119
|
+
See the [API, state table and microphone integration](https://github.com/SchlenkR/quassel/blob/main/docs/guide.md#pill-composer) and the gallery's Pill composer demo.
|
|
120
|
+
|
|
121
|
+
## Text size
|
|
122
|
+
|
|
123
|
+
quassel defaults to 13px. Set `--qsl-font-size` on a wrapper, or `1em` to inherit the host's
|
|
124
|
+
font size. Messages, the composer, action cards and text buttons use that base with line height
|
|
125
|
+
1.5, the pill input included. All small UI text, including tools and timestamps, uses 85% with
|
|
126
|
+
line height 1.4.
|
|
127
|
+
`--qsl-font` and `--qsl-mono` select the font families. There are no other typography inputs.
|
|
128
|
+
Sizes derive from an absolute base, so nested small elements never compound.
|
|
129
|
+
|
|
130
|
+
`Markdown` uses the same typography in answers and standalone documents:
|
|
107
131
|
|
|
108
132
|
```tsx
|
|
109
|
-
<
|
|
110
|
-
messages={messages}
|
|
111
|
-
showTimestamps
|
|
112
|
-
timestampOptions={{ position: "above", fontScale: 0.88 }}
|
|
113
|
-
/>
|
|
133
|
+
<Markdown text={documentText} />
|
|
114
134
|
```
|
|
115
135
|
|
|
116
|
-
|
|
117
|
-
|
|
136
|
+
User message backgrounds fill the available row by default while text keeps its width and
|
|
137
|
+
alignment. `bubbleOptions={{ userBackgroundFullWidth: false }}` restores a fitted background.
|
|
138
|
+
Timestamps sit beside messages by default; `timestampOptions={{ position: "above" }}` moves
|
|
139
|
+
them above. Message gaps and tool row spacing remain configurable through `appearance`.
|
|
140
|
+
|
|
141
|
+
For 0.6, replace separate size and line-height overrides with `--qsl-font-size` and remove
|
|
142
|
+
all typography fields from `appearance` and timestamp options. The [migration guide](https://github.com/SchlenkR/quassel/blob/main/docs/guide.md#migration-to-06)
|
|
143
|
+
lists the removed variables and options.
|
|
118
144
|
|
|
119
145
|
## Development
|
|
120
146
|
|