@textui/core 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 +21 -0
- package/README.md +67 -0
- package/dist/adapters/index.d.ts +12 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +11 -0
- package/dist/app/app.d.ts +200 -0
- package/dist/app/app.d.ts.map +1 -0
- package/dist/app/app.js +980 -0
- package/dist/core/animation.d.ts +34 -0
- package/dist/core/animation.d.ts.map +1 -0
- package/dist/core/animation.js +125 -0
- package/dist/core/clipboard.d.ts +29 -0
- package/dist/core/clipboard.d.ts.map +1 -0
- package/dist/core/clipboard.js +30 -0
- package/dist/core/commands.d.ts +42 -0
- package/dist/core/commands.d.ts.map +1 -0
- package/dist/core/commands.js +146 -0
- package/dist/core/components.d.ts +27 -0
- package/dist/core/components.d.ts.map +1 -0
- package/dist/core/components.js +78 -0
- package/dist/core/events.d.ts +23 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +77 -0
- package/dist/core/focus.d.ts +69 -0
- package/dist/core/focus.d.ts.map +1 -0
- package/dist/core/focus.js +336 -0
- package/dist/core/i18n.d.ts +27 -0
- package/dist/core/i18n.d.ts.map +1 -0
- package/dist/core/i18n.js +88 -0
- package/dist/core/keybindings.d.ts +53 -0
- package/dist/core/keybindings.d.ts.map +1 -0
- package/dist/core/keybindings.js +163 -0
- package/dist/core/layers.d.ts +28 -0
- package/dist/core/layers.d.ts.map +1 -0
- package/dist/core/layers.js +84 -0
- package/dist/core/manifest.d.ts +22 -0
- package/dist/core/manifest.d.ts.map +1 -0
- package/dist/core/manifest.js +85 -0
- package/dist/core/navigation.d.ts +47 -0
- package/dist/core/navigation.d.ts.map +1 -0
- package/dist/core/navigation.js +110 -0
- package/dist/core/resources.d.ts +115 -0
- package/dist/core/resources.d.ts.map +1 -0
- package/dist/core/resources.js +321 -0
- package/dist/core/services.d.ts +21 -0
- package/dist/core/services.d.ts.map +1 -0
- package/dist/core/services.js +63 -0
- package/dist/core/store.d.ts +60 -0
- package/dist/core/store.d.ts.map +1 -0
- package/dist/core/store.js +593 -0
- package/dist/core/surfaces.d.ts +81 -0
- package/dist/core/surfaces.d.ts.map +1 -0
- package/dist/core/surfaces.js +237 -0
- package/dist/core/syntax.d.ts +49 -0
- package/dist/core/syntax.d.ts.map +1 -0
- package/dist/core/syntax.js +172 -0
- package/dist/core/when.d.ts +15 -0
- package/dist/core/when.d.ts.map +1 -0
- package/dist/core/when.js +224 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/jsx/factory.d.ts +27 -0
- package/dist/jsx/factory.d.ts.map +1 -0
- package/dist/jsx/factory.js +102 -0
- package/dist/jsx/intrinsics.d.ts +96 -0
- package/dist/jsx/intrinsics.d.ts.map +1 -0
- package/dist/jsx/intrinsics.js +1 -0
- package/dist/jsx/jsx-dev-runtime.d.ts +13 -0
- package/dist/jsx/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/jsx/jsx-dev-runtime.js +12 -0
- package/dist/jsx/jsx-runtime.d.ts +42 -0
- package/dist/jsx/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx/jsx-runtime.js +16 -0
- package/dist/render/buffer.d.ts +77 -0
- package/dist/render/buffer.d.ts.map +1 -0
- package/dist/render/buffer.js +275 -0
- package/dist/render/color.d.ts +35 -0
- package/dist/render/color.d.ts.map +1 -0
- package/dist/render/color.js +160 -0
- package/dist/render/diff.d.ts +37 -0
- package/dist/render/diff.d.ts.map +1 -0
- package/dist/render/diff.js +66 -0
- package/dist/render/layout.d.ts +72 -0
- package/dist/render/layout.d.ts.map +1 -0
- package/dist/render/layout.js +633 -0
- package/dist/render/static.d.ts +63 -0
- package/dist/render/static.d.ts.map +1 -0
- package/dist/render/static.js +209 -0
- package/dist/runtime/bindings.d.ts +46 -0
- package/dist/runtime/bindings.d.ts.map +1 -0
- package/dist/runtime/bindings.js +116 -0
- package/dist/runtime/hooks.d.ts +284 -0
- package/dist/runtime/hooks.d.ts.map +1 -0
- package/dist/runtime/hooks.js +846 -0
- package/dist/runtime/instance.d.ts +106 -0
- package/dist/runtime/instance.d.ts.map +1 -0
- package/dist/runtime/instance.js +181 -0
- package/dist/runtime/paint.d.ts +27 -0
- package/dist/runtime/paint.d.ts.map +1 -0
- package/dist/runtime/paint.js +567 -0
- package/dist/runtime/reconcile.d.ts +23 -0
- package/dist/runtime/reconcile.d.ts.map +1 -0
- package/dist/runtime/reconcile.js +260 -0
- package/dist/runtime/runtime.d.ts +42 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +1 -0
- package/dist/runtime/style.d.ts +55 -0
- package/dist/runtime/style.d.ts.map +1 -0
- package/dist/runtime/style.js +143 -0
- package/dist/themes/borders.d.ts +10 -0
- package/dist/themes/borders.d.ts.map +1 -0
- package/dist/themes/borders.js +88 -0
- package/dist/themes/builtin.d.ts +31 -0
- package/dist/themes/builtin.d.ts.map +1 -0
- package/dist/themes/builtin.js +291 -0
- package/dist/themes/glyphs.d.ts +15 -0
- package/dist/themes/glyphs.d.ts.map +1 -0
- package/dist/themes/glyphs.js +97 -0
- package/dist/themes/index.d.ts +5 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/index.js +4 -0
- package/dist/themes/registry.d.ts +20 -0
- package/dist/themes/registry.d.ts.map +1 -0
- package/dist/themes/registry.js +204 -0
- package/dist/types/adapter.d.ts +38 -0
- package/dist/types/adapter.d.ts.map +1 -0
- package/dist/types/adapter.js +1 -0
- package/dist/types/animation.d.ts +31 -0
- package/dist/types/animation.d.ts.map +1 -0
- package/dist/types/animation.js +1 -0
- package/dist/types/app.d.ts +148 -0
- package/dist/types/app.d.ts.map +1 -0
- package/dist/types/app.js +1 -0
- package/dist/types/async.d.ts +30 -0
- package/dist/types/async.d.ts.map +1 -0
- package/dist/types/async.js +1 -0
- package/dist/types/capabilities.d.ts +44 -0
- package/dist/types/capabilities.d.ts.map +1 -0
- package/dist/types/capabilities.js +33 -0
- package/dist/types/cells.d.ts +72 -0
- package/dist/types/cells.d.ts.map +1 -0
- package/dist/types/cells.js +10 -0
- package/dist/types/command.d.ts +127 -0
- package/dist/types/command.d.ts.map +1 -0
- package/dist/types/command.js +1 -0
- package/dist/types/component-registry.d.ts +77 -0
- package/dist/types/component-registry.d.ts.map +1 -0
- package/dist/types/component-registry.js +1 -0
- package/dist/types/disposable.d.ts +8 -0
- package/dist/types/disposable.d.ts.map +1 -0
- package/dist/types/disposable.js +1 -0
- package/dist/types/focus.d.ts +72 -0
- package/dist/types/focus.d.ts.map +1 -0
- package/dist/types/focus.js +1 -0
- package/dist/types/geometry.d.ts +28 -0
- package/dist/types/geometry.d.ts.map +1 -0
- package/dist/types/geometry.js +14 -0
- package/dist/types/graph.d.ts +129 -0
- package/dist/types/graph.d.ts.map +1 -0
- package/dist/types/graph.js +31 -0
- package/dist/types/i18n.d.ts +23 -0
- package/dist/types/i18n.d.ts.map +1 -0
- package/dist/types/i18n.js +1 -0
- package/dist/types/index.d.ts +32 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +31 -0
- package/dist/types/input.d.ts +65 -0
- package/dist/types/input.d.ts.map +1 -0
- package/dist/types/input.js +1 -0
- package/dist/types/keybinding.d.ts +49 -0
- package/dist/types/keybinding.d.ts.map +1 -0
- package/dist/types/keybinding.js +1 -0
- package/dist/types/layer.d.ts +54 -0
- package/dist/types/layer.d.ts.map +1 -0
- package/dist/types/layer.js +1 -0
- package/dist/types/manifest.d.ts +114 -0
- package/dist/types/manifest.d.ts.map +1 -0
- package/dist/types/manifest.js +1 -0
- package/dist/types/markdown.d.ts +58 -0
- package/dist/types/markdown.d.ts.map +1 -0
- package/dist/types/markdown.js +1 -0
- package/dist/types/navigation.d.ts +40 -0
- package/dist/types/navigation.d.ts.map +1 -0
- package/dist/types/navigation.js +1 -0
- package/dist/types/render.d.ts +72 -0
- package/dist/types/render.d.ts.map +1 -0
- package/dist/types/render.js +1 -0
- package/dist/types/resource.d.ts +170 -0
- package/dist/types/resource.d.ts.map +1 -0
- package/dist/types/resource.js +1 -0
- package/dist/types/services.d.ts +24 -0
- package/dist/types/services.d.ts.map +1 -0
- package/dist/types/services.js +3 -0
- package/dist/types/shell.d.ts +32 -0
- package/dist/types/shell.d.ts.map +1 -0
- package/dist/types/shell.js +1 -0
- package/dist/types/store.d.ts +124 -0
- package/dist/types/store.d.ts.map +1 -0
- package/dist/types/store.js +1 -0
- package/dist/types/stream.d.ts +18 -0
- package/dist/types/stream.d.ts.map +1 -0
- package/dist/types/stream.js +1 -0
- package/dist/types/style.d.ts +166 -0
- package/dist/types/style.d.ts.map +1 -0
- package/dist/types/style.js +1 -0
- package/dist/types/surface.d.ts +97 -0
- package/dist/types/surface.d.ts.map +1 -0
- package/dist/types/surface.js +1 -0
- package/dist/types/syntax.d.ts +68 -0
- package/dist/types/syntax.d.ts.map +1 -0
- package/dist/types/syntax.js +5 -0
- package/dist/types/terminal.d.ts +52 -0
- package/dist/types/terminal.d.ts.map +1 -0
- package/dist/types/terminal.js +1 -0
- package/dist/types/theme.d.ts +117 -0
- package/dist/types/theme.d.ts.map +1 -0
- package/dist/types/theme.js +1 -0
- package/dist/types/when.d.ts +19 -0
- package/dist/types/when.d.ts.map +1 -0
- package/dist/types/when.js +1 -0
- package/dist/ui/primitives.d.ts +56 -0
- package/dist/ui/primitives.d.ts.map +1 -0
- package/dist/ui/primitives.js +108 -0
- package/dist/ui/screen.d.ts +23 -0
- package/dist/ui/screen.d.ts.map +1 -0
- package/dist/ui/screen.js +18 -0
- package/dist/util/disposable.d.ts +6 -0
- package/dist/util/disposable.d.ts.map +1 -0
- package/dist/util/disposable.js +49 -0
- package/dist/util/markdown.d.ts +24 -0
- package/dist/util/markdown.d.ts.map +1 -0
- package/dist/util/markdown.js +220 -0
- package/dist/util/paths.d.ts +47 -0
- package/dist/util/paths.d.ts.map +1 -0
- package/dist/util/paths.js +134 -0
- package/dist/util/stream.d.ts +32 -0
- package/dist/util/stream.d.ts.map +1 -0
- package/dist/util/stream.js +206 -0
- package/dist/util/text.d.ts +65 -0
- package/dist/util/text.d.ts.map +1 -0
- package/dist/util/text.js +419 -0
- package/package.json +70 -0
- package/src/adapters/index.ts +11 -0
- package/src/app/app.ts +1096 -0
- package/src/core/animation.ts +144 -0
- package/src/core/clipboard.ts +40 -0
- package/src/core/commands.ts +169 -0
- package/src/core/components.ts +91 -0
- package/src/core/events.ts +95 -0
- package/src/core/focus.ts +358 -0
- package/src/core/i18n.ts +107 -0
- package/src/core/keybindings.ts +184 -0
- package/src/core/layers.ts +94 -0
- package/src/core/manifest.ts +84 -0
- package/src/core/navigation.ts +135 -0
- package/src/core/resources.ts +362 -0
- package/src/core/services.ts +69 -0
- package/src/core/store.ts +640 -0
- package/src/core/surfaces.ts +292 -0
- package/src/core/syntax.ts +200 -0
- package/src/core/when.ts +238 -0
- package/src/index.ts +76 -0
- package/src/jsx/factory.ts +124 -0
- package/src/jsx/intrinsics.ts +99 -0
- package/src/jsx/jsx-dev-runtime.ts +23 -0
- package/src/jsx/jsx-runtime.ts +76 -0
- package/src/render/buffer.ts +318 -0
- package/src/render/color.ts +180 -0
- package/src/render/diff.ts +99 -0
- package/src/render/layout.ts +764 -0
- package/src/render/static.ts +290 -0
- package/src/runtime/bindings.ts +150 -0
- package/src/runtime/hooks.ts +1057 -0
- package/src/runtime/instance.ts +284 -0
- package/src/runtime/paint.ts +737 -0
- package/src/runtime/reconcile.ts +335 -0
- package/src/runtime/runtime.ts +47 -0
- package/src/runtime/style.ts +205 -0
- package/src/themes/borders.ts +95 -0
- package/src/themes/builtin.ts +301 -0
- package/src/themes/glyphs.ts +101 -0
- package/src/themes/index.ts +4 -0
- package/src/themes/registry.ts +224 -0
- package/src/types/adapter.ts +41 -0
- package/src/types/animation.ts +34 -0
- package/src/types/app.ts +149 -0
- package/src/types/async.ts +35 -0
- package/src/types/capabilities.ts +79 -0
- package/src/types/cells.ts +79 -0
- package/src/types/command.ts +139 -0
- package/src/types/component-registry.ts +82 -0
- package/src/types/disposable.ts +8 -0
- package/src/types/focus.ts +77 -0
- package/src/types/geometry.ts +50 -0
- package/src/types/graph.ts +174 -0
- package/src/types/i18n.ts +25 -0
- package/src/types/index.ts +31 -0
- package/src/types/input.ts +81 -0
- package/src/types/keybinding.ts +51 -0
- package/src/types/layer.ts +46 -0
- package/src/types/manifest.ts +101 -0
- package/src/types/markdown.ts +47 -0
- package/src/types/navigation.ts +42 -0
- package/src/types/render.ts +86 -0
- package/src/types/resource.ts +185 -0
- package/src/types/services.ts +28 -0
- package/src/types/shell.ts +30 -0
- package/src/types/store.ts +148 -0
- package/src/types/stream.ts +24 -0
- package/src/types/style.ts +205 -0
- package/src/types/surface.ts +119 -0
- package/src/types/syntax.ts +93 -0
- package/src/types/terminal.ts +58 -0
- package/src/types/theme.ts +121 -0
- package/src/types/when.ts +21 -0
- package/src/ui/primitives.ts +118 -0
- package/src/ui/screen.ts +41 -0
- package/src/util/disposable.ts +49 -0
- package/src/util/markdown.ts +225 -0
- package/src/util/paths.ts +138 -0
- package/src/util/stream.ts +213 -0
- package/src/util/text.ts +428 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type { Color } from './cells.js';
|
|
2
|
+
import type { EdgeSpec } from './geometry.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Semantic theme tokens. A component names a role, never a colour - which is
|
|
6
|
+
* what lets one catalog render the same under a light theme, a dark theme and
|
|
7
|
+
* a 16-colour ssh session.
|
|
8
|
+
*/
|
|
9
|
+
export type ColorToken =
|
|
10
|
+
| 'canvas' | 'surface' | 'surfaceAlt' | 'overlay'
|
|
11
|
+
| 'border' | 'borderStrong' | 'borderSubtle'
|
|
12
|
+
| 'text' | 'muted' | 'subtle' | 'inverted'
|
|
13
|
+
| 'accent' | 'primary' | 'secondary'
|
|
14
|
+
| 'success' | 'warning' | 'danger' | 'info'
|
|
15
|
+
| 'onDefault' | 'onMuted'
|
|
16
|
+
| 'onAccent' | 'onPrimary' | 'onSecondary'
|
|
17
|
+
| 'onSuccess' | 'onWarning' | 'onDanger' | 'onInfo'
|
|
18
|
+
| 'hover' | 'active' | 'selected' | 'focus' | 'disabled'
|
|
19
|
+
| 'scrim' | 'cursor' | 'shadow';
|
|
20
|
+
|
|
21
|
+
/** Anywhere a colour is accepted, a semantic token is accepted too. */
|
|
22
|
+
export type StyleColor = ColorToken | Color;
|
|
23
|
+
|
|
24
|
+
export type Dimension = number | `${number}%` | 'auto';
|
|
25
|
+
|
|
26
|
+
export type BorderStyle =
|
|
27
|
+
| 'none' | 'single' | 'double' | 'round' | 'bold'
|
|
28
|
+
| 'dashed' | 'ascii' | 'thick' | 'half';
|
|
29
|
+
|
|
30
|
+
/** The twelve glyphs a box needs. Themes may ship their own set. */
|
|
31
|
+
export interface BorderChars {
|
|
32
|
+
topLeft: string;
|
|
33
|
+
top: string;
|
|
34
|
+
topRight: string;
|
|
35
|
+
right: string;
|
|
36
|
+
bottomRight: string;
|
|
37
|
+
bottom: string;
|
|
38
|
+
bottomLeft: string;
|
|
39
|
+
left: string;
|
|
40
|
+
/** junctions, for tables and split panels */
|
|
41
|
+
cross: string;
|
|
42
|
+
teeTop: string;
|
|
43
|
+
teeBottom: string;
|
|
44
|
+
teeLeft: string;
|
|
45
|
+
teeRight: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type BorderSides = {
|
|
49
|
+
top?: boolean;
|
|
50
|
+
right?: boolean;
|
|
51
|
+
bottom?: boolean;
|
|
52
|
+
left?: boolean;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/** A colour per edge. Unnamed edges fall back to the border's `color`. */
|
|
56
|
+
export type BorderColors = {
|
|
57
|
+
top?: StyleColor;
|
|
58
|
+
right?: StyleColor;
|
|
59
|
+
bottom?: StyleColor;
|
|
60
|
+
left?: StyleColor;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type BorderSpec =
|
|
64
|
+
| BorderStyle
|
|
65
|
+
| {
|
|
66
|
+
style?: BorderStyle;
|
|
67
|
+
color?: StyleColor;
|
|
68
|
+
/**
|
|
69
|
+
* Per-edge colour, over `color`. A corner belongs to the edge that runs
|
|
70
|
+
* through it - the top rule owns both top corners - because a cell holds
|
|
71
|
+
* one colour and a terminal has no mitre to split it along.
|
|
72
|
+
*/
|
|
73
|
+
colors?: BorderColors;
|
|
74
|
+
sides?: BorderSides;
|
|
75
|
+
chars?: Partial<BorderChars>;
|
|
76
|
+
/**
|
|
77
|
+
* Draw the frame dim. The frame only: a dim attribute on the box itself
|
|
78
|
+
* would take the content with it, and a quiet border around ordinary
|
|
79
|
+
* text is the whole reason to ask.
|
|
80
|
+
*/
|
|
81
|
+
dim?: boolean;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export type Align = 'start' | 'center' | 'end' | 'stretch' | 'baseline';
|
|
85
|
+
export type Justify = 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';
|
|
86
|
+
export type Overflow = 'visible' | 'hidden' | 'scroll' | 'ellipsis';
|
|
87
|
+
export type Position = 'relative' | 'absolute';
|
|
88
|
+
export type FlexWrap = 'nowrap' | 'wrap';
|
|
89
|
+
/**
|
|
90
|
+
* How a run of text meets the edge of its box.
|
|
91
|
+
*
|
|
92
|
+
* `none`, `word` and `char` describe *wrapping*: the text keeps every
|
|
93
|
+
* character and takes as many rows as it needs. The `truncate-*` forms are the
|
|
94
|
+
* opposite bargain - one row, and whatever does not fit is replaced by an
|
|
95
|
+
* ellipsis at the named end. `truncate` is `truncate-end`, which is the one
|
|
96
|
+
* everybody means.
|
|
97
|
+
*
|
|
98
|
+
* A truncating text is one row tall by definition, so an embedded newline
|
|
99
|
+
* would have nowhere to go; those become spaces rather than being dropped,
|
|
100
|
+
* because a joined sentence still reads and a silently halved one does not.
|
|
101
|
+
*/
|
|
102
|
+
export type TextWrap =
|
|
103
|
+
| 'none' | 'word' | 'char'
|
|
104
|
+
| 'truncate' | 'truncate-start' | 'truncate-middle' | 'truncate-end';
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
export interface Style {
|
|
108
|
+
/**
|
|
109
|
+
* Wash whatever is already painted here toward this colour, instead of
|
|
110
|
+
* drawing over it. A modal scrim in a terminal: the screen behind recedes
|
|
111
|
+
* but stays legible, rather than being replaced by a rectangle of nothing.
|
|
112
|
+
* `true` uses the theme's `scrim` token; a number sets the strength.
|
|
113
|
+
*/
|
|
114
|
+
scrim?: boolean | StyleColor;
|
|
115
|
+
scrimStrength?: number;
|
|
116
|
+
|
|
117
|
+
// --- box ---
|
|
118
|
+
display?: 'flex' | 'none';
|
|
119
|
+
direction?: 'row' | 'column';
|
|
120
|
+
/** Space between children on both axes. `columnGap`/`rowGap` override it. */
|
|
121
|
+
gap?: number;
|
|
122
|
+
/**
|
|
123
|
+
* Space between columns - horizontal, whichever way the container runs. It
|
|
124
|
+
* is the gap *between* children on a row, and the gap between wrapped lines
|
|
125
|
+
* on a column.
|
|
126
|
+
*/
|
|
127
|
+
columnGap?: number;
|
|
128
|
+
/** Space between rows - vertical. The mirror of `columnGap`. */
|
|
129
|
+
rowGap?: number;
|
|
130
|
+
/**
|
|
131
|
+
* Whether children that do not fit start a new line. `nowrap` is the
|
|
132
|
+
* default and the cheaper path: one line, children shrink or get clipped.
|
|
133
|
+
*/
|
|
134
|
+
flexWrap?: FlexWrap;
|
|
135
|
+
padding?: EdgeSpec;
|
|
136
|
+
margin?: EdgeSpec;
|
|
137
|
+
width?: Dimension;
|
|
138
|
+
height?: Dimension;
|
|
139
|
+
minWidth?: number;
|
|
140
|
+
maxWidth?: number;
|
|
141
|
+
minHeight?: number;
|
|
142
|
+
maxHeight?: number;
|
|
143
|
+
/** Grow factor along the parent's main axis. 0 = size to content. */
|
|
144
|
+
flex?: number;
|
|
145
|
+
/** Shrink factor. Defaults to 1 when flex is unset. */
|
|
146
|
+
shrink?: number;
|
|
147
|
+
/** Base size along the main axis before grow/shrink. */
|
|
148
|
+
basis?: Dimension;
|
|
149
|
+
align?: Align;
|
|
150
|
+
alignSelf?: Align;
|
|
151
|
+
justify?: Justify;
|
|
152
|
+
position?: Position;
|
|
153
|
+
top?: number;
|
|
154
|
+
right?: number;
|
|
155
|
+
bottom?: number;
|
|
156
|
+
left?: number;
|
|
157
|
+
/** Painting and hit-testing order within a layer. */
|
|
158
|
+
zIndex?: number;
|
|
159
|
+
/** What happens to content past the edge, on both axes. */
|
|
160
|
+
overflow?: Overflow;
|
|
161
|
+
/** Overrides `overflow` sideways. A row that scrolls but does not grow. */
|
|
162
|
+
overflowX?: Overflow;
|
|
163
|
+
/** Overrides `overflow` downwards. The usual scroll container. */
|
|
164
|
+
overflowY?: Overflow;
|
|
165
|
+
|
|
166
|
+
// --- paint ---
|
|
167
|
+
fg?: StyleColor;
|
|
168
|
+
bg?: StyleColor;
|
|
169
|
+
bold?: boolean;
|
|
170
|
+
dim?: boolean;
|
|
171
|
+
italic?: boolean;
|
|
172
|
+
underline?: boolean;
|
|
173
|
+
inverse?: boolean;
|
|
174
|
+
strike?: boolean;
|
|
175
|
+
blink?: boolean;
|
|
176
|
+
border?: BorderSpec;
|
|
177
|
+
|
|
178
|
+
// --- text ---
|
|
179
|
+
wrap?: TextWrap;
|
|
180
|
+
textAlign?: 'left' | 'center' | 'right';
|
|
181
|
+
/** Character painted into empty cells of this box. */
|
|
182
|
+
fill?: string;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Styles selected by interaction state. Merged over the base in this order. */
|
|
186
|
+
export interface StatefulStyle {
|
|
187
|
+
base?: Style;
|
|
188
|
+
focus?: Style;
|
|
189
|
+
hover?: Style;
|
|
190
|
+
active?: Style;
|
|
191
|
+
selected?: Style;
|
|
192
|
+
disabled?: Style;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export type StyleInput = Style | StatefulStyle | (Style | StatefulStyle | undefined | false)[];
|
|
196
|
+
|
|
197
|
+
/** Global semantic variants, available to every component that opts in. */
|
|
198
|
+
export type SemanticVariant =
|
|
199
|
+
| 'default' | 'primary' | 'secondary' | 'accent'
|
|
200
|
+
| 'success' | 'warning' | 'danger' | 'info' | 'muted';
|
|
201
|
+
|
|
202
|
+
/** Presentational variants a component may support. */
|
|
203
|
+
export type SurfaceVariant = 'solid' | 'outline' | 'ghost' | 'link';
|
|
204
|
+
|
|
205
|
+
export type Density = 'compact' | 'normal' | 'airy';
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { Disposable } from './disposable.js';
|
|
2
|
+
import type { BindingPath, ComponentNode } from './graph.js';
|
|
3
|
+
import type { WhenClause } from './when.js';
|
|
4
|
+
import type { StyleColor } from './style.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Where something is mounted.
|
|
8
|
+
*
|
|
9
|
+
* A surface is the application's word, not the library's. The names below are
|
|
10
|
+
* the ones the shipped shells happen to use, and they are listed so an editor
|
|
11
|
+
* can complete them - `(string & {})` keeps the type open, so `lateral1`,
|
|
12
|
+
* `inspector` or `panel:bottom` are all equally valid and need no change here.
|
|
13
|
+
*
|
|
14
|
+
* The runtime never checks a surface name against a list. A name it has not
|
|
15
|
+
* seen gets default state the first time it is used, and a shell renders
|
|
16
|
+
* whichever surfaces it decides to render.
|
|
17
|
+
*/
|
|
18
|
+
export type SurfaceName =
|
|
19
|
+
| 'header' // title bar / tab strip
|
|
20
|
+
| 'rail' // narrow icon strip (an activity bar)
|
|
21
|
+
| 'sidebar' // primary side region
|
|
22
|
+
| 'aside' // secondary side region
|
|
23
|
+
| 'main' // the content
|
|
24
|
+
| 'panel' // bottom drawer: logs, output, terminal
|
|
25
|
+
| 'status' // one-line status bar
|
|
26
|
+
| 'overlay' // modals, palettes, popovers, tooltips
|
|
27
|
+
| 'notify' // toasts
|
|
28
|
+
| (string & {});
|
|
29
|
+
|
|
30
|
+
export interface MountDisplay {
|
|
31
|
+
title?: string;
|
|
32
|
+
subtitle?: string;
|
|
33
|
+
icon?: string;
|
|
34
|
+
color?: StyleColor;
|
|
35
|
+
badge?: string | number;
|
|
36
|
+
/** Commands offered in this mount's header. */
|
|
37
|
+
actions?: string[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface MountPolicy {
|
|
41
|
+
/** Survives a session snapshot. */
|
|
42
|
+
persistent?: boolean;
|
|
43
|
+
/** Removed on the next navigation. Previews want this. */
|
|
44
|
+
transient?: boolean;
|
|
45
|
+
closable?: boolean;
|
|
46
|
+
/** The user may move it to another surface. */
|
|
47
|
+
movable?: boolean;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** An inline node, or a binding whose value is a node. */
|
|
51
|
+
export type MountTarget = ComponentNode | { path: BindingPath };
|
|
52
|
+
|
|
53
|
+
export interface Mount {
|
|
54
|
+
key: string;
|
|
55
|
+
surface: SurfaceName;
|
|
56
|
+
target: MountTarget;
|
|
57
|
+
display?: MountDisplay;
|
|
58
|
+
policy?: MountPolicy;
|
|
59
|
+
when?: WhenClause;
|
|
60
|
+
/** Relative paths inside this mount resolve against here. */
|
|
61
|
+
dataContext?: BindingPath;
|
|
62
|
+
order?: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** How a surface arranges the several mounts it holds. */
|
|
66
|
+
export type LayoutName =
|
|
67
|
+
| 'single' // only the active one
|
|
68
|
+
| 'tabs' // tab strip plus the active one
|
|
69
|
+
| 'stack' // all of them, vertically
|
|
70
|
+
| 'split' // all of them, resizable
|
|
71
|
+
| 'rail' // icons only
|
|
72
|
+
| 'bar' // one line, horizontal
|
|
73
|
+
| 'inline' // all of them, no chrome
|
|
74
|
+
| 'floating' // positioned; overlay uses this
|
|
75
|
+
| 'toast'; // stacked, ephemeral
|
|
76
|
+
|
|
77
|
+
export interface SurfaceState {
|
|
78
|
+
/**
|
|
79
|
+
* Open, like `SurfaceName` and like `LayoutDefinition.name`. An application
|
|
80
|
+
* that registers a layout has to be able to put a surface into it, and the
|
|
81
|
+
* runtime never assumed a closed set anyway - `SurfaceArea` looks the name
|
|
82
|
+
* up in the registry and renders a diagnostic when nothing answers to it.
|
|
83
|
+
*/
|
|
84
|
+
layout: LayoutName | (string & {});
|
|
85
|
+
activeKey: string | null;
|
|
86
|
+
visible: boolean;
|
|
87
|
+
/** Cells along the surface's cross axis. Unset lets the shell decide. */
|
|
88
|
+
size?: number;
|
|
89
|
+
collapsed?: boolean;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface SurfaceRegistry {
|
|
93
|
+
open(mount: Mount): Disposable;
|
|
94
|
+
close(surface: SurfaceName, key: string): void;
|
|
95
|
+
closeAll(surface: SurfaceName): void;
|
|
96
|
+
get(surface: SurfaceName, key: string): Mount | undefined;
|
|
97
|
+
mounts(surface: SurfaceName): Mount[];
|
|
98
|
+
activate(surface: SurfaceName, key: string): void;
|
|
99
|
+
state(surface: SurfaceName): SurfaceState;
|
|
100
|
+
setState(surface: SurfaceName, patch: Partial<SurfaceState>): void;
|
|
101
|
+
/** Resolve a resource's viewer and mount it. */
|
|
102
|
+
openResource(uri: string, options?: { surface?: SurfaceName; viewerId?: string; mode?: 'view' | 'edit' }): Promise<Disposable | null>;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** A layout is a component that receives a surface's mounts and renders them. */
|
|
106
|
+
export interface LayoutDefinition {
|
|
107
|
+
name: LayoutName | (string & {});
|
|
108
|
+
/** Component name receiving `{ surface, mounts, state }`. */
|
|
109
|
+
component: string;
|
|
110
|
+
title?: string;
|
|
111
|
+
/** Surfaces this layout is offered for. Unset = all. */
|
|
112
|
+
surfaces?: SurfaceName[];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface LayoutRegistry {
|
|
116
|
+
register(def: LayoutDefinition): Disposable;
|
|
117
|
+
get(name: string): LayoutDefinition | undefined;
|
|
118
|
+
list(surface?: SurfaceName): LayoutDefinition[];
|
|
119
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { Disposable } from './disposable.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Syntax highlighting.
|
|
5
|
+
*
|
|
6
|
+
* A highlighter names *scopes*, never colours. The theme owns the palette, so
|
|
7
|
+
* one JSON highlighter looks right on a dark console, a paper report and a
|
|
8
|
+
* sixteen-colour terminal without knowing that any of them exist - and a
|
|
9
|
+
* colourless terminal simply resolves every scope to the default foreground.
|
|
10
|
+
*
|
|
11
|
+
* The scope list is closed on purpose. An open vocabulary means a theme can
|
|
12
|
+
* only guess what a highlighter will emit, and the guess is what produces the
|
|
13
|
+
* uncoloured token nobody can explain.
|
|
14
|
+
*/
|
|
15
|
+
export type SyntaxScope =
|
|
16
|
+
| 'plain'
|
|
17
|
+
| 'keyword'
|
|
18
|
+
| 'string'
|
|
19
|
+
| 'number'
|
|
20
|
+
| 'boolean'
|
|
21
|
+
| 'null'
|
|
22
|
+
| 'comment'
|
|
23
|
+
| 'punctuation'
|
|
24
|
+
/** An object key, a column name, a field label - the left of a pair. */
|
|
25
|
+
| 'key'
|
|
26
|
+
| 'operator'
|
|
27
|
+
| 'type'
|
|
28
|
+
| 'function'
|
|
29
|
+
| 'tag'
|
|
30
|
+
| 'attribute'
|
|
31
|
+
| 'regexp'
|
|
32
|
+
| 'escape'
|
|
33
|
+
/** Syntactically wrong. Worth seeing rather than hiding. */
|
|
34
|
+
| 'invalid';
|
|
35
|
+
|
|
36
|
+
export const SYNTAX_SCOPES: readonly SyntaxScope[] = [
|
|
37
|
+
'plain', 'keyword', 'string', 'number', 'boolean', 'null', 'comment',
|
|
38
|
+
'punctuation', 'key', 'operator', 'type', 'function', 'tag', 'attribute',
|
|
39
|
+
'regexp', 'escape', 'invalid',
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
/** A run of text with one scope. Never spans a newline. */
|
|
43
|
+
export interface SyntaxToken {
|
|
44
|
+
text: string;
|
|
45
|
+
scope: SyntaxScope;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** A scored region of the source, before it is split into lines. */
|
|
49
|
+
export interface SyntaxSpan {
|
|
50
|
+
start: number;
|
|
51
|
+
end: number;
|
|
52
|
+
scope: SyntaxScope;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface HighlighterDefinition {
|
|
56
|
+
id: string;
|
|
57
|
+
title?: string;
|
|
58
|
+
/** Resource kinds this claims: `file.data.json`, `log.stream`. */
|
|
59
|
+
kinds?: string[];
|
|
60
|
+
/** Filename globs, for when nothing has classified the resource yet. */
|
|
61
|
+
extensions?: string[];
|
|
62
|
+
/** Higher wins when several match. */
|
|
63
|
+
priority?: number;
|
|
64
|
+
/**
|
|
65
|
+
* Tokenise a whole document into one array per line.
|
|
66
|
+
*
|
|
67
|
+
* The result must have exactly as many entries as `text.split('\n')`, and
|
|
68
|
+
* the tokens on each line must join back to that line. The registry checks
|
|
69
|
+
* both and falls back to plain text rather than paint a file that no longer
|
|
70
|
+
* lines up with its own gutter.
|
|
71
|
+
*/
|
|
72
|
+
tokenize(text: string): SyntaxToken[][];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface SyntaxQuery {
|
|
76
|
+
/** Resource kind, when the resource has been classified. */
|
|
77
|
+
kind?: string;
|
|
78
|
+
/** URI or filename, matched against `extensions`. */
|
|
79
|
+
uri?: string;
|
|
80
|
+
/** An explicit highlighter id, which wins over everything. */
|
|
81
|
+
language?: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface SyntaxRegistry {
|
|
85
|
+
register(def: HighlighterDefinition): Disposable;
|
|
86
|
+
unregister(id: string): void;
|
|
87
|
+
get(id: string): HighlighterDefinition | undefined;
|
|
88
|
+
list(): HighlighterDefinition[];
|
|
89
|
+
/** The best highlighter for this resource, or undefined. */
|
|
90
|
+
find(query: SyntaxQuery): HighlighterDefinition | undefined;
|
|
91
|
+
/** Tokenise, falling back to one plain token per line. */
|
|
92
|
+
tokenize(text: string, query?: SyntaxQuery): SyntaxToken[][];
|
|
93
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Disposable } from './disposable.js';
|
|
2
|
+
import type { Size } from './geometry.js';
|
|
3
|
+
import type { TerminalCapabilities, CapabilityOverrides } from './capabilities.js';
|
|
4
|
+
import type { InputEvent } from './input.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Which capabilities the session wants turned on. The adapter records what it
|
|
8
|
+
* actually acquired, and `release` undoes exactly that and nothing else -
|
|
9
|
+
* which is the whole difference between a managed session and an embedded one.
|
|
10
|
+
*/
|
|
11
|
+
export interface TerminalSessionOptions {
|
|
12
|
+
/** TextUI owns setup and teardown of the terminal. */
|
|
13
|
+
managed?: boolean;
|
|
14
|
+
altScreen?: boolean;
|
|
15
|
+
mouse?: boolean;
|
|
16
|
+
wheel?: boolean;
|
|
17
|
+
focusEvents?: boolean;
|
|
18
|
+
paste?: boolean;
|
|
19
|
+
hideCursor?: boolean;
|
|
20
|
+
/** Kitty keyboard disambiguation, when available. */
|
|
21
|
+
enhancedKeys?: boolean;
|
|
22
|
+
title?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** What the adapter actually turned on, so release is exact. */
|
|
26
|
+
export interface AcquiredState {
|
|
27
|
+
altScreen: boolean;
|
|
28
|
+
mouse: boolean;
|
|
29
|
+
wheel: boolean;
|
|
30
|
+
focusEvents: boolean;
|
|
31
|
+
paste: boolean;
|
|
32
|
+
cursorHidden: boolean;
|
|
33
|
+
enhancedKeys: boolean;
|
|
34
|
+
rawMode: boolean;
|
|
35
|
+
titleSet: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface TerminalAdapter extends Disposable {
|
|
39
|
+
readonly id: string;
|
|
40
|
+
size(): Size;
|
|
41
|
+
capabilities(): TerminalCapabilities;
|
|
42
|
+
/** Explicit overrides win over detection. */
|
|
43
|
+
setCapabilityOverrides(overrides: CapabilityOverrides): void;
|
|
44
|
+
|
|
45
|
+
acquire(options: TerminalSessionOptions): Promise<AcquiredState> | AcquiredState;
|
|
46
|
+
release(): Promise<void> | void;
|
|
47
|
+
readonly acquired: AcquiredState | null;
|
|
48
|
+
|
|
49
|
+
write(data: string): void;
|
|
50
|
+
flush(): Promise<void> | void;
|
|
51
|
+
|
|
52
|
+
onInput(fn: (event: InputEvent) => void): Disposable;
|
|
53
|
+
onResize(fn: (size: Size) => void): Disposable;
|
|
54
|
+
|
|
55
|
+
/** OSC 52, when the terminal allows it. */
|
|
56
|
+
writeClipboard?(text: string): void;
|
|
57
|
+
setTitle?(title: string): void;
|
|
58
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { Color } from './cells.js';
|
|
2
|
+
import type { BorderChars, BorderStyle, ColorToken, Density, Style, StyleColor } from './style.js';
|
|
3
|
+
import type { SyntaxScope } from './syntax.js';
|
|
4
|
+
import type { Disposable } from './disposable.js';
|
|
5
|
+
import type { TerminalCapabilities } from './capabilities.js';
|
|
6
|
+
|
|
7
|
+
/** Spacing scale, in cells. Terminals have no sub-cell spacing. */
|
|
8
|
+
export interface ThemeSpacing {
|
|
9
|
+
none: number;
|
|
10
|
+
xs: number;
|
|
11
|
+
sm: number;
|
|
12
|
+
md: number;
|
|
13
|
+
lg: number;
|
|
14
|
+
xl: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The glyph vocabulary. Separated from colour because a 16-colour terminal may
|
|
19
|
+
* still be full-Unicode, and an ascii-only terminal may be truecolor.
|
|
20
|
+
*/
|
|
21
|
+
export interface ThemeGlyphs {
|
|
22
|
+
/** Status dots, bullets, arrows - keyed by role so a component names a role. */
|
|
23
|
+
bulletFilled: string;
|
|
24
|
+
bulletHollow: string;
|
|
25
|
+
bulletHalf: string;
|
|
26
|
+
check: string;
|
|
27
|
+
cross: string;
|
|
28
|
+
warning: string;
|
|
29
|
+
info: string;
|
|
30
|
+
chevronRight: string;
|
|
31
|
+
chevronDown: string;
|
|
32
|
+
chevronLeft: string;
|
|
33
|
+
chevronUp: string;
|
|
34
|
+
arrowUp: string;
|
|
35
|
+
arrowDown: string;
|
|
36
|
+
ellipsis: string;
|
|
37
|
+
search: string;
|
|
38
|
+
radioOn: string;
|
|
39
|
+
radioOff: string;
|
|
40
|
+
checkboxOn: string;
|
|
41
|
+
checkboxOff: string;
|
|
42
|
+
checkboxMixed: string;
|
|
43
|
+
/** Eight levels for sparklines and bar charts. */
|
|
44
|
+
blocks: readonly string[];
|
|
45
|
+
/** Progress bar track and fill. */
|
|
46
|
+
progressFull: string;
|
|
47
|
+
progressEmpty: string;
|
|
48
|
+
progressPartial: readonly string[];
|
|
49
|
+
spinner: readonly string[];
|
|
50
|
+
/** Text cursor when the terminal cursor is unavailable. */
|
|
51
|
+
caret: string;
|
|
52
|
+
separator: string;
|
|
53
|
+
/** Path separator in a breadcrumb. */
|
|
54
|
+
breadcrumb: string;
|
|
55
|
+
/**
|
|
56
|
+
* Where a region sits in the frame.
|
|
57
|
+
*
|
|
58
|
+
* One family, so a list of regions reads as a diagram rather than as six
|
|
59
|
+
* unrelated marks: the glyph says *where*, and `regionOff` says the region
|
|
60
|
+
* is not on screen. A tick cannot say where, which is why a list of ticks
|
|
61
|
+
* needs a second column of words to be readable at all.
|
|
62
|
+
*/
|
|
63
|
+
regionTop: string;
|
|
64
|
+
regionBottom: string;
|
|
65
|
+
regionLeft: string;
|
|
66
|
+
regionRight: string;
|
|
67
|
+
regionCentre: string;
|
|
68
|
+
regionOff: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface ThemeDefinition {
|
|
72
|
+
id: string;
|
|
73
|
+
name: string;
|
|
74
|
+
appearance: 'light' | 'dark';
|
|
75
|
+
/** Extend another registered theme; only the differences need stating. */
|
|
76
|
+
extends?: string;
|
|
77
|
+
colors: Partial<Record<ColorToken, Color>>;
|
|
78
|
+
spacing?: Partial<ThemeSpacing>;
|
|
79
|
+
glyphs?: Partial<ThemeGlyphs>;
|
|
80
|
+
/** Default border style for chrome. `'none'` gives the borderless look. */
|
|
81
|
+
border?: BorderStyle;
|
|
82
|
+
borderChars?: Partial<Record<BorderStyle, BorderChars>>;
|
|
83
|
+
density?: Density;
|
|
84
|
+
/** Per-component style overrides, keyed by component name then variant. */
|
|
85
|
+
components?: Record<string, Record<string, Style>>;
|
|
86
|
+
/**
|
|
87
|
+
* Colours for syntax scopes. Every scope has a default drawn from the
|
|
88
|
+
* semantic palette, so a theme states only what it wants to differ - and a
|
|
89
|
+
* theme that states nothing still highlights.
|
|
90
|
+
*/
|
|
91
|
+
syntax?: Partial<Record<SyntaxScope, StyleColor>>;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** A theme after `extends` resolution and capability downgrade. */
|
|
95
|
+
export interface ResolvedTheme {
|
|
96
|
+
id: string;
|
|
97
|
+
name: string;
|
|
98
|
+
appearance: 'light' | 'dark';
|
|
99
|
+
colors: Record<ColorToken, Color>;
|
|
100
|
+
spacing: ThemeSpacing;
|
|
101
|
+
glyphs: ThemeGlyphs;
|
|
102
|
+
border: BorderStyle;
|
|
103
|
+
density: Density;
|
|
104
|
+
components: Record<string, Record<string, Style>>;
|
|
105
|
+
/** Every syntax scope, resolved to a colour. */
|
|
106
|
+
syntax: Record<SyntaxScope, Color>;
|
|
107
|
+
/** Resolve a token (or pass a literal colour through). */
|
|
108
|
+
color(token: string): Color;
|
|
109
|
+
borderChars(style?: BorderStyle): BorderChars;
|
|
110
|
+
/** Component style for a name + variant list, merged in order. */
|
|
111
|
+
styleFor(component: string, variants?: string[]): Style;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface ThemeRegistry {
|
|
115
|
+
register(def: ThemeDefinition): Disposable;
|
|
116
|
+
unregister(id: string): void;
|
|
117
|
+
get(id: string): ThemeDefinition | undefined;
|
|
118
|
+
list(): ThemeDefinition[];
|
|
119
|
+
/** Resolve `extends`, apply capability downgrade, return a usable theme. */
|
|
120
|
+
resolve(id: string, caps: TerminalCapabilities): ResolvedTheme;
|
|
121
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BindingPath } from './graph.js';
|
|
2
|
+
|
|
3
|
+
export type ContextValue = string | number | boolean | null;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A small expression over store paths and context keys. Chrome that should not
|
|
7
|
+
* exist for this user does not mount, rather than mounting disabled.
|
|
8
|
+
*
|
|
9
|
+
* "$/session/role == 'admin'"
|
|
10
|
+
* "$/modus/capabilities/mouse && !$/ui/sidebar/collapsed"
|
|
11
|
+
* "$/modus/size/width >= 100"
|
|
12
|
+
*/
|
|
13
|
+
export type WhenClause = string;
|
|
14
|
+
|
|
15
|
+
export interface WhenEngine {
|
|
16
|
+
evaluate(clause: WhenClause | undefined, extra?: Record<string, ContextValue>): boolean;
|
|
17
|
+
/** Paths a clause reads, so a caller can subscribe to exactly those. */
|
|
18
|
+
dependencies(clause: WhenClause): BindingPath[];
|
|
19
|
+
setContext(key: string, value: ContextValue): void;
|
|
20
|
+
getContext(key: string): ContextValue | undefined;
|
|
21
|
+
}
|