@k2b/ui 0.17.0 → 0.19.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/README.md +3 -2
- package/dist/browser/actions/ContextMenu.js +3 -1
- package/dist/browser/actions/ContextMenu.js.map +1 -1
- package/dist/browser/actions/Dropdown.js +91 -46
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/FilterChip.js +4 -1
- package/dist/browser/actions/FilterChip.js.map +1 -1
- package/dist/browser/chat/ChatComposer.js +1311 -565
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/chat/ChatPrimitives.js +9 -6
- package/dist/browser/chat/ChatPrimitives.js.map +1 -1
- package/dist/browser/chat/chat-behavior.js +9 -0
- package/dist/browser/chat/chat-behavior.js.map +1 -1
- package/dist/browser/chat/index.js.map +1 -1
- package/dist/browser/chat/types.js.map +1 -1
- package/dist/browser/content/Calendar.js +579 -533
- package/dist/browser/content/Calendar.js.map +1 -1
- package/dist/browser/content/FileView.js +62 -36
- package/dist/browser/content/FileView.js.map +1 -1
- package/dist/browser/content/Lightbox.js +76 -40
- package/dist/browser/content/Lightbox.js.map +1 -1
- package/dist/browser/content/MarkdownView.js +9 -3
- package/dist/browser/content/MarkdownView.js.map +1 -1
- package/dist/browser/content/PdfPreview.js +146 -79
- package/dist/browser/content/PdfPreview.js.map +1 -1
- package/dist/browser/content/Timeline.js +1038 -0
- package/dist/browser/content/Timeline.js.map +1 -0
- package/dist/browser/content/VideoPlayer.js +299 -0
- package/dist/browser/content/VideoPlayer.js.map +1 -0
- package/dist/browser/content/chart-inspection.js +7 -2
- package/dist/browser/content/chart-inspection.js.map +1 -1
- package/dist/browser/content/file-view-preview.js +2 -2
- package/dist/browser/content/file-view-preview.js.map +1 -1
- package/dist/browser/content/index.js +3 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/markdown-links.js +178 -0
- package/dist/browser/content/markdown-links.js.map +1 -0
- package/dist/browser/content/timeline-model.js +579 -0
- package/dist/browser/content/timeline-model.js.map +1 -0
- package/dist/browser/feedback/dialog-core.js +26 -14
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/inputs/ChoiceChips.js +66 -0
- package/dist/browser/inputs/ChoiceChips.js.map +1 -0
- package/dist/browser/inputs/ChoiceGroups.js +53 -12
- package/dist/browser/inputs/ChoiceGroups.js.map +1 -1
- package/dist/browser/inputs/FileDropTarget.js +129 -0
- package/dist/browser/inputs/FileDropTarget.js.map +1 -0
- package/dist/browser/inputs/FileInputs.js +84 -43
- package/dist/browser/inputs/FileInputs.js.map +1 -1
- package/dist/browser/inputs/SignatureInput.js +558 -0
- package/dist/browser/inputs/SignatureInput.js.map +1 -0
- package/dist/browser/inputs/emoji/EmojiPicker.js +841 -0
- package/dist/browser/inputs/emoji/EmojiPicker.js.map +1 -0
- package/dist/browser/inputs/emoji/emoji-data.js +1903 -0
- package/dist/browser/inputs/emoji/emoji-data.js.map +1 -0
- package/dist/browser/inputs/emoji/emoji-index.js +209 -0
- package/dist/browser/inputs/emoji/emoji-index.js.map +1 -0
- package/dist/browser/inputs/emoji/emoji-messages.js +64 -0
- package/dist/browser/inputs/emoji/emoji-messages.js.map +1 -0
- package/dist/browser/inputs/file-drop.js +338 -0
- package/dist/browser/inputs/file-drop.js.map +1 -0
- package/dist/browser/inputs/index.js +6 -0
- package/dist/browser/inputs/index.js.map +1 -1
- package/dist/browser/inputs/markdown/MarkdownEditor.js +72 -78
- package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
- package/dist/browser/inputs/markdown/actions.js +48 -2
- package/dist/browser/inputs/markdown/actions.js.map +1 -1
- package/dist/browser/inputs/markdown/code-zone.js +38 -2
- package/dist/browser/inputs/markdown/code-zone.js.map +1 -1
- package/dist/browser/inputs/signature-messages.js +39 -0
- package/dist/browser/inputs/signature-messages.js.map +1 -0
- package/dist/browser/inputs/signature.js +208 -0
- package/dist/browser/inputs/signature.js.map +1 -0
- package/dist/browser/internal/render-error.js +49 -0
- package/dist/browser/internal/render-error.js.map +1 -0
- package/dist/browser/intl/messages.js +205 -4
- package/dist/browser/intl/messages.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +483 -218
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/FloatingWindow.js +4 -1
- package/dist/browser/layout/FloatingWindow.js.map +1 -1
- package/dist/browser/layout/Navigation.js +274 -197
- package/dist/browser/layout/Navigation.js.map +1 -1
- package/dist/browser/layout/SidebarItemPreview.js +5 -1
- package/dist/browser/layout/SidebarItemPreview.js.map +1 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/layout/navigation-model.js +2 -0
- package/dist/browser/layout/navigation-model.js.map +1 -1
- package/dist/browser/surfaces/NoticeCard.js +47 -44
- package/dist/browser/surfaces/NoticeCard.js.map +1 -1
- package/dist/browser/surfaces/ResourceCard.js +212 -0
- package/dist/browser/surfaces/ResourceCard.js.map +1 -0
- package/dist/browser/surfaces/index.js +1 -0
- package/dist/browser/surfaces/index.js.map +1 -1
- package/dist/licenses/emojibase-data.txt +21 -0
- package/dist/ssr/actions/ContextMenu.js +3 -1
- package/dist/ssr/actions/ContextMenu.js.map +1 -1
- package/dist/ssr/actions/Dropdown.js +49 -12
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/FilterChip.js +4 -1
- package/dist/ssr/actions/FilterChip.js.map +1 -1
- package/dist/ssr/chat/ChatComposer.js +823 -221
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/chat/ChatPrimitives.js +9 -6
- package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
- package/dist/ssr/chat/chat-behavior.js +9 -0
- package/dist/ssr/chat/chat-behavior.js.map +1 -1
- package/dist/ssr/chat/index.js.map +1 -1
- package/dist/ssr/chat/types.js.map +1 -1
- package/dist/ssr/content/Calendar.js +183 -142
- package/dist/ssr/content/Calendar.js.map +1 -1
- package/dist/ssr/content/FileView.js +30 -6
- package/dist/ssr/content/FileView.js.map +1 -1
- package/dist/ssr/content/Lightbox.js +19 -5
- package/dist/ssr/content/Lightbox.js.map +1 -1
- package/dist/ssr/content/MarkdownView.js +9 -3
- package/dist/ssr/content/MarkdownView.js.map +1 -1
- package/dist/ssr/content/PdfPreview.js +77 -36
- package/dist/ssr/content/PdfPreview.js.map +1 -1
- package/dist/ssr/content/Timeline.js +804 -0
- package/dist/ssr/content/Timeline.js.map +1 -0
- package/dist/ssr/content/VideoPlayer.js +228 -0
- package/dist/ssr/content/VideoPlayer.js.map +1 -0
- package/dist/ssr/content/chart-inspection.js +7 -2
- package/dist/ssr/content/chart-inspection.js.map +1 -1
- package/dist/ssr/content/file-view-preview.js +2 -2
- package/dist/ssr/content/file-view-preview.js.map +1 -1
- package/dist/ssr/content/index.js +3 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/markdown-links.js +178 -0
- package/dist/ssr/content/markdown-links.js.map +1 -0
- package/dist/ssr/content/timeline-model.js +579 -0
- package/dist/ssr/content/timeline-model.js.map +1 -0
- package/dist/ssr/feedback/dialog-core.js +26 -14
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/inputs/ChoiceChips.js +66 -0
- package/dist/ssr/inputs/ChoiceChips.js.map +1 -0
- package/dist/ssr/inputs/ChoiceGroups.js +12 -4
- package/dist/ssr/inputs/ChoiceGroups.js.map +1 -1
- package/dist/ssr/inputs/FileDropTarget.js +103 -0
- package/dist/ssr/inputs/FileDropTarget.js.map +1 -0
- package/dist/ssr/inputs/FileInputs.js +49 -12
- package/dist/ssr/inputs/FileInputs.js.map +1 -1
- package/dist/ssr/inputs/SignatureInput.js +404 -0
- package/dist/ssr/inputs/SignatureInput.js.map +1 -0
- package/dist/ssr/inputs/emoji/EmojiPicker.js +551 -0
- package/dist/ssr/inputs/emoji/EmojiPicker.js.map +1 -0
- package/dist/ssr/inputs/emoji/emoji-data.js +1903 -0
- package/dist/ssr/inputs/emoji/emoji-data.js.map +1 -0
- package/dist/ssr/inputs/emoji/emoji-index.js +209 -0
- package/dist/ssr/inputs/emoji/emoji-index.js.map +1 -0
- package/dist/ssr/inputs/emoji/emoji-messages.js +64 -0
- package/dist/ssr/inputs/emoji/emoji-messages.js.map +1 -0
- package/dist/ssr/inputs/file-drop.js +338 -0
- package/dist/ssr/inputs/file-drop.js.map +1 -0
- package/dist/ssr/inputs/index.js +6 -0
- package/dist/ssr/inputs/index.js.map +1 -1
- package/dist/ssr/inputs/markdown/MarkdownEditor.js +14 -2
- package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
- package/dist/ssr/inputs/markdown/actions.js +48 -2
- package/dist/ssr/inputs/markdown/actions.js.map +1 -1
- package/dist/ssr/inputs/markdown/code-zone.js +38 -2
- package/dist/ssr/inputs/markdown/code-zone.js.map +1 -1
- package/dist/ssr/inputs/signature-messages.js +39 -0
- package/dist/ssr/inputs/signature-messages.js.map +1 -0
- package/dist/ssr/inputs/signature.js +208 -0
- package/dist/ssr/inputs/signature.js.map +1 -0
- package/dist/ssr/internal/render-error.js +49 -0
- package/dist/ssr/internal/render-error.js.map +1 -0
- package/dist/ssr/intl/messages.js +205 -4
- package/dist/ssr/intl/messages.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +264 -47
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/FloatingWindow.js +4 -1
- package/dist/ssr/layout/FloatingWindow.js.map +1 -1
- package/dist/ssr/layout/Navigation.js +169 -122
- package/dist/ssr/layout/Navigation.js.map +1 -1
- package/dist/ssr/layout/SidebarItemPreview.js +5 -1
- package/dist/ssr/layout/SidebarItemPreview.js.map +1 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/layout/navigation-model.js +2 -0
- package/dist/ssr/layout/navigation-model.js.map +1 -1
- package/dist/ssr/surfaces/NoticeCard.js +17 -12
- package/dist/ssr/surfaces/NoticeCard.js.map +1 -1
- package/dist/ssr/surfaces/ResourceCard.js +115 -0
- package/dist/ssr/surfaces/ResourceCard.js.map +1 -0
- package/dist/ssr/surfaces/index.js +1 -0
- package/dist/ssr/surfaces/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/Dropdown.d.ts +13 -1
- package/dist/types/actions/FilterChip.d.ts +5 -0
- package/dist/types/chat/ChatComposer.d.ts +24 -1
- package/dist/types/chat/ChatPrimitives.d.ts +1 -1
- package/dist/types/chat/chat-behavior.d.ts +15 -0
- package/dist/types/chat/index.d.ts +1 -1
- package/dist/types/chat/types.d.ts +34 -0
- package/dist/types/content/Calendar.d.ts +28 -8
- package/dist/types/content/Lightbox.d.ts +8 -0
- package/dist/types/content/Timeline.d.ts +49 -0
- package/dist/types/content/VideoPlayer.d.ts +41 -0
- package/dist/types/content/index.d.ts +6 -2
- package/dist/types/content/markdown-links.d.ts +66 -0
- package/dist/types/content/timeline-model.d.ts +148 -0
- package/dist/types/feedback/dialog-core.d.ts +1 -1
- package/dist/types/inputs/ChoiceChips.d.ts +20 -0
- package/dist/types/inputs/ChoiceGroups.d.ts +11 -2
- package/dist/types/inputs/FileDropTarget.d.ts +23 -0
- package/dist/types/inputs/FileInputs.d.ts +8 -0
- package/dist/types/inputs/SignatureInput.d.ts +22 -0
- package/dist/types/inputs/emoji/EmojiPicker.d.ts +42 -0
- package/dist/types/inputs/emoji/emoji-data.d.ts +2 -0
- package/dist/types/inputs/emoji/emoji-index.d.ts +109 -0
- package/dist/types/inputs/emoji/emoji-messages.d.ts +30 -0
- package/dist/types/inputs/file-drop.d.ts +80 -0
- package/dist/types/inputs/index.d.ts +12 -0
- package/dist/types/inputs/markdown/actions.d.ts +4 -0
- package/dist/types/inputs/markdown/code-zone.d.ts +7 -0
- package/dist/types/inputs/signature-messages.d.ts +11 -0
- package/dist/types/inputs/signature.d.ts +72 -0
- package/dist/types/internal/render-error.d.ts +13 -0
- package/dist/types/intl/messages.d.ts +101 -0
- package/dist/types/layout/AppWorkspace.d.ts +38 -0
- package/dist/types/layout/SidebarItemPreview.d.ts +2 -0
- package/dist/types/layout/index.d.ts +2 -2
- package/dist/types/layout/navigation-model.d.ts +18 -0
- package/dist/types/surfaces/ResourceCard.d.ts +31 -0
- package/dist/types/surfaces/index.d.ts +2 -0
- package/package.json +5 -4
|
@@ -18,7 +18,8 @@ export type DropdownAction = (DropdownActionBase & {
|
|
|
18
18
|
}) | (DropdownActionBase & {
|
|
19
19
|
href: string;
|
|
20
20
|
external?: boolean;
|
|
21
|
-
|
|
21
|
+
/** Runs on a plain click instead of following the link; modified clicks, middle-click, and the link's menu keep it. */
|
|
22
|
+
action?: () => void;
|
|
22
23
|
}) | (DropdownActionBase & {
|
|
23
24
|
disabled: true;
|
|
24
25
|
action?: never;
|
|
@@ -35,6 +36,11 @@ export type DropdownChoice = DropdownActionBase & {
|
|
|
35
36
|
};
|
|
36
37
|
export type DropdownSection = {
|
|
37
38
|
sectionLabel?: string;
|
|
39
|
+
/**
|
|
40
|
+
* `row` sets a few short radio choices, such as a sort direction, side by side as one segmented row. Give it a
|
|
41
|
+
* `sectionLabel`: the label names the choice above the row and for screen readers.
|
|
42
|
+
*/
|
|
43
|
+
layout?: "row";
|
|
38
44
|
items: readonly (DropdownAction | DropdownChoice)[];
|
|
39
45
|
};
|
|
40
46
|
export type DropdownItem = DropdownAction | DropdownChoice | DropdownSection;
|
|
@@ -82,9 +88,15 @@ export type DropdownItemProps = {
|
|
|
82
88
|
variant?: "danger";
|
|
83
89
|
href?: string;
|
|
84
90
|
external?: boolean;
|
|
91
|
+
/** Runs when the item is chosen. With `href`, a plain click runs it instead of following the link. */
|
|
85
92
|
onSelect?: () => void;
|
|
86
93
|
class?: string;
|
|
87
94
|
};
|
|
95
|
+
/**
|
|
96
|
+
* Left and Right cycle through the segments of a row section; Up and Down leave it like any item. Returns whether
|
|
97
|
+
* the key moved focus.
|
|
98
|
+
*/
|
|
99
|
+
export declare const focusRowSegment: (items: HTMLElement[], key: string) => boolean;
|
|
88
100
|
export declare const dropdownPosition: (trigger: DOMRect, menu: Pick<DOMRect, "width" | "height">, position: DropdownPosition, viewport: {
|
|
89
101
|
width: number;
|
|
90
102
|
height: number;
|
|
@@ -10,6 +10,11 @@ export type FilterChipSection = {
|
|
|
10
10
|
label?: string;
|
|
11
11
|
options: readonly FilterChipOption[];
|
|
12
12
|
multiple?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* `row` sets a few short single-select options side by side as one segmented row under its `label`. Selecting the
|
|
15
|
+
* chosen option again keeps it; give the row a value in `defaultValue` so Reset keeps a choice too.
|
|
16
|
+
*/
|
|
17
|
+
layout?: "row";
|
|
13
18
|
};
|
|
14
19
|
export type FilterChipProps = {
|
|
15
20
|
label: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type JSX } from "solid-js";
|
|
2
|
-
import type { ChatAction, ChatAttachment, ChatComposerState, ChatContextUsageData, ChatMention, ChatModelOption, ChatSubmitInput } from "./types";
|
|
2
|
+
import type { ChatAction, ChatAttachment, ChatComposerEmoji, ChatComposerMicrophone, ChatComposerState, ChatContextUsageData, ChatMention, ChatModelOption, ChatSubmitInput } from "./types";
|
|
3
3
|
export type ChatCommandContext = {
|
|
4
4
|
setValue: (value: string) => void;
|
|
5
5
|
submit: () => void;
|
|
@@ -17,6 +17,12 @@ export type ChatCommand = {
|
|
|
17
17
|
};
|
|
18
18
|
export type ChatFileSelection = {
|
|
19
19
|
onSelect: (files: readonly File[]) => void | Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Chooses files for "Attach files" instead of the device's file dialog, for example to offer other sources as well.
|
|
22
|
+
* Called within the menu activation, so it may still open the device's dialog; resolve `[]` when the user cancels.
|
|
23
|
+
* `multiple: false` keeps the first chosen file, and a rejection reaches `onError`.
|
|
24
|
+
*/
|
|
25
|
+
choose?: () => Promise<readonly File[]>;
|
|
20
26
|
onError?: (error: unknown) => void;
|
|
21
27
|
accept?: string;
|
|
22
28
|
multiple?: boolean;
|
|
@@ -71,5 +77,22 @@ export type ChatComposerProps = {
|
|
|
71
77
|
focusToken?: unknown;
|
|
72
78
|
draftKey?: unknown;
|
|
73
79
|
class?: string;
|
|
80
|
+
/**
|
|
81
|
+
* `"conversation"` is the composer for messages between people: one row with attach, a pill-shaped field and Send,
|
|
82
|
+
* without the assistant prompt's footer. The field starts with one line and grows to a third of its nearest size
|
|
83
|
+
* container, a hint line of fixed height sits above it, its buttons keep it focused, and Enter breaks the line
|
|
84
|
+
* inside an open code block and on touch-only devices. The default is the assistant prompt.
|
|
85
|
+
*/
|
|
86
|
+
variant?: "default" | "conversation";
|
|
87
|
+
/** `"enter"` (default): Enter sends and Shift+Enter breaks the line. `"mod-enter"`: Enter breaks the line. Ctrl/⌘+Enter always sends. */
|
|
88
|
+
sendKey?: "enter" | "mod-enter";
|
|
89
|
+
/** Adds "Aa", which opens one row of Markdown formatting buttons above the field; the field and its controls stay put. */
|
|
90
|
+
formatting?: boolean;
|
|
91
|
+
/** An emoji button at a fixed place. Touch-only devices hide it; their keyboard has emoji. */
|
|
92
|
+
emoji?: ChatComposerEmoji;
|
|
93
|
+
/** A microphone at a fixed place: a tap dictates, holding it or its menu asks for a voice message. */
|
|
94
|
+
microphone?: ChatComposerMicrophone;
|
|
95
|
+
/** One line above the field. The conversation variant always keeps its height; the default shows it only with content. */
|
|
96
|
+
hint?: JSX.Element;
|
|
74
97
|
};
|
|
75
98
|
export declare function ChatComposer(props: ChatComposerProps): JSX.Element;
|
|
@@ -44,7 +44,7 @@ export type ChatActivityProps = {
|
|
|
44
44
|
export type ChatContextUsageProps = ChatContextUsageData & {
|
|
45
45
|
action?: ChatAction;
|
|
46
46
|
onActionError?: (error: unknown) => void;
|
|
47
|
-
/** Host-owned number formatting. The default
|
|
47
|
+
/** Host-owned number formatting. The default groups whole numbers in the inherited render locale. */
|
|
48
48
|
formatNumber?: (value: number) => string;
|
|
49
49
|
class?: string;
|
|
50
50
|
};
|
|
@@ -24,3 +24,18 @@ export declare const runChatSubmission: (run: ChatSubmissionRun) => Promise<bool
|
|
|
24
24
|
export declare const reportChatFailure: (perform: () => unknown, onError?: (error: unknown) => void) => void;
|
|
25
25
|
/** Executes the one behavior guaranteed by the ChatAction contract. */
|
|
26
26
|
export declare const executeChatAction: (action: ChatAction) => Promise<void>;
|
|
27
|
+
export type ChatEnterKey = {
|
|
28
|
+
shiftKey: boolean;
|
|
29
|
+
ctrlKey: boolean;
|
|
30
|
+
metaKey: boolean;
|
|
31
|
+
altKey: boolean;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* What Enter does in a conversation composer: Ctrl/⌘+Enter always sends; Shift+Enter, Enter inside an open code
|
|
35
|
+
* block, and Enter on a touch-only device break the line; otherwise `sendKey` decides. IME input is the caller's check.
|
|
36
|
+
*/
|
|
37
|
+
export declare const conversationEnterAction: (key: ChatEnterKey, context: {
|
|
38
|
+
sendKey: "enter" | "mod-enter";
|
|
39
|
+
touchOnly: boolean;
|
|
40
|
+
inCodeBlock: boolean;
|
|
41
|
+
}) => "send" | "newline";
|
|
@@ -11,7 +11,7 @@ export type { ChatActivityProps, ChatContextUsageProps, ChatMessageProps } from
|
|
|
11
11
|
export { formatChatTokens } from "./ChatPrimitives";
|
|
12
12
|
export type { ChatRootProps } from "./ChatRoot";
|
|
13
13
|
export type { ChatActivityItem, ChatMessageItem, ChatTimelineItem, ChatTimelineProps } from "./ChatTimeline";
|
|
14
|
-
export type { ChatAction, ChatActivityTone, ChatAttachment, ChatComposerState, ChatContextUsageData, ChatMention, ChatMessageStatus, ChatModelOption, ChatRole, ChatSubmitInput, ChatSubmitIntent, ChatUsage, } from "./types";
|
|
14
|
+
export type { ChatAction, ChatActivityTone, ChatAttachment, ChatComposerEmoji, ChatComposerMicrophone, ChatComposerState, ChatContextUsageData, ChatDictationState, ChatMention, ChatMessageStatus, ChatModelOption, ChatRole, ChatSubmitInput, ChatSubmitIntent, ChatUsage, } from "./types";
|
|
15
15
|
/**
|
|
16
16
|
* Portable, controlled chat surface. Applications own storage, streaming,
|
|
17
17
|
* authorization, rich message rendering, and domain actions.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EmojiSkinTone } from "../inputs/emoji/emoji-index";
|
|
1
2
|
export type ChatRole = "user" | "assistant" | "system" | "tool";
|
|
2
3
|
export type ChatMessageStatus = "pending" | "streaming" | "complete" | "error";
|
|
3
4
|
export type ChatActivityTone = "neutral" | "ai" | "success" | "danger";
|
|
@@ -68,4 +69,37 @@ export type ChatMention = {
|
|
|
68
69
|
end: number;
|
|
69
70
|
attachment: ChatAttachment;
|
|
70
71
|
};
|
|
72
|
+
/**
|
|
73
|
+
* Live dictation as the caller runs it: `listening` while speech arrives, `refining` after the stop until the refined
|
|
74
|
+
* text replaced it, `refined` afterwards, `unrefined` when the raw text stays, and `interrupted` when the connection
|
|
75
|
+
* ended early and the text so far stays.
|
|
76
|
+
*/
|
|
77
|
+
export type ChatDictationState = "listening" | "refining" | "refined" | "unrefined" | "interrupted";
|
|
78
|
+
/** The composer's microphone. Dictation comes first; a voice message is the deliberate second action. */
|
|
79
|
+
export type ChatComposerMicrophone = {
|
|
80
|
+
/** A tap starts or stops live dictation. Without it, a tap opens the microphone menu. */
|
|
81
|
+
onDictate?: () => void;
|
|
82
|
+
/** Holding the microphone, or "Record voice message" in its menu. Omit it where recording is not available. */
|
|
83
|
+
onVoiceMessage?: () => void;
|
|
84
|
+
/** The dictation state, shown on the microphone and in the hint line. */
|
|
85
|
+
dictation?: ChatDictationState | null;
|
|
86
|
+
/** Offered as "Restore original" while `dictation` is `refined`. */
|
|
87
|
+
onRestoreOriginal?: () => void;
|
|
88
|
+
disabled?: boolean;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* The composer's emoji button and `:shortcode` completion. Typing a colon and two letters suggests emoji by their
|
|
92
|
+
* English or German name or GitHub shortcode; a complete `:thumbsup:` becomes 👍 when its closing colon is typed.
|
|
93
|
+
*/
|
|
94
|
+
export type ChatComposerEmoji = {
|
|
95
|
+
/** Opens the emoji choice next to `anchor`, usually `EmojiPicker.Popover`; `insert` puts the chosen text at the caret. */
|
|
96
|
+
onOpen: (context: {
|
|
97
|
+
anchor: HTMLElement;
|
|
98
|
+
insert: (text: string) => void;
|
|
99
|
+
}) => void;
|
|
100
|
+
/** The skin tone of completed emoji that have one, as in the picker. */
|
|
101
|
+
skinTone?: EmojiSkinTone;
|
|
102
|
+
/** Called with each emoji the completion inserted, for example to remember it with `rememberEmoji`. */
|
|
103
|
+
onPick?: (emoji: string) => void;
|
|
104
|
+
};
|
|
71
105
|
export {};
|
|
@@ -15,7 +15,16 @@ export type CalendarEvent = {
|
|
|
15
15
|
dataSpaceItemId?: string;
|
|
16
16
|
meta?: string;
|
|
17
17
|
description?: string;
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* `marker` draws a point in time, such as a deadline, as a colored marker
|
|
20
|
+
* beside its title instead of a filled band.
|
|
21
|
+
*/
|
|
22
|
+
display?: "event" | "background" | "marker";
|
|
23
|
+
/**
|
|
24
|
+
* Short text the accessible name adds after the title and time, for state the event shows only visually, such as
|
|
25
|
+
* a priority flag in custom `renderEvent` content.
|
|
26
|
+
*/
|
|
27
|
+
accessibleDetail?: string;
|
|
19
28
|
location?: string;
|
|
20
29
|
calendarName?: string;
|
|
21
30
|
attendees?: CalendarAttendee[];
|
|
@@ -55,11 +64,20 @@ export type CalendarEventRenderContext = {
|
|
|
55
64
|
durationHours: number;
|
|
56
65
|
timeLabel: string;
|
|
57
66
|
};
|
|
58
|
-
|
|
67
|
+
/** A view the application adds to the switcher; the calendar shows its header and toolbar, the application the body. */
|
|
68
|
+
export type CalendarCustomView<V extends string = string> = {
|
|
69
|
+
value: V;
|
|
70
|
+
label: string;
|
|
71
|
+
};
|
|
72
|
+
export type CalendarProps<V extends string = never> = {
|
|
59
73
|
date: Date | string;
|
|
60
74
|
events: CalendarEvent[];
|
|
61
|
-
view?: CalendarView;
|
|
75
|
+
view?: CalendarView | V;
|
|
62
76
|
views?: CalendarView[];
|
|
77
|
+
/** Views after the built-in ones. While one is active, `children` is the body and the header pages by day. */
|
|
78
|
+
customViews?: CalendarCustomView<V>[];
|
|
79
|
+
/** The body of the active custom view. */
|
|
80
|
+
children?: JSX.Element;
|
|
63
81
|
labels?: CalendarLabels;
|
|
64
82
|
/** stdlib date context used for timezone-aware rendering and calendar math. */
|
|
65
83
|
dateConfig?: DateContext;
|
|
@@ -76,8 +94,8 @@ export type CalendarProps = {
|
|
|
76
94
|
selectedDate?: Date | string;
|
|
77
95
|
selectedEventId?: string;
|
|
78
96
|
dayBadges?: Record<string, CalendarDayBadge>;
|
|
79
|
-
getViewHref
|
|
80
|
-
getDateHref
|
|
97
|
+
getViewHref?(view: CalendarView | V): string;
|
|
98
|
+
getDateHref?(date: Date, view: CalendarView | V): string;
|
|
81
99
|
getEventHref?: (event: CalendarEvent) => string | undefined;
|
|
82
100
|
renderEvent?: (event: CalendarEvent, context: CalendarEventRenderContext) => JSX.Element;
|
|
83
101
|
/** Progressively enhance canonical calendar links after the app has loaded their target state. */
|
|
@@ -87,8 +105,8 @@ export type CalendarProps = {
|
|
|
87
105
|
/** Optionally preload the target behind a canonical calendar link. */
|
|
88
106
|
onPrefetch?: (href: string) => void;
|
|
89
107
|
navigationPending?: boolean;
|
|
90
|
-
onViewChange
|
|
91
|
-
onDateChange
|
|
108
|
+
onViewChange?(view: CalendarView | V): void;
|
|
109
|
+
onDateChange?(date: Date, view: CalendarView | V): void;
|
|
92
110
|
/** One activation contract for pointer and keyboard input. */
|
|
93
111
|
onEventActivate?: (event: CalendarEvent) => void;
|
|
94
112
|
/** Pointer gesture used for activation. Keyboard activation is always immediate. */
|
|
@@ -111,5 +129,7 @@ export type CalendarDayBadge = {
|
|
|
111
129
|
icon?: string;
|
|
112
130
|
label: string;
|
|
113
131
|
};
|
|
114
|
-
|
|
132
|
+
/** JSX infers the values of `customViews`; inference from the last signature, as in `createComponent`, sees plain props. */
|
|
133
|
+
declare function Calendar<V extends string = never>(props: CalendarProps<V>): JSX.Element;
|
|
134
|
+
declare function Calendar(props: CalendarProps): JSX.Element;
|
|
115
135
|
export default Calendar;
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
/** One more thing to do with the shown image, beside Download: a short label, its icon class, and what it does. */
|
|
2
|
+
export type LightboxAction = {
|
|
3
|
+
label: string;
|
|
4
|
+
icon: string;
|
|
5
|
+
onClick: () => void;
|
|
6
|
+
};
|
|
1
7
|
export type LightboxImage = {
|
|
2
8
|
src: string;
|
|
3
9
|
alt?: string;
|
|
4
10
|
downloadUrl?: string;
|
|
11
|
+
/** Actions for this image, shown before Download in the same style. */
|
|
12
|
+
actions?: readonly LightboxAction[];
|
|
5
13
|
};
|
|
6
14
|
type LightboxProps = {
|
|
7
15
|
images: LightboxImage[];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { DateContext } from "@k2b/stdlib";
|
|
2
|
+
import { type JSX } from "solid-js";
|
|
3
|
+
import { type TimelineItem } from "./timeline-model";
|
|
4
|
+
export type { TimelineColor, TimelineItem } from "./timeline-model";
|
|
5
|
+
export type TimelineController = {
|
|
6
|
+
/** Scrolls a time into view; `start` (default) puts it near the start edge, `center` in the middle. */
|
|
7
|
+
scrollToTime: (time: Date | string, options?: {
|
|
8
|
+
align?: "start" | "center";
|
|
9
|
+
}) => void;
|
|
10
|
+
/** Scrolls the current time to the middle of the view. */
|
|
11
|
+
scrollToNow: () => void;
|
|
12
|
+
};
|
|
13
|
+
export type TimelineProps = {
|
|
14
|
+
items: readonly TimelineItem[];
|
|
15
|
+
/** Start of the loaded range. The view starts here, so pass the first time the reader should see. */
|
|
16
|
+
from: Date | string;
|
|
17
|
+
/** End of the loaded range (exclusive). */
|
|
18
|
+
to: Date | string;
|
|
19
|
+
/** The current time. Without it the timeline uses the clock and moves the now line every 30 seconds. */
|
|
20
|
+
now?: Date | string;
|
|
21
|
+
/** Accessible name of the region. Defaults to "Timeline". */
|
|
22
|
+
label?: string;
|
|
23
|
+
/** stdlib date context: time zone and locale of days, hours, and folds. */
|
|
24
|
+
dateConfig?: DateContext;
|
|
25
|
+
/** Convenience override for `dateConfig.timeZone`. */
|
|
26
|
+
timeZone?: string;
|
|
27
|
+
/** Level of the per-day headings. Defaults to 3. */
|
|
28
|
+
headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
29
|
+
/** Opens an item, on click, Enter, or Space. */
|
|
30
|
+
onActivate?: (item: TimelineItem) => void;
|
|
31
|
+
/** Changes the checkbox of an item, on a click on the box or Space. Leave it out when the reader may not change it. */
|
|
32
|
+
onToggle?: (item: TimelineItem, checked: boolean) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Called once when the reader nears the start, again once `from` moved and changed the strip's length. Extend `from`
|
|
35
|
+
* to load earlier days.
|
|
36
|
+
*/
|
|
37
|
+
onLoadEarlier?: () => unknown;
|
|
38
|
+
/** Called once when the reader nears the end, again once `to` moved and changed the strip's length. Extend `to` to load later days. */
|
|
39
|
+
onLoadLater?: () => unknown;
|
|
40
|
+
/** Marks the region busy, for example while a range loads. */
|
|
41
|
+
busy?: boolean;
|
|
42
|
+
controller?: (controller: TimelineController) => void;
|
|
43
|
+
class?: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* A continuous filmstrip of time: waking hours are proportional, nights and empty days fold, overlapping bands share
|
|
47
|
+
* lanes. Wide containers show it horizontally, narrow ones vertically; both use the same model.
|
|
48
|
+
*/
|
|
49
|
+
export default function Timeline(props: TimelineProps): JSX.Element;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VideoPlayer — one video with the browser's own controls inside a frame whose
|
|
3
|
+
* size never depends on the video. The frame fills the height its host gives
|
|
4
|
+
* it, or keeps a ratio where the host leaves the height open. The picture fits
|
|
5
|
+
* inside uncropped, so a portrait reel and a wide recording both show whole and
|
|
6
|
+
* nothing moves while the video loads.
|
|
7
|
+
*/
|
|
8
|
+
import { type JSX } from "solid-js";
|
|
9
|
+
export type VideoPlayerProps = {
|
|
10
|
+
/**
|
|
11
|
+
* Inline address of the video. Seeking needs a server that answers `Range` requests; Safari plays nothing without.
|
|
12
|
+
* Null while the host still fetches it, for example a signed URL: the frame already shows at its final size.
|
|
13
|
+
*/
|
|
14
|
+
src: string | null;
|
|
15
|
+
/** Names the video for assistive technology, for example its file name. */
|
|
16
|
+
label: string;
|
|
17
|
+
/** Picture shown before playback starts. Without one, the player shows the first frame. */
|
|
18
|
+
poster?: string;
|
|
19
|
+
/** Width divided by height of the frame where the host leaves its height open. Defaults to 16 / 9. */
|
|
20
|
+
ratio?: number;
|
|
21
|
+
/** CORS mode for a video on another origin. Omit to keep the browser default. */
|
|
22
|
+
crossOrigin?: "anonymous" | "use-credentials";
|
|
23
|
+
/**
|
|
24
|
+
* Resolves a fresh address of the same video, for example a renewed signed URL. When playback fails, the player asks
|
|
25
|
+
* for one and continues at the same time, playing if it was. A renewed address that fails before it shows that point,
|
|
26
|
+
* or within ten seconds after, shows the fallback, so a renewed address must stay valid for longer.
|
|
27
|
+
*/
|
|
28
|
+
renew?: () => Promise<string>;
|
|
29
|
+
/** Offered with the fallback when the browser cannot play the video, typically a download. */
|
|
30
|
+
fallbackAction?: JSX.Element;
|
|
31
|
+
/**
|
|
32
|
+
* Shown in the frame instead of the video while set, for example the host's own error with a retry when it could not
|
|
33
|
+
* fetch the address. The frame keeps its size.
|
|
34
|
+
*/
|
|
35
|
+
error?: JSX.Element;
|
|
36
|
+
/** Called when the player gives up on the video and shows its fallback. */
|
|
37
|
+
onFallback?: () => void;
|
|
38
|
+
class?: string;
|
|
39
|
+
};
|
|
40
|
+
export declare function VideoPlayer(props: VideoPlayerProps): JSX.Element;
|
|
41
|
+
export default VideoPlayer;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { CalendarAttendee, CalendarDayBadge, CalendarEvent, CalendarEventColor, CalendarEventRenderContext, CalendarEventTimeChange, CalendarLabels, CalendarProps, CalendarRecurrence, CalendarResource, CalendarView, } from "./Calendar";
|
|
1
|
+
export type { CalendarAttendee, CalendarCustomView, CalendarDayBadge, CalendarEvent, CalendarEventColor, CalendarEventRenderContext, CalendarEventTimeChange, CalendarLabels, CalendarProps, CalendarRecurrence, CalendarResource, CalendarView, } from "./Calendar";
|
|
2
2
|
export { default as Calendar } from "./Calendar";
|
|
3
3
|
export type { ChartKind, ChartLabels, ChartProps, ChartRenderOptions } from "./Chart";
|
|
4
4
|
export { default as Chart } from "./Chart";
|
|
@@ -26,7 +26,7 @@ export { FileBrowserPanel, type FileBrowserPanelProps, type FileSource, openFile
|
|
|
26
26
|
export { FileGrid, type FileGridProps } from "./FileGrid";
|
|
27
27
|
export { default as FileTree, type FileTreeActions, type FileTreeEntry, type FileTreeProps } from "./FileTree";
|
|
28
28
|
export { canPreviewFile, default as FileView, type FileViewContent, type FileViewFile, type FileViewPreviewKind, type FileViewProps, type FileViewRenderer, type FileViewRendererProps, formatFileViewSize, getFileViewPreviewKind, } from "./FileView";
|
|
29
|
-
export type { LightboxImage } from "./Lightbox";
|
|
29
|
+
export type { LightboxAction, LightboxImage } from "./Lightbox";
|
|
30
30
|
export { default as Lightbox } from "./Lightbox";
|
|
31
31
|
export type { LogTableEntry } from "./LogEntriesTable";
|
|
32
32
|
export { default as LogEntriesTable } from "./LogEntriesTable";
|
|
@@ -34,6 +34,7 @@ export { default as MarkdownView, type MarkdownRenderOptions, type MarkdownViewP
|
|
|
34
34
|
export type { MessageGroupEntry, MessageRowAction, MessageRowAttachment, MessageRowAuthor, MessageRowFile, MessageRowMedia, MessageRowProgress, MessageRowProps, MessageRowQuote, MessageRowReaction, MessageRowStatus, MessageRowThread, MessageSystemRowProps, } from "./MessageRow";
|
|
35
35
|
export { MessageRow, MessageSystemRow, startsMessageGroup } from "./MessageRow";
|
|
36
36
|
export { type MarkdownInfoBlock, type MarkdownInfoBlockRenderInput, type MarkdownInfoBlockType, markdownInfoBlocks, renderMarkdownInfoBlock, scanMarkdownInfoBlock, } from "./markdown-info-blocks";
|
|
37
|
+
export { type MarkdownLinkInput, type MarkdownReference, type MarkdownReferenceKind, type MarkdownReferenceType, markdownLinkReference, markdownReferenceIcon, markdownReferenceType, markdownReferenceTypeLabel, markStandaloneLinks, renderMarkdownLink, } from "./markdown-links";
|
|
37
38
|
export { Pagination, type PaginationProps } from "./Pagination";
|
|
38
39
|
export type { PdfPreviewProps, PdfPreviewRequest } from "./PdfPreview";
|
|
39
40
|
export { default as PdfPreview } from "./PdfPreview";
|
|
@@ -41,6 +42,9 @@ export type { RangeOption, RangePickerProps } from "./RangePicker";
|
|
|
41
42
|
export { default as RangePicker } from "./RangePicker";
|
|
42
43
|
export type { StructuredDataPreviewMode, StructuredDataPreviewProps, StructuredDataValue } from "./StructuredDataPreview";
|
|
43
44
|
export { default as StructuredDataPreview, isStructuredDataValue } from "./StructuredDataPreview";
|
|
45
|
+
export type { TimelineColor, TimelineController, TimelineItem, TimelineProps } from "./Timeline";
|
|
46
|
+
export { default as Timeline } from "./Timeline";
|
|
47
|
+
export { VideoPlayer, type VideoPlayerProps } from "./VideoPlayer";
|
|
44
48
|
export type { VirtualFeedController, VirtualFeedProps, VirtualFeedScrollOptions } from "./VirtualFeed";
|
|
45
49
|
export { VirtualFeed } from "./VirtualFeed";
|
|
46
50
|
export type { ZoomPanAction, ZoomPanFullscreen, ZoomPanViewportProps } from "./ZoomPanViewport";
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Token, Tokens } from "marked";
|
|
2
|
+
/** What a reference points to inside the host application. */
|
|
3
|
+
export type MarkdownReferenceKind = "file" | "note" | "heading" | "task" | "page";
|
|
4
|
+
/** The type a reference shows: a file's type from its extension, or the kind of the referenced content. */
|
|
5
|
+
export type MarkdownReferenceType = "pdf" | "image" | "design" | "file" | "note" | "heading" | "task" | "page";
|
|
6
|
+
/**
|
|
7
|
+
* A link to content inside the host application, as opposed to a web or mail link.
|
|
8
|
+
* References render as a calm pill whose icon names the type.
|
|
9
|
+
*/
|
|
10
|
+
export type MarkdownReference = {
|
|
11
|
+
kind: MarkdownReferenceKind;
|
|
12
|
+
/** The file's name, which decides its type and icon. Defaults to the link text. */
|
|
13
|
+
fileName?: string;
|
|
14
|
+
/** The file's formatted size. It shows only when the link stands alone on its line. */
|
|
15
|
+
size?: string;
|
|
16
|
+
/** Plain-text title of the document that holds a heading, for a heading in another document. */
|
|
17
|
+
document?: string;
|
|
18
|
+
};
|
|
19
|
+
export type MarkdownLinkInput = {
|
|
20
|
+
/** The final, already validated link destination. */
|
|
21
|
+
href: string;
|
|
22
|
+
/** The rendered link text. It crosses a trust boundary: the caller sanitizes it. */
|
|
23
|
+
html: string;
|
|
24
|
+
/** The link text as plain text, for the accessible name. Defaults to the text of `html`. */
|
|
25
|
+
text?: string;
|
|
26
|
+
title?: string;
|
|
27
|
+
target?: "_blank";
|
|
28
|
+
/** Link relations without a new tab, such as `noreferrer`. `target: "_blank"` always sets `noopener noreferrer`. */
|
|
29
|
+
rel?: string;
|
|
30
|
+
/** A reference inside the host. Without one, the link is a web link, or a mail link for `mailto:` and `tel:`. */
|
|
31
|
+
reference?: MarkdownReference | null;
|
|
32
|
+
/** The link is the only content of its line. Only then does a file show its size. */
|
|
33
|
+
standalone?: boolean;
|
|
34
|
+
/** Locale of the type name in the accessible name. Defaults to English on the server and the page language in the browser. */
|
|
35
|
+
locale?: string;
|
|
36
|
+
};
|
|
37
|
+
/** The type of a file reference, from the extension of its name. */
|
|
38
|
+
export declare const markdownFileType: (fileName: string) => "pdf" | "image" | "design" | "file";
|
|
39
|
+
/**
|
|
40
|
+
* The reference a link destination names on its own: `#anchor` is a heading in the same document, and any other
|
|
41
|
+
* relative URL is a page of the host, or a file when its last path segment has a file extension. Absolute URLs,
|
|
42
|
+
* every scheme, and relative URLs that a browser resolves to another host, such as `//host` or `/\host`, are web
|
|
43
|
+
* or mail links; the result is then `null`.
|
|
44
|
+
*/
|
|
45
|
+
export declare const markdownLinkReference: (href: string) => MarkdownReference | null;
|
|
46
|
+
/** The type a reference shows. */
|
|
47
|
+
export declare const markdownReferenceType: (reference: MarkdownReference, text: string) => MarkdownReferenceType;
|
|
48
|
+
/** The Tabler glyph of a reference type; any other file keeps the glyph of its file family. */
|
|
49
|
+
export declare const markdownReferenceIcon: (type: MarkdownReferenceType, fileName?: string) => string;
|
|
50
|
+
/** The localized name of a reference type, such as "PDF" or "Überschrift". */
|
|
51
|
+
export declare const markdownReferenceTypeLabel: (type: MarkdownReferenceType, locale?: string) => string;
|
|
52
|
+
/**
|
|
53
|
+
* One link of rendered Markdown. A reference to content of the host renders as a calm pill: a neutral fill, the
|
|
54
|
+
* text in the prose colour, and an icon whose colour names the type. Its accessible name starts with the type, as
|
|
55
|
+
* in "PDF: Brand-2026.pdf". A heading in another document shows that document first ("Notes › Heading"). A web
|
|
56
|
+
* link stays prose text with a thin underline in the link accent and a small ↗; a mail link has no arrow. A link
|
|
57
|
+
* around an image is the image: a plain anchor that the image's own text names.
|
|
58
|
+
*/
|
|
59
|
+
export declare const renderMarkdownLink: (input: MarkdownLinkInput) => string;
|
|
60
|
+
/**
|
|
61
|
+
* The links among `tokens` that stand alone on their line: the only content of a paragraph or list item line,
|
|
62
|
+
* between line breaks. Pass the result's check as `standalone` to `renderMarkdownLink`, so a file shows its size
|
|
63
|
+
* in a list of files but not inside a sentence. Call it from `walkTokens` of a renderer with GFM line breaks
|
|
64
|
+
* (`breaks: true`), where every source line is a visual line.
|
|
65
|
+
*/
|
|
66
|
+
export declare const markStandaloneLinks: (token: Token, standalone: WeakSet<Tokens.Link>) => void;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { type DateContext } from "@k2b/stdlib";
|
|
2
|
+
/** A color token of the shared calendar palette, or a hex color such as a label color. */
|
|
3
|
+
export type TimelineColor = "blue" | "emerald" | "amber" | "red" | "violet" | "cyan" | "zinc" | `#${string}`;
|
|
4
|
+
export type TimelineItem = {
|
|
5
|
+
/** Unique among the items. */
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
/** A date-only string (`2026-10-08`) is a day in the time zone; anything else is an instant. */
|
|
9
|
+
start: Date | string;
|
|
10
|
+
/** End of a band. Without it, the item is a point in time. For all-day items, a midnight end is exclusive. */
|
|
11
|
+
end?: Date | string;
|
|
12
|
+
allDay?: boolean;
|
|
13
|
+
/** `band` (default) shows the duration; `marker` shows a point in time at `start`, such as a deadline. */
|
|
14
|
+
kind?: "band" | "marker";
|
|
15
|
+
color?: TimelineColor;
|
|
16
|
+
/** Extra text such as a place or a category: read with the item and shown where there is room. */
|
|
17
|
+
detail?: string;
|
|
18
|
+
/** Checkbox state. Leave it out for items without a checkbox. */
|
|
19
|
+
checked?: boolean;
|
|
20
|
+
/** Link target; without it the item is a button. */
|
|
21
|
+
href?: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* A place on the main axis as the count of each unit before it: hours of waking time, nights, folds of empty days,
|
|
25
|
+
* day headings, and all-day rows. The axis gives every unit its size, so one model serves both axes.
|
|
26
|
+
*/
|
|
27
|
+
export type TimelineSpan = readonly [hours: number, nights: number, folds: number, heads: number, rows: number];
|
|
28
|
+
export type TimelineUnits = TimelineSpan;
|
|
29
|
+
export declare const TIMELINE_UNIT_NAMES: readonly ["hour", "night", "fold", "head", "row"];
|
|
30
|
+
/** Waking hours; the night between them is folded. */
|
|
31
|
+
export declare const TIMELINE_WAKE_HOURS: readonly [6, 22];
|
|
32
|
+
/** Visible lanes of overlapping bands and of all-day items; more overlaps collapse into a "+n" entry in the last lane. */
|
|
33
|
+
export declare const TIMELINE_BAND_LANES = 3;
|
|
34
|
+
export declare const TIMELINE_ALL_DAY_LANES = 2;
|
|
35
|
+
/** Visible items stacked in one night or fold; more collapse into a "+n" entry in the last place. */
|
|
36
|
+
export declare const TIMELINE_FOLD_LANES = 3;
|
|
37
|
+
export declare const addSpan: (a: TimelineSpan, b: TimelineSpan) => TimelineSpan;
|
|
38
|
+
export declare const subtractSpan: (a: TimelineSpan, b: TimelineSpan) => TimelineSpan;
|
|
39
|
+
export declare const spanPx: (span: TimelineSpan, units: TimelineUnits) => number;
|
|
40
|
+
/** The span as a CSS length over the `--k2b-timeline-<unit>` sizes the axis sets. */
|
|
41
|
+
export declare const spanCss: (span: TimelineSpan) => string;
|
|
42
|
+
export type TimelineSegment = {
|
|
43
|
+
kind: "head" | "row" | "wake" | "night" | "fold";
|
|
44
|
+
t0: number;
|
|
45
|
+
t1: number;
|
|
46
|
+
at: TimelineSpan;
|
|
47
|
+
size: TimelineSpan;
|
|
48
|
+
group: number;
|
|
49
|
+
};
|
|
50
|
+
type EntryBase = {
|
|
51
|
+
/** Entry id: the item id, or for a "+n" entry `more:<first hidden id>`, made unique among the item ids. */
|
|
52
|
+
id: string;
|
|
53
|
+
group: number;
|
|
54
|
+
/** The item's own times, also beyond the loaded range; for all-day entries, group indexes. */
|
|
55
|
+
start: number;
|
|
56
|
+
end: number;
|
|
57
|
+
/** Main-axis place relative to the group, and length. */
|
|
58
|
+
at: TimelineSpan;
|
|
59
|
+
size: TimelineSpan;
|
|
60
|
+
lane: number;
|
|
61
|
+
lanes: number;
|
|
62
|
+
};
|
|
63
|
+
export type TimelineItemEntry = EntryBase & {
|
|
64
|
+
kind: "band" | "marker" | "folded" | "all-day";
|
|
65
|
+
item: TimelineItem;
|
|
66
|
+
/** For all-day items: the first and last day of the item inside the range. */
|
|
67
|
+
firstKey: string;
|
|
68
|
+
lastKey: string;
|
|
69
|
+
};
|
|
70
|
+
export type TimelineMoreEntry = EntryBase & {
|
|
71
|
+
kind: "more";
|
|
72
|
+
area: "band" | "fold" | "all-day";
|
|
73
|
+
hidden: TimelineItemEntry[];
|
|
74
|
+
};
|
|
75
|
+
export type TimelineEntry = TimelineItemEntry | TimelineMoreEntry;
|
|
76
|
+
export type TimelineGroup = {
|
|
77
|
+
index: number;
|
|
78
|
+
/** `day:<date>` or `fold:<first>:<last>`; stable while the group keeps its days. */
|
|
79
|
+
key: string;
|
|
80
|
+
kind: "day" | "fold";
|
|
81
|
+
firstKey: string;
|
|
82
|
+
lastKey: string;
|
|
83
|
+
t0: number;
|
|
84
|
+
t1: number;
|
|
85
|
+
/** Times the group's entries reach, beyond its own span for items in a neighbouring fold or over several days. */
|
|
86
|
+
reach: [number, number];
|
|
87
|
+
at: TimelineSpan;
|
|
88
|
+
size: TimelineSpan;
|
|
89
|
+
/** The group reserves a row for all-day items (vertical axis only). */
|
|
90
|
+
row: boolean;
|
|
91
|
+
today: boolean;
|
|
92
|
+
past: boolean;
|
|
93
|
+
/** List order: all-day items, then timed entries by start. */
|
|
94
|
+
entries: TimelineEntry[];
|
|
95
|
+
/** All-day entries of earlier groups that cover this group too. */
|
|
96
|
+
echoes: TimelineEntry[];
|
|
97
|
+
hours: Array<{
|
|
98
|
+
time: number;
|
|
99
|
+
at: TimelineSpan;
|
|
100
|
+
}>;
|
|
101
|
+
folds: Array<{
|
|
102
|
+
kind: "night" | "fold";
|
|
103
|
+
at: TimelineSpan;
|
|
104
|
+
size: TimelineSpan;
|
|
105
|
+
}>;
|
|
106
|
+
gaps: Array<{
|
|
107
|
+
at: TimelineSpan;
|
|
108
|
+
end: number;
|
|
109
|
+
hours: number;
|
|
110
|
+
long: boolean;
|
|
111
|
+
}>;
|
|
112
|
+
};
|
|
113
|
+
export type TimelineModel = {
|
|
114
|
+
from: number;
|
|
115
|
+
to: number;
|
|
116
|
+
segments: TimelineSegment[];
|
|
117
|
+
groups: TimelineGroup[];
|
|
118
|
+
total: TimelineSpan;
|
|
119
|
+
entries: Map<string, TimelineEntry>;
|
|
120
|
+
/** Keyboard order of every entry id. */
|
|
121
|
+
order: string[];
|
|
122
|
+
posOf: (time: number) => TimelineSpan;
|
|
123
|
+
/** The time at a pixel offset along the main axis. */
|
|
124
|
+
timeAt: (px: number, units: TimelineUnits) => number;
|
|
125
|
+
};
|
|
126
|
+
export declare const parseTimelineTime: (value: Date | string | undefined, context?: DateContext) => number;
|
|
127
|
+
/** The day (`YYYY-MM-DD`) of an instant in the context's time zone. */
|
|
128
|
+
export declare const timelineDayKey: (time: number, context?: DateContext) => string;
|
|
129
|
+
export declare const shiftDayKey: (key: string, days: number) => string;
|
|
130
|
+
/**
|
|
131
|
+
* The instant of a whole hour (0–24) on a day in the context's time zone. As stdlib's `compatible` disambiguation, a
|
|
132
|
+
* repeated hour resolves to its first occurrence and a skipped one to the time after the gap.
|
|
133
|
+
*/
|
|
134
|
+
export declare const timelineHourOf: (key: string, hour: number, context?: DateContext) => number;
|
|
135
|
+
export type TimelineModelInput = {
|
|
136
|
+
from: number;
|
|
137
|
+
to: number;
|
|
138
|
+
/** The current day (`YYYY-MM-DD`), which always stays open. */
|
|
139
|
+
today: string;
|
|
140
|
+
items: readonly TimelineItem[];
|
|
141
|
+
context?: DateContext;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Builds the filmstrip: waking hours (6–22) are proportional, every night is one fold, and a run of days without
|
|
145
|
+
* timed items is one fold. Positions depend only on the times and the items, never on measurement.
|
|
146
|
+
*/
|
|
147
|
+
export declare const buildTimelineModel: ({ from, to, today, items, context }: TimelineModelInput) => TimelineModel;
|
|
148
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { JSX } from "solid-js";
|
|
2
|
+
import type { ValueFieldProps } from "./field-contract";
|
|
3
|
+
export type ChoiceChipOption<T extends string = string> = {
|
|
4
|
+
value: T;
|
|
5
|
+
label: string;
|
|
6
|
+
icon?: string;
|
|
7
|
+
};
|
|
8
|
+
export type ChoiceChipsProps<T extends string = string> = Omit<ValueFieldProps<T | null>, "onValueChange" | "onValueCommit"> & {
|
|
9
|
+
options: readonly ChoiceChipOption<T>[];
|
|
10
|
+
/** Receives the chosen value; choosing never reports `null`. */
|
|
11
|
+
onValueChange?: (value: T) => void;
|
|
12
|
+
onValueCommit?: (value: T) => void;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A labeled single choice shown as one row of chips, for a handful of quick picks such as a preset or a proposed date.
|
|
16
|
+
* The row scrolls sideways instead of wrapping, so its height stays the same on every screen and for every selection.
|
|
17
|
+
* `null` selects no chip; the first chip then holds the tab stop. Use `Select` for long or searchable lists and
|
|
18
|
+
* `SegmentedControl` for switching between views or modes.
|
|
19
|
+
*/
|
|
20
|
+
export declare function ChoiceChips<T extends string = string>(props: ChoiceChipsProps<T>): JSX.Element;
|