@k2b/ui 0.44.0 → 0.46.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/actions/Dropdown.js +8 -1
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/FilterChip.js +11 -5
- package/dist/browser/actions/FilterChip.js.map +1 -1
- package/dist/browser/actions/Tabs.js +3 -4
- package/dist/browser/actions/Tabs.js.map +1 -1
- package/dist/browser/actions/ViewTabs.js +225 -93
- package/dist/browser/actions/ViewTabs.js.map +1 -1
- package/dist/browser/actions/menu-sheet.js +2 -3
- package/dist/browser/actions/menu-sheet.js.map +1 -1
- package/dist/browser/actions/phone-sheet.js +4 -0
- package/dist/browser/actions/phone-sheet.js.map +1 -0
- package/dist/browser/content/DataTable.js +47 -51
- package/dist/browser/content/DataTable.js.map +1 -1
- package/dist/browser/content/FileGrid.js +125 -99
- package/dist/browser/content/FileGrid.js.map +1 -1
- package/dist/browser/feedback/dialog-core.js +5 -1
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/feedback/dialog-tone.js +26 -0
- package/dist/browser/feedback/dialog-tone.js.map +1 -0
- package/dist/browser/feedback/index.js.map +1 -1
- package/dist/browser/feedback/prompt-confirm.js +223 -0
- package/dist/browser/feedback/prompt-confirm.js.map +1 -0
- package/dist/browser/feedback/prompts.js +195 -343
- package/dist/browser/feedback/prompts.js.map +1 -1
- package/dist/browser/inputs/ChoiceList.js +45 -17
- package/dist/browser/inputs/ChoiceList.js.map +1 -1
- package/dist/browser/inputs/DatePicker.js +1647 -334
- package/dist/browser/inputs/DatePicker.js.map +1 -1
- package/dist/browser/inputs/TextInput.js +5 -4
- package/dist/browser/inputs/TextInput.js.map +1 -1
- package/dist/browser/inputs/choice.js +36 -9
- package/dist/browser/inputs/choice.js.map +1 -1
- package/dist/browser/inputs/date-input-messages.js +128 -0
- package/dist/browser/inputs/date-input-messages.js.map +1 -0
- package/dist/browser/inputs/date-input-status.js +132 -0
- package/dist/browser/inputs/date-input-status.js.map +1 -0
- package/dist/browser/inputs/date-input.js +334 -0
- package/dist/browser/inputs/date-input.js.map +1 -0
- package/dist/browser/inputs/date-sheet.js +49 -0
- package/dist/browser/inputs/date-sheet.js.map +1 -0
- package/dist/browser/internal/reveal-in-scroller.js +28 -0
- package/dist/browser/internal/reveal-in-scroller.js.map +1 -0
- package/dist/browser/intl/messages.js +6 -0
- package/dist/browser/intl/messages.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +556 -528
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/BottomSheet.js +3 -0
- package/dist/browser/layout/BottomSheet.js.map +1 -1
- package/dist/browser/layout/DetailPanel.js +130 -108
- package/dist/browser/layout/DetailPanel.js.map +1 -1
- package/dist/browser/layout/DetailSections.js +1019 -0
- package/dist/browser/layout/DetailSections.js.map +1 -0
- package/dist/browser/layout/DetailsToggle.js +32 -0
- package/dist/browser/layout/DetailsToggle.js.map +1 -0
- package/dist/browser/layout/Discussion.js +3 -0
- package/dist/browser/layout/Discussion.js.map +1 -1
- package/dist/browser/layout/MobileShell.js +116 -94
- package/dist/browser/layout/MobileShell.js.map +1 -1
- package/dist/browser/layout/PageTitle.js +33 -10
- package/dist/browser/layout/PageTitle.js.map +1 -1
- package/dist/browser/layout/PanelDialog.js +167 -132
- package/dist/browser/layout/PanelDialog.js.map +1 -1
- package/dist/browser/layout/Settings.js +175 -139
- package/dist/browser/layout/Settings.js.map +1 -1
- package/dist/browser/layout/SettingsModal.js +2 -4
- package/dist/browser/layout/SettingsModal.js.map +1 -1
- package/dist/browser/layout/app-workspace-controller.js +12 -0
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/detail-sections-messages.js +123 -0
- package/dist/browser/layout/detail-sections-messages.js.map +1 -0
- package/dist/browser/layout/index.js +2 -0
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/surfaces/Avatar.js +3 -1
- package/dist/browser/surfaces/Avatar.js.map +1 -1
- package/dist/browser/surfaces/AvatarStack.js +95 -61
- package/dist/browser/surfaces/AvatarStack.js.map +1 -1
- package/dist/browser/surfaces/ChangeList.js +77 -0
- package/dist/browser/surfaces/ChangeList.js.map +1 -0
- package/dist/browser/surfaces/StatusBadge.js +47 -14
- package/dist/browser/surfaces/StatusBadge.js.map +1 -1
- package/dist/browser/surfaces/index.js +2 -1
- package/dist/browser/surfaces/index.js.map +1 -1
- package/dist/browser/text-editor/TextEditor.js +26 -8
- package/dist/browser/text-editor/TextEditor.js.map +1 -1
- package/dist/ssr/actions/Dropdown.js +6 -0
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/FilterChip.js +1 -1
- package/dist/ssr/actions/FilterChip.js.map +1 -1
- package/dist/ssr/actions/Tabs.js +3 -4
- package/dist/ssr/actions/Tabs.js.map +1 -1
- package/dist/ssr/actions/ViewTabs.js +144 -37
- package/dist/ssr/actions/ViewTabs.js.map +1 -1
- package/dist/ssr/actions/menu-sheet.js +2 -3
- package/dist/ssr/actions/menu-sheet.js.map +1 -1
- package/dist/ssr/actions/phone-sheet.js +4 -0
- package/dist/ssr/actions/phone-sheet.js.map +1 -0
- package/dist/ssr/content/DataTable.js +1 -2
- package/dist/ssr/content/DataTable.js.map +1 -1
- package/dist/ssr/content/FileGrid.js +36 -22
- package/dist/ssr/content/FileGrid.js.map +1 -1
- package/dist/ssr/feedback/dialog-core.js +5 -1
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/feedback/dialog-tone.js +26 -0
- package/dist/ssr/feedback/dialog-tone.js.map +1 -0
- package/dist/ssr/feedback/index.js.map +1 -1
- package/dist/ssr/feedback/prompt-confirm.js +123 -0
- package/dist/ssr/feedback/prompt-confirm.js.map +1 -0
- package/dist/ssr/feedback/prompts.js +60 -132
- package/dist/ssr/feedback/prompts.js.map +1 -1
- package/dist/ssr/inputs/ChoiceList.js +29 -9
- package/dist/ssr/inputs/ChoiceList.js.map +1 -1
- package/dist/ssr/inputs/DatePicker.js +1183 -166
- package/dist/ssr/inputs/DatePicker.js.map +1 -1
- package/dist/ssr/inputs/TextInput.js +5 -4
- package/dist/ssr/inputs/TextInput.js.map +1 -1
- package/dist/ssr/inputs/choice.js +36 -9
- package/dist/ssr/inputs/choice.js.map +1 -1
- package/dist/ssr/inputs/date-input-messages.js +128 -0
- package/dist/ssr/inputs/date-input-messages.js.map +1 -0
- package/dist/ssr/inputs/date-input-status.js +132 -0
- package/dist/ssr/inputs/date-input-status.js.map +1 -0
- package/dist/ssr/inputs/date-input.js +334 -0
- package/dist/ssr/inputs/date-input.js.map +1 -0
- package/dist/ssr/inputs/date-sheet.js +44 -0
- package/dist/ssr/inputs/date-sheet.js.map +1 -0
- package/dist/ssr/internal/reveal-in-scroller.js +28 -0
- package/dist/ssr/internal/reveal-in-scroller.js.map +1 -0
- package/dist/ssr/intl/messages.js +6 -0
- package/dist/ssr/intl/messages.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +71 -50
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/BottomSheet.js +3 -0
- package/dist/ssr/layout/BottomSheet.js.map +1 -1
- package/dist/ssr/layout/DetailPanel.js +17 -0
- package/dist/ssr/layout/DetailPanel.js.map +1 -1
- package/dist/ssr/layout/DetailSections.js +762 -0
- package/dist/ssr/layout/DetailSections.js.map +1 -0
- package/dist/ssr/layout/DetailsToggle.js +29 -0
- package/dist/ssr/layout/DetailsToggle.js.map +1 -0
- package/dist/ssr/layout/Discussion.js +3 -0
- package/dist/ssr/layout/Discussion.js.map +1 -1
- package/dist/ssr/layout/MobileShell.js +45 -28
- package/dist/ssr/layout/MobileShell.js.map +1 -1
- package/dist/ssr/layout/PageTitle.js +29 -6
- package/dist/ssr/layout/PageTitle.js.map +1 -1
- package/dist/ssr/layout/PanelDialog.js +48 -30
- package/dist/ssr/layout/PanelDialog.js.map +1 -1
- package/dist/ssr/layout/Settings.js +34 -18
- package/dist/ssr/layout/Settings.js.map +1 -1
- package/dist/ssr/layout/SettingsModal.js +2 -4
- package/dist/ssr/layout/SettingsModal.js.map +1 -1
- package/dist/ssr/layout/app-workspace-controller.js +12 -0
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/detail-sections-messages.js +123 -0
- package/dist/ssr/layout/detail-sections-messages.js.map +1 -0
- package/dist/ssr/layout/index.js +2 -0
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/surfaces/Avatar.js +3 -1
- package/dist/ssr/surfaces/Avatar.js.map +1 -1
- package/dist/ssr/surfaces/AvatarStack.js +61 -32
- package/dist/ssr/surfaces/AvatarStack.js.map +1 -1
- package/dist/ssr/surfaces/ChangeList.js +37 -0
- package/dist/ssr/surfaces/ChangeList.js.map +1 -0
- package/dist/ssr/surfaces/StatusBadge.js +26 -8
- package/dist/ssr/surfaces/StatusBadge.js.map +1 -1
- package/dist/ssr/surfaces/index.js +2 -1
- package/dist/ssr/surfaces/index.js.map +1 -1
- package/dist/ssr/text-editor/TextEditor.js +26 -8
- package/dist/ssr/text-editor/TextEditor.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/FilterChip.d.ts +4 -0
- package/dist/types/actions/ViewTabs.d.ts +11 -1
- package/dist/types/actions/menu-sheet.d.ts +1 -3
- package/dist/types/actions/phone-sheet.d.ts +3 -0
- package/dist/types/content/FileGrid.d.ts +6 -0
- package/dist/types/feedback/dialog-tone.d.ts +10 -0
- package/dist/types/feedback/index.d.ts +1 -0
- package/dist/types/feedback/prompt-confirm.d.ts +19 -0
- package/dist/types/feedback/prompts.d.ts +4 -8
- package/dist/types/inputs/ChoiceList.d.ts +7 -3
- package/dist/types/inputs/DatePicker.d.ts +13 -3
- package/dist/types/inputs/TextInput.d.ts +1 -1
- package/dist/types/inputs/choice.d.ts +9 -3
- package/dist/types/inputs/date-input-messages.d.ts +64 -0
- package/dist/types/inputs/date-input-status.d.ts +35 -0
- package/dist/types/inputs/date-input.d.ts +90 -0
- package/dist/types/inputs/date-sheet.d.ts +14 -0
- package/dist/types/internal/reveal-in-scroller.d.ts +6 -0
- package/dist/types/intl/messages.d.ts +3 -0
- package/dist/types/layout/AppWorkspace.d.ts +14 -0
- package/dist/types/layout/BottomSheet.d.ts +3 -0
- package/dist/types/layout/DetailPanel.d.ts +9 -0
- package/dist/types/layout/DetailSections.d.ts +156 -0
- package/dist/types/layout/DetailsToggle.d.ts +13 -0
- package/dist/types/layout/PageTitle.d.ts +7 -0
- package/dist/types/layout/PanelDialog.d.ts +3 -0
- package/dist/types/layout/Settings.d.ts +17 -1
- package/dist/types/layout/detail-sections-messages.d.ts +59 -0
- package/dist/types/layout/index.d.ts +5 -2
- package/dist/types/surfaces/Avatar.d.ts +3 -0
- package/dist/types/surfaces/AvatarStack.d.ts +20 -1
- package/dist/types/surfaces/ChangeList.d.ts +20 -0
- package/dist/types/surfaces/StatusBadge.d.ts +5 -0
- package/dist/types/surfaces/index.d.ts +5 -3
- package/package.json +3 -3
|
@@ -58,6 +58,10 @@ export type FilterToggleProps = {
|
|
|
58
58
|
/** Link to the URL with the filter switched. The link keeps working without JavaScript. */
|
|
59
59
|
href?: string;
|
|
60
60
|
onClick?: (event: MouseEvent) => void;
|
|
61
|
+
/** The button opens a dialog with more filters, such as a filter builder; it stays pressed while they apply. */
|
|
62
|
+
opensDialog?: boolean;
|
|
63
|
+
/** The button is loading what it opens; it stays enabled so it keeps focus for the dialog to return it. */
|
|
64
|
+
busy?: boolean;
|
|
61
65
|
title?: string;
|
|
62
66
|
disabled?: boolean;
|
|
63
67
|
class?: string;
|
|
@@ -5,6 +5,10 @@ export type ViewTab = {
|
|
|
5
5
|
href: string;
|
|
6
6
|
icon?: string;
|
|
7
7
|
count?: number | string;
|
|
8
|
+
/** A short quiet label after the count, such as "New" for a view people have not opened yet. */
|
|
9
|
+
badge?: string;
|
|
10
|
+
/** Stays in the strip after More at every width, for a view of another kind than the ones that overflow. */
|
|
11
|
+
pinned?: boolean;
|
|
8
12
|
};
|
|
9
13
|
export type ViewTabsProps = {
|
|
10
14
|
/** Accessible name of the navigation landmark, e.g. "Views". */
|
|
@@ -12,14 +16,20 @@ export type ViewTabsProps = {
|
|
|
12
16
|
items: readonly ViewTab[];
|
|
13
17
|
/** Id of the open view; the server reads it from `?view=`. Unknown ids select nothing. */
|
|
14
18
|
current: string | undefined;
|
|
15
|
-
/**
|
|
19
|
+
/** At most this many views before More (default 5). */
|
|
16
20
|
max?: number;
|
|
21
|
+
/**
|
|
22
|
+
* The strip shows only the views that fit its room and counts the rest in More, instead of scrolling them. The open
|
|
23
|
+
* view and pinned views stay. Pair it with a larger `max` so a wide head shows more views.
|
|
24
|
+
*/
|
|
25
|
+
fit?: boolean;
|
|
17
26
|
class?: string;
|
|
18
27
|
};
|
|
19
28
|
/** Two deterministic strip levels; only opening the menu reads CSS visibility. */
|
|
20
29
|
export declare function viewTabsLayout(items: readonly ViewTab[], current: string | undefined, max?: number): {
|
|
21
30
|
wide: number[];
|
|
22
31
|
compact: number[];
|
|
32
|
+
pinned: number[];
|
|
23
33
|
wideHidden: number;
|
|
24
34
|
compactHidden: number;
|
|
25
35
|
};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { type JSX } from "solid-js";
|
|
2
2
|
import type { DropdownItem, DropdownSearch } from "./Dropdown";
|
|
3
|
-
|
|
4
|
-
export declare const PHONE_SHEET_QUERY = "(max-width: 47.999rem)";
|
|
5
|
-
export declare const prefersMenuSheet: () => boolean;
|
|
3
|
+
export { PHONE_SHEET_QUERY, prefersMenuSheet } from "./phone-sheet";
|
|
6
4
|
export type MenuSheetOptions = {
|
|
7
5
|
/** Renders the rows: the dropdown's own `DropdownItems`, passed in so this module does not import it back. */
|
|
8
6
|
Items: (props: {
|
|
@@ -34,6 +34,11 @@ type FileGridBaseProps<T> = {
|
|
|
34
34
|
export type FileGridSelectableProps<T> = FileGridBaseProps<T> & {
|
|
35
35
|
selection: CollectionSelection;
|
|
36
36
|
onRowClick?: (row: T) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Shows a check box before each item that `checks` returns `true` for, or a circle when only one item may be
|
|
39
|
+
* selected. The check only mirrors the selection; items without one keep its slot, so names stay in line.
|
|
40
|
+
*/
|
|
41
|
+
checks?: (row: T) => boolean;
|
|
37
42
|
limit?: never;
|
|
38
43
|
expanded?: never;
|
|
39
44
|
onExpandedChange?: never;
|
|
@@ -45,6 +50,7 @@ export type FileGridSelectableProps<T> = FileGridBaseProps<T> & {
|
|
|
45
50
|
export type FileGridOpenProps<T> = FileGridBaseProps<T> & {
|
|
46
51
|
selection?: never;
|
|
47
52
|
onRowClick?: never;
|
|
53
|
+
checks?: never;
|
|
48
54
|
/** Shows the first `limit` items, then "Show all N", which opens the full list in place. Without it, the list is always full. */
|
|
49
55
|
limit?: number;
|
|
50
56
|
/** Controls whether the full list is open. Without it, the list keeps its own state. */
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { UiMessages } from "../intl/messages";
|
|
2
|
+
/** A dialog's outcome or risk: a 2 px edge in its colour inside the frame and its icon in the header. */
|
|
3
|
+
export type DialogTone = "success" | "warning" | "danger";
|
|
4
|
+
/** The header icon of a toned dialog; it replaces the dialog's own icon. */
|
|
5
|
+
export declare const dialogToneIcon: (tone: DialogTone) => string;
|
|
6
|
+
/**
|
|
7
|
+
* The tone's word for screen readers, so the tone is not carried by colour alone. Headers render it hidden with
|
|
8
|
+
* `data-dialog-tone-label`; the dialog core makes it the dialog's description, and the heading keeps the title alone.
|
|
9
|
+
*/
|
|
10
|
+
export declare const dialogToneLabel: (messages: UiMessages, tone: DialogTone) => string;
|
|
@@ -2,6 +2,7 @@ export type { AnnounceOptions, AnnouncePoliteness } from "./announce";
|
|
|
2
2
|
export { announce } from "./announce";
|
|
3
3
|
export type { DialogClose, DialogCore, DialogRender, OpenDialogOptions } from "./dialog-core";
|
|
4
4
|
export { dialogCore } from "./dialog-core";
|
|
5
|
+
export type { DialogTone } from "./dialog-tone";
|
|
5
6
|
export type { HoverPreviewController, HoverPreviewOptions, HoverPreviewPlacement, HoverPreviewProps } from "./HoverPreview";
|
|
6
7
|
export { createHoverPreview, HoverPreview } from "./HoverPreview";
|
|
7
8
|
export type { InlineGuidanceProps } from "./InlineGuidance";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type JSX } from "solid-js";
|
|
2
|
+
import { type DialogTone } from "./dialog-tone";
|
|
3
|
+
import type { ConfirmOptions, DialogOptions } from "./prompts";
|
|
4
|
+
export type PromptContent = string | HTMLElement | JSX.Element;
|
|
5
|
+
/** A prompt's `variant` is its tone too: a success or danger prompt carries the dialog tone of that name. */
|
|
6
|
+
export declare const promptTone: (variant: DialogOptions["variant"]) => DialogTone | undefined;
|
|
7
|
+
export declare const DialogHeader: (props: {
|
|
8
|
+
close: () => void;
|
|
9
|
+
title?: string;
|
|
10
|
+
icon?: string;
|
|
11
|
+
tone?: DialogTone;
|
|
12
|
+
}) => JSX.Element;
|
|
13
|
+
export declare const panelClass: (options?: Pick<DialogOptions, "size" | "surface" | "variant">) => string;
|
|
14
|
+
export declare const contentClass: (surface?: DialogOptions["surface"]) => string;
|
|
15
|
+
export declare const confirmPrompt: (content: PromptContent, options?: ConfirmOptions) => Promise<boolean | undefined>;
|
|
16
|
+
/** `prompts` starts as this object; `PanelDialog` asks through it, so it reaches a replaced `prompts.confirm` too. */
|
|
17
|
+
export declare const sharedPrompts: {
|
|
18
|
+
confirm: typeof confirmPrompt;
|
|
19
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type JSX } from "solid-js";
|
|
2
2
|
import { type DialogRender, type OpenDialogOptions } from "./dialog-core";
|
|
3
|
+
import { type PromptContent } from "./prompt-confirm";
|
|
4
|
+
export { DialogHeader } from "./prompt-confirm";
|
|
3
5
|
export interface DialogOptions {
|
|
4
6
|
signal?: AbortSignal;
|
|
5
7
|
title?: string;
|
|
@@ -19,7 +21,6 @@ export interface DialogOptions {
|
|
|
19
21
|
export interface ConfirmOptions extends DialogOptions {
|
|
20
22
|
confirmationPhrase?: string;
|
|
21
23
|
}
|
|
22
|
-
type PromptContent = string | HTMLElement | JSX.Element;
|
|
23
24
|
export type PromptSearchItem<T = unknown> = {
|
|
24
25
|
/**
|
|
25
26
|
* Stable identity of the result, such as its record ID. With it, a newer answer that contains the same result keeps
|
|
@@ -153,11 +154,6 @@ export declare const createFormState: <T extends Record<string, FieldSchema>>(sc
|
|
|
153
154
|
validateAll: () => boolean;
|
|
154
155
|
reset: () => void;
|
|
155
156
|
};
|
|
156
|
-
export declare const DialogHeader: (props: {
|
|
157
|
-
close: () => void;
|
|
158
|
-
title?: string;
|
|
159
|
-
icon?: string;
|
|
160
|
-
}) => JSX.Element;
|
|
161
157
|
type CloudSearchResolver<T> = (input: PromptSearchInput) => Promise<PromptSearchItem<T>[]> | PromptSearchItem<T>[];
|
|
162
158
|
declare const openSearchPrompt: <T extends unknown = unknown>(resolver: CloudSearchResolver<T>, options?: PromptSearchOptions) => Promise<PromptSearchItem<T> | undefined>;
|
|
163
159
|
declare const promptText: (content: string, defaultValue?: string, options?: DialogOptions) => Promise<string | null>;
|
|
@@ -166,9 +162,10 @@ declare const promptNumber: (content: string, defaultValue?: number, options?: D
|
|
|
166
162
|
max?: number;
|
|
167
163
|
}) => Promise<number | null>;
|
|
168
164
|
export declare const prompts: {
|
|
165
|
+
confirm: typeof import("./prompt-confirm").confirmPrompt;
|
|
166
|
+
} & {
|
|
169
167
|
alert: (content: PromptContent, options?: DialogOptions) => Promise<void | undefined>;
|
|
170
168
|
success: (content: PromptContent, options?: Omit<DialogOptions, "variant">) => Promise<void | undefined>;
|
|
171
|
-
confirm: (content: PromptContent, options?: ConfirmOptions) => Promise<boolean | undefined>;
|
|
172
169
|
prompt: typeof promptText;
|
|
173
170
|
promptNumber: typeof promptNumber;
|
|
174
171
|
form: <T extends Record<string, FieldSchema>>(config: PromptFormOptions<T>) => Promise<InferFormValues<T> | null>;
|
|
@@ -182,4 +179,3 @@ export declare const prompts: {
|
|
|
182
179
|
search: typeof openSearchPrompt;
|
|
183
180
|
error: (content: string | HTMLElement, options?: DialogOptions) => Promise<unknown>;
|
|
184
181
|
};
|
|
185
|
-
export {};
|
|
@@ -7,6 +7,10 @@ export type ChoiceListOption<T extends string = string> = {
|
|
|
7
7
|
description?: string;
|
|
8
8
|
/** A quiet tag after the label, such as "Default" for the choice that applies without one. */
|
|
9
9
|
marker?: string;
|
|
10
|
+
/** A Tabler icon class before the text, such as `ti ti-truck`, when a picture helps tell the choices apart. */
|
|
11
|
+
icon?: string;
|
|
12
|
+
/** This choice is not possible now. Say why in `description`; a disabled chosen option still shows as chosen. */
|
|
13
|
+
disabled?: boolean;
|
|
10
14
|
};
|
|
11
15
|
export type ChoiceListProps<T extends string = string> = Omit<ValueFieldProps<T | null>, "onValueChange" | "onValueCommit"> & {
|
|
12
16
|
options: readonly ChoiceListOption<T>[];
|
|
@@ -20,9 +24,9 @@ export type ChoiceListProps<T extends string = string> = Omit<ValueFieldProps<T
|
|
|
20
24
|
onValueCommit?: (value: T) => void;
|
|
21
25
|
};
|
|
22
26
|
/**
|
|
23
|
-
* A labeled single choice shown as
|
|
24
|
-
* means, for a few choices whose consequences need words. Choosing changes only paint, so no
|
|
25
|
-
* opens under the chosen row. Use `ChoiceChips` for quick picks without explanation, `RichSelect` for longer lists
|
|
27
|
+
* A labeled single choice shown as cards, each with a radio, a label and one sentence on what it
|
|
28
|
+
* means, for a few choices whose consequences need words. Choosing changes only paint, so no card moves; `details`
|
|
29
|
+
* opens under the chosen card's row. Use `ChoiceChips` for quick picks without explanation, `RichSelect` for longer lists
|
|
26
30
|
* in a dropdown, and `ChoiceTiles` when a preview decides.
|
|
27
31
|
*/
|
|
28
32
|
export declare function ChoiceList<T extends string = string>(props: ChoiceListProps<T>): JSX.Element;
|
|
@@ -18,11 +18,20 @@ export type DatePickerBaseProps<T> = Omit<ValueFieldProps<T>, "value"> & {
|
|
|
18
18
|
presets?: readonly DatePreset<T>[];
|
|
19
19
|
dateConfig?: DateContext;
|
|
20
20
|
clearable?: boolean;
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* `field` (default) is a text field: people type a date or open the calendar. `plain` shows the value as text for
|
|
23
|
+
* property rows and only opens the calendar; a clearable plain picker offers clearing in its panel.
|
|
24
|
+
*/
|
|
22
25
|
appearance?: ChoiceAppearance;
|
|
26
|
+
/** Earliest selectable day as a date key such as `2026-11-02`; earlier days are locked and typed ones refused. */
|
|
27
|
+
min?: string;
|
|
28
|
+
/** Latest selectable day as a date key. */
|
|
29
|
+
max?: string;
|
|
30
|
+
/** Shows and announces the value without changing it; the field stays focusable. */
|
|
31
|
+
readOnly?: boolean;
|
|
23
32
|
};
|
|
24
33
|
export type DatePickerProps = DatePickerBaseProps<string | null> & {
|
|
25
|
-
/**
|
|
34
|
+
/** Content for a set value: the trigger of a `plain` picker, or the resting status line of a typed field. */
|
|
26
35
|
renderValue?: (value: string) => JSX.Element;
|
|
27
36
|
};
|
|
28
37
|
export type DateTimePickerProps = DatePickerBaseProps<string | null> & {
|
|
@@ -41,7 +50,8 @@ export type DateRangePickerProps = DatePickerBaseProps<DateRangeValue> & {
|
|
|
41
50
|
datePresets?: readonly DatePreset<string | null>[];
|
|
42
51
|
durationPresets?: readonly DurationPreset[];
|
|
43
52
|
};
|
|
44
|
-
|
|
53
|
+
/** `below` is a line under the trigger that the panel must not cover, such as a typed field's status line. */
|
|
54
|
+
export declare const placeDatePopover: (trigger: HTMLElement, popover: HTMLElement, wide: boolean, below?: HTMLElement) => void;
|
|
45
55
|
export declare function DatePicker(props: DatePickerProps): JSX.Element;
|
|
46
56
|
export declare function DateTimePicker(props: DateTimePickerProps): JSX.Element;
|
|
47
57
|
export declare function DateRangePicker(props: DateRangePickerProps): JSX.Element;
|
|
@@ -6,7 +6,7 @@ export type TextInputProps = Omit<JSX.InputHTMLAttributes<HTMLInputElement>, "on
|
|
|
6
6
|
maxLength?: number;
|
|
7
7
|
type?: "text" | "search" | "email" | "url" | "tel";
|
|
8
8
|
variant?: "default" | "ai" | "compact";
|
|
9
|
-
/**
|
|
9
|
+
/** A leading icon such as a search magnifier. Plain text fields have none. */
|
|
10
10
|
icon?: string | false;
|
|
11
11
|
activeIcon?: string;
|
|
12
12
|
/** ID of a consumer-owned visible error; caller owns its announcement. Native controls only. */
|
|
@@ -45,14 +45,20 @@ export declare function createChoiceLoader<T extends string>(loader: () => Choic
|
|
|
45
45
|
};
|
|
46
46
|
export type ChoicePopoverPlacement = {
|
|
47
47
|
/**
|
|
48
|
-
* `trigger` (default)
|
|
49
|
-
*
|
|
48
|
+
* `trigger` (default) makes the popover at least as wide as the trigger and
|
|
49
|
+
* as wide as its longest name, so names stay on one line; `own` keeps
|
|
50
|
+
* the width its stylesheet sets, such as a RichSelect with a preview.
|
|
50
51
|
*/
|
|
51
52
|
width?: "trigger" | "own";
|
|
52
53
|
/** The side tried first. The popover flips when the other side has more room. */
|
|
53
54
|
side?: "below" | "above";
|
|
54
55
|
};
|
|
55
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Places the popover under (or above) its trigger. `floor` is the narrowest
|
|
58
|
+
* width it may take, such as the width it already had while open, so filtering
|
|
59
|
+
* the options never makes it narrower.
|
|
60
|
+
*/
|
|
61
|
+
export declare const placeChoicePopover: (trigger: HTMLElement, popover: HTMLElement, placement?: ChoicePopoverPlacement, floor?: number) => void;
|
|
56
62
|
export declare function createChoicePopover(disabled: () => boolean, placement?: () => ChoicePopoverPlacement): {
|
|
57
63
|
open: () => boolean;
|
|
58
64
|
setTrigger: Setter<HTMLElement | undefined>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** Status line and errors of the typed date field; dates, weekdays and distances come from Intl. */
|
|
2
|
+
declare const dateInputMessages: import("@k2b/stdlib").Catalog<{
|
|
3
|
+
dayLetters: string;
|
|
4
|
+
monthLetters: string;
|
|
5
|
+
yearLetters: string;
|
|
6
|
+
openCalendar: string;
|
|
7
|
+
closeCalendar: string;
|
|
8
|
+
notADate: ({ example }: {
|
|
9
|
+
example: string;
|
|
10
|
+
}) => string;
|
|
11
|
+
notYet: string;
|
|
12
|
+
ambiguous: string;
|
|
13
|
+
incompleteYear: ({ year }: {
|
|
14
|
+
year: string;
|
|
15
|
+
}) => string;
|
|
16
|
+
unknownUnit: string;
|
|
17
|
+
noSuchMonth: ({ month }: {
|
|
18
|
+
month: number;
|
|
19
|
+
}) => string;
|
|
20
|
+
shortMonth: ({ month, days }: {
|
|
21
|
+
month: string;
|
|
22
|
+
days: number;
|
|
23
|
+
}) => string;
|
|
24
|
+
earliest: ({ date }: {
|
|
25
|
+
date: string;
|
|
26
|
+
}) => string;
|
|
27
|
+
latest: ({ date }: {
|
|
28
|
+
date: string;
|
|
29
|
+
}) => string;
|
|
30
|
+
outsideRange: string;
|
|
31
|
+
required: string;
|
|
32
|
+
endBeforeStart: string;
|
|
33
|
+
missingEnd: string;
|
|
34
|
+
missingStart: string;
|
|
35
|
+
nextWeekday: ({ weekday }: {
|
|
36
|
+
weekday: string;
|
|
37
|
+
}) => string;
|
|
38
|
+
nextWeek: string;
|
|
39
|
+
notSelectable: ({ date }: {
|
|
40
|
+
date: string;
|
|
41
|
+
}) => string;
|
|
42
|
+
limitFrom: ({ date }: {
|
|
43
|
+
date: string;
|
|
44
|
+
}) => string;
|
|
45
|
+
limitUntil: ({ date }: {
|
|
46
|
+
date: string;
|
|
47
|
+
}) => string;
|
|
48
|
+
start: string;
|
|
49
|
+
end: string;
|
|
50
|
+
startOf: ({ label }: {
|
|
51
|
+
label: string;
|
|
52
|
+
}) => string;
|
|
53
|
+
endOf: ({ label }: {
|
|
54
|
+
label: string;
|
|
55
|
+
}) => string;
|
|
56
|
+
startMissing: string;
|
|
57
|
+
endMissing: string;
|
|
58
|
+
noDate: string;
|
|
59
|
+
}>;
|
|
60
|
+
export type DateInputMessages = ReturnType<(typeof dateInputMessages)["resolve"]>["t"];
|
|
61
|
+
/** Resolved from the date locale, so the words join the dates they describe in one language. */
|
|
62
|
+
export declare const resolveDateInputMessages: (locale?: string) => DateInputMessages;
|
|
63
|
+
export declare const checkDateInputMessages: () => import("@k2b/stdlib").CatalogIssue[];
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type DateInputError, type DateInputNote } from "./date-input";
|
|
2
|
+
import type { DateInputMessages } from "./date-input-messages";
|
|
3
|
+
/**
|
|
4
|
+
* The line under a typed date field. It always says which day is meant: grey at rest (weekday and distance), blue
|
|
5
|
+
* while typing (the absolute date that a commit would save), red after a commit that failed.
|
|
6
|
+
*/
|
|
7
|
+
export type DateStatusTone = "rest" | "draft" | "error";
|
|
8
|
+
export type DateStatus = {
|
|
9
|
+
tone: DateStatusTone;
|
|
10
|
+
text: string;
|
|
11
|
+
};
|
|
12
|
+
/** "Mi., 4. Nov. 2026" / "Wed, Nov 4, 2026": the absolute date of a draft. */
|
|
13
|
+
export declare const formatDateLong: (key: string, locale?: string) => string;
|
|
14
|
+
/** "Mittwoch, in 9 Tagen": the saved date at rest. */
|
|
15
|
+
export declare const restStatusText: (key: string, today: string, locale?: string) => string;
|
|
16
|
+
/** What a word or offset meant: "morgen", "nächster Mittwoch", "gestern + 34 Tage". */
|
|
17
|
+
export declare const noteText: (note: DateInputNote, locale: string | undefined, t: DateInputMessages) => string;
|
|
18
|
+
/** The draft line: "→ Mi., 4. Nov. 2026 · nächster Mittwoch". */
|
|
19
|
+
export declare const draftStatusText: (key: string, note: DateInputNote | undefined, locale: string | undefined, t: DateInputMessages) => string;
|
|
20
|
+
/** The reason a text is not a date, short enough for one line. */
|
|
21
|
+
export declare const errorText: (error: DateInputError, locale: string | undefined, t: DateInputMessages, today: string) => string;
|
|
22
|
+
/** A date outside `min`/`max` (date keys) is refused with the nearest allowed day. */
|
|
23
|
+
export declare const limitErrorText: (key: string, limits: {
|
|
24
|
+
min?: string;
|
|
25
|
+
max?: string;
|
|
26
|
+
}, locale: string | undefined, t: DateInputMessages) => string | undefined;
|
|
27
|
+
/** While typing nothing is red yet: an unfinished entry says so calmly, a definite mistake already names the reason. */
|
|
28
|
+
export declare const typingStatusText: (error: DateInputError, locale: string | undefined, t: DateInputMessages, today: string) => string;
|
|
29
|
+
/** "Mittwoch, 4. November 2026, nächster Mittwoch": what the live region reads after typing pauses. */
|
|
30
|
+
export declare const spokenDateText: (key: string, note: DateInputNote | undefined, locale: string | undefined, t: DateInputMessages) => string;
|
|
31
|
+
/** "Mi., 11. Nov. 2026 – Sa., 14. Nov. 2026 · 4 Tage", or one end with what is missing. */
|
|
32
|
+
export declare const rangeStatusText: (range: {
|
|
33
|
+
start: string | null;
|
|
34
|
+
end: string | null;
|
|
35
|
+
}, locale: string | undefined, t: DateInputMessages) => string;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed date input: a small, predictable grammar instead of a natural-language parser. Every input resolves to one
|
|
3
|
+
* calendar day (a date key such as `2026-11-11`), so the field can show the absolute date before it is committed.
|
|
4
|
+
*
|
|
5
|
+
* - Dates in the locale's order of day, month and year: `11.11.2026`, `11.11.26`, `11.11.`, `11.11`, `11/11/2026`.
|
|
6
|
+
* - Digits only: 1–2 digits are a day of the current month; 4, 6 or 8 digits are day, month and year without separators.
|
|
7
|
+
* - ISO dates (`2026-11-11`) and month names (`11. November 2026`, `Nov 11, 2026`).
|
|
8
|
+
* - Day words and weekdays in German and English: `heute`, `morgen`, `mi`, `wed`, `Mittwoch`. A weekday is its next
|
|
9
|
+
* occurrence after today; today's weekday is the same day next week.
|
|
10
|
+
* - One offset at the end: `[anchor] ± N [unit]`, such as `+14`, `-3`, `heute +2w`, `gestern + 34`, `mi +7`, `11.11. -3`.
|
|
11
|
+
* The anchor is any of the forms above; without one it is today, never the saved value.
|
|
12
|
+
*/
|
|
13
|
+
export type DatePart = "day" | "month" | "year";
|
|
14
|
+
export type DateUnit = "day" | "week" | "month" | "year";
|
|
15
|
+
/** What a word or offset meant, so the field can say it next to the resolved date. */
|
|
16
|
+
export type DateInputAnchor = {
|
|
17
|
+
kind: "today";
|
|
18
|
+
} | {
|
|
19
|
+
kind: "date";
|
|
20
|
+
date: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: "day";
|
|
23
|
+
offset: number;
|
|
24
|
+
} | {
|
|
25
|
+
kind: "weekday";
|
|
26
|
+
weekday: number;
|
|
27
|
+
};
|
|
28
|
+
export type DateInputNote = {
|
|
29
|
+
kind: "day";
|
|
30
|
+
offset: number;
|
|
31
|
+
} | {
|
|
32
|
+
kind: "weekday";
|
|
33
|
+
weekday: number;
|
|
34
|
+
nextWeek: boolean;
|
|
35
|
+
} | {
|
|
36
|
+
kind: "offset";
|
|
37
|
+
anchor: DateInputAnchor;
|
|
38
|
+
amount: number;
|
|
39
|
+
unit: DateUnit;
|
|
40
|
+
};
|
|
41
|
+
export type DateInputError = {
|
|
42
|
+
code: "not-a-date";
|
|
43
|
+
} | {
|
|
44
|
+
code: "incomplete";
|
|
45
|
+
} | {
|
|
46
|
+
code: "ambiguous";
|
|
47
|
+
} | {
|
|
48
|
+
code: "year";
|
|
49
|
+
} | {
|
|
50
|
+
code: "unit";
|
|
51
|
+
} | {
|
|
52
|
+
code: "month";
|
|
53
|
+
month: number;
|
|
54
|
+
} | {
|
|
55
|
+
code: "day";
|
|
56
|
+
year: number;
|
|
57
|
+
month: number;
|
|
58
|
+
days: number;
|
|
59
|
+
};
|
|
60
|
+
export type DateInputResult = {
|
|
61
|
+
kind: "empty";
|
|
62
|
+
} | {
|
|
63
|
+
kind: "date";
|
|
64
|
+
date: string;
|
|
65
|
+
note?: DateInputNote;
|
|
66
|
+
} | {
|
|
67
|
+
kind: "error";
|
|
68
|
+
error: DateInputError;
|
|
69
|
+
};
|
|
70
|
+
export declare const addDaysToKey: (key: string, days: number) => string;
|
|
71
|
+
/** Months and years keep the day where it exists and otherwise end on the last day of the month (31.01. + 1m = 28.02.). */
|
|
72
|
+
export declare const addMonthsToKey: (key: string, months: number) => string;
|
|
73
|
+
/** Monday 0 … Sunday 6. */
|
|
74
|
+
export declare const weekdayOfKey: (key: string) => number;
|
|
75
|
+
/** Whole days from `from` to `to`. */
|
|
76
|
+
export declare const daysBetweenKeys: (from: string, to: string) => number;
|
|
77
|
+
/** The locale's order of day, month and year in a numeric date, read from Intl; day-month-year without data. */
|
|
78
|
+
export declare const dateOrder: (locale?: string) => DatePart[];
|
|
79
|
+
/** The numeric form the field shows after a commit, such as `11.11.2026` or `11/11/2026`. */
|
|
80
|
+
export declare const formatDateInput: (key: string, locale?: string) => string;
|
|
81
|
+
/** The placeholder pattern in the locale's order, with letters from the caller (`TT.MM.JJJJ`, `MM/DD/YYYY`). */
|
|
82
|
+
export declare const dateInputPattern: (locale: string | undefined, letters: Record<DatePart, string>) => string;
|
|
83
|
+
/**
|
|
84
|
+
* Parses what a person typed into a date field. `today` is the current date key in the field's time zone; the result
|
|
85
|
+
* never depends on the clock.
|
|
86
|
+
*/
|
|
87
|
+
export declare const parseDateInput: (raw: string, options: {
|
|
88
|
+
today: string;
|
|
89
|
+
locale?: string;
|
|
90
|
+
}) => DateInputResult;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { JSX } from "solid-js";
|
|
2
|
+
/**
|
|
3
|
+
* The phone calendar of a typed date field as a bottom sheet. Date pickers load this module only when the sheet opens:
|
|
4
|
+
* the sheet reaches `PanelDialog`, whose prompts render date pickers, so a static import would be a cycle.
|
|
5
|
+
*/
|
|
6
|
+
export declare const openDateSheet: <T>(options: {
|
|
7
|
+
title: JSX.Element;
|
|
8
|
+
subtitle: string;
|
|
9
|
+
ariaLabel?: string;
|
|
10
|
+
/** The calendar's id, which the field's `aria-controls` names while the sheet is open. */
|
|
11
|
+
id: string;
|
|
12
|
+
locale: string;
|
|
13
|
+
content: (close: (result: T) => void) => JSX.Element;
|
|
14
|
+
}) => Promise<T | undefined>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scrolls `scroller` alone so `item` sits fully inside it, with the "nearest" rule of `scrollIntoView`: an item already
|
|
3
|
+
* in view stays put, and one larger than the view keeps its start in view. Unlike `scrollIntoView`, no ancestor moves,
|
|
4
|
+
* so a strip that keeps its selection visible never scrolls the page or panel around it.
|
|
5
|
+
*/
|
|
6
|
+
export declare function revealInScroller(scroller: HTMLElement | undefined, item: HTMLElement | undefined): void;
|
|
@@ -106,8 +106,22 @@ export type AppWorkspaceMainPaneProps = {
|
|
|
106
106
|
description?: JSX.Element;
|
|
107
107
|
/** Levels mode: a small mark before the level title, such as the colour dot of the object's container. */
|
|
108
108
|
lead?: JSX.Element;
|
|
109
|
+
/**
|
|
110
|
+
* Levels mode: the level's own parent inside the same column, such as a sub-view of a detail that replaces the
|
|
111
|
+
* detail in place. Its back step shows at every width and replaces the shared step to the level before.
|
|
112
|
+
*/
|
|
113
|
+
back?: {
|
|
114
|
+
href: string;
|
|
115
|
+
label: string;
|
|
116
|
+
};
|
|
109
117
|
/** Controls at the end of the level head. */
|
|
110
118
|
actions?: JSX.Element;
|
|
119
|
+
/**
|
|
120
|
+
* Levels mode: `"page"` marks the level that holds the page itself, such as a settings form or the list of an
|
|
121
|
+
* area, rather than a column that leads there or a detail beside it. Its title takes the page step of the type
|
|
122
|
+
* scale, above every group title in it, and its content starts at the title's edge without an inset of its own.
|
|
123
|
+
*/
|
|
124
|
+
heading?: "page";
|
|
111
125
|
surface?: "default" | "navigation";
|
|
112
126
|
open?: boolean;
|
|
113
127
|
resizable?: boolean;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type JSX } from "solid-js";
|
|
2
|
+
import type { DialogTone } from "../feedback/dialog-tone";
|
|
2
3
|
/** Initial focus goes to the first input of the top sheet, otherwise to the
|
|
3
4
|
* dialog element itself. Native `showModal()` focuses the first focusable
|
|
4
5
|
* descendant, which is the drag handle; iOS shows a ring for that programmatic
|
|
@@ -24,6 +25,8 @@ export type BottomSheetProps = {
|
|
|
24
25
|
dismissDisabled?: boolean;
|
|
25
26
|
dismissLabel?: string;
|
|
26
27
|
handle?: boolean;
|
|
28
|
+
/** See `PanelDialog`'s `tone`. */
|
|
29
|
+
tone?: DialogTone;
|
|
27
30
|
};
|
|
28
31
|
declare function BottomSheetRoot(props: BottomSheetProps): JSX.Element;
|
|
29
32
|
/** Bottom-edge presentation; dialogCore continues to own all modal state. */
|
|
@@ -100,6 +100,14 @@ export type DetailPanelActionButtonProps = DetailPanelActionBaseProps & DetailPa
|
|
|
100
100
|
href?: never;
|
|
101
101
|
};
|
|
102
102
|
export type DetailPanelActionProps = DetailPanelActionLinkProps | DetailPanelActionButtonProps;
|
|
103
|
+
/** A row that only shows something, such as a person and their role: the columns of an action, without a command. */
|
|
104
|
+
export type DetailPanelRowProps = {
|
|
105
|
+
title: JSX.Element;
|
|
106
|
+
description?: JSX.Element;
|
|
107
|
+
leading?: JSX.Element;
|
|
108
|
+
trailing?: JSX.Element;
|
|
109
|
+
class?: string;
|
|
110
|
+
};
|
|
103
111
|
export type DetailPanelSectionProps = DetailPanelSectionBaseProps & ({
|
|
104
112
|
children?: JSX.Element;
|
|
105
113
|
actions?: JSX.Element;
|
|
@@ -127,6 +135,7 @@ type DetailPanelComponent = ((props: DetailPanelProps) => JSX.Element) & {
|
|
|
127
135
|
Group: (props: DetailPanelGroupProps) => JSX.Element;
|
|
128
136
|
Section: (props: DetailPanelSectionProps) => JSX.Element;
|
|
129
137
|
Action: (props: DetailPanelActionProps) => JSX.Element;
|
|
138
|
+
Row: (props: DetailPanelRowProps) => JSX.Element;
|
|
130
139
|
};
|
|
131
140
|
/** A count chip, or "None yet" for zero; shared by sections and discussions. */
|
|
132
141
|
export declare const DetailPanelCount: (props: {
|