@mk-kit/ui 0.36.0 → 0.37.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.
@@ -15,6 +15,8 @@ export * from '@mk-kit/ui/rich-text';
15
15
  export * from '@mk-kit/ui/block-editor';
16
16
  export * from '@mk-kit/ui/context-menu';
17
17
  export * from '@mk-kit/ui/layout';
18
+ export * from '@mk-kit/ui/chat';
19
+ export * from '@mk-kit/ui/query-builder';
18
20
  export * from '@mk-kit/ui/media';
19
21
 
20
22
  /*
@@ -1 +1 @@
1
- {"version":3,"file":"mk-kit-ui.mjs","sources":["../../../projects/mk-kit/src/public-api.ts","../../../projects/mk-kit/src/mk-kit-ui.ts"],"sourcesContent":["/*\n * Public API Surface of @mk-kit/ui.\n *\n * The library ships Material-style secondary entry points — import from the\n * group entries (`@mk-kit/ui/forms`, `@mk-kit/ui/table`, …) so a code-split\n * app only carries the groups each chunk uses. This root entry re-exports\n * everything for convenience; importing it eagerly pulls all groups into the\n * importing chunk.\n */\nexport * from '@mk-kit/ui/core';\nexport * from '@mk-kit/ui/icon';\nexport * from '@mk-kit/ui/chip';\nexport * from '@mk-kit/ui/checkbox';\nexport * from '@mk-kit/ui/button';\nexport * from '@mk-kit/ui/directives';\nexport * from '@mk-kit/ui/dnd';\nexport * from '@mk-kit/ui/navigation';\nexport * from '@mk-kit/ui/forms';\nexport * from '@mk-kit/ui/datetime';\nexport * from '@mk-kit/ui/table';\nexport * from '@mk-kit/ui/data';\nexport * from '@mk-kit/ui/feedback';\nexport * from '@mk-kit/ui/rich-text';\nexport * from '@mk-kit/ui/block-editor';\nexport * from '@mk-kit/ui/context-menu';\nexport * from '@mk-kit/ui/layout';\nexport * from '@mk-kit/ui/media';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;AAQG;;ACRH;;AAEG"}
1
+ {"version":3,"file":"mk-kit-ui.mjs","sources":["../../../projects/mk-kit/src/public-api.ts","../../../projects/mk-kit/src/mk-kit-ui.ts"],"sourcesContent":["/*\n * Public API Surface of @mk-kit/ui.\n *\n * The library ships Material-style secondary entry points — import from the\n * group entries (`@mk-kit/ui/forms`, `@mk-kit/ui/table`, …) so a code-split\n * app only carries the groups each chunk uses. This root entry re-exports\n * everything for convenience; importing it eagerly pulls all groups into the\n * importing chunk.\n */\nexport * from '@mk-kit/ui/core';\nexport * from '@mk-kit/ui/icon';\nexport * from '@mk-kit/ui/chip';\nexport * from '@mk-kit/ui/checkbox';\nexport * from '@mk-kit/ui/button';\nexport * from '@mk-kit/ui/directives';\nexport * from '@mk-kit/ui/dnd';\nexport * from '@mk-kit/ui/navigation';\nexport * from '@mk-kit/ui/forms';\nexport * from '@mk-kit/ui/datetime';\nexport * from '@mk-kit/ui/table';\nexport * from '@mk-kit/ui/data';\nexport * from '@mk-kit/ui/feedback';\nexport * from '@mk-kit/ui/rich-text';\nexport * from '@mk-kit/ui/block-editor';\nexport * from '@mk-kit/ui/context-menu';\nexport * from '@mk-kit/ui/layout';\nexport * from '@mk-kit/ui/chat';\nexport * from '@mk-kit/ui/query-builder';\nexport * from '@mk-kit/ui/media';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;AAQG;;ACRH;;AAEG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mk-kit/ui",
3
- "version": "0.36.0",
3
+ "version": "0.37.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -63,6 +63,10 @@
63
63
  "types": "./types/mk-kit-ui-button.d.ts",
64
64
  "default": "./fesm2022/mk-kit-ui-button.mjs"
65
65
  },
66
+ "./chat": {
67
+ "types": "./types/mk-kit-ui-chat.d.ts",
68
+ "default": "./fesm2022/mk-kit-ui-chat.mjs"
69
+ },
66
70
  "./checkbox": {
67
71
  "types": "./types/mk-kit-ui-checkbox.d.ts",
68
72
  "default": "./fesm2022/mk-kit-ui-checkbox.mjs"
@@ -119,6 +123,10 @@
119
123
  "types": "./types/mk-kit-ui-navigation.d.ts",
120
124
  "default": "./fesm2022/mk-kit-ui-navigation.mjs"
121
125
  },
126
+ "./query-builder": {
127
+ "types": "./types/mk-kit-ui-query-builder.d.ts",
128
+ "default": "./fesm2022/mk-kit-ui-query-builder.mjs"
129
+ },
122
130
  "./rich-text": {
123
131
  "types": "./types/mk-kit-ui-rich-text.d.ts",
124
132
  "default": "./fesm2022/mk-kit-ui-rich-text.mjs"
@@ -0,0 +1,288 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { TemplateRef } from '@angular/core';
3
+ import * as _mk_kit_ui_core from '@mk-kit/ui/core';
4
+
5
+ /** Who a message comes from. `system` renders as a centred note. */
6
+ type MkChatRole = 'user' | 'assistant' | 'system';
7
+ /** Display identity of a message author. */
8
+ interface MkChatAuthor {
9
+ /** Shown beside the message and used for avatar initials. */
10
+ name: string;
11
+ /** Avatar image URL; initials from `name` when omitted. */
12
+ avatar?: string;
13
+ }
14
+ /** A file shown with a message (an image when `type` is `image/*` and `url` is set). */
15
+ interface MkChatAttachment {
16
+ name: string;
17
+ /** MIME type, e.g. `image/png`. */
18
+ type?: string;
19
+ /** Size in bytes, shown formatted. */
20
+ size?: number;
21
+ /** Link / image source. */
22
+ url?: string;
23
+ }
24
+ /** Lifecycle of a tool / function call an assistant made while answering. */
25
+ type MkChatToolStatus = 'running' | 'done' | 'error';
26
+ /** A tool call card rendered above the message text. */
27
+ interface MkChatToolCall {
28
+ id?: string;
29
+ /** Tool name, e.g. `search_orders`. */
30
+ name: string;
31
+ status: MkChatToolStatus;
32
+ /** One-line human summary, e.g. `3 orders found`. */
33
+ summary?: string;
34
+ /** Raw input, shown under the disclosure. */
35
+ input?: string;
36
+ /** Raw output, shown under the disclosure. */
37
+ output?: string;
38
+ }
39
+ /** One message in the conversation. Replace the object (new reference) to update it. */
40
+ interface MkChatMessage {
41
+ id: string;
42
+ role: MkChatRole;
43
+ /** Message body — Markdown for assistants (when `markdown` is on), plain text otherwise. */
44
+ text: string;
45
+ author?: MkChatAuthor;
46
+ /** When it was sent; a `Date`, ISO string or epoch ms. */
47
+ timestamp?: Date | string | number;
48
+ /** Still receiving text: shows a cursor and keeps the log pinned to the bottom. */
49
+ streaming?: boolean;
50
+ /** Delivery / generation failed; shown under the bubble with a retry button. */
51
+ error?: string;
52
+ attachments?: MkChatAttachment[];
53
+ tools?: MkChatToolCall[];
54
+ }
55
+ /** Payload of the `send` output. */
56
+ interface MkChatSend {
57
+ text: string;
58
+ files: File[];
59
+ }
60
+
61
+ /**
62
+ * PromptBox — the composer of a chat: an auto-growing textarea, attachments
63
+ * (button, drop, paste), quick-reply suggestions and a send button that turns
64
+ * into *stop* while a reply is being generated.
65
+ *
66
+ * Enter sends, Shift+Enter breaks the line (`sendOnEnter="false"` to swap).
67
+ *
68
+ * ```html
69
+ * <mk-prompt-box
70
+ * [(value)]="draft"
71
+ * [busy]="generating()"
72
+ * attachments
73
+ * [suggestions]="['Summarise this page', 'Draft a reply']"
74
+ * (send)="ask($event)"
75
+ * (stop)="abort()"
76
+ * />
77
+ * ```
78
+ */
79
+ declare class MkPromptBox {
80
+ protected readonly i18n: _mk_kit_ui_core.MkI18nStrings;
81
+ protected readonly id: string;
82
+ /** The draft text (two-way). */
83
+ readonly value: _angular_core.ModelSignal<string>;
84
+ /** Placeholder of the textarea. */
85
+ readonly placeholder: _angular_core.InputSignal<string>;
86
+ /** Disable everything (e.g. while offline). */
87
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
88
+ /** A reply is being generated: the send button becomes *stop*, sending is paused. */
89
+ readonly busy: _angular_core.InputSignalWithTransform<boolean, unknown>;
90
+ /** Allow attaching files (button, drag & drop, paste). */
91
+ readonly attachments: _angular_core.InputSignalWithTransform<boolean, unknown>;
92
+ /** Accepted file types for the picker (`accept` attribute syntax). */
93
+ readonly accept: _angular_core.InputSignal<string>;
94
+ /** Maximum number of attached files (0 = unlimited). */
95
+ readonly maxFiles: _angular_core.InputSignalWithTransform<number, unknown>;
96
+ /** Maximum draft length; shows a counter when set. */
97
+ readonly maxLength: _angular_core.InputSignalWithTransform<number, unknown>;
98
+ /** Minimum visible rows. */
99
+ readonly rows: _angular_core.InputSignalWithTransform<number, unknown>;
100
+ /** Rows the textarea grows to before scrolling. */
101
+ readonly maxRows: _angular_core.InputSignalWithTransform<number, unknown>;
102
+ /** Enter sends and Shift+Enter breaks the line (default); `false` swaps them. */
103
+ readonly sendOnEnter: _angular_core.InputSignalWithTransform<boolean, unknown>;
104
+ /** Quick replies shown above the box; clicking one sends it. */
105
+ readonly suggestions: _angular_core.InputSignal<readonly string[]>;
106
+ /** Focus the textarea on render. */
107
+ readonly autofocus: _angular_core.InputSignalWithTransform<boolean, unknown>;
108
+ /** The user submitted the draft (and any files). */
109
+ readonly send: _angular_core.OutputEmitterRef<MkChatSend>;
110
+ /** The user pressed *stop* while `busy`. */
111
+ readonly stop: _angular_core.OutputEmitterRef<void>;
112
+ /** Files waiting to be sent. */
113
+ readonly files: _angular_core.WritableSignal<File[]>;
114
+ protected readonly dragging: _angular_core.WritableSignal<boolean>;
115
+ private readonly textarea;
116
+ private readonly fileInput;
117
+ protected readonly canSend: _angular_core.Signal<boolean>;
118
+ protected readonly remaining: _angular_core.Signal<number | null>;
119
+ constructor();
120
+ /** Focus the textarea. */
121
+ focus(): void;
122
+ /** Empty the draft and the attachment list. */
123
+ clear(): void;
124
+ /** Submit the current draft (no-op when there is nothing to send or while busy). */
125
+ submit(): void;
126
+ /** Add files, honouring `maxFiles` and `accept`. */
127
+ addFiles(list: ArrayLike<File> | null | undefined): void;
128
+ removeFile(index: number): void;
129
+ protected onInput(event: Event): void;
130
+ protected onKeydown(event: KeyboardEvent): void;
131
+ protected onPaste(event: ClipboardEvent): void;
132
+ protected onDragOver(event: DragEvent): void;
133
+ protected onDrop(event: DragEvent): void;
134
+ protected openPicker(): void;
135
+ protected onFilesPicked(event: Event): void;
136
+ protected onSuggestion(text: string): void;
137
+ protected onPrimary(): void;
138
+ /** Human-readable size, e.g. `1.2 MB`. */
139
+ protected formatSize(bytes: number): string;
140
+ private accepts;
141
+ private autosize;
142
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkPromptBox, never>;
143
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkPromptBox, "mk-prompt-box", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; "attachments": { "alias": "attachments"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "maxRows": { "alias": "maxRows"; "required": false; "isSignal": true; }; "sendOnEnter": { "alias": "sendOnEnter"; "required": false; "isSignal": true; }; "suggestions": { "alias": "suggestions"; "required": false; "isSignal": true; }; "autofocus": { "alias": "autofocus"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "send": "send"; "stop": "stop"; }, never, never, true, never>;
144
+ }
145
+
146
+ /**
147
+ * ChatMessage — one bubble: avatar, author and time, attachment previews,
148
+ * tool-call cards, the text (Markdown for assistants) with a streaming
149
+ * cursor, and copy / retry actions. `mk-chat` renders these for you; use it
150
+ * directly to build your own list.
151
+ */
152
+ declare class MkChatMessageComponent {
153
+ protected readonly i18n: _mk_kit_ui_core.MkI18nStrings;
154
+ /** The message to render. */
155
+ readonly message: _angular_core.InputSignal<MkChatMessage>;
156
+ /** Render on the "own" (end) side — `mk-chat` sets this from `ownRole`. */
157
+ readonly own: _angular_core.InputSignalWithTransform<boolean, unknown>;
158
+ /** Render `text` as Markdown (assistants only; user text is always plain). */
159
+ readonly markdown: _angular_core.InputSignalWithTransform<boolean, unknown>;
160
+ readonly showAvatar: _angular_core.InputSignalWithTransform<boolean, unknown>;
161
+ readonly showTimestamp: _angular_core.InputSignalWithTransform<boolean, unknown>;
162
+ /** Offer a copy button on hover / focus. */
163
+ readonly copyable: _angular_core.InputSignalWithTransform<boolean, unknown>;
164
+ /** The retry button of a failed message was pressed. */
165
+ readonly retry: _angular_core.OutputEmitterRef<MkChatMessage>;
166
+ protected readonly authorName: _angular_core.Signal<string>;
167
+ protected readonly time: _angular_core.Signal<string>;
168
+ protected readonly ariaLabel: _angular_core.Signal<string | null>;
169
+ protected readonly useMarkdown: _angular_core.Signal<boolean>;
170
+ protected isImage(a: MkChatAttachment): boolean;
171
+ protected formatSize(bytes: number | undefined): string;
172
+ protected toolIcon(tool: MkChatToolCall): string;
173
+ protected toolStatus(tool: MkChatToolCall): string;
174
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkChatMessageComponent, never>;
175
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkChatMessageComponent, "mk-chat-message", never, { "message": { "alias": "message"; "required": true; "isSignal": true; }; "own": { "alias": "own"; "required": false; "isSignal": true; }; "markdown": { "alias": "markdown"; "required": false; "isSignal": true; }; "showAvatar": { "alias": "showAvatar"; "required": false; "isSignal": true; }; "showTimestamp": { "alias": "showTimestamp"; "required": false; "isSignal": true; }; "copyable": { "alias": "copyable"; "required": false; "isSignal": true; }; }, { "retry": "retry"; }, never, never, true, never>;
176
+ }
177
+
178
+ /** Context handed to an `*mkChatMessageDef` template. */
179
+ interface MkChatMessageContext {
180
+ $implicit: MkChatMessage;
181
+ own: boolean;
182
+ index: number;
183
+ }
184
+ /**
185
+ * Custom message rendering for `mk-chat`:
186
+ *
187
+ * ```html
188
+ * <mk-chat [messages]="messages()">
189
+ * <ng-template mkChatMessageDef let-message let-own="own">
190
+ * <my-bubble [message]="message" [mine]="own" />
191
+ * </ng-template>
192
+ * </mk-chat>
193
+ * ```
194
+ */
195
+ declare class MkChatMessageDef {
196
+ readonly template: TemplateRef<any>;
197
+ static ngTemplateContextGuard(_dir: MkChatMessageDef, ctx: unknown): ctx is MkChatMessageContext;
198
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkChatMessageDef, never>;
199
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MkChatMessageDef, "ng-template[mkChatMessageDef]", never, {}, {}, never, never, true, never>;
200
+ }
201
+ /**
202
+ * Chat — a conversation: a scrolling, screen-reader-announced log of
203
+ * `mk-chat-message` bubbles that stays pinned to the newest message while
204
+ * text streams in (with a *jump to latest* button once the reader scrolls
205
+ * up), a typing indicator, and an `mk-prompt-box` composer.
206
+ *
207
+ * The component is presentational: hand it `messages` (replace the array or
208
+ * a message object to update — signals compare by reference) and react to
209
+ * `(send)` / `(stop)` / `(retry)` with your own transport.
210
+ *
211
+ * ```html
212
+ * <mk-chat
213
+ * [messages]="messages()"
214
+ * [busy]="generating()"
215
+ * [typing]="peerTyping()"
216
+ * attachments
217
+ * [suggestions]="starters"
218
+ * (send)="ask($event)"
219
+ * (stop)="abort()"
220
+ * (retry)="resend($event)"
221
+ * style="height: 32rem"
222
+ * >
223
+ * <div mkChatHeader>…title, model picker…</div>
224
+ * <div mkChatEmpty>…first-run hint…</div>
225
+ * </mk-chat>
226
+ * ```
227
+ *
228
+ * Slots: `[mkChatHeader]`, `[mkChatEmpty]`, `[mkChatFooter]` (under the composer).
229
+ */
230
+ declare class MkChat {
231
+ protected readonly i18n: _mk_kit_ui_core.MkI18nStrings;
232
+ /** The conversation, oldest first. */
233
+ readonly messages: _angular_core.InputSignal<readonly MkChatMessage[]>;
234
+ /** Which role renders on the "own" side (default `user`). */
235
+ readonly ownRole: _angular_core.InputSignal<MkChatRole>;
236
+ /** Render assistant text as Markdown. */
237
+ readonly markdown: _angular_core.InputSignalWithTransform<boolean, unknown>;
238
+ readonly showAvatars: _angular_core.InputSignalWithTransform<boolean, unknown>;
239
+ readonly showTimestamps: _angular_core.InputSignalWithTransform<boolean, unknown>;
240
+ /** Someone else is typing (shows the dots indicator). */
241
+ readonly typing: _angular_core.InputSignalWithTransform<boolean, unknown>;
242
+ /** A reply is being generated: composer shows *stop*. */
243
+ readonly busy: _angular_core.InputSignalWithTransform<boolean, unknown>;
244
+ /** Disable the composer. */
245
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
246
+ /** Hide the composer entirely (read-only transcript). */
247
+ readonly readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
248
+ readonly placeholder: _angular_core.InputSignal<string | undefined>;
249
+ /** Allow attachments in the composer. */
250
+ readonly attachments: _angular_core.InputSignalWithTransform<boolean, unknown>;
251
+ readonly accept: _angular_core.InputSignal<string>;
252
+ readonly maxFiles: _angular_core.InputSignal<number>;
253
+ readonly maxLength: _angular_core.InputSignal<number>;
254
+ /** Quick replies above the composer; each click sends its text. */
255
+ readonly suggestions: _angular_core.InputSignal<readonly string[]>;
256
+ /** Text shown when there are no messages (or project `[mkChatEmpty]`). */
257
+ readonly emptyMessage: _angular_core.InputSignal<string | undefined>;
258
+ /** Keep the log pinned to the newest message while the reader is at the bottom. */
259
+ readonly autoScroll: _angular_core.InputSignalWithTransform<boolean, unknown>;
260
+ /** Accessible name of the log region. */
261
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
262
+ readonly send: _angular_core.OutputEmitterRef<MkChatSend>;
263
+ readonly stop: _angular_core.OutputEmitterRef<void>;
264
+ readonly retry: _angular_core.OutputEmitterRef<MkChatMessage>;
265
+ protected readonly messageDef: _angular_core.Signal<MkChatMessageDef | undefined>;
266
+ private readonly log;
267
+ private readonly composer;
268
+ /** The reader is (near) the bottom of the log. */
269
+ protected readonly atBottom: _angular_core.WritableSignal<boolean>;
270
+ /** Messages that arrived while scrolled up. */
271
+ protected readonly unseen: _angular_core.WritableSignal<number>;
272
+ private lastCount;
273
+ protected readonly resolvedEmpty: _angular_core.Signal<string>;
274
+ protected readonly resolvedPlaceholder: _angular_core.Signal<string>;
275
+ constructor();
276
+ /** Scroll the log to the newest message. */
277
+ scrollToBottom(): void;
278
+ /** Focus the composer. */
279
+ focus(): void;
280
+ protected onScroll(): void;
281
+ protected isOwn(m: MkChatMessage): boolean;
282
+ protected trackMessage: (_: number, m: MkChatMessage) => string;
283
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkChat, never>;
284
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkChat, "mk-chat", never, { "messages": { "alias": "messages"; "required": false; "isSignal": true; }; "ownRole": { "alias": "ownRole"; "required": false; "isSignal": true; }; "markdown": { "alias": "markdown"; "required": false; "isSignal": true; }; "showAvatars": { "alias": "showAvatars"; "required": false; "isSignal": true; }; "showTimestamps": { "alias": "showTimestamps"; "required": false; "isSignal": true; }; "typing": { "alias": "typing"; "required": false; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "attachments": { "alias": "attachments"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "suggestions": { "alias": "suggestions"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; "autoScroll": { "alias": "autoScroll"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "send": "send"; "stop": "stop"; "retry": "retry"; }, ["messageDef"], ["[mkChatHeader]", "[mkChatEmpty]", "[mkChatFooter]"], true, never>;
285
+ }
286
+
287
+ export { MkChat, MkChatMessageComponent, MkChatMessageDef, MkPromptBox };
288
+ export type { MkChatAttachment, MkChatAuthor, MkChatMessage, MkChatMessageContext, MkChatRole, MkChatSend, MkChatToolCall, MkChatToolStatus };
@@ -933,6 +933,89 @@ interface MkI18nStrings {
933
933
  logCopyAll: string;
934
934
  /** Log viewer: soft-wrap toolbar toggle. */
935
935
  logWrapLines: string;
936
+ /** Chat: accessible name of the message log. */
937
+ chatLabel: string;
938
+ /** Chat: accessible name of the composer textarea. */
939
+ chatComposerLabel: string;
940
+ /** Chat: composer placeholder. */
941
+ chatPlaceholder: string;
942
+ /** Chat: send button. */
943
+ chatSend: string;
944
+ /** Chat: stop-generating button (replaces send while busy). */
945
+ chatStop: string;
946
+ /** Chat: attach-files button. */
947
+ chatAttach: string;
948
+ /** Chat: remove one pending attachment. */
949
+ chatRemoveAttachment: string;
950
+ /** Chat: group label of pending / shown attachments. */
951
+ chatAttachments: string;
952
+ /** Chat: group label of quick-reply suggestions. */
953
+ chatSuggestions: string;
954
+ /** Chat: copy-message button. */
955
+ chatCopy: string;
956
+ /** Chat: retry a failed message. */
957
+ chatRetry: string;
958
+ /** Chat: typing indicator. */
959
+ chatTyping: string;
960
+ /** Chat: screen-reader text while a reply streams in. */
961
+ chatStreaming: string;
962
+ /** Chat: scroll-to-newest button. */
963
+ chatJumpToLatest: string;
964
+ /** Chat: empty-state text. */
965
+ chatEmpty: string;
966
+ /** Chat: author fallback for the user's own messages. */
967
+ chatYou: string;
968
+ /** Chat: author fallback for assistant messages. */
969
+ chatAssistant: string;
970
+ /** Chat: tool call in progress. */
971
+ chatToolRunning: string;
972
+ /** Chat: tool call finished. */
973
+ chatToolDone: string;
974
+ /** Chat: tool call failed. */
975
+ chatToolError: string;
976
+ /** Query builder: accessible name of the whole builder. */
977
+ queryBuilderLabel: string;
978
+ queryAddRule: string;
979
+ queryAddGroup: string;
980
+ queryRemoveRule: string;
981
+ queryRemoveGroup: string;
982
+ /** Combinator labels — also used by `mkQueryToText`. */
983
+ queryAnd: string;
984
+ queryOr: string;
985
+ queryNot: string;
986
+ queryField: string;
987
+ queryOperator: string;
988
+ queryValue: string;
989
+ queryValueFrom: string;
990
+ queryValueTo: string;
991
+ queryEmptyGroup: string;
992
+ queryTrue: string;
993
+ queryFalse: string;
994
+ queryOpEq: string;
995
+ queryOpNeq: string;
996
+ queryOpContains: string;
997
+ queryOpNotContains: string;
998
+ queryOpStartsWith: string;
999
+ queryOpEndsWith: string;
1000
+ queryOpGt: string;
1001
+ queryOpGte: string;
1002
+ queryOpLt: string;
1003
+ queryOpLte: string;
1004
+ queryOpBetween: string;
1005
+ queryOpIn: string;
1006
+ queryOpNotIn: string;
1007
+ queryOpBefore: string;
1008
+ queryOpAfter: string;
1009
+ queryOpEmpty: string;
1010
+ queryOpNotEmpty: string;
1011
+ /** Dialog: label of the move grip (arrow keys move, Home resets). */
1012
+ dialogMove: string;
1013
+ /** Dialog: label of the resize grip (arrow keys resize, Home resets). */
1014
+ dialogResize: string;
1015
+ /** Listbox: filter box placeholder / label. */
1016
+ listboxFilter: string;
1017
+ /** Listbox: shown when the filter matches nothing. */
1018
+ listboxEmpty: string;
936
1019
  /** Announced when an event is picked up in keyboard move mode. */
937
1020
  eventCalendarGrabbed: (title: string, from: string, to: string) => string;
938
1021
  /** Announced after each keyboard step: current day + time range. */
@@ -1181,5 +1264,83 @@ type MkErrorMessages = Readonly<Record<string, string | ((err: any) => string)>>
1181
1264
  */
1182
1265
  declare function mkFirstErrorMessage(errors: ValidationErrors | null | undefined, strings: MkValidationStrings, overrides?: MkErrorMessages): string | null;
1183
1266
 
1184
- export { MK_BREAKPOINTS, MK_DEFAULT_BREAKPOINTS, MK_DEFAULT_DATE_NAMES, MK_DEFAULT_I18N, MK_DEFAULT_VALIDATION, MK_I18N, MK_OVERLAY_DATA, MkAnchoredPanel, MkBreakpointService, MkFieldContext, MkFocusTrap, MkLiveAnnouncer, MkOverlayRef, MkOverlayService, MkThemeService, mkComputeAnchoredPosition, mkFirstErrorMessage, mkGetFocusable, mkHighlight, mkHighlightJson, mkIsResponsive, mkUniqueId, mkValidatorChange, provideMkI18n };
1185
- export type { MkAnchoredPosition, MkAnchoredPositionOptions, MkAriaLivePoliteness, MkBlockEditorStrings, MkBreakpoint, MkBreakpoints, MkCodeLanguage, MkDateNames, MkDensity, MkErrorMessages, MkI18nStrings, MkOverlayConfig, MkPlacement, MkResolvedTheme, MkResponsive, MkSize$1 as MkSize, MkSortAnnounceDirection, MkThemePreference, MkTone, MkValidationStrings, MkValidatorChangeRef, MkVariant };
1267
+ /** Value kind of a filterable field; decides the editor and the operators offered. */
1268
+ type MkQueryValueType = 'string' | 'number' | 'boolean' | 'date' | 'select';
1269
+ /** A choice for `select` fields. */
1270
+ interface MkQueryFieldOption {
1271
+ label: string;
1272
+ value: unknown;
1273
+ }
1274
+ /** A field the user can filter on. */
1275
+ interface MkQueryField {
1276
+ /** Property key on the row objects / the API's filter name. */
1277
+ key: string;
1278
+ /** Label shown in the field picker. */
1279
+ label: string;
1280
+ /** Default `string`. */
1281
+ type?: MkQueryValueType;
1282
+ /** Choices for `select` fields. */
1283
+ options?: readonly MkQueryFieldOption[];
1284
+ /** Restrict / reorder the operators offered (default: all for the type). */
1285
+ operators?: readonly MkQueryOperator[];
1286
+ /** Placeholder of the value editor. */
1287
+ placeholder?: string;
1288
+ }
1289
+ /** Comparison operators. Which apply depends on the field type. */
1290
+ type MkQueryOperator = 'eq' | 'neq' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'in' | 'notIn' | 'before' | 'after' | 'empty' | 'notEmpty';
1291
+ /** A leaf condition. `value` is `[from, to]` for `between`, an array for `in` / `notIn`, absent for `empty` / `notEmpty`. Dates are ISO strings. */
1292
+ interface MkQueryRule {
1293
+ id: string;
1294
+ field: string;
1295
+ operator: MkQueryOperator;
1296
+ value?: unknown;
1297
+ }
1298
+ type MkQueryCombinator = 'and' | 'or';
1299
+ /** A group of rules and nested groups joined by one combinator, optionally negated. */
1300
+ interface MkQueryGroup {
1301
+ id: string;
1302
+ combinator: MkQueryCombinator;
1303
+ /** Negate the whole group. */
1304
+ not?: boolean;
1305
+ rules: MkQueryNode[];
1306
+ }
1307
+ type MkQueryNode = MkQueryRule | MkQueryGroup;
1308
+
1309
+ /** Operators offered per field type, in menu order. */
1310
+ declare const MK_QUERY_OPERATORS: Readonly<Record<MkQueryValueType, readonly MkQueryOperator[]>>;
1311
+ /** Operators that take no value. */
1312
+ declare const MK_QUERY_UNARY: ReadonlySet<MkQueryOperator>;
1313
+ /** True for a group node (as opposed to a rule). */
1314
+ declare function mkIsQueryGroup(node: MkQueryNode): node is MkQueryGroup;
1315
+ /** A fresh empty group. */
1316
+ declare function mkCreateQueryGroup(init?: Partial<Omit<MkQueryGroup, 'id'>>): MkQueryGroup;
1317
+ /** A fresh rule on `field`, using its first operator. */
1318
+ declare function mkCreateQueryRule(field: MkQueryField): MkQueryRule;
1319
+ /** Operators a field offers (its own list, else the defaults for its type). */
1320
+ declare function mkQueryOperatorsFor(field: MkQueryField | undefined): readonly MkQueryOperator[];
1321
+ /** True when the tree holds no rule at all (empty groups only). */
1322
+ declare function mkQueryIsEmpty(group: MkQueryGroup): boolean;
1323
+ /** Number of rules in the tree. */
1324
+ declare function mkQueryRuleCount(group: MkQueryGroup): number;
1325
+ /** Drop empty groups and rules that still need a value, so the API gets only complete conditions. */
1326
+ declare function mkQueryCompact(group: MkQueryGroup): MkQueryGroup;
1327
+ /** A rule is complete when its operator needs no value or has one. */
1328
+ declare function mkQueryRuleIsComplete(rule: MkQueryRule): boolean;
1329
+ /** Evaluate one rule against a row. */
1330
+ declare function mkQueryRuleMatches(rule: MkQueryRule, row: Record<string, unknown>, field?: MkQueryField): boolean;
1331
+ /**
1332
+ * Compile a query into a row predicate for client-side filtering
1333
+ * (`rows.filter(mkQueryToPredicate(query, fields))`). Unfinished rules are
1334
+ * ignored, so a half-edited query never blanks the table.
1335
+ */
1336
+ declare function mkQueryToPredicate<T extends object = Record<string, unknown>>(group: MkQueryGroup, fields?: readonly MkQueryField[]): (row: T) => boolean;
1337
+ /** Localised label of an operator. */
1338
+ declare function mkQueryOperatorLabel(op: MkQueryOperator, i18n?: MkI18nStrings): string;
1339
+ /**
1340
+ * Human-readable sentence for a query, e.g.
1341
+ * `(Name contains "ada" and Orders at least 10) or Status is any of Active, Invited`.
1342
+ */
1343
+ declare function mkQueryToText(group: MkQueryGroup, fields?: readonly MkQueryField[], i18n?: MkI18nStrings): string;
1344
+
1345
+ export { MK_BREAKPOINTS, MK_DEFAULT_BREAKPOINTS, MK_DEFAULT_DATE_NAMES, MK_DEFAULT_I18N, MK_DEFAULT_VALIDATION, MK_I18N, MK_OVERLAY_DATA, MK_QUERY_OPERATORS, MK_QUERY_UNARY, MkAnchoredPanel, MkBreakpointService, MkFieldContext, MkFocusTrap, MkLiveAnnouncer, MkOverlayRef, MkOverlayService, MkThemeService, mkComputeAnchoredPosition, mkCreateQueryGroup, mkCreateQueryRule, mkFirstErrorMessage, mkGetFocusable, mkHighlight, mkHighlightJson, mkIsQueryGroup, mkIsResponsive, mkQueryCompact, mkQueryIsEmpty, mkQueryOperatorLabel, mkQueryOperatorsFor, mkQueryRuleCount, mkQueryRuleIsComplete, mkQueryRuleMatches, mkQueryToPredicate, mkQueryToText, mkUniqueId, mkValidatorChange, provideMkI18n };
1346
+ export type { MkAnchoredPosition, MkAnchoredPositionOptions, MkAriaLivePoliteness, MkBlockEditorStrings, MkBreakpoint, MkBreakpoints, MkCodeLanguage, MkDateNames, MkDensity, MkErrorMessages, MkI18nStrings, MkOverlayConfig, MkPlacement, MkQueryCombinator, MkQueryField, MkQueryFieldOption, MkQueryGroup, MkQueryNode, MkQueryOperator, MkQueryRule, MkQueryValueType, MkResolvedTheme, MkResponsive, MkSize$1 as MkSize, MkSortAnnounceDirection, MkThemePreference, MkTone, MkValidationStrings, MkValidatorChangeRef, MkVariant };
@@ -543,13 +543,53 @@ declare class MkDialog {
543
543
  readonly titleId: _angular_core.InputSignal<string>;
544
544
  /** Hide the header close button. */
545
545
  readonly hideClose: _angular_core.InputSignalWithTransform<boolean, unknown>;
546
+ /**
547
+ * Let the user move the dialog by dragging its header (pointer / touch) or
548
+ * with the arrow keys on the grip that appears in the header. Double-click
549
+ * the header or press Home on the grip to snap back to the centre.
550
+ */
551
+ readonly draggable: _angular_core.InputSignalWithTransform<boolean, unknown>;
552
+ /**
553
+ * Let the user resize the dialog from the corner grip (pointer / touch, or
554
+ * arrow keys on the grip; Home resets). The panel never grows past the
555
+ * viewport or shrinks below a usable minimum.
556
+ */
557
+ readonly resizable: _angular_core.InputSignalWithTransform<boolean, unknown>;
558
+ private readonly destroyRef;
559
+ /** The body-level overlay panel this dialog lives in (`null` when inline). */
560
+ private panelEl;
561
+ /** Current drag offset from the centred position, px. */
562
+ private offset;
546
563
  constructor();
547
564
  /** Close the surrounding overlay, if any. */
548
565
  protected close(): void;
566
+ /** Snap back to the centred, preset-sized panel. */
567
+ reset(): void;
568
+ protected onHeaderPointerDown(event: PointerEvent): void;
569
+ protected onGripPointerDown(event: PointerEvent): void;
570
+ protected onResizerPointerDown(event: PointerEvent): void;
571
+ protected onHeaderDoubleClick(event: MouseEvent): void;
572
+ protected onGripKeydown(event: KeyboardEvent): void;
573
+ protected onResizerKeydown(event: KeyboardEvent): void;
574
+ private static arrowDelta;
575
+ private startPointer;
576
+ /** Move the panel to `(x, y)` px from its centred spot, kept inside the viewport. */
577
+ private moveTo;
578
+ /** Resize the panel to `w × h` px within [minimum, viewport]. */
579
+ private resizeTo;
580
+ /**
581
+ * Once the user takes hold, the entrance animation must never run again —
582
+ * toggling `animation` back on (as a transient class would) restarts it,
583
+ * so the panel would blink after every drag. The class is never removed.
584
+ */
585
+ private markMoved;
586
+ private clampIntoView;
587
+ private isRtl;
588
+ private panel;
549
589
  /** Point the owning dialog panel's `aria-labelledby` at the title element. */
550
590
  private wireLabelledBy;
551
591
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkDialog, never>;
552
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkDialog, "mk-dialog", never, { "dialogTitle": { "alias": "dialogTitle"; "required": false; "isSignal": true; }; "titleId": { "alias": "titleId"; "required": false; "isSignal": true; }; "hideClose": { "alias": "hideClose"; "required": false; "isSignal": true; }; }, {}, never, ["[mkDialogHeader], mk-dialog-title", "*", "[mkDialogFooter]"], true, never>;
592
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkDialog, "mk-dialog", never, { "dialogTitle": { "alias": "dialogTitle"; "required": false; "isSignal": true; }; "titleId": { "alias": "titleId"; "required": false; "isSignal": true; }; "hideClose": { "alias": "hideClose"; "required": false; "isSignal": true; }; "draggable": { "alias": "draggable"; "required": false; "isSignal": true; }; "resizable": { "alias": "resizable"; "required": false; "isSignal": true; }; }, {}, never, ["[mkDialogHeader], mk-dialog-title", "*", "[mkDialogFooter]"], true, never>;
553
593
  }
554
594
 
555
595
  /** Data contract for {@link MkConfirmDialog} / `MkDialogService.confirm`. */
@@ -1266,5 +1306,74 @@ declare class MkTourService {
1266
1306
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<MkTourService>;
1267
1307
  }
1268
1308
 
1269
- export { MK_TOUR_DATA, MkAlert, MkBanner, MkBottomSheet, MkBottomSheetService, MkConfirmDialog, MkDialog, MkDialogService, MkDialogTitle, MkHovercard, MkHovercardTrigger, MkLoadingBar, MkLoadingBarService, MkNotificationCenter, MkPopconfirm, MkPopconfirmTrigger, MkPopover, MkPopoverTrigger, MkPromptDialog, MkResult, MkSnackbar, MkSnackbarContainer, MkSnackbarRef, MkSnackbarService, MkToast, MkToastContainer, MkToastService, MkTooltip, MkTooltipPanel, MkTourPopup, MkTourService };
1309
+ /**
1310
+ * The translucent panel with a spinner that `mkBlockUi` and
1311
+ * `MkBlockUiService` drop over a region or the page.
1312
+ */
1313
+ declare class MkBlockUiOverlay {
1314
+ protected readonly i18n: _mk_kit_ui_core.MkI18nStrings;
1315
+ readonly message: _angular_core.WritableSignal<string>;
1316
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkBlockUiOverlay, never>;
1317
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkBlockUiOverlay, "mk-block-ui-overlay", never, {}, {}, never, never, true, never>;
1318
+ }
1319
+ /**
1320
+ * Block UI — cover the host element with a translucent panel and spinner
1321
+ * while something loads, so its contents can neither be read nor operated:
1322
+ * a card refreshing, a form submitting, a table re-fetching.
1323
+ *
1324
+ * Children get `inert` (no clicks, no Tab stops) and the host `aria-busy`.
1325
+ * `mkBlockUiDelay` (ms) holds the overlay back for quick operations so the
1326
+ * screen does not flash.
1327
+ *
1328
+ * ```html
1329
+ * <mk-card [mkBlockUi]="saving()" mkBlockUiMessage="Saving…">…</mk-card>
1330
+ * <form [mkBlockUi]="submitting()" [mkBlockUiDelay]="300">…</form>
1331
+ * ```
1332
+ */
1333
+ declare class MkBlockUi {
1334
+ private readonly host;
1335
+ private readonly document;
1336
+ private readonly injector;
1337
+ private readonly appRef;
1338
+ /** Block while `true`. */
1339
+ readonly mkBlockUi: _angular_core.InputSignalWithTransform<boolean, unknown>;
1340
+ /** Text under the spinner (also its accessible label). */
1341
+ readonly mkBlockUiMessage: _angular_core.InputSignal<string>;
1342
+ /** Wait this many ms before showing, to avoid a flash on fast operations. */
1343
+ readonly mkBlockUiDelay: _angular_core.InputSignalWithTransform<number, unknown>;
1344
+ private mounted;
1345
+ private timer;
1346
+ constructor();
1347
+ private mount;
1348
+ private unmount;
1349
+ private cancelTimer;
1350
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkBlockUi, never>;
1351
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MkBlockUi, "[mkBlockUi]", never, { "mkBlockUi": { "alias": "mkBlockUi"; "required": false; "isSignal": true; }; "mkBlockUiMessage": { "alias": "mkBlockUiMessage"; "required": false; "isSignal": true; }; "mkBlockUiDelay": { "alias": "mkBlockUiDelay"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1352
+ }
1353
+ /**
1354
+ * Block the whole page. Reference-counted: every `block()` returns a release
1355
+ * function, and the overlay disappears once all of them have been called.
1356
+ *
1357
+ * ```ts
1358
+ * const release = this.blockUi.block('Exporting…');
1359
+ * try { await this.api.export(); } finally { release(); }
1360
+ * ```
1361
+ */
1362
+ declare class MkBlockUiService {
1363
+ private readonly document;
1364
+ private readonly injector;
1365
+ private readonly appRef;
1366
+ private mounted;
1367
+ private readonly _count;
1368
+ /** Number of active blocks. */
1369
+ readonly count: _angular_core.Signal<number>;
1370
+ /** Show the page overlay (or update its message); call the returned function to release. */
1371
+ block(message?: string): () => void;
1372
+ /** True while the page is blocked. */
1373
+ isBlocked(): boolean;
1374
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkBlockUiService, never>;
1375
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<MkBlockUiService>;
1376
+ }
1377
+
1378
+ export { MK_TOUR_DATA, MkAlert, MkBanner, MkBlockUi, MkBlockUiOverlay, MkBlockUiService, MkBottomSheet, MkBottomSheetService, MkConfirmDialog, MkDialog, MkDialogService, MkDialogTitle, MkHovercard, MkHovercardTrigger, MkLoadingBar, MkLoadingBarService, MkNotificationCenter, MkPopconfirm, MkPopconfirmTrigger, MkPopover, MkPopoverTrigger, MkPromptDialog, MkResult, MkSnackbar, MkSnackbarContainer, MkSnackbarRef, MkSnackbarService, MkToast, MkToastContainer, MkToastService, MkTooltip, MkTooltipPanel, MkTourPopup, MkTourService };
1270
1379
  export type { MkAlertTone, MkAlertVariant, MkBottomSheetConfig, MkConfirmDialogData, MkDialogConfig, MkDialogSize, MkNotification, MkPromptDialogData, MkResultIconVariant, MkResultStatus, MkResultTone, MkSnackbarConfig, MkSnackbarDismissReason, MkSnackbarItem, MkSnackbarTone, MkToastAction, MkToastConfig, MkToastItem, MkToastTone, MkTourController, MkTourData, MkTourStep };