@exponential_app/eui 0.0.0-stage → 0.2.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/LICENSE +201 -0
- package/NOTICE +54 -0
- package/README.md +377 -2
- package/catalog/a11y.json +705 -0
- package/catalog/basic-map.json +104 -0
- package/catalog/code.json +58 -0
- package/catalog/core.catalog.json +5190 -0
- package/catalog/core.schema.json +24542 -0
- package/catalog/host.json +95 -0
- package/catalog/layout.json +20 -0
- package/catalog/limits.json +9 -0
- package/catalog/locale.json +48 -0
- package/catalog/macros.json +4152 -0
- package/catalog/recipes.json +64 -0
- package/catalog/strings.json +84 -0
- package/catalog/style.json +180 -0
- package/catalog/theme.schema.json +47754 -0
- package/catalog/tokens.json +47 -0
- package/conformance/README.md +218 -0
- package/conformance/baseline.ts +101 -0
- package/conformance/browser-page.ts +146 -0
- package/conformance/browser-suites.ts +699 -0
- package/conformance/compare.ts +201 -0
- package/conformance/dom.ts +97 -0
- package/conformance/dump.ts +163 -0
- package/conformance/fonts.json +157 -0
- package/conformance/manifest.json +233 -0
- package/conformance/parity-compare.ts +191 -0
- package/conformance/parity-report.schema.json +73 -0
- package/conformance/parity.ts +412 -0
- package/conformance/pixel.ts +177 -0
- package/conformance/primitives-page.ts +49 -0
- package/conformance/report.schema.json +66 -0
- package/conformance/run.ts +118 -0
- package/conformance/voice-wave-child.ts +102 -0
- package/dist/chunks/index-5fmaa0xq.js +8384 -0
- package/dist/chunks/index-5fmaa0xq.js.map +10 -0
- package/dist/chunks/index-62yzr94z.js +2784 -0
- package/dist/chunks/index-62yzr94z.js.map +10 -0
- package/dist/chunks/index-bg2jsgjq.js +8541 -0
- package/dist/chunks/index-bg2jsgjq.js.map +15 -0
- package/dist/chunks/index-fy7y2nz8.js +186 -0
- package/dist/chunks/index-fy7y2nz8.js.map +9 -0
- package/dist/chunks/index-gtk2gwsb.js +4555 -0
- package/dist/chunks/index-gtk2gwsb.js.map +31 -0
- package/dist/chunks/index-t6qz1770.js +95 -0
- package/dist/chunks/index-t6qz1770.js.map +11 -0
- package/dist/conformance.js +230462 -0
- package/dist/conformance.js.map +10 -0
- package/dist/entries/prompt.js +251 -0
- package/dist/entries/prompt.js.map +11 -0
- package/dist/entries/schema.js +1725 -0
- package/dist/entries/schema.js.map +11 -0
- package/dist/host/index.js +194 -0
- package/dist/host/index.js.map +9 -0
- package/dist/index.js +3840 -0
- package/dist/index.js.map +29 -0
- package/dist/types/src/a11y.d.ts +21 -0
- package/dist/types/src/animation.d.ts +76 -0
- package/dist/types/src/basic-map.d.ts +38 -0
- package/dist/types/src/builder.d.ts +50 -0
- package/dist/types/src/catalog.d.ts +54 -0
- package/dist/types/src/catalog.described.d.ts +33 -0
- package/dist/types/src/catalog.generated.d.ts +904 -0
- package/dist/types/src/chart.d.ts +46 -0
- package/dist/types/src/code.d.ts +44 -0
- package/dist/types/src/color.d.ts +20 -0
- package/dist/types/src/conformance.d.ts +39 -0
- package/dist/types/src/connector/app.d.ts +14 -0
- package/dist/types/src/connector/connector.d.ts +77 -0
- package/dist/types/src/connector/index.d.ts +4 -0
- package/dist/types/src/css.d.ts +27 -0
- package/dist/types/src/define.d.ts +66 -0
- package/dist/types/src/direction.d.ts +16 -0
- package/dist/types/src/dynamic.d.ts +161 -0
- package/dist/types/src/entries/prompt.d.ts +11 -0
- package/dist/types/src/entries/schema.d.ts +8 -0
- package/dist/types/src/expr.d.ts +71 -0
- package/dist/types/src/extension.d.ts +4 -0
- package/dist/types/src/format.d.ts +112 -0
- package/dist/types/src/geometry.d.ts +40 -0
- package/dist/types/src/host/contract.d.ts +225 -0
- package/dist/types/src/host/decoders.d.ts +61 -0
- package/dist/types/src/host/index.d.ts +15 -0
- package/dist/types/src/host/package.d.ts +102 -0
- package/dist/types/src/host/policy.d.ts +107 -0
- package/dist/types/src/host/record-store.d.ts +103 -0
- package/dist/types/src/host/records.d.ts +45 -0
- package/dist/types/src/host/router.d.ts +38 -0
- package/dist/types/src/host/runtime.d.ts +213 -0
- package/dist/types/src/host/signature.d.ts +52 -0
- package/dist/types/src/host/sources.d.ts +22 -0
- package/dist/types/src/host/tools.d.ts +42 -0
- package/dist/types/src/host/transports.d.ts +109 -0
- package/dist/types/src/index.d.ts +69 -0
- package/dist/types/src/layout.d.ts +20 -0
- package/dist/types/src/limits.d.ts +21 -0
- package/dist/types/src/list.d.ts +133 -0
- package/dist/types/src/locale.d.ts +22 -0
- package/dist/types/src/macros.d.ts +29 -0
- package/dist/types/src/overlay.d.ts +27 -0
- package/dist/types/src/prompt.d.ts +44 -0
- package/dist/types/src/qr-code.d.ts +30 -0
- package/dist/types/src/recipes.d.ts +17 -0
- package/dist/types/src/reducer.d.ts +41 -0
- package/dist/types/src/resizable.d.ts +38 -0
- package/dist/types/src/schema.d.ts +7 -0
- package/dist/types/src/strings.d.ts +13 -0
- package/dist/types/src/style.d.ts +201 -0
- package/dist/types/src/test-preload.d.ts +1 -0
- package/dist/types/src/text-shimmer.d.ts +24 -0
- package/dist/types/src/theme-types.d.ts +162 -0
- package/dist/types/src/theme.d.ts +75 -0
- package/dist/types/src/themes.d.ts +22 -0
- package/dist/types/src/tree-guides.d.ts +17 -0
- package/dist/types/src/types.d.ts +320 -0
- package/dist/types/src/validate.d.ts +31 -0
- package/dist/types/src/voice-wave.d.ts +181 -0
- package/dist/types/src/web/base-css.d.ts +1 -0
- package/dist/types/src/web/box-css.d.ts +63 -0
- package/dist/types/src/web/coerce.d.ts +32 -0
- package/dist/types/src/web/custom-icons.generated.d.ts +4 -0
- package/dist/types/src/web/data.d.ts +107 -0
- package/dist/types/src/web/dates.d.ts +12 -0
- package/dist/types/src/web/form.d.ts +44 -0
- package/dist/types/src/web/host-types.d.ts +126 -0
- package/dist/types/src/web/index.d.ts +35 -0
- package/dist/types/src/web/inputs.d.ts +55 -0
- package/dist/types/src/web/list.d.ts +16 -0
- package/dist/types/src/web/listbox.d.ts +14 -0
- package/dist/types/src/web/markdown.d.ts +96 -0
- package/dist/types/src/web/media.d.ts +63 -0
- package/dist/types/src/web/parts.d.ts +4 -0
- package/dist/types/src/web/primitives/alert-dialog.d.ts +10 -0
- package/dist/types/src/web/primitives/alert.d.ts +9 -0
- package/dist/types/src/web/primitives/avatar-color.d.ts +2 -0
- package/dist/types/src/web/primitives/avatar.d.ts +13 -0
- package/dist/types/src/web/primitives/badge.d.ts +10 -0
- package/dist/types/src/web/primitives/breadcrumb.d.ts +10 -0
- package/dist/types/src/web/primitives/button.d.ts +6 -0
- package/dist/types/src/web/primitives/calendar.d.ts +43 -0
- package/dist/types/src/web/primitives/card.d.ts +9 -0
- package/dist/types/src/web/primitives/checkbox.d.ts +5 -0
- package/dist/types/src/web/primitives/choice-tiles.d.ts +32 -0
- package/dist/types/src/web/primitives/cn.d.ts +3 -0
- package/dist/types/src/web/primitives/code-block.d.ts +24 -0
- package/dist/types/src/web/primitives/command.d.ts +134 -0
- package/dist/types/src/web/primitives/context-ring.d.ts +24 -0
- package/dist/types/src/web/primitives/dialog-arms.d.ts +6 -0
- package/dist/types/src/web/primitives/dialog.d.ts +24 -0
- package/dist/types/src/web/primitives/disclosure-header.d.ts +5 -0
- package/dist/types/src/web/primitives/dock.d.ts +42 -0
- package/dist/types/src/web/primitives/dropdown-menu.d.ts +14 -0
- package/dist/types/src/web/primitives/empty-state.d.ts +15 -0
- package/dist/types/src/web/primitives/glass-card.d.ts +4 -0
- package/dist/types/src/web/primitives/hover-card.d.ts +7 -0
- package/dist/types/src/web/primitives/icon-disc.d.ts +12 -0
- package/dist/types/src/web/primitives/index.d.ts +50 -0
- package/dist/types/src/web/primitives/input.d.ts +5 -0
- package/dist/types/src/web/primitives/kbd.d.ts +4 -0
- package/dist/types/src/web/primitives/label.d.ts +3 -0
- package/dist/types/src/web/primitives/measure.d.ts +16 -0
- package/dist/types/src/web/primitives/menu-surface.d.ts +17 -0
- package/dist/types/src/web/primitives/meter.d.ts +21 -0
- package/dist/types/src/web/primitives/popover.d.ts +3 -0
- package/dist/types/src/web/primitives/progress-ring.d.ts +5 -0
- package/dist/types/src/web/primitives/progress.d.ts +8 -0
- package/dist/types/src/web/primitives/scroll-area.d.ts +49 -0
- package/dist/types/src/web/primitives/segmented-control.d.ts +5 -0
- package/dist/types/src/web/primitives/select.d.ts +47 -0
- package/dist/types/src/web/primitives/separator.d.ts +3 -0
- package/dist/types/src/web/primitives/sheet-chrome.d.ts +4 -0
- package/dist/types/src/web/primitives/sheet.d.ts +20 -0
- package/dist/types/src/web/primitives/skeleton.d.ts +3 -0
- package/dist/types/src/web/primitives/spinner.d.ts +3 -0
- package/dist/types/src/web/primitives/switch.d.ts +4 -0
- package/dist/types/src/web/primitives/table.d.ts +11 -0
- package/dist/types/src/web/primitives/tabs.d.ts +13 -0
- package/dist/types/src/web/primitives/textarea.d.ts +3 -0
- package/dist/types/src/web/primitives/toast.d.ts +163 -0
- package/dist/types/src/web/primitives/tooltip.d.ts +3 -0
- package/dist/types/src/web/primitives/truncate.d.ts +7 -0
- package/dist/types/src/web/primitives/typeahead-portal.d.ts +12 -0
- package/dist/types/src/web/primitives/voice-wave.d.ts +50 -0
- package/dist/types/src/web/round5.d.ts +107 -0
- package/dist/types/src/web/share.d.ts +6 -0
- package/dist/types/src/web/table.d.ts +20 -0
- package/dist/types/src/web/theme-css.d.ts +69 -0
- package/dist/types/src/web/urls.d.ts +21 -0
- package/dist/web/index.js +2565 -0
- package/dist/web/index.js.map +28 -0
- package/dist/web/primitives/index.js +1476 -0
- package/dist/web/primitives/index.js.map +57 -0
- package/docs/components.generated.json +6783 -0
- package/docs/package-format.md +182 -0
- package/docs/round-1-contract.md +679 -0
- package/docs/round-2-contract.md +476 -0
- package/docs/round-3-contract.md +174 -0
- package/docs/round-5-contract.md +268 -0
- package/docs/themes.generated.json +3647 -0
- package/fixtures/animations.json +2890 -0
- package/fixtures/bench-list.json +58 -0
- package/fixtures/bind-time.json +54734 -0
- package/fixtures/catalog-basic-map.json +1692 -0
- package/fixtures/catalog-components.json +10293 -0
- package/fixtures/catalog-extension.json +620 -0
- package/fixtures/catalog-macros.json +51805 -0
- package/fixtures/code-tokens.json +1993 -0
- package/fixtures/conformance-baseline.json +59016 -0
- package/fixtures/conformance-cases.json +49 -0
- package/fixtures/conformance-known.json +2111 -0
- package/fixtures/control-geometry.json +5129 -0
- package/fixtures/dashboard.data.json +74 -0
- package/fixtures/dashboard.json +781 -0
- package/fixtures/demo-surface.json +47 -0
- package/fixtures/format.json +870 -0
- package/fixtures/host-package.json +1262 -0
- package/fixtures/host-policy.json +1209 -0
- package/fixtures/host-router.json +2034 -0
- package/fixtures/host-transport.json +590 -0
- package/fixtures/interactions-round1.json +1058 -0
- package/fixtures/kitchen-sink.expanded.json +11972 -0
- package/fixtures/kitchen-sink.json +3140 -0
- package/fixtures/layout-geometry-round1.json +7278 -0
- package/fixtures/layout-geometry.json +2072 -0
- package/fixtures/overlay-geometry.json +272 -0
- package/fixtures/pointer.json +89 -0
- package/fixtures/primitive-specimens.json +59 -0
- package/fixtures/prompt-budget.json +33 -0
- package/fixtures/qr-code.json +480 -0
- package/fixtures/resizable.json +714 -0
- package/fixtures/round4-contract.json +2985 -0
- package/fixtures/specimens.json +11168 -0
- package/fixtures/style-conditions.json +336 -0
- package/fixtures/template-items.json +2215 -0
- package/fixtures/text-direction.json +309 -0
- package/fixtures/text-shimmer.json +96 -0
- package/fixtures/theme-extends.json +573 -0
- package/fixtures/theme-invalid.json +1300 -0
- package/fixtures/theme-recipes.json +61762 -0
- package/fixtures/theme-resolved.json +25969 -0
- package/fixtures/toast-stack.json +215 -0
- package/fixtures/tree-guides.json +224 -0
- package/fixtures/virtual-list.json +733 -0
- package/fixtures/voice-wave.json +19236 -0
- package/generated/ExponentialUICatalog.generated.kt +67 -0
- package/generated/ExponentialUICatalog.generated.swift +67 -0
- package/generated/ExponentialUIThemes.generated.kt +23 -0
- package/generated/ExponentialUIThemes.generated.swift +23 -0
- package/generated/catalog.descriptions.generated.rs +6 -0
- package/generated/catalog.generated.rs +80 -0
- package/generated/catalog.themes.generated.rs +34 -0
- package/generated/core.descriptions.json +2726 -0
- package/generated/core.runtime.json +3944 -0
- package/package.json +87 -4
- package/themes/exponential.recipes.json +49 -0
- package/themes/exponential.theme.json +768 -0
- package/themes/neutral.theme.json +6178 -0
- package/themes/orange.theme.json +43 -0
- package/themes/playful.theme.json +219 -0
- package/vendor/a2ui/LICENSE.txt +203 -0
- package/vendor/a2ui/README.md +27 -0
- package/vendor/a2ui/v0_9/basic_catalog.json +1387 -0
- package/vendor/a2ui/v0_9/basic_catalog_rules.txt +5 -0
- package/vendor/a2ui/v0_9/client_capabilities.json +97 -0
- package/vendor/a2ui/v0_9/client_to_server.json +104 -0
- package/vendor/a2ui/v0_9/common_types.json +315 -0
- package/vendor/a2ui/v0_9/server_to_client.json +132 -0
- package/vendor/json-render/LICENSE.txt +201 -0
- package/vendor/json-render/README.md +13 -0
- package/vendor/nayuki-qr/LICENSE.txt +20 -0
- package/vendor/nayuki-qr/README.md +10 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { CatalogView, ExtensionDef, Formatter } from "@exponential_app/eui";
|
|
2
|
+
export type DataModel = Record<string, unknown> | unknown[];
|
|
3
|
+
export interface DataBinding {
|
|
4
|
+
path: string;
|
|
5
|
+
}
|
|
6
|
+
export interface FunctionCall {
|
|
7
|
+
call: string;
|
|
8
|
+
args?: Record<string, unknown>;
|
|
9
|
+
returnType?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function isBinding(value: unknown): value is DataBinding;
|
|
12
|
+
export declare function isCall(value: unknown): value is FunctionCall;
|
|
13
|
+
/** A pointer's tokens; `` and `/` are the whole model. */
|
|
14
|
+
export declare function pointerTokens(pointer: string): string[];
|
|
15
|
+
/** `path` made absolute against a template scope (`/items/3`). */
|
|
16
|
+
export declare function absolutePath(path: string, scope?: string): string;
|
|
17
|
+
/** The core's `readPointer`: real indices and OWN keys only, `-` = the
|
|
18
|
+
* last element. */
|
|
19
|
+
export declare const getPointer: (data: unknown, pointer: string) => unknown;
|
|
20
|
+
/** A copy of `data` with the value at `pointer` replaced (or removed when
|
|
21
|
+
* `value` is undefined): the core's `writePointer` (missing containers are
|
|
22
|
+
* OBJECTS, an array index up to its length, `-` appends). A refused write
|
|
23
|
+
* (pointer limits, a non-index token, an index past the end) leaves the
|
|
24
|
+
* data as it is. */
|
|
25
|
+
export declare function setPointer<T extends DataModel>(data: T, pointer: string, value: unknown): T;
|
|
26
|
+
export interface ResolveContext {
|
|
27
|
+
data: unknown;
|
|
28
|
+
/** The template item's pointer, for relative paths. */
|
|
29
|
+
scope?: string;
|
|
30
|
+
functions?: Record<string, ClientFunction>;
|
|
31
|
+
/** `openUrl` and other side effects go to the host. */
|
|
32
|
+
openUrl?: (url: string) => void;
|
|
33
|
+
/** The surface locale (BCP 47) the format functions use; default en-US. */
|
|
34
|
+
locale?: string;
|
|
35
|
+
/** The surface's built-in string table: `$string.<id>` resolves through it. */
|
|
36
|
+
strings?: Readonly<Record<string, string>>;
|
|
37
|
+
/** Round 2: the surface's Formatter (locale + time zone); the format
|
|
38
|
+
* functions, Table cells, charts and pickers format through it. */
|
|
39
|
+
formatter?: Formatter;
|
|
40
|
+
/** The clock `formatRelativeTime` reads without a `now` argument. */
|
|
41
|
+
now?: () => number;
|
|
42
|
+
}
|
|
43
|
+
/** The synthetic root a Table's LITERAL rows are mounted under in a slot
|
|
44
|
+
* cell's read view: never written to the real data model (the table keeps
|
|
45
|
+
* those edits), never reported to the host as a path. */
|
|
46
|
+
export declare const LITERAL_ROWS_ROOT = "/$xuiRows";
|
|
47
|
+
/** A bound path the host may see (`undefined` for a synthetic one). */
|
|
48
|
+
export declare function hostPath(path: string | undefined): string | undefined;
|
|
49
|
+
export type ClientFunction = (args: Record<string, unknown>, ctx: ResolveContext) => unknown;
|
|
50
|
+
/** `intlFormatter` builds a new Intl instance per call (~18 µs for a
|
|
51
|
+
* currency); a windowed Table re-formats every visible cell per scroll
|
|
52
|
+
* step. This wrapper memoises the RESULTS of the pure members (number,
|
|
53
|
+
* currency, percent, date, plural) per formatter, bounded; relativeTime
|
|
54
|
+
* (it reads a clock) passes through. */
|
|
55
|
+
export declare function memoFormatter(base: Formatter, max?: number): Formatter;
|
|
56
|
+
/** The context's Formatter: the surface's (`ctx.formatter`), else an Intl
|
|
57
|
+
* one in its locale and UTC (a bare `resolveValue` call in a test). */
|
|
58
|
+
export declare function formatterOf(ctx: ResolveContext): Formatter;
|
|
59
|
+
export declare const CLIENT_FUNCTIONS: Record<string, ClientFunction>;
|
|
60
|
+
/** A prop value with its bindings and calls resolved for one render. Plain
|
|
61
|
+
* objects recurse (a check's `condition`, a menu item's label). */
|
|
62
|
+
export declare function resolveValue(value: unknown, ctx: ResolveContext): unknown;
|
|
63
|
+
export declare function resolveProps(props: Record<string, unknown>, ctx: ResolveContext): Record<string, unknown>;
|
|
64
|
+
/** The catalog (core + extensions) a node's props resolve along. */
|
|
65
|
+
export declare function viewOf(extensions?: readonly ExtensionDef[]): CatalogView;
|
|
66
|
+
/** A node's props resolved along its component's schema (an unknown
|
|
67
|
+
* component's resolve at any depth); undefined results are dropped. */
|
|
68
|
+
export declare function resolveNodeProps(component: string, props: Record<string, unknown>, ctx: ResolveContext, extensions?: readonly ExtensionDef[]): Record<string, unknown>;
|
|
69
|
+
/** The pointer a bindable prop writes back to (two-way state), if bound. */
|
|
70
|
+
export declare function boundPath(props: Record<string, unknown>, name: string, scope?: string): string | undefined;
|
|
71
|
+
/** A node's `visible`: absent = shown, else its resolved truthiness. */
|
|
72
|
+
export declare function resolveVisible(visible: unknown, ctx: ResolveContext): boolean;
|
|
73
|
+
/** True when a value holds a binding or a call anywhere (a style value the
|
|
74
|
+
* expander left dynamic). */
|
|
75
|
+
export declare function hasDynamic(value: unknown): boolean;
|
|
76
|
+
/** The React renderer's BIND pass as a pure function (round-1 contract §1;
|
|
77
|
+
* `@exponential_app/eui` `bindTree` is the reference, fixtures/bind-time.json
|
|
78
|
+
* locks both): a node whose `visible` resolves falsy is dropped with its
|
|
79
|
+
* subtree, props / style values / recipe props resolve, `visible` goes,
|
|
80
|
+
* actions and templates stay. `NodeView` binds node by node with the same
|
|
81
|
+
* `resolveValue`; this is the whole-tree form for tests and hosts. */
|
|
82
|
+
/** A node's `accessibility` resolved against the data (bindings, calls,
|
|
83
|
+
* `$string`), undefined members dropped; null when nothing is left. */
|
|
84
|
+
export declare function resolveAccessibility(accessibility: unknown, ctx: ResolveContext): Record<string, unknown> | null;
|
|
85
|
+
/** The ARIA attributes of a RESOLVED `accessibility` (contract §6): `role`
|
|
86
|
+
* (`text` = none of its own, `hidden` = aria-hidden), label/description,
|
|
87
|
+
* `level`, `expanded`, `current` (page|step; false = absent), `selected`,
|
|
88
|
+
* `pressed`, `checked`, `valueNow/Min/Max`, `hidden`; `autoFocus` →
|
|
89
|
+
* `data-xui-autofocus` (an opening dialog focuses it). */
|
|
90
|
+
export declare function ariaAttributes(a11y: Record<string, unknown> | null): Record<string, string>;
|
|
91
|
+
export declare function bindTree<T extends {
|
|
92
|
+
id: string;
|
|
93
|
+
component: string;
|
|
94
|
+
props: Record<string, unknown>;
|
|
95
|
+
children: T[];
|
|
96
|
+
style?: Record<string, unknown>;
|
|
97
|
+
visible?: unknown;
|
|
98
|
+
slots?: Record<string, T>;
|
|
99
|
+
recipe?: {
|
|
100
|
+
macro: string;
|
|
101
|
+
part: string;
|
|
102
|
+
props: Record<string, unknown>;
|
|
103
|
+
};
|
|
104
|
+
on?: unknown;
|
|
105
|
+
accessibility?: unknown;
|
|
106
|
+
template?: unknown;
|
|
107
|
+
}>(node: T, ctx: ResolveContext, extensions?: readonly ExtensionDef[]): T | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const isoDate: (d: Date) => string;
|
|
2
|
+
export declare const parseIsoDate: (s: string) => Date | null;
|
|
3
|
+
export declare const addDays: (d: Date, n: number) => Date;
|
|
4
|
+
/** `n` months on, the day clamped to the target month's last. */
|
|
5
|
+
export declare const addMonths: (d: Date, n: number) => Date;
|
|
6
|
+
export declare const sameDay: (a: Date | null, b: Date | null) => boolean;
|
|
7
|
+
/** The 6×7 days of `view`'s month, starting on `first` (0 = Sunday). */
|
|
8
|
+
export declare function monthGrid(view: Date, first: number): Date[];
|
|
9
|
+
/** The roving tab stop of a month view: the focused day when it is in the
|
|
10
|
+
* visible month and enabled, else the enabled in-month day nearest to it,
|
|
11
|
+
* else none (a disabled day never holds the stop). */
|
|
12
|
+
export declare function calendarStop(days: readonly Date[], view: Date, focus: Date, disabled: (d: Date) => boolean): Date | null;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** One registered field (a renderer's handle onto its control). */
|
|
2
|
+
export interface FormField {
|
|
3
|
+
name: string;
|
|
4
|
+
domId: string;
|
|
5
|
+
value: () => unknown;
|
|
6
|
+
errors: () => string[];
|
|
7
|
+
focus: () => void;
|
|
8
|
+
element: () => Element | null;
|
|
9
|
+
}
|
|
10
|
+
export interface FormError {
|
|
11
|
+
name: string;
|
|
12
|
+
message: string;
|
|
13
|
+
}
|
|
14
|
+
export type FormCheck<F extends FormField = FormField> = {
|
|
15
|
+
ok: false;
|
|
16
|
+
errors: FormError[];
|
|
17
|
+
first: F | null;
|
|
18
|
+
} | {
|
|
19
|
+
ok: true;
|
|
20
|
+
values: Record<string, unknown>;
|
|
21
|
+
};
|
|
22
|
+
/** A component's catalog default `validateOn`, or undefined. */
|
|
23
|
+
export declare function validateOnDefault(component: string): string | undefined;
|
|
24
|
+
/** Whether a field shows its failing messages now. */
|
|
25
|
+
export declare function fieldErrorsVisible(state: {
|
|
26
|
+
validateOn: string;
|
|
27
|
+
submitted: boolean;
|
|
28
|
+
attempts: number;
|
|
29
|
+
dirty: boolean;
|
|
30
|
+
touched: boolean;
|
|
31
|
+
}): boolean;
|
|
32
|
+
/** Fields in document order (unmounted ones keep their place). */
|
|
33
|
+
export declare function documentOrder<F extends FormField>(fields: Iterable<F>): F[];
|
|
34
|
+
export declare class FormRegistry<F extends FormField = FormField> {
|
|
35
|
+
readonly fields: Set<F>;
|
|
36
|
+
/** Adds a field; the returned function removes it. */
|
|
37
|
+
register(field: F): () => void;
|
|
38
|
+
/** Every field's checks: the failures (document order) and the first
|
|
39
|
+
* invalid field, or the values by name. */
|
|
40
|
+
check(): FormCheck<F>;
|
|
41
|
+
/** The summary entries whose field still fails with that message (they
|
|
42
|
+
* clear as their fields become valid). */
|
|
43
|
+
stillFailing(summary: readonly FormError[]): FormError[];
|
|
44
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { FunctionCallInfo, MediaOptions, MediaRequest, ThemeIssue, UiNode, UrlPolicy } from "@exponential_app/eui";
|
|
2
|
+
import type { ClientFunction } from "./data.js";
|
|
3
|
+
import type { QrScannerHost } from "./round5.js";
|
|
4
|
+
/** A registry name → the renderer's icon component (a map or a lookup). */
|
|
5
|
+
export type IconMap<Icon = unknown> = Record<string, Icon | undefined> | ((name: string) => Icon | undefined);
|
|
6
|
+
/** A user action: a node's `on.<event>` with an `event` action, resolved. */
|
|
7
|
+
export interface SurfaceActionEvent {
|
|
8
|
+
surfaceId: string;
|
|
9
|
+
/** The catalog event (`press`, `change`, `select`, `submit`…). */
|
|
10
|
+
event: string;
|
|
11
|
+
/** The action's `event.name`. */
|
|
12
|
+
name: string;
|
|
13
|
+
componentId: string;
|
|
14
|
+
context: Record<string, unknown>;
|
|
15
|
+
/** What the component adds (a Select's `value`, a Tabs' `value`…). */
|
|
16
|
+
payload?: Record<string, unknown>;
|
|
17
|
+
timestamp: string;
|
|
18
|
+
}
|
|
19
|
+
/** A host-owned input edit. `change` fires debounced while typing with a
|
|
20
|
+
* monotonically increasing `revision`; `commit` on blur / Enter. The host's
|
|
21
|
+
* echo (a data model write at `path`) is applied only while no newer
|
|
22
|
+
* revision is outstanding and the field is not focused. */
|
|
23
|
+
export interface SurfaceInputEvent {
|
|
24
|
+
surfaceId: string;
|
|
25
|
+
componentId: string;
|
|
26
|
+
/** The input's `name` prop. */
|
|
27
|
+
name: string;
|
|
28
|
+
/** The bound data model pointer, when `value` is a binding. */
|
|
29
|
+
path?: string;
|
|
30
|
+
value: unknown;
|
|
31
|
+
revision: number;
|
|
32
|
+
kind: `change` | `commit`;
|
|
33
|
+
}
|
|
34
|
+
/** A painter that failed: the surface, the component, why. */
|
|
35
|
+
export interface PaintError {
|
|
36
|
+
surfaceId: string;
|
|
37
|
+
componentId: string;
|
|
38
|
+
message: string;
|
|
39
|
+
}
|
|
40
|
+
/** One option a host source supplies (the catalog's `option` shape). */
|
|
41
|
+
export interface SourceOption {
|
|
42
|
+
label: string;
|
|
43
|
+
value: string;
|
|
44
|
+
icon?: string;
|
|
45
|
+
disabled?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export interface HostPlugin<Icon = unknown, Markdown = unknown> {
|
|
48
|
+
/** The icon registry: the catalog's `Icon` names → components. */
|
|
49
|
+
icons?: IconMap<Icon>;
|
|
50
|
+
/** Server events. Returning a promise keeps the source control in its
|
|
51
|
+
* optimistic pending state until it settles. */
|
|
52
|
+
onAction?: (event: SurfaceActionEvent) => void | Promise<void>;
|
|
53
|
+
/** Host-owned input edits. Returning a promise acknowledges the revision
|
|
54
|
+
* when it settles; a sync host acknowledges at once. */
|
|
55
|
+
onInput?: (event: SurfaceInputEvent) => void | Promise<void>;
|
|
56
|
+
/** Opens an href the URL policy allowed (`openUrl`, `Link`); default
|
|
57
|
+
* `window.open(url, "_blank")`. */
|
|
58
|
+
openUrl?: (url: string) => void;
|
|
59
|
+
/** The URL policy EVERY href passes (Link, markdown links, FileUpload
|
|
60
|
+
* file urls, openUrl): `catalog/host.json` urls. Unset = the default
|
|
61
|
+
* schemes; relative urls resolve against `baseUrl`, else `media.baseUrl`,
|
|
62
|
+
* else the document's. A denied href paints as text. */
|
|
63
|
+
urls?: UrlPolicy;
|
|
64
|
+
/** The media policy every src passes when there is no `mediaRequest`
|
|
65
|
+
* (schemes, hosts, private opt-ins, base, header rules):
|
|
66
|
+
* `catalog/host.json` media. */
|
|
67
|
+
media?: MediaOptions;
|
|
68
|
+
/** Extra or overriding client functions, web renderers only (`{call,
|
|
69
|
+
* args}` in a prop; an action naming one runs it). Any OTHER action
|
|
70
|
+
* function name goes to onFunctionCall (the portable host functions). */
|
|
71
|
+
functions?: Record<string, ClientFunction>;
|
|
72
|
+
/** An action `functionCall` to a name outside the built-ins (the host
|
|
73
|
+
* function registry + its policy gate, `ExponentialHost.callFunction`).
|
|
74
|
+
* A promise keeps the source control pending until it settles. */
|
|
75
|
+
onFunctionCall?: (call: FunctionCallInfo) => unknown | Promise<unknown>;
|
|
76
|
+
/** The media loader's request for a source (absolute url + headers, e.g.
|
|
77
|
+
* auth for /api/attachments); null = denied. A request WITH headers is
|
|
78
|
+
* fetched (under the media limits) and shown as a blob url; without, its
|
|
79
|
+
* url is used as is. Its url is re-checked against `media`'s schemes,
|
|
80
|
+
* hosts and private opt-ins. */
|
|
81
|
+
mediaRequest?: (src: string) => MediaRequest | null;
|
|
82
|
+
/** Video/Audio (`catalog/host.json` media: the byte limits do not apply,
|
|
83
|
+
* they stream): a url the browser's player loads WITHOUT headers for a
|
|
84
|
+
* request that carries some (a signed or cookie-authed url), so the
|
|
85
|
+
* player streams and seeks. Its result passes the media policy again.
|
|
86
|
+
* Unset = the request is fetched whole into a blob url under the media
|
|
87
|
+
* byte cap and timeout for the WHOLE download (VAPP-107), so a long
|
|
88
|
+
* video needs this hook. */
|
|
89
|
+
mediaStreamUrl?: (request: MediaRequest) => string | Promise<string>;
|
|
90
|
+
/** A richer markdown renderer than the built-in one (a component taking
|
|
91
|
+
* `{text, className}` in the renderer's framework). */
|
|
92
|
+
Markdown?: Markdown;
|
|
93
|
+
/** Rewrites a media src BEFORE the media policy (signed URLs). */
|
|
94
|
+
resolveUrl?: (src: string) => string;
|
|
95
|
+
/** `onPaintError` (`catalog/host.json` paint): a component's painter
|
|
96
|
+
* failed; it paints an empty box. `hostPlugin(host)` forwards it to the
|
|
97
|
+
* agent as an A2UI `RENDER_FAILED` error. */
|
|
98
|
+
onPaintError?: (error: PaintError) => void;
|
|
99
|
+
/** Called with the node for every Unknown placeholder painted. */
|
|
100
|
+
onUnknown?: (node: UiNode) => void;
|
|
101
|
+
/** Round 4 (VAPP-103): the `theme` prop was unusable (an unknown built-in
|
|
102
|
+
* id, a theme file with issues). The surface never throws: it paints
|
|
103
|
+
* with the default theme and reports why here. */
|
|
104
|
+
onThemeIssues?: (issues: ThemeIssue[]) => void;
|
|
105
|
+
/** Round 1, FileUpload: the picked/dropped files' BYTES (the `upload`
|
|
106
|
+
* event carries only `{name, size, type}`). Return a promise to keep the
|
|
107
|
+
* drop zone busy until it settles. */
|
|
108
|
+
onUpload?: (files: File[], target: {
|
|
109
|
+
nodeId: string;
|
|
110
|
+
name: string;
|
|
111
|
+
}) => void | Promise<void>;
|
|
112
|
+
/** Round 1, Select `source`: a host list id (`exp:statuses`) → its
|
|
113
|
+
* options for a query (`""` when not searchable). */
|
|
114
|
+
optionSource?: (source: string, query: string) => SourceOption[] | Promise<SourceOption[]>;
|
|
115
|
+
/** VAPP-162, QrScanner: THE camera (host-owned, like FileUpload's bytes):
|
|
116
|
+
* `start(feed, formats, onValue)` renders the live feed into `feed`,
|
|
117
|
+
* decodes codes of `formats` and calls `onValue` per decoded string;
|
|
118
|
+
* returns the stop. Unset (or `start` returning false) = no camera: the
|
|
119
|
+
* scanner shows its placeholder and `Camera unavailable`. */
|
|
120
|
+
qrScanner?: QrScannerHost;
|
|
121
|
+
}
|
|
122
|
+
/** Any renderer's plugin (what the framework-free helpers take). */
|
|
123
|
+
export type AnyHostPlugin = HostPlugin<unknown, unknown>;
|
|
124
|
+
/** A registry lookup: the host's map (or function) first, then the
|
|
125
|
+
* renderer's own fallbacks. */
|
|
126
|
+
export declare function lookupIcon<Icon>(icons: IconMap<Icon> | undefined, name: string, fallbacks?: Readonly<Record<string, Icon>>): Icon | undefined;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export { compileTheme, compiledTheme, globalsCss, themeScope, partClass, propAttribute, tokenVar, tokenVarName, cssValue, declarations, animationDeclarations, shimmerRule, rule, ruleSelectors, isMacroComponent, STATE_SELECTORS, LAYERS } from "./theme-css.js";
|
|
2
|
+
export type { CompiledTheme } from "./theme-css.js";
|
|
3
|
+
export { nodeSheet, compileNodeSheet, nodeSheetBatches, dynamicStyleEntries, queryToken, nodeClass, surfaceClass, walkNodes, cssEscape, resolvedMediaKey, styleDirection } from "./box-css.js";
|
|
4
|
+
export type { NodeSheet, NodeSheetBatch, DynamicStyleEntry } from "./box-css.js";
|
|
5
|
+
export { BASE_CSS } from "./base-css.js";
|
|
6
|
+
export { getPointer, setPointer, pointerTokens, absolutePath, resolveValue, resolveProps, resolveNodeProps, resolveVisible, resolveAccessibility, ariaAttributes, bindTree, boundPath, hostPath, isBinding, isCall, hasDynamic, memoFormatter, formatterOf, viewOf, CLIENT_FUNCTIONS, LITERAL_ROWS_ROOT } from "./data.js";
|
|
7
|
+
export type { DataModel, DataBinding, FunctionCall, ClientFunction, ResolveContext } from "./data.js";
|
|
8
|
+
export { linkHref, mediaRequestOf, mediaUrlAllowed, openAllowed, ownPrivateHosts, urlPolicyOf } from "./urls.js";
|
|
9
|
+
export { lookupIcon } from "./host-types.js";
|
|
10
|
+
export { CUSTOM_ICON_NODES } from "./custom-icons.generated.js";
|
|
11
|
+
export type { CustomIconNode } from "./custom-icons.generated.js";
|
|
12
|
+
export type { HostPlugin, AnyHostPlugin, IconMap, PaintError, SourceOption, SurfaceActionEvent, SurfaceInputEvent } from "./host-types.js";
|
|
13
|
+
export { str, num, bool, arr, objects, phrase, formatFileSize, acceptsFile, failingChecks, failingCheck, builtinIconName, joinIds } from "./coerce.js";
|
|
14
|
+
export { sortRows } from "./table.js";
|
|
15
|
+
export type { TableColumn, TableSort } from "./table.js";
|
|
16
|
+
export { isoDate, parseIsoDate, addDays, addMonths, sameDay, monthGrid, calendarStop } from "./dates.js";
|
|
17
|
+
export { DEBOUNCE_MS, HostOwnedController, parseLocaleNumber } from "./inputs.js";
|
|
18
|
+
export type { HostOwnedControllerOptions, HostOwnedSend } from "./inputs.js";
|
|
19
|
+
export { MEDIA_CACHE_IDLE_MAX, acquireMedia, releaseMedia, mediaCacheKey, mediaCacheStats, clearMediaCache, openMediaSource, streamEntry, fetchStream, fetchLimited } from "./media.js";
|
|
20
|
+
export type { MediaKind, MediaCacheEntry, MediaSourcePlan } from "./media.js";
|
|
21
|
+
export { MAX_LINK_NESTING, MAX_LINK_DEST, MAX_BLOCK_NESTING, LIST_ITEM, linkAt, wholeImage, parseInline, parseList, parseMarkdown } from "./markdown.js";
|
|
22
|
+
export type { MarkdownInline, MarkdownBlock, MarkdownList, MarkdownListItem } from "./markdown.js";
|
|
23
|
+
export { FormRegistry, documentOrder, fieldErrorsVisible, validateOnDefault } from "./form.js";
|
|
24
|
+
export type { FormField, FormError, FormCheck } from "./form.js";
|
|
25
|
+
export { scrollParent, listViewport } from "./list.js";
|
|
26
|
+
export type { ListAxis } from "./list.js";
|
|
27
|
+
export { layoutSize, visualScale, elementScale } from "./primitives/measure.js";
|
|
28
|
+
export type { LayoutSize } from "./primitives/measure.js";
|
|
29
|
+
export { nextEnabledIndex, typeaheadStep, TYPEAHEAD_RESET_MS } from "./listbox.js";
|
|
30
|
+
export type { TypeaheadBuffer } from "./listbox.js";
|
|
31
|
+
export { PLACED, placedPartId } from "./parts.js";
|
|
32
|
+
export { share } from "./share.js";
|
|
33
|
+
export { voiceWaveAnimates, voiceWaveClock, voiceWaveFitChild, voiceWaveName } from "./primitives/voice-wave.js";
|
|
34
|
+
export { qrPaint, qrScanReporter, qrScanFormats, qrCornerPath, qrFeedColour, QR_CORNERS, QR_SCANNER, segmentedBadge, ButtonHold, HOLD_SLOP, withinSlop } from "./round5.js";
|
|
35
|
+
export type { QrPaint, QrScannerHost, QrCorner, HoldEvent, HoldRect } from "./round5.js";
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export declare const DEBOUNCE_MS = 150;
|
|
2
|
+
export type HostOwnedSend<T> = (value: T, revision: number, kind: `change` | `commit`) => void | Promise<void>;
|
|
3
|
+
export interface HostOwnedControllerOptions<T> {
|
|
4
|
+
/** The value the host holds when the field mounts. */
|
|
5
|
+
initial: T;
|
|
6
|
+
/** Sends an edit; a returned promise acknowledges the revision on settle. */
|
|
7
|
+
send: HostOwnedSend<T>;
|
|
8
|
+
/** Optional local write-through (the bound data model path). */
|
|
9
|
+
writeLocal?: (value: T) => void;
|
|
10
|
+
debounceMs?: number;
|
|
11
|
+
/** Called after every change of `value`, `pending` or `focused`. */
|
|
12
|
+
onChange?: () => void;
|
|
13
|
+
}
|
|
14
|
+
export declare class HostOwnedController<T> {
|
|
15
|
+
/** The field's value (the last edit, or the last adopted host push). */
|
|
16
|
+
value: T;
|
|
17
|
+
/** The newest revision sent or scheduled. */
|
|
18
|
+
revision: number;
|
|
19
|
+
/** True while a revision the host has not acknowledged exists. */
|
|
20
|
+
pending: boolean;
|
|
21
|
+
focused: boolean;
|
|
22
|
+
private acked;
|
|
23
|
+
private timer;
|
|
24
|
+
private live;
|
|
25
|
+
private send;
|
|
26
|
+
private writeLocal?;
|
|
27
|
+
private debounceMs;
|
|
28
|
+
private readonly onChange?;
|
|
29
|
+
constructor(options: HostOwnedControllerOptions<T>);
|
|
30
|
+
/** The latest callbacks (a re-render may hand new closures). */
|
|
31
|
+
configure(options: Pick<HostOwnedControllerOptions<T>, `send` | `writeLocal` | `debounceMs`>): void;
|
|
32
|
+
/** A local edit: bump the revision, write through, debounce a `change`. */
|
|
33
|
+
edit(next: T): void;
|
|
34
|
+
/** Flush the debounce and send a `commit`. */
|
|
35
|
+
commit(): void;
|
|
36
|
+
focus(): void;
|
|
37
|
+
/** Blur commits. */
|
|
38
|
+
blur(): void;
|
|
39
|
+
/** The host's push: adopted only when idle and fully acknowledged.
|
|
40
|
+
* Returns whether it was adopted. */
|
|
41
|
+
push(external: T): boolean;
|
|
42
|
+
/** (Re)attach after `dispose` (a remount). */
|
|
43
|
+
attach(): void;
|
|
44
|
+
/** Unmount: the pending debounce is dropped, acknowledgements no longer
|
|
45
|
+
* notify. */
|
|
46
|
+
dispose(): void;
|
|
47
|
+
private clearTimer;
|
|
48
|
+
private notify;
|
|
49
|
+
private ack;
|
|
50
|
+
private dispatch;
|
|
51
|
+
}
|
|
52
|
+
/** A typed number in the surface locale (its group and decimal separators
|
|
53
|
+
* AND its digits; ASCII digits are always accepted too) → the number, or
|
|
54
|
+
* null. */
|
|
55
|
+
export declare function parseLocaleNumber(text: string, locale: string): number | null;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ListAxis = `vertical` | `horizontal`;
|
|
2
|
+
/** The nearest ancestor that scrolls on `axis`: overflow auto/scroll AND a
|
|
3
|
+
* box shorter than its content (a content-sized `overflow: auto` box is not
|
|
4
|
+
* a viewport). Null = the document scrolls (the window). */
|
|
5
|
+
export declare function scrollParent(el: HTMLElement | null, axis?: ListAxis): HTMLElement | null;
|
|
6
|
+
/** Where the list's content starts relative to the viewport's start on the
|
|
7
|
+
* axis (the scroll offset in list coordinates) and the viewport length.
|
|
8
|
+
* `known` = the scroller already found (null = the window). NEW-82: both
|
|
9
|
+
* in the LIST's layout px: rect deltas are visual px (CSS zoom,
|
|
10
|
+
* transforms), so they divide by the list's scale; the scroller's
|
|
11
|
+
* client box is in its own layout px, so it multiplies by the scroller's. */
|
|
12
|
+
export declare function listViewport(el: HTMLElement, axis: ListAxis, rtl: boolean, known?: HTMLElement | null): {
|
|
13
|
+
scroll: number;
|
|
14
|
+
viewport: number;
|
|
15
|
+
scroller: HTMLElement | null;
|
|
16
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** The TYPE-AHEAD buffer resets after this pause (ms). */
|
|
2
|
+
export declare const TYPEAHEAD_RESET_MS = 700;
|
|
3
|
+
/** The next enabled index `delta` steps from `from` (wrapping), or -1. */
|
|
4
|
+
export declare function nextEnabledIndex(count: number, from: number, delta: number, isDisabled?: (index: number) => boolean): number;
|
|
5
|
+
export interface TypeaheadBuffer {
|
|
6
|
+
text: string;
|
|
7
|
+
at: number;
|
|
8
|
+
}
|
|
9
|
+
/** One printable key typed: the new buffer and the index it lands on (-1 =
|
|
10
|
+
* no label starts with the buffer; the active option stays). */
|
|
11
|
+
export declare function typeaheadStep(buffer: TypeaheadBuffer, key: string, now: number, active: number, count: number, isDisabled: (index: number) => boolean, labelOf: (index: number) => string): {
|
|
12
|
+
buffer: TypeaheadBuffer;
|
|
13
|
+
index: number;
|
|
14
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/** Link labels nest at most this deep (×4): a link inside 32 enclosing link
|
|
2
|
+
* labels is its text. */
|
|
3
|
+
export declare const MAX_LINK_NESTING = 32;
|
|
4
|
+
/** A link / image destination longer than this (UTF-16 units) is no link. */
|
|
5
|
+
export declare const MAX_LINK_DEST = 8192;
|
|
6
|
+
/** `[label](dest)` / `` starting at `s[at]` (the `[`): the label
|
|
7
|
+
* (brackets balanced), the destination (`<…>` or balanced parentheses, no
|
|
8
|
+
* whitespace) and the end index. An optional `"title"` is skipped. */
|
|
9
|
+
export declare function linkAt(s: string, at: number): {
|
|
10
|
+
label: string;
|
|
11
|
+
dest: string;
|
|
12
|
+
end: number;
|
|
13
|
+
} | null;
|
|
14
|
+
/** A paragraph that is exactly one `` → its alt + src (a BLOCK
|
|
15
|
+
* image, as every renderer paints it; an image inside running text is its
|
|
16
|
+
* alt text). */
|
|
17
|
+
export declare function wholeImage(text: string): {
|
|
18
|
+
alt: string;
|
|
19
|
+
src: string;
|
|
20
|
+
} | null;
|
|
21
|
+
/** An inline run's tree: text, code, strong/em (nested), strike, a link
|
|
22
|
+
* (raw `dest`, label nested). */
|
|
23
|
+
export type MarkdownInline = string | {
|
|
24
|
+
type: `code`;
|
|
25
|
+
text: string;
|
|
26
|
+
} | {
|
|
27
|
+
type: `strong`;
|
|
28
|
+
children: MarkdownInline[];
|
|
29
|
+
} | {
|
|
30
|
+
type: `em`;
|
|
31
|
+
children: MarkdownInline[];
|
|
32
|
+
} | {
|
|
33
|
+
type: `del`;
|
|
34
|
+
text: string;
|
|
35
|
+
} | {
|
|
36
|
+
type: `link`;
|
|
37
|
+
dest: string;
|
|
38
|
+
children: MarkdownInline[];
|
|
39
|
+
};
|
|
40
|
+
export type MarkdownBlock = {
|
|
41
|
+
type: `paragraph`;
|
|
42
|
+
children: MarkdownInline[];
|
|
43
|
+
}
|
|
44
|
+
/** A paragraph that is exactly one image. */
|
|
45
|
+
| {
|
|
46
|
+
type: `image`;
|
|
47
|
+
alt: string;
|
|
48
|
+
src: string;
|
|
49
|
+
} | {
|
|
50
|
+
type: `codeBlock`;
|
|
51
|
+
lang?: string;
|
|
52
|
+
text: string;
|
|
53
|
+
} | {
|
|
54
|
+
type: `heading`;
|
|
55
|
+
level: number;
|
|
56
|
+
children: MarkdownInline[];
|
|
57
|
+
} | {
|
|
58
|
+
type: `quote`;
|
|
59
|
+
children: MarkdownBlock[];
|
|
60
|
+
} | {
|
|
61
|
+
type: `list`;
|
|
62
|
+
list: MarkdownList;
|
|
63
|
+
} | {
|
|
64
|
+
type: `table`;
|
|
65
|
+
align: (`start` | `center` | `end` | undefined)[];
|
|
66
|
+
head: MarkdownInline[][];
|
|
67
|
+
rows: MarkdownInline[][][];
|
|
68
|
+
} | {
|
|
69
|
+
type: `rule`;
|
|
70
|
+
};
|
|
71
|
+
/** One inline run, linear in its length: the link geometry is precomputed
|
|
72
|
+
* (LinkScanner), the simple spans come off one global regex that never
|
|
73
|
+
* rescans, and link labels recurse at most MAX_LINK_NESTING deep. */
|
|
74
|
+
export declare function parseInline(text: string, depth?: number): MarkdownInline[];
|
|
75
|
+
export declare const LIST_ITEM: RegExp;
|
|
76
|
+
export interface MarkdownListItem {
|
|
77
|
+
/** The item's raw text (its inline markdown). */
|
|
78
|
+
text: string;
|
|
79
|
+
/** `text` parsed. */
|
|
80
|
+
content: MarkdownInline[];
|
|
81
|
+
/** A task item: done (`[x]`) or not (`[ ]`). */
|
|
82
|
+
task?: boolean;
|
|
83
|
+
children: MarkdownList[];
|
|
84
|
+
}
|
|
85
|
+
export interface MarkdownList {
|
|
86
|
+
indent: number;
|
|
87
|
+
ordered: boolean;
|
|
88
|
+
items: MarkdownListItem[];
|
|
89
|
+
}
|
|
90
|
+
/** Consecutive list item lines → a list tree: an item whose marker is
|
|
91
|
+
* indented 2+ columns past its list's nests under the previous item. */
|
|
92
|
+
export declare function parseList(lines: readonly string[]): MarkdownList;
|
|
93
|
+
/** Block quotes and lists nest at most this deep (deeper = text). */
|
|
94
|
+
export declare const MAX_BLOCK_NESTING = 32;
|
|
95
|
+
/** Markdown text → its block tree. */
|
|
96
|
+
export declare function parseMarkdown(text: string): MarkdownBlock[];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { AnyHostPlugin as HostPlugin } from "./host-types.js";
|
|
2
|
+
/** What a source feeds: an image (the limits hold) or a player stream. */
|
|
3
|
+
export type MediaKind = `image` | `stream`;
|
|
4
|
+
/** How many fetched media nobody shows stay cached (their blob urls live). */
|
|
5
|
+
export declare const MEDIA_CACHE_IDLE_MAX = 64;
|
|
6
|
+
export interface MediaCacheEntry {
|
|
7
|
+
promise: Promise<string>;
|
|
8
|
+
/** Set once the fetch resolved. */
|
|
9
|
+
url?: string;
|
|
10
|
+
/** Mounted consumers. */
|
|
11
|
+
refs: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function mediaCacheKey(url: string, headers: Record<string, string>): string;
|
|
14
|
+
export declare function acquireMedia(k: string, load: () => Promise<string>): MediaCacheEntry;
|
|
15
|
+
export declare function releaseMedia(k: string, e: MediaCacheEntry): void;
|
|
16
|
+
/** The cache's size (tests). */
|
|
17
|
+
export declare function mediaCacheStats(): {
|
|
18
|
+
entries: number;
|
|
19
|
+
inUse: number;
|
|
20
|
+
};
|
|
21
|
+
/** Drop every idle entry and revoke its url (tests, a host that logs out). */
|
|
22
|
+
export declare function clearMediaCache(): void;
|
|
23
|
+
/** One source, planned: `direct` = the url to use as is (no headers, or
|
|
24
|
+
* undefined when the policy denies it), `denied` = the policy refused a
|
|
25
|
+
* non-empty src, `key` = the cache identity of a FETCHED source ('' when
|
|
26
|
+
* direct), `open()` = start (or join) its load: the url promise and the
|
|
27
|
+
* release a consumer calls when it unmounts. */
|
|
28
|
+
export interface MediaSourcePlan {
|
|
29
|
+
fetched: boolean;
|
|
30
|
+
key: string;
|
|
31
|
+
direct: string | undefined;
|
|
32
|
+
denied: boolean;
|
|
33
|
+
open: () => {
|
|
34
|
+
promise: Promise<string>;
|
|
35
|
+
release: () => void;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export declare function openMediaSource(host: HostPlugin, src: string, kind?: MediaKind): MediaSourcePlan;
|
|
39
|
+
/** A host stream url (never cached here, never revoked: the host owns
|
|
40
|
+
* it), re-checked against the media policy. */
|
|
41
|
+
export declare function streamEntry(host: HostPlugin, req: {
|
|
42
|
+
url: string;
|
|
43
|
+
headers: Record<string, string>;
|
|
44
|
+
}): MediaCacheEntry;
|
|
45
|
+
/** A Video/Audio fetch (no `mediaStreamUrl`): the whole body into a blob
|
|
46
|
+
* under `maxBytes` (Content-Length up front, then as it streams) and
|
|
47
|
+
* `timeoutMs` for the WHOLE download (VAPP-107); no pixel check. */
|
|
48
|
+
export declare function fetchStream(url: string, headers: Record<string, string>, limits?: {
|
|
49
|
+
maxBytes: number;
|
|
50
|
+
timeoutMs: number;
|
|
51
|
+
}, allowed?: (url: string) => boolean): Promise<Blob>;
|
|
52
|
+
/** A fetch under `MEDIA_LIMITS`: the whole request within `timeoutMs`, the
|
|
53
|
+
* body (Content-Length up front, then as it streams) within `maxBytes`, an
|
|
54
|
+
* image's width × height × frames within `maxPixels` before any decode
|
|
55
|
+
* (`mediaImageWithinLimits`: SVG sizes count, an unreadable raster is
|
|
56
|
+
* refused; `image = false` skips that check: a stream's bytes are not
|
|
57
|
+
* an image). A redirected response's final url must pass `allowed` (the
|
|
58
|
+
* host's media policy) or the load fails before a byte is read. */
|
|
59
|
+
export declare function fetchLimited(url: string, headers: Record<string, string>, limits?: {
|
|
60
|
+
maxBytes: number;
|
|
61
|
+
timeoutMs: number;
|
|
62
|
+
maxPixels: number;
|
|
63
|
+
}, image?: boolean, allowed?: (url: string) => boolean): Promise<Blob>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const PLACED: Readonly<Record<string, readonly string[]>>;
|
|
2
|
+
/** The painted id of a SINGLE part (`<domId>.<part>`), or null when the
|
|
3
|
+
* component does not place it. */
|
|
4
|
+
export declare function placedPartId(component: string, part: string, domId: string): string | null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const ALERT_DIALOG_CLASSES: {
|
|
2
|
+
readonly overlay: "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:duration-fast data-[state=closed]:ease-accelerate data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:duration-standard data-[state=open]:ease-decelerate";
|
|
3
|
+
readonly content: "fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg motion-dialog sm:max-w-lg";
|
|
4
|
+
readonly header: "flex flex-col gap-2 text-center sm:text-left";
|
|
5
|
+
readonly footer: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end";
|
|
6
|
+
readonly title: "text-lg font-semibold";
|
|
7
|
+
readonly description: "text-sm text-muted-foreground";
|
|
8
|
+
readonly action: string;
|
|
9
|
+
readonly cancel: string;
|
|
10
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type VariantProps } from "class-variance-authority";
|
|
2
|
+
export declare const alertVariants: (props?: ({
|
|
3
|
+
variant?: "default" | "destructive" | null | undefined;
|
|
4
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
5
|
+
export type AlertVariantProps = VariantProps<typeof alertVariants>;
|
|
6
|
+
export declare const ALERT_CLASSES: {
|
|
7
|
+
readonly title: "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight";
|
|
8
|
+
readonly description: "col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed";
|
|
9
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const AVATAR_CLASSES: {
|
|
2
|
+
readonly root: "relative flex size-8 shrink-0 overflow-hidden rounded-full select-none";
|
|
3
|
+
readonly image: "aspect-square size-full";
|
|
4
|
+
readonly fallback: "flex size-full items-center justify-center rounded-full text-sm";
|
|
5
|
+
/** The fallback without a `userId`: the muted chrome. */
|
|
6
|
+
readonly fallbackMuted: "bg-muted text-muted-foreground";
|
|
7
|
+
};
|
|
8
|
+
export declare function avatarFallbackHue(userId: string | null | undefined): string | undefined;
|
|
9
|
+
/** The inline colours of a hued fallback. */
|
|
10
|
+
export declare function avatarFallbackColors(hue: string): {
|
|
11
|
+
backgroundColor: string;
|
|
12
|
+
color: string;
|
|
13
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type BadgeTone = `muted` | `primary`;
|
|
2
|
+
export declare const BADGE_CLASSES: {
|
|
3
|
+
readonly root: "pointer-events-none inline-flex h-4 min-w-4 shrink-0 items-center justify-center rounded-full px-1 text-[10px] leading-none font-semibold tabular-nums";
|
|
4
|
+
readonly tones: {
|
|
5
|
+
readonly primary: "bg-primary text-primary-foreground";
|
|
6
|
+
readonly muted: "bg-muted text-muted-foreground";
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
/** What the badge prints for `count` (zero and below render nothing). */
|
|
10
|
+
export declare function badgeLabel(count: number, max?: number): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const BREADCRUMB_CLASSES: {
|
|
2
|
+
readonly list: "flex list-none flex-wrap items-center gap-1.5 text-sm break-words text-muted-foreground sm:gap-2.5";
|
|
3
|
+
readonly item: "inline-flex items-center gap-1.5";
|
|
4
|
+
readonly link: "transition-colors hover:text-foreground";
|
|
5
|
+
readonly page: "font-normal text-foreground";
|
|
6
|
+
readonly separator: "[&>svg]:size-3.5";
|
|
7
|
+
readonly ellipsis: "flex size-9 items-center justify-center";
|
|
8
|
+
readonly ellipsisIcon: "size-4";
|
|
9
|
+
readonly srOnly: "sr-only";
|
|
10
|
+
};
|