@k2b/ui 0.44.0 → 0.45.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/Tabs.js +3 -4
- package/dist/browser/actions/Tabs.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/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/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 +536 -512
- 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/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/index.js.map +1 -1
- package/dist/browser/surfaces/StatusBadge.js +47 -14
- package/dist/browser/surfaces/StatusBadge.js.map +1 -1
- package/dist/browser/text-editor/TextEditor.js +7 -0
- package/dist/browser/text-editor/TextEditor.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/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/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/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 +44 -23
- 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/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/index.js.map +1 -1
- package/dist/ssr/surfaces/StatusBadge.js +26 -8
- package/dist/ssr/surfaces/StatusBadge.js.map +1 -1
- package/dist/ssr/text-editor/TextEditor.js +7 -0
- package/dist/ssr/text-editor/TextEditor.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/menu-sheet.d.ts +1 -3
- package/dist/types/actions/phone-sheet.d.ts +3 -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/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/PanelDialog.d.ts +3 -0
- package/dist/types/layout/Settings.d.ts +17 -1
- package/dist/types/layout/index.d.ts +1 -1
- package/dist/types/surfaces/StatusBadge.d.ts +5 -0
- package/package.json +1 -1
|
@@ -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: {
|
|
@@ -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. */
|
|
@@ -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. */
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { type JSX } from "solid-js";
|
|
2
|
+
import { type DialogTone } from "../feedback/dialog-tone";
|
|
2
3
|
export type PanelDialogSurface = "contained" | "floating";
|
|
3
4
|
export type PanelDialogProps = {
|
|
4
5
|
children: JSX.Element;
|
|
5
6
|
surface?: PanelDialogSurface;
|
|
7
|
+
/** A 2 px edge in the tone's colour inside the dialog frame; the header shows the tone's icon instead of its own. */
|
|
8
|
+
tone?: DialogTone;
|
|
6
9
|
};
|
|
7
10
|
export type PanelDialogHeaderProps = {
|
|
8
11
|
title: JSX.Element;
|
|
@@ -25,7 +25,8 @@ export type SettingsSectionProps = {
|
|
|
25
25
|
};
|
|
26
26
|
/**
|
|
27
27
|
* A full-page settings group: a heading, optional actions and its fields on the
|
|
28
|
-
* page surface without a card.
|
|
28
|
+
* page surface without a card. From 860 px of its own width the heading takes a
|
|
29
|
+
* column beside the fields. Dialogs keep using PanelDialog.Section.
|
|
29
30
|
*/
|
|
30
31
|
export declare function SettingsSection(props: SettingsSectionProps): JSX.Element;
|
|
31
32
|
export type SettingsGroupProps = {
|
|
@@ -46,11 +47,26 @@ export declare const readSettingsError: (response: Pick<Response, "json">, fallb
|
|
|
46
47
|
message: string;
|
|
47
48
|
fields: Record<string, string>;
|
|
48
49
|
}>;
|
|
50
|
+
/**
|
|
51
|
+
* The room a setting's control takes: `short` for a number, `medium` for a choice, `long` for text, and `full` for
|
|
52
|
+
* an editor, which keeps its name above it and takes the whole row.
|
|
53
|
+
*/
|
|
54
|
+
export type SettingsFieldWidth = "short" | "medium" | "long" | "full";
|
|
49
55
|
export type SettingsFieldProps = {
|
|
50
56
|
label: string;
|
|
57
|
+
/** One sentence of help; longer guidance belongs in the page's guide. */
|
|
51
58
|
description: string;
|
|
52
59
|
error: MaybeAccessor<string | undefined>;
|
|
53
60
|
changed?: MaybeAccessor<boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* Where the value comes from, at a fixed place after the control: quiet text such as "Default", or the one way
|
|
63
|
+
* back to it, such as a Reset button that only a value of its own shows.
|
|
64
|
+
*/
|
|
65
|
+
source?: JSX.Element;
|
|
66
|
+
/** The control's width by kind, so a number never stretches like a URL. Defaults to `long`, the full column. */
|
|
67
|
+
width?: SettingsFieldWidth;
|
|
68
|
+
/** The row's id, for a link that leads to this one setting. */
|
|
69
|
+
id?: string;
|
|
54
70
|
children: JSX.Element | ((control: SettingsFieldControlProps) => JSX.Element);
|
|
55
71
|
class?: string;
|
|
56
72
|
};
|
|
@@ -38,7 +38,7 @@ export { default as ResizeSeparator, type ResizeSeparatorProps } from "./ResizeS
|
|
|
38
38
|
export { attachResizeSeparator, type ResizeSeparatorOptions } from "./resize-separator";
|
|
39
39
|
export type { ScrollAreaProps } from "./ScrollArea";
|
|
40
40
|
export { default as ScrollArea } from "./ScrollArea";
|
|
41
|
-
export type { SaveStatusProps, SaveStatusState, SettingsFieldControlProps, SettingsFieldProps, SettingsGroupActionProps, SettingsGroupProps, SettingsPageProps, SettingsPanelFooterProps, SettingsSaveBarProps, SettingsSectionProps, } from "./Settings";
|
|
41
|
+
export type { SaveStatusProps, SaveStatusState, SettingsFieldControlProps, SettingsFieldProps, SettingsFieldWidth, SettingsGroupActionProps, SettingsGroupProps, SettingsPageProps, SettingsPanelFooterProps, SettingsSaveBarProps, SettingsSectionProps, } from "./Settings";
|
|
42
42
|
export { readSettingsError, SaveStatus, SettingsField, SettingsGroup, SettingsPage, SettingsPanelFooter, SettingsSaveBar, SettingsSection, sameSettingValue, } from "./Settings";
|
|
43
43
|
export type { SettingsCollectionActionProps, SettingsCollectionItemActionsProps, SettingsCollectionItemProps, SettingsCollectionItemReorderProps, SettingsCollectionItemStatusProps, SettingsCollectionProps, } from "./SettingsCollection";
|
|
44
44
|
export { default as SettingsCollection } from "./SettingsCollection";
|
|
@@ -5,6 +5,11 @@ export type StatusBadgeProps = {
|
|
|
5
5
|
label: JSX.Element;
|
|
6
6
|
icon?: string | null;
|
|
7
7
|
variant?: "chip" | "dot" | "text";
|
|
8
|
+
/**
|
|
9
|
+
* Every label this place can show, such as all states of a list's status. The badge keeps the width of the longest,
|
|
10
|
+
* so in a right-aligned slot its dot starts at one x in every row and stays put when the state changes.
|
|
11
|
+
*/
|
|
12
|
+
labels?: readonly string[];
|
|
8
13
|
title?: string;
|
|
9
14
|
class?: string;
|
|
10
15
|
};
|