@k2b/ui 0.39.0 → 0.41.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/dist/browser/chat/ChatComposer.js +759 -570
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/inputs/ChoiceGroups.js +30 -18
- package/dist/browser/inputs/ChoiceGroups.js.map +1 -1
- package/dist/browser/inputs/Select.js +32 -19
- package/dist/browser/inputs/Select.js.map +1 -1
- package/dist/browser/inputs/SpecialInputs.js +54 -25
- package/dist/browser/inputs/SpecialInputs.js.map +1 -1
- package/dist/browser/inputs/choice.js +4 -1
- package/dist/browser/inputs/choice.js.map +1 -1
- package/dist/browser/inputs/dictation/Dictation.js +546 -0
- package/dist/browser/inputs/dictation/Dictation.js.map +1 -0
- package/dist/browser/inputs/dictation/create-dictation.js +324 -0
- package/dist/browser/inputs/dictation/create-dictation.js.map +1 -0
- package/dist/browser/inputs/dictation/dictation-messages.js +115 -0
- package/dist/browser/inputs/dictation/dictation-messages.js.map +1 -0
- package/dist/browser/inputs/dictation/text-dictation.js +152 -0
- package/dist/browser/inputs/dictation/text-dictation.js.map +1 -0
- package/dist/browser/inputs/dictation/types.js +2 -0
- package/dist/browser/inputs/dictation/types.js.map +1 -0
- package/dist/browser/inputs/icon-messages.js +29 -2
- package/dist/browser/inputs/icon-messages.js.map +1 -1
- package/dist/browser/inputs/icon-texts.js +172 -0
- package/dist/browser/inputs/icon-texts.js.map +1 -0
- package/dist/browser/inputs/index.js +2 -0
- package/dist/browser/inputs/index.js.map +1 -1
- package/dist/browser/layout/AnchoredPopover.js +1 -1
- package/dist/browser/layout/AnchoredPopover.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +31 -17
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/SettingsModal.js +10 -5
- package/dist/browser/layout/SettingsModal.js.map +1 -1
- package/dist/browser/layout/app-workspace-controller.js +49 -5
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/text-editor/TextEditor.js +74 -25
- package/dist/browser/text-editor/TextEditor.js.map +1 -1
- package/dist/browser/text-editor/dictation.js +166 -0
- package/dist/browser/text-editor/dictation.js.map +1 -0
- package/dist/browser/text-editor.js +1 -0
- package/dist/browser/text-editor.js.map +1 -1
- package/dist/ssr/chat/ChatComposer.js +271 -99
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/inputs/ChoiceGroups.js +12 -3
- package/dist/ssr/inputs/ChoiceGroups.js.map +1 -1
- package/dist/ssr/inputs/Select.js +8 -2
- package/dist/ssr/inputs/Select.js.map +1 -1
- package/dist/ssr/inputs/SpecialInputs.js +54 -25
- package/dist/ssr/inputs/SpecialInputs.js.map +1 -1
- package/dist/ssr/inputs/choice.js +4 -1
- package/dist/ssr/inputs/choice.js.map +1 -1
- package/dist/ssr/inputs/dictation/Dictation.js +386 -0
- package/dist/ssr/inputs/dictation/Dictation.js.map +1 -0
- package/dist/ssr/inputs/dictation/create-dictation.js +324 -0
- package/dist/ssr/inputs/dictation/create-dictation.js.map +1 -0
- package/dist/ssr/inputs/dictation/dictation-messages.js +115 -0
- package/dist/ssr/inputs/dictation/dictation-messages.js.map +1 -0
- package/dist/ssr/inputs/dictation/text-dictation.js +152 -0
- package/dist/ssr/inputs/dictation/text-dictation.js.map +1 -0
- package/dist/ssr/inputs/dictation/types.js +2 -0
- package/dist/ssr/inputs/dictation/types.js.map +1 -0
- package/dist/ssr/inputs/icon-messages.js +29 -2
- package/dist/ssr/inputs/icon-messages.js.map +1 -1
- package/dist/ssr/inputs/icon-texts.js +172 -0
- package/dist/ssr/inputs/icon-texts.js.map +1 -0
- package/dist/ssr/inputs/index.js +2 -0
- package/dist/ssr/inputs/index.js.map +1 -1
- package/dist/ssr/layout/AnchoredPopover.js +1 -1
- package/dist/ssr/layout/AnchoredPopover.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +31 -17
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/SettingsModal.js +10 -5
- package/dist/ssr/layout/SettingsModal.js.map +1 -1
- package/dist/ssr/layout/app-workspace-controller.js +49 -5
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/text-editor/TextEditor.js +74 -25
- package/dist/ssr/text-editor/TextEditor.js.map +1 -1
- package/dist/ssr/text-editor/dictation.js +166 -0
- package/dist/ssr/text-editor/dictation.js.map +1 -0
- package/dist/ssr/text-editor.js +1 -0
- package/dist/ssr/text-editor.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/chat/ChatComposer.d.ts +9 -0
- package/dist/types/inputs/SpecialInputs.d.ts +8 -0
- package/dist/types/inputs/dictation/Dictation.d.ts +26 -0
- package/dist/types/inputs/dictation/create-dictation.d.ts +77 -0
- package/dist/types/inputs/dictation/dictation-messages.d.ts +54 -0
- package/dist/types/inputs/dictation/text-dictation.d.ts +36 -0
- package/dist/types/inputs/dictation/types.d.ts +74 -0
- package/dist/types/inputs/icon-messages.d.ts +14 -0
- package/dist/types/inputs/icon-texts.d.ts +13 -0
- package/dist/types/inputs/index.d.ts +5 -0
- package/dist/types/layout/AnchoredPopover.d.ts +5 -0
- package/dist/types/layout/AppWorkspace.d.ts +14 -0
- package/dist/types/layout/app-workspace-controller.d.ts +2 -0
- package/dist/types/text-editor/TextEditor.d.ts +10 -1
- package/dist/types/text-editor/dictation.d.ts +20 -0
- package/dist/types/text-editor.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type JSX } from "solid-js";
|
|
2
|
+
import type { DictationAlternative, DictationSource } from "../inputs/dictation/types";
|
|
2
3
|
import type { ChatAction, ChatAttachment, ChatComposerEmoji, ChatComposerMicrophone, ChatComposerState, ChatContextUsageData, ChatMention, ChatModelOption, ChatSubmitInput } from "./types";
|
|
3
4
|
export type ChatCommandContext = {
|
|
4
5
|
setValue: (value: string) => void;
|
|
@@ -237,6 +238,14 @@ export type ChatComposerProps = {
|
|
|
237
238
|
emoji?: ChatComposerEmoji;
|
|
238
239
|
/** A microphone at a fixed place: a tap dictates, holding it or its menu asks for a voice message. */
|
|
239
240
|
microphone?: ChatComposerMicrophone;
|
|
241
|
+
/**
|
|
242
|
+
* Live dictation at the microphone's place, before Send. A press starts it; while it runs, the dictation bar stands in
|
|
243
|
+
* for the footer and the words land at the caret, also when the person types elsewhere. Sending waits until it ended.
|
|
244
|
+
*/
|
|
245
|
+
dictation?: {
|
|
246
|
+
source: DictationSource;
|
|
247
|
+
alternative?: DictationAlternative;
|
|
248
|
+
};
|
|
240
249
|
/** One line above the field. The conversation variant always keeps its height; the default shows it only with content. */
|
|
241
250
|
hint?: JSX.Element;
|
|
242
251
|
/**
|
|
@@ -18,4 +18,12 @@ export type IconInputProps = ValueFieldProps<string | null> & {
|
|
|
18
18
|
gridSize?: SelectGridSize;
|
|
19
19
|
name?: string;
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Every query word has to appear in the icon's names or keywords: as the start
|
|
23
|
+
* of a word, or anywhere in one once it has three letters, so German compounds
|
|
24
|
+
* such as "Kreditkarte" match "karte". A loose subsequence match let "gro" find
|
|
25
|
+
* "warninG eRrOr", so it is not used. Ranked by where the query hits: the label
|
|
26
|
+
* start, a label word, a keyword, then anywhere.
|
|
27
|
+
*/
|
|
28
|
+
export declare const searchIconOptions: <T extends IconOption>(source: readonly T[], query: string, limit: number) => T[];
|
|
21
29
|
export declare function IconInput(props: IconInputProps): JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type JSX } from "solid-js";
|
|
2
|
+
import { type DictationController } from "./create-dictation";
|
|
3
|
+
/** Whether the bar stands in for the host's controls: while dictating, finishing, or showing a bar notice. */
|
|
4
|
+
export declare const dictationBarShown: (dictation: DictationController) => boolean;
|
|
5
|
+
export type DictationButtonProps = {
|
|
6
|
+
dictation: DictationController;
|
|
7
|
+
size?: "xs" | "sm";
|
|
8
|
+
class?: string;
|
|
9
|
+
/** The box the notice cards line up with, such as the whole composer; defaults to the button. */
|
|
10
|
+
cardAnchor?: () => HTMLElement | undefined;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* The microphone at its fixed place. A press starts live dictation; offline it stays focusable and says why it waits.
|
|
14
|
+
* Notices that need a decision, such as a blocked microphone or a used-up allowance, open as cards above it.
|
|
15
|
+
*/
|
|
16
|
+
export declare function DictationButton(props: DictationButtonProps): JSX.Element;
|
|
17
|
+
export type DictationBarProps = {
|
|
18
|
+
dictation: DictationController;
|
|
19
|
+
class?: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* The row that stands in for the host's controls while dictating, at the same place and height: Discard, level, time,
|
|
23
|
+
* microphone and Stop; then "Finishing …" until the last words arrived; and a notice with "Continue" when the session
|
|
24
|
+
* ended early. Render it where `dictationBarShown()` is true. Escape stops, after closing an open menu.
|
|
25
|
+
*/
|
|
26
|
+
export declare function DictationBar(props: DictationBarProps): JSX.Element;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type Accessor } from "solid-js";
|
|
2
|
+
import type { DictationAlternative, DictationDevice, DictationSource, DictationTarget } from "./types";
|
|
3
|
+
export type DictationStatus = "idle" | "starting" | "live" | "finishing";
|
|
4
|
+
/**
|
|
5
|
+
* What stays visible after a session could not start or ended on its own. `interrupted` and `ended` replace the bar,
|
|
6
|
+
* so "Continue" writes on at the same mark; the others are cards at the microphone.
|
|
7
|
+
*/
|
|
8
|
+
export type DictationNotice = {
|
|
9
|
+
kind: "blocked";
|
|
10
|
+
} | {
|
|
11
|
+
kind: "unavailable";
|
|
12
|
+
} | {
|
|
13
|
+
kind: "not_available";
|
|
14
|
+
} | {
|
|
15
|
+
kind: "quota";
|
|
16
|
+
resetsAt?: string;
|
|
17
|
+
} | {
|
|
18
|
+
kind: "overloaded";
|
|
19
|
+
} | {
|
|
20
|
+
kind: "elsewhere";
|
|
21
|
+
} | {
|
|
22
|
+
kind: "interrupted";
|
|
23
|
+
} | {
|
|
24
|
+
kind: "ended";
|
|
25
|
+
reason: "max_duration" | "silence";
|
|
26
|
+
maxMs: number;
|
|
27
|
+
};
|
|
28
|
+
export type DictationOptions = {
|
|
29
|
+
source: DictationSource;
|
|
30
|
+
target: DictationTarget;
|
|
31
|
+
/** Offered beside "Try again" when live dictation is busy. */
|
|
32
|
+
alternative?: DictationAlternative;
|
|
33
|
+
/** While true, dictation cannot start, such as in a read-only field; the host calls `end()` when it turns true. */
|
|
34
|
+
disabled?: () => boolean;
|
|
35
|
+
};
|
|
36
|
+
export type DictationController = {
|
|
37
|
+
status: Accessor<DictationStatus>;
|
|
38
|
+
/** Dictating, starting, or finishing: the bar stands in for the host's controls. */
|
|
39
|
+
active: Accessor<boolean>;
|
|
40
|
+
notice: Accessor<DictationNotice | null>;
|
|
41
|
+
/** Recent levels from 0 to 1, newest last. */
|
|
42
|
+
levels: Accessor<readonly number[]>;
|
|
43
|
+
elapsedMs: Accessor<number>;
|
|
44
|
+
maxMs: Accessor<number>;
|
|
45
|
+
offline: Accessor<boolean>;
|
|
46
|
+
device: Accessor<DictationDevice | undefined>;
|
|
47
|
+
deviceId: Accessor<string | undefined>;
|
|
48
|
+
devices: Accessor<readonly DictationDevice[]>;
|
|
49
|
+
loadDevices(): Promise<void>;
|
|
50
|
+
chooseDevice(id: string): void;
|
|
51
|
+
alternative?: DictationAlternative;
|
|
52
|
+
start(): void;
|
|
53
|
+
stop(): Promise<void>;
|
|
54
|
+
/** Ends the session at once and removes only the text it inserted. */
|
|
55
|
+
discard(): void;
|
|
56
|
+
/** Closes a notice; the text stays. */
|
|
57
|
+
dismiss(): void;
|
|
58
|
+
/** Ends any session at once and closes the dictation; the text stays. For a field that changes or turns read-only. */
|
|
59
|
+
end(): void;
|
|
60
|
+
/** Whether dictation may start now. */
|
|
61
|
+
disabled: Accessor<boolean>;
|
|
62
|
+
/** Elements that receive focus: the microphone after the end, the stop button after the start. */
|
|
63
|
+
bind(role: "microphone" | "stop" | "continue", element: HTMLElement | undefined): void;
|
|
64
|
+
};
|
|
65
|
+
/** Bar notices stand where the bar was; card notices open at the microphone. */
|
|
66
|
+
export declare const isBarNotice: (notice: DictationNotice | null) => notice is {
|
|
67
|
+
kind: "interrupted";
|
|
68
|
+
} | {
|
|
69
|
+
kind: "ended";
|
|
70
|
+
reason: "max_duration" | "silence";
|
|
71
|
+
maxMs: number;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* The state of one dictation place: which session runs, what its bar shows, and the notice it leaves. Render it with
|
|
75
|
+
* `DictationButton` and `DictationBar`; the target decides where text lands. One controller runs one session at a time.
|
|
76
|
+
*/
|
|
77
|
+
export declare function createDictation(options: DictationOptions): DictationController;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export declare const dictationMessages: import("@k2b/stdlib").Catalog<{
|
|
2
|
+
dictate: string;
|
|
3
|
+
dictateOffline: string;
|
|
4
|
+
offline: string;
|
|
5
|
+
discard: string;
|
|
6
|
+
stop: string;
|
|
7
|
+
running: string;
|
|
8
|
+
finishingGroup: string;
|
|
9
|
+
finishing: string;
|
|
10
|
+
starting: string;
|
|
11
|
+
ended: string;
|
|
12
|
+
discarded: string;
|
|
13
|
+
microphone: string;
|
|
14
|
+
microphoneNamed: ({ name }: {
|
|
15
|
+
name: string;
|
|
16
|
+
}) => string;
|
|
17
|
+
systemDefault: string;
|
|
18
|
+
interrupted: string;
|
|
19
|
+
interruptedShort: string;
|
|
20
|
+
maxDone: ({ minutes }: {
|
|
21
|
+
minutes: number;
|
|
22
|
+
}) => string;
|
|
23
|
+
maxDoneShort: ({ minutes }: {
|
|
24
|
+
minutes: number;
|
|
25
|
+
}) => string;
|
|
26
|
+
silenceDone: string;
|
|
27
|
+
silenceDoneShort: string;
|
|
28
|
+
continue: string;
|
|
29
|
+
dismiss: string;
|
|
30
|
+
blockedTitle: string;
|
|
31
|
+
blockedBody: string;
|
|
32
|
+
blockedStep1: string;
|
|
33
|
+
blockedStep2: string;
|
|
34
|
+
retry: string;
|
|
35
|
+
quotaTitle: string;
|
|
36
|
+
quotaBody: ({ time }: {
|
|
37
|
+
time: string;
|
|
38
|
+
}) => string;
|
|
39
|
+
quotaBodyTomorrow: ({ time }: {
|
|
40
|
+
time: string;
|
|
41
|
+
}) => string;
|
|
42
|
+
overloadedTitle: string;
|
|
43
|
+
overloadedBody: string;
|
|
44
|
+
elsewhereTitle: string;
|
|
45
|
+
elsewhereBody: string;
|
|
46
|
+
unavailableTitle: string;
|
|
47
|
+
unavailableBody: string;
|
|
48
|
+
notAvailableTitle: string;
|
|
49
|
+
notAvailableBody: string;
|
|
50
|
+
ok: string;
|
|
51
|
+
timeLeft: ({ time }: {
|
|
52
|
+
time: string;
|
|
53
|
+
}) => string;
|
|
54
|
+
}>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dictation into plain text, such as a textarea: a mark where the next words land and the ranges dictation inserted.
|
|
3
|
+
* Both follow edits the person makes anywhere else, so typing elsewhere never moves the dictated text.
|
|
4
|
+
*/
|
|
5
|
+
export type TextDictationState = {
|
|
6
|
+
mark: number;
|
|
7
|
+
/** Inserted ranges, as UTF-16 offsets into the current text, in order. */
|
|
8
|
+
ranges: readonly (readonly [number, number])[];
|
|
9
|
+
/** Whether the next insert is the first of a session, which adjusts the space before it. */
|
|
10
|
+
fresh: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare const beginTextDictation: (mark: number) => TextDictationState;
|
|
13
|
+
/** Where `offset` lands after `previous` became `next`; `after` keeps it behind text inserted exactly at it. */
|
|
14
|
+
export declare const mapTextOffset: (previous: string, next: string, offset: number, after: boolean) => number;
|
|
15
|
+
/** Follow an edit that dictation did not make. Ranges that the edit removed entirely disappear. */
|
|
16
|
+
export declare const mapTextDictation: (state: TextDictationState, previous: string, next: string) => TextDictationState;
|
|
17
|
+
/** Append `text` at the mark. The first words of a session get one space from earlier text, never two. */
|
|
18
|
+
export declare const insertTextDictation: (state: TextDictationState, value: string, text: string) => {
|
|
19
|
+
state: TextDictationState;
|
|
20
|
+
value: string;
|
|
21
|
+
};
|
|
22
|
+
/** Remove every dictated range; text that was there before stays. */
|
|
23
|
+
export declare const discardTextDictation: (state: TextDictationState, value: string) => {
|
|
24
|
+
value: string;
|
|
25
|
+
caret: number;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Split highlight segments of a field's text at the newest dictated words and the mark, for an overlay that tints the
|
|
29
|
+
* fresh words and shows where the next ones land. A mark arrives as an empty segment.
|
|
30
|
+
*/
|
|
31
|
+
export declare const splitDictationSegments: <T extends {
|
|
32
|
+
text: string;
|
|
33
|
+
}>(segments: readonly T[], fresh: readonly (readonly [number, number])[], mark: number | undefined) => (T & {
|
|
34
|
+
fresh?: boolean;
|
|
35
|
+
mark?: boolean;
|
|
36
|
+
})[];
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A speech-to-text stream as dictation consumes it. The library knows no server: an application passes a source, such
|
|
3
|
+
* as one that relays the microphone to a speech model, and a target that places the text.
|
|
4
|
+
*/
|
|
5
|
+
export type DictationErrorCode = "not_configured" | "no_access" | "daily_limit" | "overloaded" | "busy_elsewhere" | "provider_failed" | "connection_lost" | "microphone_blocked" | "microphone_unavailable";
|
|
6
|
+
export type DictationDevice = {
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
};
|
|
10
|
+
/** Why a session ended on its own; the text so far stays. */
|
|
11
|
+
export type DictationEndReason = "max_duration" | "silence" | "daily_limit";
|
|
12
|
+
export type DictationEvent = {
|
|
13
|
+
type: "state";
|
|
14
|
+
state: "connecting";
|
|
15
|
+
} | {
|
|
16
|
+
type: "state";
|
|
17
|
+
state: "live";
|
|
18
|
+
maxMs: number;
|
|
19
|
+
device?: DictationDevice;
|
|
20
|
+
} | {
|
|
21
|
+
type: "state";
|
|
22
|
+
state: "finishing";
|
|
23
|
+
} | {
|
|
24
|
+
type: "state";
|
|
25
|
+
state: "finished";
|
|
26
|
+
reason?: DictationEndReason;
|
|
27
|
+
}
|
|
28
|
+
/** 0 to 1, about every 100 ms while live. */
|
|
29
|
+
| {
|
|
30
|
+
type: "level";
|
|
31
|
+
level: number;
|
|
32
|
+
}
|
|
33
|
+
/** New text to append at the dictation mark; earlier text is never revised. */
|
|
34
|
+
| {
|
|
35
|
+
type: "text";
|
|
36
|
+
text: string;
|
|
37
|
+
} | {
|
|
38
|
+
type: "error";
|
|
39
|
+
code: DictationErrorCode;
|
|
40
|
+
retryable: boolean;
|
|
41
|
+
resetsAt?: string;
|
|
42
|
+
};
|
|
43
|
+
export type DictationSession = {
|
|
44
|
+
/** Ends after `finished` or `error`, or without further events once the start signal aborted. */
|
|
45
|
+
events: AsyncIterable<DictationEvent>;
|
|
46
|
+
/** Regular stop: resolves after `finished` or an error, so the last words arrive before it. */
|
|
47
|
+
stop(): Promise<void>;
|
|
48
|
+
};
|
|
49
|
+
export type DictationSource = {
|
|
50
|
+
/** Aborting `signal` closes the microphone and the connection at once, for discarding or leaving the page. */
|
|
51
|
+
start(options: {
|
|
52
|
+
deviceId?: string;
|
|
53
|
+
signal: AbortSignal;
|
|
54
|
+
}): DictationSession;
|
|
55
|
+
/** Microphones with their names; names may be empty before the first permission. */
|
|
56
|
+
devices(): Promise<DictationDevice[]>;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Where dictated text lands. `begin` starts each session: the first one remembers the insertion point, later ones of
|
|
60
|
+
* the same dictation write on at it. `insert` appends at the mark, `discard` removes exactly the inserted text, and
|
|
61
|
+
* `end` closes the dictation; the text stays.
|
|
62
|
+
*/
|
|
63
|
+
export type DictationTarget = {
|
|
64
|
+
begin(): void;
|
|
65
|
+
insert(text: string): void;
|
|
66
|
+
discard(): void;
|
|
67
|
+
end(): void;
|
|
68
|
+
};
|
|
69
|
+
/** A second way out when live dictation is busy, such as recording instead, with what it changes. */
|
|
70
|
+
export type DictationAlternative = {
|
|
71
|
+
label: string;
|
|
72
|
+
note: string;
|
|
73
|
+
run: () => void;
|
|
74
|
+
};
|
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
declare const iconMessages: import("@k2b/stdlib").Catalog<{
|
|
2
2
|
filterIcons: string;
|
|
3
3
|
pickIcon: string;
|
|
4
|
+
recommended: string;
|
|
5
|
+
people: string;
|
|
6
|
+
work: string;
|
|
7
|
+
communication: string;
|
|
8
|
+
files: string;
|
|
9
|
+
data: string;
|
|
10
|
+
commerce: string;
|
|
11
|
+
places: string;
|
|
12
|
+
food: string;
|
|
13
|
+
media: string;
|
|
14
|
+
devices: string;
|
|
4
15
|
}>;
|
|
5
16
|
export type IconMessages = ReturnType<(typeof iconMessages)["resolve"]>["t"];
|
|
17
|
+
export type IconGroupMessage = keyof Omit<IconMessages, "filterIcons" | "pickIcon">;
|
|
6
18
|
/** Resolved from the inherited render locale. */
|
|
19
|
+
/** The catalog locale the render locale resolves to, such as "de" for "de-AT". */
|
|
20
|
+
export declare const useIconLocale: () => (() => string);
|
|
7
21
|
export declare const useIconMessages: () => (() => IconMessages);
|
|
8
22
|
export declare const checkIconMessages: () => import("@k2b/stdlib").CatalogIssue[];
|
|
9
23
|
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IconOption } from "./SpecialInputs";
|
|
2
|
+
type IconText = readonly [label: string, description: string, keywords: string];
|
|
3
|
+
/**
|
|
4
|
+
* German names for the default catalogue, keyed by the Tabler glyph name.
|
|
5
|
+
* Keywords are extra German search words; the English label and keywords stay
|
|
6
|
+
* searchable in every locale. This is catalogue data, not UI messages: the
|
|
7
|
+
* locale itself resolves through the icon message catalog, and
|
|
8
|
+
* `icon-options.test.ts` keeps the table complete.
|
|
9
|
+
*/
|
|
10
|
+
export declare const GERMAN_ICON_TEXTS: Readonly<Record<string, IconText>>;
|
|
11
|
+
/** The default catalogue in a resolved locale; English is the catalogue itself. */
|
|
12
|
+
export declare const localizedIconOptions: (locale: string) => readonly IconOption[];
|
|
13
|
+
export {};
|
|
@@ -25,6 +25,11 @@ export type { Completion, QueryContext, SuggestContext, Suggestion, } from "./co
|
|
|
25
25
|
export { abbreviations } from "./completion";
|
|
26
26
|
export type { DatePickerBaseProps, DatePickerProps, DatePreset, DateRangePickerProps, DateRangeValue, DateTimePickerProps, DurationPreset, } from "./DatePicker";
|
|
27
27
|
export { DatePicker, DateRangePicker, DateTimePicker } from "./DatePicker";
|
|
28
|
+
export type { DictationController, DictationNotice, DictationOptions, DictationStatus } from "./dictation/create-dictation";
|
|
29
|
+
export { createDictation } from "./dictation/create-dictation";
|
|
30
|
+
export type { DictationBarProps, DictationButtonProps } from "./dictation/Dictation";
|
|
31
|
+
export { DictationBar, DictationButton, dictationBarShown } from "./dictation/Dictation";
|
|
32
|
+
export type { DictationAlternative, DictationDevice, DictationEndReason, DictationErrorCode, DictationEvent, DictationSession, DictationSource, DictationTarget, } from "./dictation/types";
|
|
28
33
|
export type { EmojiPickerPopoverProps, EmojiPickerProps } from "./emoji/EmojiPicker";
|
|
29
34
|
export { EmojiPicker } from "./emoji/EmojiPicker";
|
|
30
35
|
export type { EmojiSkinTone } from "./emoji/emoji-index";
|
|
@@ -18,6 +18,11 @@ export type AnchoredPopoverProps = {
|
|
|
18
18
|
plannedHeight?: number;
|
|
19
19
|
/** Width of the panel on wide screens, such as `21rem`. On a phone it is a bottom sheet across the screen. */
|
|
20
20
|
width?: string;
|
|
21
|
+
/**
|
|
22
|
+
* `false` keeps a small notice beside its control on a phone too, inside the screen with a margin, instead of a
|
|
23
|
+
* bottom sheet that would cover the control. Defaults to `true`.
|
|
24
|
+
*/
|
|
25
|
+
sheet?: boolean;
|
|
21
26
|
/** Moves the focus into the panel when it opens; defaults to the panel itself. */
|
|
22
27
|
initialFocus?: () => HTMLElement | null | undefined;
|
|
23
28
|
class?: string;
|
|
@@ -46,6 +46,14 @@ export type AppWorkspaceProps = {
|
|
|
46
46
|
layoutState?: () => AppWorkspaceLayoutState | null | undefined;
|
|
47
47
|
/** Called with the full layout whenever a resize settles. Persist it here. */
|
|
48
48
|
onLayoutChange?: (state: AppWorkspaceLayoutState) => void;
|
|
49
|
+
/**
|
|
50
|
+
* `false` draws no head row. The application then shows the page's title itself and gives people the sidebar and
|
|
51
|
+
* Detail buttons the head would hold: a control with `data-app-workspace-sidebar-toggle` (it opens the overlay
|
|
52
|
+
* sidebar, and shows or hides a sidebar with `onHiddenChange` where it is a column) and, for each Detail with
|
|
53
|
+
* `toggle={false}`, a control with `data-app-workspace-detail-toggle` and `aria-controls` set to
|
|
54
|
+
* `appWorkspaceDetailElementId(id)`. The controller runs both and keeps their `aria-expanded` current.
|
|
55
|
+
*/
|
|
56
|
+
head?: false;
|
|
49
57
|
/**
|
|
50
58
|
* Opt out of the built-in controller. Only needed when the application calls
|
|
51
59
|
* `installAppWorkspaceController` itself — installing twice would double up
|
|
@@ -118,6 +126,12 @@ export type AppWorkspaceDetailProps = {
|
|
|
118
126
|
open: boolean;
|
|
119
127
|
/** Keeps the shared head control reachable while closed; set the app's existing open state synchronously. */
|
|
120
128
|
onOpen?: () => void;
|
|
129
|
+
/**
|
|
130
|
+
* `false` draws no Details button of the workspace's own: the application gives one with
|
|
131
|
+
* `data-app-workspace-detail-toggle` and `aria-controls` set to `appWorkspaceDetailElementId(id)`, as with
|
|
132
|
+
* `AppWorkspace head={false}`.
|
|
133
|
+
*/
|
|
134
|
+
toggle?: false;
|
|
121
135
|
/** Whether the current object may show details. False disables reopening and hides the panel. */
|
|
122
136
|
available?: boolean;
|
|
123
137
|
/**
|
|
@@ -11,6 +11,8 @@ export declare const parkWorkspaceDetailDrawers: (root?: ParentNode) => void;
|
|
|
11
11
|
* stays application state, so the controller only requests the change.
|
|
12
12
|
*/
|
|
13
13
|
export declare const APP_WORKSPACE_SIDEBAR_HIDE_EVENT = "k2b-app-workspace-sidebar-hide";
|
|
14
|
+
/** Asks the owning `AppWorkspace.Sidebar` to show again; its `onHiddenChange` decides. */
|
|
15
|
+
export declare const APP_WORKSPACE_SIDEBAR_SHOW_EVENT = "k2b-app-workspace-sidebar-show";
|
|
14
16
|
/** Asks the owning Detail to reopen its current available object. */
|
|
15
17
|
export declare const APP_WORKSPACE_DETAIL_OPEN_EVENT = "k2b-app-workspace-detail-open";
|
|
16
18
|
/** Asks the owning `AppWorkspace.Detail` to close; its `onClose` decides. */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Extension } from "@codemirror/state";
|
|
2
2
|
import { type JSX } from "solid-js";
|
|
3
3
|
import { type DropdownPosition } from "../actions/Dropdown";
|
|
4
|
+
import type { DictationAlternative, DictationSource } from "../inputs/dictation/types";
|
|
4
5
|
import { type TextEditorController, type TextEditorMode, type TextEditorOptions } from "./engine";
|
|
5
6
|
import { type InlineFormat } from "./format";
|
|
6
7
|
import { type TableHost } from "./table";
|
|
@@ -28,8 +29,16 @@ export type TextEditorProps = {
|
|
|
28
29
|
/** Opens the host's attachment picker when clipboard images cannot be inserted. */
|
|
29
30
|
onAttachImages?: () => void;
|
|
30
31
|
onTableCheck?: (needsCheck: boolean) => void;
|
|
31
|
-
/** Host-owned sync status
|
|
32
|
+
/** Host-owned sync status. Its row appears only while there is a status or a table check; keep it set across transitions. */
|
|
32
33
|
status?: JSX.Element;
|
|
34
|
+
/**
|
|
35
|
+
* Live dictation as the last control of the toolbar, so it never scrolls away. While it runs, the dictation bar
|
|
36
|
+
* stands in for the formatting controls in the same row. Words land at the caret as typed text does.
|
|
37
|
+
*/
|
|
38
|
+
dictation?: {
|
|
39
|
+
source: DictationSource;
|
|
40
|
+
alternative?: DictationAlternative;
|
|
41
|
+
};
|
|
33
42
|
class?: string;
|
|
34
43
|
};
|
|
35
44
|
export type TableSizePickerProps = {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type RangeSet, StateField } from "@codemirror/state";
|
|
2
|
+
import { Decoration, type DecorationSet, EditorView } from "@codemirror/view";
|
|
3
|
+
import type { DictationTarget } from "../inputs/dictation/types";
|
|
4
|
+
type DictationState = {
|
|
5
|
+
/** Where the next words land; `null` while no dictation is open. */
|
|
6
|
+
mark: number | null;
|
|
7
|
+
/** Every range dictation inserted, mapped through all later edits. */
|
|
8
|
+
dictated: RangeSet<Decoration>;
|
|
9
|
+
/** The newest words, tinted for a moment. */
|
|
10
|
+
fresh: DecorationSet;
|
|
11
|
+
};
|
|
12
|
+
/** The editor state dictation needs; add it to the view that `codeMirrorDictationTarget` writes into. */
|
|
13
|
+
export declare const dictationExtension: () => StateField<DictationState>;
|
|
14
|
+
/**
|
|
15
|
+
* A dictation target for a CodeMirror view. Words go into the document at once, as typed text does, so a shared
|
|
16
|
+
* document shows them to everyone and they last as long as the host saves typed text. The mark follows local and
|
|
17
|
+
* remote edits; Discard removes exactly the dictated ranges in one step, including what the person typed inside them.
|
|
18
|
+
*/
|
|
19
|
+
export declare function codeMirrorDictationTarget(editorView: () => EditorView | undefined): DictationTarget;
|
|
20
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { codeMirrorDictationTarget, dictationExtension } from "./text-editor/dictation";
|
|
1
2
|
export { createTextEditor, type TextEditorController, type TextEditorMode, type TextEditorOptions } from "./text-editor/engine";
|
|
2
3
|
export { commands as textEditorCommands, formatLabels as textEditorFormatLabels, type InlineFormat } from "./text-editor/format";
|
|
3
4
|
export { TableSizePicker, type TableSizePickerProps, TextEditor, type TextEditorControls, type TextEditorProps, } from "./text-editor/TextEditor";
|