@exponential-at/ui 0.0.0-stage → 0.1.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 +360 -2
- package/catalog/a11y.json +668 -0
- package/catalog/basic-map.json +104 -0
- package/catalog/code.json +58 -0
- package/catalog/core.catalog.json +4752 -0
- package/catalog/core.schema.json +22667 -0
- package/catalog/host.json +64 -0
- package/catalog/layout.json +20 -0
- package/catalog/limits.json +9 -0
- package/catalog/locale.json +48 -0
- package/catalog/macros.json +3417 -0
- package/catalog/recipes.json +61 -0
- package/catalog/strings.json +72 -0
- package/catalog/style.json +128 -0
- package/catalog/theme.schema.json +42543 -0
- package/catalog/tokens.json +47 -0
- package/conformance/README.md +217 -0
- package/conformance/baseline.ts +101 -0
- package/conformance/browser-page.ts +146 -0
- package/conformance/browser-suites.ts +683 -0
- package/conformance/compare.ts +201 -0
- package/conformance/dom.ts +96 -0
- package/conformance/dump.ts +163 -0
- package/conformance/fonts.json +154 -0
- package/conformance/manifest.json +224 -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/dist/chunks/index-98npjvsd.js +3940 -0
- package/dist/chunks/index-98npjvsd.js.map +27 -0
- package/dist/chunks/index-gwkt14w3.js +7314 -0
- package/dist/chunks/index-gwkt14w3.js.map +10 -0
- package/dist/chunks/index-njt7yzzm.js +134 -0
- package/dist/chunks/index-njt7yzzm.js.map +9 -0
- package/dist/chunks/index-we7va6v6.js +7984 -0
- package/dist/chunks/index-we7va6v6.js.map +15 -0
- package/dist/chunks/index-xrm6f7wc.js +2563 -0
- package/dist/chunks/index-xrm6f7wc.js.map +10 -0
- package/dist/conformance.js +182749 -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 +122 -0
- package/dist/host/index.js.map +9 -0
- package/dist/index.js +3213 -0
- package/dist/index.js.map +27 -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 +829 -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 +29 -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 +159 -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 +188 -0
- package/dist/types/src/host/decoders.d.ts +61 -0
- package/dist/types/src/host/index.d.ts +11 -0
- package/dist/types/src/host/package.d.ts +58 -0
- package/dist/types/src/host/policy.d.ts +105 -0
- package/dist/types/src/host/router.d.ts +34 -0
- package/dist/types/src/host/runtime.d.ts +205 -0
- package/dist/types/src/host/sources.d.ts +15 -0
- package/dist/types/src/host/transports.d.ts +109 -0
- package/dist/types/src/index.d.ts +63 -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/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 +73 -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 +314 -0
- package/dist/types/src/validate.d.ts +31 -0
- package/dist/types/src/web/base-css.d.ts +1 -0
- package/dist/types/src/web/box-css.d.ts +55 -0
- package/dist/types/src/web/coerce.d.ts +32 -0
- package/dist/types/src/web/data.d.ts +105 -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 +119 -0
- package/dist/types/src/web/index.d.ts +28 -0
- package/dist/types/src/web/inputs.d.ts +55 -0
- package/dist/types/src/web/list.d.ts +13 -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 +62 -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 +48 -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/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/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 +2303 -0
- package/dist/web/index.js.map +26 -0
- package/dist/web/primitives/index.js +1450 -0
- package/dist/web/primitives/index.js.map +57 -0
- package/docs/components.generated.json +6238 -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/themes.generated.json +3503 -0
- package/fixtures/animations.json +2890 -0
- package/fixtures/bench-list.json +58 -0
- package/fixtures/bind-time.json +30664 -0
- package/fixtures/catalog-basic-map.json +1692 -0
- package/fixtures/catalog-components.json +9323 -0
- package/fixtures/catalog-extension.json +620 -0
- package/fixtures/catalog-macros.json +36370 -0
- package/fixtures/code-tokens.json +1993 -0
- package/fixtures/conformance-baseline.json +55544 -0
- package/fixtures/conformance-cases.json +49 -0
- package/fixtures/conformance-known.json +2123 -0
- package/fixtures/control-geometry.json +4200 -0
- package/fixtures/dashboard.data.json +74 -0
- package/fixtures/dashboard.json +752 -0
- package/fixtures/demo-surface.json +47 -0
- package/fixtures/format.json +870 -0
- package/fixtures/host-policy.json +1067 -0
- package/fixtures/host-router.json +1152 -0
- package/fixtures/host-transport.json +590 -0
- package/fixtures/interactions-round1.json +773 -0
- package/fixtures/kitchen-sink.expanded.json +10844 -0
- package/fixtures/kitchen-sink.json +3049 -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/primitive-specimens.json +58 -0
- package/fixtures/prompt-budget.json +33 -0
- package/fixtures/resizable.json +714 -0
- package/fixtures/round4-contract.json +2985 -0
- package/fixtures/specimens.json +9832 -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 +1296 -0
- package/fixtures/theme-recipes.json +58600 -0
- package/fixtures/theme-resolved.json +23949 -0
- package/fixtures/toast-stack.json +215 -0
- package/fixtures/tree-guides.json +224 -0
- package/fixtures/virtual-list.json +733 -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 +2505 -0
- package/generated/core.runtime.json +3609 -0
- package/package.json +87 -4
- package/themes/exponential.recipes.json +49 -0
- package/themes/exponential.theme.json +755 -0
- package/themes/neutral.theme.json +5676 -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
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ComponentDef, ExtensionDef } from "./types.js";
|
|
2
|
+
/** The sections of the prompt, in print order (VAPP-108): an agent (or the
|
|
3
|
+
* host serving it) asks for the ones it needs. `index` = one line per
|
|
4
|
+
* component (name, group, description) instead of the full `components`
|
|
5
|
+
* blocks: the agent reads the index, then asks for `componentPrompt(name)`
|
|
6
|
+
* of the ones it will use. */
|
|
7
|
+
export type PromptSection = `rules` | `components` | `index` | `shapes` | `functions` | `style` | `extensions`;
|
|
8
|
+
export declare const PROMPT_SECTIONS: readonly PromptSection[];
|
|
9
|
+
/** What `catalogPrompt()` prints without `sections`. */
|
|
10
|
+
export declare const DEFAULT_SECTIONS: readonly PromptSection[];
|
|
11
|
+
export interface PromptOptions {
|
|
12
|
+
extensions?: readonly ExtensionDef[];
|
|
13
|
+
/** The core-lite subset (the app-shaped vocabulary: no overlays, media, Chart, data tables or the rarer controls). */
|
|
14
|
+
lite?: boolean;
|
|
15
|
+
/** Omit the per-prop lines (names + types only). */
|
|
16
|
+
terse?: boolean;
|
|
17
|
+
/** VAPP-108: which sections to print (default `DEFAULT_SECTIONS`, in that order whatever the order given). */
|
|
18
|
+
sections?: readonly PromptSection[];
|
|
19
|
+
/** VAPP-108: print only these components (full blocks) and the shapes they reach; `index` still lists every one. */
|
|
20
|
+
only?: readonly string[];
|
|
21
|
+
}
|
|
22
|
+
/** The rules every surface author (a model) must follow, shared by the core
|
|
23
|
+
* and the basic catalog. Kept to a few lines on purpose. */
|
|
24
|
+
export declare const PROMPT_RULES: readonly string[];
|
|
25
|
+
/** Props whose meaning is the same everywhere: described ONCE in the full
|
|
26
|
+
* prompt (the per-prop line then carries only name, marks and type). The
|
|
27
|
+
* catalog keeps every per-component description for the docs. */
|
|
28
|
+
export declare const COMMON_PROPS: Readonly<Record<string, string>>;
|
|
29
|
+
export declare function componentBlock(name: string, def: ComponentDef, enums: Record<string, readonly string[]>, terse: boolean): string;
|
|
30
|
+
/** Every catalog function as `name(arg:type,…)→returns` (round 4: the
|
|
31
|
+
* model sees the argument names, not just the function names). */
|
|
32
|
+
export declare function functionSignatures(): string[];
|
|
33
|
+
/** VAPP-108: one component's full block on demand (the per-component
|
|
34
|
+
* section an agent requests after reading the index), with the shapes its
|
|
35
|
+
* props reach. Unknown or hidden names give an empty string. */
|
|
36
|
+
export declare function componentPrompt(name: string, options?: Pick<PromptOptions, `extensions` | `terse`>): string;
|
|
37
|
+
/** VAPP-108: the index — every offered component on one line (name, group, kind, its sentence), grouped. */
|
|
38
|
+
export declare function catalogIndex(options?: Pick<PromptOptions, `extensions` | `lite`>): string[];
|
|
39
|
+
/** The system prompt for a surface author. */
|
|
40
|
+
export declare function catalogPrompt(options?: PromptOptions): string;
|
|
41
|
+
/** Characters per token the budget assumes (the same rule as the context
|
|
42
|
+
* layout's `charsPerToken`): an estimate, not a tokenizer. */
|
|
43
|
+
export declare const CHARS_PER_TOKEN = 4;
|
|
44
|
+
export declare function estimateTokens(text: string): number;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ExtensionDef, MacroDef } from "./types.js";
|
|
2
|
+
export declare const RECIPE_STATES: readonly string[];
|
|
3
|
+
export declare const RECIPE_KEYS: readonly string[];
|
|
4
|
+
export interface PartSpec {
|
|
5
|
+
parts: string[];
|
|
6
|
+
/** The prop names a `when` may use (besides `state`). */
|
|
7
|
+
props: string[];
|
|
8
|
+
}
|
|
9
|
+
/** A macro's parts and recipe props, read off its template. */
|
|
10
|
+
export declare function macroParts(def: MacroDef): PartSpec;
|
|
11
|
+
/** Every component (core + the given extensions) → its parts and `when`
|
|
12
|
+
* props. An extension's natives declare `recipe: {parts, props}` on their
|
|
13
|
+
* component def; without it a native gets `root` and its enum/boolean props. */
|
|
14
|
+
export declare function recipeParts(extensions?: readonly ExtensionDef[]): Record<string, PartSpec>;
|
|
15
|
+
/** The recipe query a NATIVE node answers to: its `when` props with the
|
|
16
|
+
* catalog defaults filled in (a macro part carries its own `recipe`). */
|
|
17
|
+
export declare function nativeRecipeProps(component: string, props: Record<string, unknown>, extensions?: readonly ExtensionDef[]): Record<string, unknown>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ChildTemplate, ExtensionDef, FlatComponent, NestedNode, ReduceIssue, UiNode, Visible, WireChildTemplate } from "./types.js";
|
|
2
|
+
/** The keys of a flat component that are not props (round 1 adds `visible`). */
|
|
3
|
+
export declare const RESERVED_KEYS: readonly string[];
|
|
4
|
+
export interface ReduceOptions {
|
|
5
|
+
/** The surface's catalog: the core, the lite subset, the basic catalog or an extension's id. */
|
|
6
|
+
catalogId: string;
|
|
7
|
+
extensions?: readonly ExtensionDef[];
|
|
8
|
+
/** The root component id (A2UI: `root`). */
|
|
9
|
+
rootId?: string;
|
|
10
|
+
/** Expand macros (default true); false keeps the pre-expansion tree. */
|
|
11
|
+
expand?: boolean;
|
|
12
|
+
/** Record prop validation issues (default true). */
|
|
13
|
+
validate?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface ReduceResult {
|
|
16
|
+
root: UiNode;
|
|
17
|
+
issues: ReduceIssue[];
|
|
18
|
+
/** Round 2 (docs/round-2-contract.md §4): the nodes a data `template`
|
|
19
|
+
* renders per item, by component id, LIFTED out of the tree (a template
|
|
20
|
+
* node listed as a child too never renders in place), validated and
|
|
21
|
+
* expanded like the root; in discovery order. Absent without templates. */
|
|
22
|
+
templates?: Record<string, UiNode>;
|
|
23
|
+
}
|
|
24
|
+
/** A `visible` value is a boolean or a dynamic value (a binding or a call). */
|
|
25
|
+
export declare function validVisible(value: unknown): value is Visible;
|
|
26
|
+
export declare function childTemplate(value: WireChildTemplate): ChildTemplate;
|
|
27
|
+
/** Reduce a flat component list. Children are resolved from the root down, so
|
|
28
|
+
* components nothing references (a basic Button's consumed Text child) do
|
|
29
|
+
* not appear. A missing or cyclic reference becomes an Unknown placeholder
|
|
30
|
+
* plus an issue. VAPP-103: an id placed a second time (two parents, or one
|
|
31
|
+
* parent twice) renders at its first place only (`id used twice`), a node
|
|
32
|
+
* deeper than `maxDepth` is an Unknown placeholder, and past
|
|
33
|
+
* `maxComponents` nodes the rest is dropped (catalog/limits.json). */
|
|
34
|
+
export declare function reduceSurface(components: readonly FlatComponent[], options: ReduceOptions): ReduceResult;
|
|
35
|
+
/** A component's slot list admits a name when it lists it or lists `*`. */
|
|
36
|
+
export declare function slotAllowed(slots: readonly string[] | undefined, name: string): boolean;
|
|
37
|
+
/** The nested authoring form → a normalized tree (same validation and
|
|
38
|
+
* expansion as reduceSurface). */
|
|
39
|
+
export declare function reduceNested(tree: NestedNode, options: Omit<ReduceOptions, `rootId`>): ReduceResult;
|
|
40
|
+
/** Pre-order ids of a tree, the painters' accessibility order. */
|
|
41
|
+
export declare function preorder(root: UiNode): string[];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** One panel's limits (Resizable `panels[i]`), percent. */
|
|
2
|
+
export interface PanelLimits {
|
|
3
|
+
min?: number;
|
|
4
|
+
max?: number;
|
|
5
|
+
/** Dragging below half its `min` collapses it to 0; Enter toggles. */
|
|
6
|
+
collapsible?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export { PANEL_MIN, RESIZE_HANDLE_HIT, RESIZE_STEP } from "./layout.js";
|
|
9
|
+
/** The sizes a group of `count` panels starts with: the valid given sizes
|
|
10
|
+
* (finite, ≥ 0), the missing ones sharing what is left of 100 (equal split
|
|
11
|
+
* when nothing is given), scaled to sum 100, then each clamped into its
|
|
12
|
+
* [min, max] (a collapsible panel may stay at 0) with the difference handed
|
|
13
|
+
* to the panels that still have room, in order. A `min` above 100 / count
|
|
14
|
+
* is lowered to it. */
|
|
15
|
+
export declare function normalizeSizes(sizes: readonly unknown[] | undefined, count: number, limits?: readonly PanelLimits[]): number[];
|
|
16
|
+
/** Move handle `handle` (between panels `handle` and `handle + 1`) by
|
|
17
|
+
* `delta` percentage points (positive = the first panel grows). Always
|
|
18
|
+
* computed from the sizes at the START of a drag (no drift). The move is
|
|
19
|
+
* clamped so both panels stay in their [min, max]; a collapsible panel
|
|
20
|
+
* dragged below half its min collapses to 0 (the other takes its space, if
|
|
21
|
+
* it can), and a collapsed one dragged past half its min reopens: at its
|
|
22
|
+
* min, or where the pointer is when that is further (clamped as above).
|
|
23
|
+
* Other panels never change. */
|
|
24
|
+
export declare function resizePanels(sizes: readonly number[], handle: number, delta: number, limits?: readonly PanelLimits[]): number[];
|
|
25
|
+
export type ResizeKey = `ArrowLeft` | `ArrowRight` | `ArrowUp` | `ArrowDown` | `Home` | `End` | `Enter`;
|
|
26
|
+
/** A key on a focused handle. Arrows move the HANDLE on screen by
|
|
27
|
+
* RESIZE_STEP (horizontal group: Left/Right — in rtl the first panel sits
|
|
28
|
+
* on the right, so ArrowRight shrinks it; vertical group: Up/Down); Home /
|
|
29
|
+
* End take the first panel to its min / max (as far as the second allows);
|
|
30
|
+
* Enter collapses the first panel when collapsible (else the second),
|
|
31
|
+
* reopening a collapsed one at its min. Other keys change nothing. */
|
|
32
|
+
export declare function keyboardResize(sizes: readonly number[], handle: number, key: ResizeKey | string, orientation: `horizontal` | `vertical`, direction?: `ltr` | `rtl`, limits?: readonly PanelLimits[]): number[];
|
|
33
|
+
/** Panel lengths in px on the main axis: the container minus every handle
|
|
34
|
+
* (`handleExtent` each, `$control.hairline`), shared by the sizes. */
|
|
35
|
+
export declare function panelExtents(sizes: readonly number[], container: number, handleExtent?: number): number[];
|
|
36
|
+
/** A pointer movement (px on the main axis, screen direction) as the
|
|
37
|
+
* percentage delta `resizePanels` takes (rtl horizontal groups flip it). */
|
|
38
|
+
export declare function dragDelta(px: number, container: number, panelCount: number, orientation: `horizontal` | `vertical`, direction?: `ltr` | `rtl`, handleExtent?: number): number;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ExtensionDef } from "./types.js";
|
|
2
|
+
type Json = Record<string, unknown>;
|
|
3
|
+
/** The core catalog's JSON Schema. */
|
|
4
|
+
export declare function coreSchema(iconNames: readonly string[]): Json;
|
|
5
|
+
/** An extension's JSON Schema: its own id, `extends` the core, its components. */
|
|
6
|
+
export declare function extensionSchema(ext: ExtensionDef, iconNames: readonly string[]): Json;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const DEFAULT_STRINGS: Readonly<Record<string, string>>;
|
|
2
|
+
export declare const STRING_IDS: readonly string[];
|
|
3
|
+
/** `$string.choose` → `choose`; null for any other value. */
|
|
4
|
+
export declare function parseStringRef(value: unknown): string | null;
|
|
5
|
+
/** True for a well-formed reference to a KNOWN id. */
|
|
6
|
+
export declare function isStringRef(value: unknown): boolean;
|
|
7
|
+
/** The host's overrides merged over the defaults. */
|
|
8
|
+
export declare function stringTable(overrides?: Readonly<Record<string, string>>): Record<string, string>;
|
|
9
|
+
/** `{name}` placeholders filled from `params`; unknown ones stay. */
|
|
10
|
+
export declare function formatString(template: string, params?: Record<string, unknown>): string;
|
|
11
|
+
/** A prop value with any `$string.<id>` reference replaced by the table's
|
|
12
|
+
* text (an unknown id resolves to the id itself); other values pass. */
|
|
13
|
+
export declare function resolveString(value: unknown, table?: Readonly<Record<string, string>>): unknown;
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
export declare const STYLE_KEYS: readonly string[];
|
|
2
|
+
export declare const STYLE_LAYOUT_KEYS: readonly string[];
|
|
3
|
+
export declare const STYLE_VISUAL_KEYS: readonly string[];
|
|
4
|
+
/** The visual keys that move layout (`borderWidth` and the four sides). */
|
|
5
|
+
export declare const STYLE_LAYOUT_EFFECT_KEYS: readonly string[];
|
|
6
|
+
export declare const STYLE_MEDIA: RegExp;
|
|
7
|
+
export declare const STYLE_TRANSFORM: RegExp;
|
|
8
|
+
/** The state keys in the order they apply (the last wins). */
|
|
9
|
+
export declare const STYLE_STATES: readonly string[];
|
|
10
|
+
export declare const STYLE_MEDIA_PATTERN: string;
|
|
11
|
+
export declare const STYLE_TRANSFORM_PATTERN: string;
|
|
12
|
+
type Len = number | `${number}%` | `${number}px` | `auto` | `$${string}`;
|
|
13
|
+
type Color = `$color.${string}`;
|
|
14
|
+
type Align = `flex-start` | `flex-end` | `start` | `end` | `center` | `stretch` | `baseline`;
|
|
15
|
+
type Distribute = Align | `space-between` | `space-around` | `space-evenly`;
|
|
16
|
+
type Overflow = `visible` | `hidden` | `clip` | `scroll` | `auto`;
|
|
17
|
+
/** A gradient painted over `backgroundColor`: CSS angle (0 = up, 90 = right)
|
|
18
|
+
* and colour stops at 0..1 offsets. */
|
|
19
|
+
export interface Gradient {
|
|
20
|
+
angle: number;
|
|
21
|
+
stops: {
|
|
22
|
+
color: Color;
|
|
23
|
+
offset: number;
|
|
24
|
+
}[];
|
|
25
|
+
}
|
|
26
|
+
/** Typed keys = editor autocomplete + a compile error for anything else. */
|
|
27
|
+
export interface StyleProps {
|
|
28
|
+
display?: `flex` | `grid` | `block` | `none`;
|
|
29
|
+
flexDirection?: `row` | `column` | `row-reverse` | `column-reverse`;
|
|
30
|
+
flexWrap?: `nowrap` | `wrap` | `wrap-reverse`;
|
|
31
|
+
justifyContent?: Distribute;
|
|
32
|
+
alignItems?: Align;
|
|
33
|
+
alignContent?: Distribute;
|
|
34
|
+
alignSelf?: Align;
|
|
35
|
+
justifySelf?: Align;
|
|
36
|
+
flexGrow?: number;
|
|
37
|
+
flexShrink?: number;
|
|
38
|
+
flexBasis?: Len;
|
|
39
|
+
gap?: Len;
|
|
40
|
+
rowGap?: Len;
|
|
41
|
+
columnGap?: Len;
|
|
42
|
+
direction?: `ltr` | `rtl`;
|
|
43
|
+
overflow?: Overflow;
|
|
44
|
+
overflowX?: Overflow;
|
|
45
|
+
overflowY?: Overflow;
|
|
46
|
+
width?: Len;
|
|
47
|
+
height?: Len;
|
|
48
|
+
minWidth?: Len;
|
|
49
|
+
minHeight?: Len;
|
|
50
|
+
maxWidth?: Len;
|
|
51
|
+
maxHeight?: Len;
|
|
52
|
+
aspectRatio?: number | `${number}/${number}`;
|
|
53
|
+
position?: `relative` | `absolute` | `sticky`;
|
|
54
|
+
top?: Len;
|
|
55
|
+
right?: Len;
|
|
56
|
+
bottom?: Len;
|
|
57
|
+
left?: Len;
|
|
58
|
+
inset?: Len;
|
|
59
|
+
insetInlineStart?: Len;
|
|
60
|
+
insetInlineEnd?: Len;
|
|
61
|
+
insetBlockStart?: Len;
|
|
62
|
+
insetBlockEnd?: Len;
|
|
63
|
+
padding?: Len;
|
|
64
|
+
paddingTop?: Len;
|
|
65
|
+
paddingRight?: Len;
|
|
66
|
+
paddingBottom?: Len;
|
|
67
|
+
paddingLeft?: Len;
|
|
68
|
+
paddingHorizontal?: Len;
|
|
69
|
+
paddingVertical?: Len;
|
|
70
|
+
paddingInlineStart?: Len;
|
|
71
|
+
paddingInlineEnd?: Len;
|
|
72
|
+
margin?: Len;
|
|
73
|
+
marginTop?: Len;
|
|
74
|
+
marginRight?: Len;
|
|
75
|
+
marginBottom?: Len;
|
|
76
|
+
marginLeft?: Len;
|
|
77
|
+
marginHorizontal?: Len;
|
|
78
|
+
marginVertical?: Len;
|
|
79
|
+
marginInlineStart?: Len;
|
|
80
|
+
marginInlineEnd?: Len;
|
|
81
|
+
/** Track list: px, %, fr, auto, min-content, max-content, minmax(a, b), repeat(n, …). */
|
|
82
|
+
gridTemplateColumns?: string;
|
|
83
|
+
gridTemplateRows?: string;
|
|
84
|
+
/** One string per row (`["nav main", "nav footer"]`). */
|
|
85
|
+
gridTemplateAreas?: ReadonlyArray<string>;
|
|
86
|
+
gridArea?: string;
|
|
87
|
+
gridColumn?: string;
|
|
88
|
+
gridRow?: string;
|
|
89
|
+
backgroundColor?: Color;
|
|
90
|
+
backgroundGradient?: Gradient;
|
|
91
|
+
color?: Color;
|
|
92
|
+
borderWidth?: number | `$border.${string}`;
|
|
93
|
+
borderTopWidth?: number | `$border.${string}`;
|
|
94
|
+
borderRightWidth?: number | `$border.${string}`;
|
|
95
|
+
borderBottomWidth?: number | `$border.${string}`;
|
|
96
|
+
borderLeftWidth?: number | `$border.${string}`;
|
|
97
|
+
borderColor?: Color;
|
|
98
|
+
borderStyle?: `solid` | `dashed` | `dotted`;
|
|
99
|
+
borderRadius?: Len;
|
|
100
|
+
borderTopLeftRadius?: Len;
|
|
101
|
+
borderTopRightRadius?: Len;
|
|
102
|
+
borderBottomRightRadius?: Len;
|
|
103
|
+
borderBottomLeftRadius?: Len;
|
|
104
|
+
opacity?: number | `$opacity.${string}`;
|
|
105
|
+
boxShadow?: `$shadow.${string}`;
|
|
106
|
+
fontSize?: Len;
|
|
107
|
+
fontWeight?: 300 | 400 | 500 | 600 | 700 | 800;
|
|
108
|
+
lineHeight?: Len;
|
|
109
|
+
letterSpacing?: Len;
|
|
110
|
+
textAlign?: `left` | `right` | `center` | `start` | `end` | `justify`;
|
|
111
|
+
textDecoration?: `none` | `underline` | `line-through`;
|
|
112
|
+
textTransform?: `none` | `uppercase` | `lowercase` | `capitalize`;
|
|
113
|
+
fontStyle?: `normal` | `italic`;
|
|
114
|
+
fontFamily?: `$type.family.${string}`;
|
|
115
|
+
transition?: `$motion.${string}`;
|
|
116
|
+
transitionEasing?: `$ease.${string}`;
|
|
117
|
+
/** `translate(Xpx, Ypx) scale(N) rotate(Ndeg)`, paint-only. */
|
|
118
|
+
transform?: string;
|
|
119
|
+
visibility?: `visible` | `hidden`;
|
|
120
|
+
pointerEvents?: `auto` | `none`;
|
|
121
|
+
userSelect?: `auto` | `none` | `text`;
|
|
122
|
+
cursor?: `auto` | `default` | `pointer` | `text` | `not-allowed` | `grab` | `grabbing` | `move` | `col-resize` | `row-resize`;
|
|
123
|
+
/** Round 2: `$blur.<name>`; blurs what is behind the box. */
|
|
124
|
+
backdropBlur?: `$blur.${string}`;
|
|
125
|
+
/** Round 2: a keyframe set (style.json `animations`). */
|
|
126
|
+
animation?: `pulse` | `spin` | `fade-in` | `slide-in-up` | `slide-in-down` | `slide-in-left` | `slide-in-right` | `shimmer`;
|
|
127
|
+
/** Round 2: `$motion.<name>` instead of the animation's own token. */
|
|
128
|
+
animationDuration?: `$motion.${string}`;
|
|
129
|
+
}
|
|
130
|
+
export type MediaKey = `@media (${string})`;
|
|
131
|
+
export type StateKey = `:hover` | `:focus-visible` | `:pressed`;
|
|
132
|
+
/** A style = base props + media condition blocks + state blocks, one level. */
|
|
133
|
+
export type Style = StyleProps & {
|
|
134
|
+
[K in MediaKey]?: StyleProps;
|
|
135
|
+
} & {
|
|
136
|
+
[K in StateKey]?: StyleProps;
|
|
137
|
+
};
|
|
138
|
+
export interface StyleIssue {
|
|
139
|
+
path: string;
|
|
140
|
+
message: string;
|
|
141
|
+
}
|
|
142
|
+
/** The enum a style key takes (`borderStyle` → solid|dashed|dotted), if any. */
|
|
143
|
+
export declare function styleKeyEnum(key: string): readonly (string | number)[] | undefined;
|
|
144
|
+
/** The value type a style key takes (`length`, `color`, `token`, …). */
|
|
145
|
+
export declare function styleKeyType(key: string): string | undefined;
|
|
146
|
+
/** A `@media` or state condition key. */
|
|
147
|
+
export declare function isConditionKey(key: string): boolean;
|
|
148
|
+
/** Every rule the client resolver relies on: whitelisted keys, well-typed
|
|
149
|
+
* values, conditions one level deep (round 2: `direction` on any node). */
|
|
150
|
+
export declare function validateStyle(style: unknown, options?: {
|
|
151
|
+
path?: string;
|
|
152
|
+
root?: boolean;
|
|
153
|
+
}): StyleIssue[];
|
|
154
|
+
/** Identity + validation, frozen so a render cannot mutate a shared style.
|
|
155
|
+
* `Record<K, Style>` (not a generic) keeps the excess-property check on the
|
|
156
|
+
* literal, so an unknown key is a compile error too. */
|
|
157
|
+
export declare function create<K extends string>(styles: Record<K, Style>): Readonly<Record<K, Style>>;
|
|
158
|
+
type Falsy = false | null | undefined | 0 | ``;
|
|
159
|
+
/** Merge in order (last wins, StyleX semantics). Condition blocks merge KEY
|
|
160
|
+
* BY KEY with the same rule, and stay nested: the output is exactly what the
|
|
161
|
+
* wire carries (plain JSON) and what the client resolver reads. */
|
|
162
|
+
export declare function props(...styles: ReadonlyArray<Style | Falsy | ReadonlyArray<Style | Falsy>>): Style;
|
|
163
|
+
/** What a client knows when it flattens a style: the SURFACE box, the
|
|
164
|
+
* platform's pointer and motion preference, the node's interaction states
|
|
165
|
+
* and the theme's breakpoint values (px). */
|
|
166
|
+
export interface ConditionContext {
|
|
167
|
+
width: number;
|
|
168
|
+
height?: number;
|
|
169
|
+
/** A hover-capable pointer (mouse, trackpad); false on touch. */
|
|
170
|
+
hover?: boolean;
|
|
171
|
+
/** The platform asks for reduced motion. */
|
|
172
|
+
reducedMotion?: boolean;
|
|
173
|
+
/** The node's active states, as the state keys without the colon
|
|
174
|
+
* (`hover`, `focus-visible`, `pressed`). */
|
|
175
|
+
states?: readonly string[];
|
|
176
|
+
/** `$breakpoint.<name>` → px; a block naming an unknown token never matches. */
|
|
177
|
+
breakpoints?: Record<string, number>;
|
|
178
|
+
}
|
|
179
|
+
export interface MediaCondition {
|
|
180
|
+
feature: `min-width` | `max-width` | `min-height` | `max-height` | `orientation` | `hover` | `prefers-reduced-motion`;
|
|
181
|
+
/** The px value or the `$breakpoint.<name>` token for the size features;
|
|
182
|
+
* the keyword for the others. */
|
|
183
|
+
value: string;
|
|
184
|
+
}
|
|
185
|
+
/** `"@media (min-width: $breakpoint.md)"` → `{feature, value}`; null when the
|
|
186
|
+
* key is not a media condition of the grammar. */
|
|
187
|
+
export declare function parseMediaCondition(key: string): MediaCondition | null;
|
|
188
|
+
/** Does a media condition hold for the context? `min-*` = size >= N,
|
|
189
|
+
* `max-*` = size < N, orientation portrait = height >= width (landscape
|
|
190
|
+
* when the height is unknown). */
|
|
191
|
+
export declare function mediaMatches(condition: MediaCondition, ctx: ConditionContext): boolean;
|
|
192
|
+
/** Flatten a style for one pass: the base keys, then every matching `@media`
|
|
193
|
+
* block in source order, then the matching state blocks in STYLE_STATES
|
|
194
|
+
* order. Token values pass through untouched (the theme resolves them). */
|
|
195
|
+
export declare function resolveConditions(style: Record<string, unknown>, ctx: ConditionContext): Record<string, unknown>;
|
|
196
|
+
/** The breakpoint a surface of this width is in: the LAST `$breakpoint`
|
|
197
|
+
* name (tokens.json order, ascending) whose px is <= width; null below the
|
|
198
|
+
* first (= `base`). A native's responsive prop takes
|
|
199
|
+
* `responsiveAt(value, activeBreakpoint(width, theme.tokens.breakpoint))`. */
|
|
200
|
+
export declare function activeBreakpoint(width: number, breakpoints: Record<string, number>): string | null;
|
|
201
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const TEXT_SHIMMER: {
|
|
2
|
+
$comment: string;
|
|
3
|
+
durationMs: number;
|
|
4
|
+
angleDeg: number;
|
|
5
|
+
spreadPx: number;
|
|
6
|
+
highlightLightnessMin: number;
|
|
7
|
+
highlightLightnessBoost: number;
|
|
8
|
+
highlightAlphaBoost: number;
|
|
9
|
+
lightAlphaFactor: number;
|
|
10
|
+
};
|
|
11
|
+
export interface TextShimmer {
|
|
12
|
+
/** The text colour (`#rrggbb[aa]`). */
|
|
13
|
+
base: string;
|
|
14
|
+
/** The band's centre. */
|
|
15
|
+
highlight: string;
|
|
16
|
+
/** The 50% OKLab mix at ± spread/2. */
|
|
17
|
+
mid: string;
|
|
18
|
+
durationMs: number;
|
|
19
|
+
angleDeg: number;
|
|
20
|
+
spreadPx: number;
|
|
21
|
+
}
|
|
22
|
+
/** The shimmer colours for a text colour (`#rrggbb[aa]`); `dark` = the
|
|
23
|
+
* surface's dark mode. An unparsable colour shimmers from black. */
|
|
24
|
+
export declare function textShimmer(color: string, dark: boolean): TextShimmer;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/** `#rrggbb` or `#rrggbbaa`, lowercase. The only colour form a theme carries
|
|
2
|
+
* (the builder converts oklch/hsl/rgb on import, `src/color.ts`). */
|
|
3
|
+
export type HexColor = `#${string}`;
|
|
4
|
+
export interface Shadow {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
blur: number;
|
|
8
|
+
spread: number;
|
|
9
|
+
color: HexColor;
|
|
10
|
+
}
|
|
11
|
+
/** `cubic-bezier(x1, y1, x2, y2)` control points, P0 = (0,0) and P3 = (1,1)
|
|
12
|
+
* implicit — the one form web, Compose, SwiftUI and gpui all accept. */
|
|
13
|
+
export type Easing = [number, number, number, number];
|
|
14
|
+
/** The per-mode values: colours and shadows (shadows differ in the dark). */
|
|
15
|
+
export interface ThemeMode {
|
|
16
|
+
color: Record<string, HexColor>;
|
|
17
|
+
shadow: Record<string, Shadow[]>;
|
|
18
|
+
}
|
|
19
|
+
export type ModeName = `light` | `dark`;
|
|
20
|
+
/** What a host asks for: a mode, or `system` = the platform's preference. */
|
|
21
|
+
export type ModeSetting = ModeName | `system`;
|
|
22
|
+
/** The surface density; `default` = the tokens as written. */
|
|
23
|
+
export type Density = `compact` | `default` | `comfortable`;
|
|
24
|
+
export interface ThemeTokens {
|
|
25
|
+
spacing: Record<string, number>;
|
|
26
|
+
radius: Record<string, number>;
|
|
27
|
+
type: {
|
|
28
|
+
size: Record<string, number>;
|
|
29
|
+
lineHeight: Record<string, number>;
|
|
30
|
+
weight: Record<string, number>;
|
|
31
|
+
/** Family NAMES (`Inter`); `fonts` describes how the host registers them. */
|
|
32
|
+
family: Record<string, string>;
|
|
33
|
+
};
|
|
34
|
+
control: Record<string, number>;
|
|
35
|
+
shadow?: never;
|
|
36
|
+
opacity: Record<string, number>;
|
|
37
|
+
border: Record<string, number>;
|
|
38
|
+
/** Milliseconds. */
|
|
39
|
+
motion: Record<string, number>;
|
|
40
|
+
/** Surface widths in px the style conditions may name (`$breakpoint.md`). */
|
|
41
|
+
breakpoint: Record<string, number>;
|
|
42
|
+
ease: Record<string, Easing>;
|
|
43
|
+
/** Multipliers over `control` and `spacing` for the non-default densities. */
|
|
44
|
+
density: Record<string, number>;
|
|
45
|
+
/** Round 2: backdrop blur radii in px (`backdropBlur: $blur.md`). */
|
|
46
|
+
blur: Record<string, number>;
|
|
47
|
+
/** EXP-1259: the motion scale multipliers painters read (`press`, `popoverFrom`). */
|
|
48
|
+
scale: Record<string, number>;
|
|
49
|
+
}
|
|
50
|
+
/** How a host registers a family the theme names: the files are the host's
|
|
51
|
+
* (per platform); the theme only says what to fall back to. */
|
|
52
|
+
export interface FontSpec {
|
|
53
|
+
fallback?: string;
|
|
54
|
+
weights?: number[];
|
|
55
|
+
/** `system` = the platform's own family of that kind, nothing to load. */
|
|
56
|
+
source?: `system` | `host`;
|
|
57
|
+
}
|
|
58
|
+
/** The values a recipe style may set (catalog/recipes.json `keys`): the
|
|
59
|
+
* whitelisted subset of the Box visual keys, token references allowed. */
|
|
60
|
+
export interface RecipeStyle {
|
|
61
|
+
backgroundColor?: string;
|
|
62
|
+
color?: string;
|
|
63
|
+
borderColor?: string;
|
|
64
|
+
borderWidth?: number | string;
|
|
65
|
+
borderTopWidth?: number | string;
|
|
66
|
+
borderRightWidth?: number | string;
|
|
67
|
+
borderBottomWidth?: number | string;
|
|
68
|
+
borderLeftWidth?: number | string;
|
|
69
|
+
borderRadius?: number | string;
|
|
70
|
+
borderStyle?: string;
|
|
71
|
+
padding?: number | string;
|
|
72
|
+
paddingHorizontal?: number | string;
|
|
73
|
+
paddingVertical?: number | string;
|
|
74
|
+
gap?: number | string;
|
|
75
|
+
width?: number | string;
|
|
76
|
+
height?: number | string;
|
|
77
|
+
minWidth?: number | string;
|
|
78
|
+
minHeight?: number | string;
|
|
79
|
+
fontSize?: number | string;
|
|
80
|
+
fontWeight?: number | string;
|
|
81
|
+
lineHeight?: number | string;
|
|
82
|
+
fontFamily?: string;
|
|
83
|
+
letterSpacing?: number;
|
|
84
|
+
textDecoration?: string;
|
|
85
|
+
textTransform?: string;
|
|
86
|
+
fontStyle?: string;
|
|
87
|
+
boxShadow?: string;
|
|
88
|
+
opacity?: number | string;
|
|
89
|
+
/** `$motion.<name>`: the duration this part's changes animate with. */
|
|
90
|
+
transition?: string;
|
|
91
|
+
/** `$ease.<name>`. */
|
|
92
|
+
transitionEasing?: string;
|
|
93
|
+
/** `translate(…) scale(…) rotate(…)`, paint-only. */
|
|
94
|
+
transform?: string;
|
|
95
|
+
/** Round 2: `$blur.<name>`: blur what is behind the part. */
|
|
96
|
+
backdropBlur?: string;
|
|
97
|
+
/** Round 2: a keyframe set of catalog/style.json `animations`. */
|
|
98
|
+
animation?: string;
|
|
99
|
+
/** The painter may use the platform's own control for this part. */
|
|
100
|
+
native?: boolean;
|
|
101
|
+
}
|
|
102
|
+
export type RecipeWhenValue = string | number | boolean | (string | number | boolean)[];
|
|
103
|
+
/** One rule: applies when every `when` entry matches (`state` = every listed
|
|
104
|
+
* state is active; any other key = the recipe prop equals the value or is
|
|
105
|
+
* in the list). Rules merge by specificity, ties in order, later wins; a
|
|
106
|
+
* child theme's rules come after its parent's. No `when` = the part's base. */
|
|
107
|
+
export interface RecipeRule {
|
|
108
|
+
when?: Record<string, RecipeWhenValue>;
|
|
109
|
+
style: RecipeStyle;
|
|
110
|
+
}
|
|
111
|
+
/** Component → part → rules. */
|
|
112
|
+
export type ThemeRecipes = Record<string, Record<string, RecipeRule[]>>;
|
|
113
|
+
/** The theme FILE. With `extends`, every section is optional and overrides
|
|
114
|
+
* the parent's; without it, every token name needs a value. */
|
|
115
|
+
export interface ThemeSource {
|
|
116
|
+
/** Required: `THEME_SCHEMA_ID` (round 4: a loader refuses any other). */
|
|
117
|
+
$schema: string;
|
|
118
|
+
$comment?: string;
|
|
119
|
+
id: string;
|
|
120
|
+
name: string;
|
|
121
|
+
extends?: string;
|
|
122
|
+
modes?: Partial<Record<ModeName, Partial<ThemeMode>>>;
|
|
123
|
+
/** Round 1: PARTIAL colour/shadow overlays a renderer applies over the
|
|
124
|
+
* mode when the platform asks for high contrast (`applyContrast`). */
|
|
125
|
+
contrast?: Partial<Record<ModeName, Partial<ThemeMode>>>;
|
|
126
|
+
tokens?: Partial<Omit<ThemeTokens, `type`>> & {
|
|
127
|
+
type?: Partial<ThemeTokens[`type`]>;
|
|
128
|
+
};
|
|
129
|
+
fonts?: Record<string, FontSpec>;
|
|
130
|
+
recipes?: ThemeRecipes;
|
|
131
|
+
}
|
|
132
|
+
/** What a painter receives: complete, flat, `extends` gone. Recipes keep
|
|
133
|
+
* their token references (colours depend on the mode); `resolveRecipe`
|
|
134
|
+
* turns a part's rules into concrete values for one mode. */
|
|
135
|
+
export interface ResolvedTheme {
|
|
136
|
+
id: string;
|
|
137
|
+
name: string;
|
|
138
|
+
/** The chain this theme was built from, root first. */
|
|
139
|
+
chain: string[];
|
|
140
|
+
modes: Record<ModeName, ThemeMode>;
|
|
141
|
+
/** The high-contrast overlays per mode (partial tables, may be empty). */
|
|
142
|
+
contrast: Record<ModeName, ThemeMode>;
|
|
143
|
+
tokens: ThemeTokens;
|
|
144
|
+
fonts: Record<string, FontSpec>;
|
|
145
|
+
recipes: ThemeRecipes;
|
|
146
|
+
}
|
|
147
|
+
/** The question a painter asks: which part of which component, with which
|
|
148
|
+
* recipe props and which interaction states. */
|
|
149
|
+
export interface RecipeQuery {
|
|
150
|
+
component: string;
|
|
151
|
+
part: string;
|
|
152
|
+
props?: Record<string, unknown>;
|
|
153
|
+
states?: readonly string[];
|
|
154
|
+
}
|
|
155
|
+
/** A recipe's concrete values for one mode: colours as hex, lengths as
|
|
156
|
+
* numbers, shadows as lists, families as names, easings as 4 numbers. */
|
|
157
|
+
export type ResolvedValue = number | string | boolean | Shadow[] | Easing;
|
|
158
|
+
export type ResolvedStyle = Record<string, ResolvedValue>;
|
|
159
|
+
export interface ThemeIssue {
|
|
160
|
+
path: string;
|
|
161
|
+
message: string;
|
|
162
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { ExtensionDef, UiNode } from "./types.js";
|
|
2
|
+
import type { Density, Easing, ModeName, ModeSetting, RecipeQuery, RecipeRule, RecipeStyle, ResolvedStyle, ResolvedTheme, ResolvedValue, Shadow, ThemeIssue, ThemeMode, ThemeRecipes, ThemeSource, ThemeTokens } from "./theme-types.js";
|
|
3
|
+
export declare const MODES: readonly ModeName[];
|
|
4
|
+
export declare const DENSITIES: readonly Density[];
|
|
5
|
+
export declare const THEME_SCHEMA_ID = "https://ui.exponential.at/schemas/theme/v1.json";
|
|
6
|
+
export declare function isFontText(value: unknown): value is string;
|
|
7
|
+
export declare class ThemeError extends Error {
|
|
8
|
+
readonly issues: ThemeIssue[];
|
|
9
|
+
constructor(id: string, issues: ThemeIssue[]);
|
|
10
|
+
}
|
|
11
|
+
export interface ThemeOptions {
|
|
12
|
+
/** Themes an `extends` may name (sources or already resolved). */
|
|
13
|
+
themes?: readonly (ThemeSource | ResolvedTheme)[];
|
|
14
|
+
extensions?: readonly ExtensionDef[];
|
|
15
|
+
}
|
|
16
|
+
/** Every problem in ONE theme file, each with a path and a readable
|
|
17
|
+
* message. Never throws: a non-object is one issue. */
|
|
18
|
+
export declare function validateTheme(source: unknown, options?: ThemeOptions): ThemeIssue[];
|
|
19
|
+
/** Validate + flatten, returning issues instead of throwing. */
|
|
20
|
+
export declare function tryLoadTheme(source: unknown, options?: ThemeOptions): {
|
|
21
|
+
theme: ResolvedTheme | null;
|
|
22
|
+
issues: ThemeIssue[];
|
|
23
|
+
};
|
|
24
|
+
/** A theme file → the flat theme a painter uses. Throws `ThemeError` with
|
|
25
|
+
* every issue listed, never anything else. */
|
|
26
|
+
export declare function loadTheme(source: unknown, options?: ThemeOptions): ResolvedTheme;
|
|
27
|
+
/** `system` → what the platform prefers; a mode stays itself. */
|
|
28
|
+
export declare function resolveMode(setting: ModeSetting, systemPrefersDark: boolean): ModeName;
|
|
29
|
+
/** The theme a surface of this density runs with: `control` and `spacing`
|
|
30
|
+
* scaled by the theme's `$density.<name>` multiplier and rounded to whole
|
|
31
|
+
* px; `default` returns the theme itself. Done once per surface, so every
|
|
32
|
+
* resolver and fixture stays density-agnostic. */
|
|
33
|
+
export declare function applyDensity(theme: ResolvedTheme, density: Density): ResolvedTheme;
|
|
34
|
+
/** The theme with its high-contrast overlays merged into the modes (the
|
|
35
|
+
* platform asked for more contrast). A theme without overlays is unchanged. */
|
|
36
|
+
export declare function applyContrast(theme: ResolvedTheme): ResolvedTheme;
|
|
37
|
+
/** `$color.primary` in `dark` → `#e5e5e5`; `$spacing.md` → 12; `$shadow.sm`
|
|
38
|
+
* → the layers; `$type.family.sans` → `Inter`; `$ease.standard` → the four
|
|
39
|
+
* control points. Undefined when not a token. */
|
|
40
|
+
export declare function resolveToken(theme: ResolvedTheme, ref: unknown, mode: ModeName): ResolvedValue | undefined;
|
|
41
|
+
/** A media key with its `$breakpoint.<name>` replaced by the theme's px. */
|
|
42
|
+
export declare function resolveConditionKey(theme: ResolvedTheme, key: string): string;
|
|
43
|
+
/** Every token reference in a style object replaced by its value for the
|
|
44
|
+
* mode (nested condition blocks, gradients and arrays included, and the
|
|
45
|
+
* `$breakpoint` tokens inside media keys); other values pass through. */
|
|
46
|
+
export declare function resolveStyleValues<T extends Record<string, unknown>>(theme: ResolvedTheme, style: T, mode: ModeName): T;
|
|
47
|
+
/** How specific a rule is: one point per `when` condition (a `state` list
|
|
48
|
+
* counts each state). VAPP-90: rules merge in SPECIFICITY order, like the
|
|
49
|
+
* CSS the web renderer compiles them to — a base rule (no `when`) never
|
|
50
|
+
* shadows a `checked`/`focus`/`variant` rule that sits before it, which is
|
|
51
|
+
* what a child theme's appended base override used to do under plain
|
|
52
|
+
* source order. Ties keep source order (later wins). */
|
|
53
|
+
export declare function ruleSpecificity(rule: RecipeRule): number;
|
|
54
|
+
/** The matching rules' styles merged by specificity (token refs kept). */
|
|
55
|
+
export declare function recipeStyle(theme: ResolvedTheme, query: RecipeQuery): RecipeStyle;
|
|
56
|
+
/** A part's concrete visuals for one mode: the fixture
|
|
57
|
+
* `theme-recipes.json` locks this per theme × component. */
|
|
58
|
+
export declare function resolveRecipe(theme: ResolvedTheme, query: RecipeQuery, mode: ModeName): ResolvedStyle;
|
|
59
|
+
/** The recipe query a NORMALIZED node answers to: its macro part, or the
|
|
60
|
+
* native's root with its own recipe props. */
|
|
61
|
+
export declare function nodeRecipeQuery(node: UiNode, extensions?: readonly ExtensionDef[]): RecipeQuery;
|
|
62
|
+
/** What a painter paints a node with: native recipe < node style < macro
|
|
63
|
+
* part recipe, token references resolved, condition blocks kept nested
|
|
64
|
+
* (the client resolves `@media` and the state keys itself). */
|
|
65
|
+
export declare function resolveNodeStyle(theme: ResolvedTheme, node: UiNode, mode: ModeName, states?: readonly string[], extensions?: readonly ExtensionDef[]): ResolvedStyle;
|
|
66
|
+
/** The shadow layers as one CSS `box-shadow` string (for web painters). */
|
|
67
|
+
export declare function shadowCss(layers: Shadow[]): string;
|
|
68
|
+
/** An easing as CSS `cubic-bezier(…)`. */
|
|
69
|
+
export declare function easingCss(curve: Easing): string;
|
|
70
|
+
/** The parts of the theme a mode-less consumer may list (the builder). */
|
|
71
|
+
export declare function themeTokens(theme: ResolvedTheme): ThemeTokens;
|
|
72
|
+
export declare function themeMode(theme: ResolvedTheme, mode: ModeName): ThemeMode;
|
|
73
|
+
export type { ThemeRecipes };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ResolvedTheme, ThemeIssue, ThemeSource } from "./theme-types.js";
|
|
2
|
+
export declare const neutralTheme: ThemeSource;
|
|
3
|
+
export declare const exponentialTheme: ThemeSource;
|
|
4
|
+
export declare const playfulTheme: ThemeSource;
|
|
5
|
+
export declare const orangeTheme: ThemeSource;
|
|
6
|
+
/** Source order = resolution order: a built-in may only extend one before it. */
|
|
7
|
+
export declare const BUILTIN_THEMES: readonly ThemeSource[];
|
|
8
|
+
export declare const BUILTIN_THEME_IDS: readonly string[];
|
|
9
|
+
export declare const DEFAULT_THEME_ID = "exponential";
|
|
10
|
+
/** A built-in, resolved once per process. */
|
|
11
|
+
export declare function builtinTheme(id: string): ResolvedTheme;
|
|
12
|
+
/** Round 4 (VAPP-103): the theme a host paints with, NEVER a throw: a
|
|
13
|
+
* built-in id or a theme file over the built-ins; anything unusable (an
|
|
14
|
+
* unknown id, a bad `$schema`, an unknown token, a missing value) falls back
|
|
15
|
+
* to the default theme with the issues saying why (Rust
|
|
16
|
+
* `themes::theme_or_default`, Swift/Kotlin `ThemeHandle.loadOrDefault`). */
|
|
17
|
+
export declare function themeOrDefault(input: unknown): {
|
|
18
|
+
theme: ResolvedTheme;
|
|
19
|
+
issues: ThemeIssue[];
|
|
20
|
+
};
|
|
21
|
+
/** Every built-in resolved, in source order. */
|
|
22
|
+
export declare function builtinThemes(): ResolvedTheme[];
|