@textui/core 0.1.0 → 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/README.md +17 -20
- package/dist/app/app.d.ts +36 -0
- package/dist/app/app.d.ts.map +1 -1
- package/dist/app/app.js +150 -1
- package/dist/core/focus.d.ts.map +1 -1
- package/dist/core/focus.js +12 -1
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +2 -10
- package/dist/jsx/intrinsics.d.ts +18 -0
- package/dist/jsx/intrinsics.d.ts.map +1 -1
- package/dist/render/layout.js +10 -2
- package/dist/themes/builtin.d.ts +2 -0
- package/dist/themes/builtin.d.ts.map +1 -1
- package/dist/themes/builtin.js +64 -1
- package/dist/themes/dividers.d.ts +14 -0
- package/dist/themes/dividers.d.ts.map +1 -0
- package/dist/themes/dividers.js +42 -0
- package/dist/themes/glyphs.d.ts.map +1 -1
- package/dist/themes/glyphs.js +4 -0
- package/dist/themes/index.d.ts +1 -0
- package/dist/themes/index.d.ts.map +1 -1
- package/dist/themes/index.js +1 -0
- package/dist/themes/registry.d.ts.map +1 -1
- package/dist/themes/registry.js +31 -1
- package/dist/types/command.d.ts +18 -1
- package/dist/types/command.d.ts.map +1 -1
- package/dist/types/input.d.ts +9 -0
- package/dist/types/input.d.ts.map +1 -1
- package/dist/types/markdown.d.ts +36 -1
- package/dist/types/markdown.d.ts.map +1 -1
- package/dist/types/style.d.ts +28 -1
- package/dist/types/style.d.ts.map +1 -1
- package/dist/types/terminal.d.ts +9 -0
- package/dist/types/terminal.d.ts.map +1 -1
- package/dist/types/theme.d.ts +26 -1
- package/dist/types/theme.d.ts.map +1 -1
- package/dist/util/markdown.d.ts.map +1 -1
- package/dist/util/markdown.js +172 -2
- package/dist/util/paths.d.ts +9 -3
- package/dist/util/paths.d.ts.map +1 -1
- package/dist/util/paths.js +11 -16
- package/package.json +5 -5
- package/src/app/app.ts +144 -1
- package/src/core/focus.ts +12 -1
- package/src/core/store.ts +2 -7
- package/src/jsx/intrinsics.ts +18 -0
- package/src/render/layout.ts +7 -2
- package/src/themes/builtin.ts +65 -1
- package/src/themes/dividers.ts +48 -0
- package/src/themes/glyphs.ts +4 -0
- package/src/themes/index.ts +1 -0
- package/src/themes/registry.ts +30 -2
- package/src/types/command.ts +18 -1
- package/src/types/input.ts +9 -0
- package/src/types/markdown.ts +38 -2
- package/src/types/style.ts +33 -1
- package/src/types/terminal.ts +9 -0
- package/src/types/theme.ts +29 -1
- package/src/util/markdown.ts +202 -3
- package/src/util/paths.ts +12 -15
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# @textui/core
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@textui/core) [](https://github.com/softov/textui/blob/main/LICENSE)
|
|
4
|
+
|
|
5
|
+
The runtime: a reactive store, typed registries, a cell-diffing renderer, hooks, and the four host primitives. Everything else in TextUI sits on this.
|
|
5
6
|
|
|
6
7
|
```bash
|
|
7
8
|
npm install @textui/core
|
|
@@ -9,10 +10,7 @@ npm install @textui/core
|
|
|
9
10
|
|
|
10
11
|
## The one idea
|
|
11
12
|
|
|
12
|
-
**JSX compiles to data.** `<Row gap={1}/>` and `{ component: 'Row', gap: 1 }` are
|
|
13
|
-
the same value, and the runtime mounts either. A screen can be written in
|
|
14
|
-
TypeScript, loaded from JSON, generated, edited or sent over a wire without the
|
|
15
|
-
runtime changing.
|
|
13
|
+
**JSX compiles to data.** `<Row gap={1}/>` and `{ component: 'Row', gap: 1 }` are the same value, and the runtime mounts either. A screen can be written in TypeScript, loaded from JSON, generated, edited or sent over a wire without the runtime changing.
|
|
16
14
|
|
|
17
15
|
```ts
|
|
18
16
|
import { h, renderToString } from '@textui/core';
|
|
@@ -23,18 +21,13 @@ console.log(renderToString(
|
|
|
23
21
|
));
|
|
24
22
|
```
|
|
25
23
|
|
|
26
|
-
Capitalized spellings of the primitives exist for JSX - `Box`, `Text`, `Canvas`
|
|
27
|
-
are the strings themselves, so `<Box/>` and `<box/>` produce the identical node.
|
|
24
|
+
Capitalized spellings of the primitives exist for JSX - `Box`, `Text`, `Canvas` are the strings themselves, so `<Box/>` and `<box/>` produce the identical node.
|
|
28
25
|
|
|
29
26
|
## What is in here, and what is not
|
|
30
27
|
|
|
31
|
-
The four primitives - `box`, `text`, `canvas`, `spacer` - are here because the
|
|
32
|
-
layout engine and the painter are the things that reason about them. The
|
|
33
|
-
eighty-seven components built out of them are [`@textui/widgets`](https://github.com/softov/textui/tree/main/packages/widgets),
|
|
34
|
-
a separate package that depends on this one.
|
|
28
|
+
The four primitives - `box`, `text`, `canvas`, `spacer` - are here because the layout engine and the painter are the things that reason about them. The eighty-seven components built out of them are [`@textui/widgets`](https://www.npmjs.com/package/@textui/widgets), a separate package that depends on this one.
|
|
35
29
|
|
|
36
|
-
That split is not tidiness. An imported component travels on its own node, so a
|
|
37
|
-
screen written in JSX resolves without a registry at all:
|
|
30
|
+
That split is not tidiness. An imported component travels on its own node, so a screen written in JSX resolves without a registry at all:
|
|
38
31
|
|
|
39
32
|
```ts
|
|
40
33
|
import { Badge } from '@textui/widgets';
|
|
@@ -42,9 +35,7 @@ import { Badge } from '@textui/widgets';
|
|
|
42
35
|
renderToString(h(Badge, { label: 'ok' }), { width: 20 }); // registry empty
|
|
43
36
|
```
|
|
44
37
|
|
|
45
|
-
The registry is for the case JSX cannot cover - a component named by a string,
|
|
46
|
-
in JSON, a template renderer, or an extension. `render` takes those through its
|
|
47
|
-
`components` option.
|
|
38
|
+
The registry is for the case JSX cannot cover - a component named by a string, in JSON, a template renderer, or an extension. `render` takes those through its `components` option.
|
|
48
39
|
|
|
49
40
|
## The parts
|
|
50
41
|
|
|
@@ -58,10 +49,16 @@ in JSON, a template renderer, or an extension. `render` takes those through its
|
|
|
58
49
|
|
|
59
50
|
## Runtime
|
|
60
51
|
|
|
61
|
-
No dependencies, and no `node:` imports - this package never touches a
|
|
62
|
-
filesystem or a process. It runs on Node 22+ and on Bun, and would run in a
|
|
63
|
-
browser against a virtual terminal.
|
|
52
|
+
No dependencies, and no `node:` imports - this package never touches a filesystem or a process. It runs on Node 22+ and on Bun, and would run in a browser against a virtual terminal.
|
|
64
53
|
|
|
65
54
|
## Documentation
|
|
66
55
|
|
|
67
56
|
<https://softov.github.io/textui/>
|
|
57
|
+
|
|
58
|
+
<!-- family -->
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
Part of **[TextUI](https://github.com/softov/textui)** - [documentation](https://softov.github.io/textui/) - [getting started](https://softov.github.io/textui/getting-started.html)
|
|
63
|
+
|
|
64
|
+
[`@textui/kit`](https://www.npmjs.com/package/@textui/kit) one install · **`@textui/core`** the runtime · [`@textui/widgets`](https://www.npmjs.com/package/@textui/widgets) the catalog · [`@textui/terminal`](https://www.npmjs.com/package/@textui/terminal) adapters and input · [`@textui/testing`](https://www.npmjs.com/package/@textui/testing) the harness · [`@textui/cli`](https://www.npmjs.com/package/@textui/cli) the CLI
|
package/dist/app/app.d.ts
CHANGED
|
@@ -60,6 +60,27 @@ export declare class App implements TextUIApp {
|
|
|
60
60
|
private resolvedTheme;
|
|
61
61
|
private bag;
|
|
62
62
|
private hovered;
|
|
63
|
+
/**
|
|
64
|
+
* Whoever took the last button down, until it comes back up.
|
|
65
|
+
*
|
|
66
|
+
* Mouse dispatch is a hit test, so without this a drag stops the moment the
|
|
67
|
+
* pointer leaves the box it started in - which is precisely when a drag
|
|
68
|
+
* becomes interesting. A selection dragged off the bottom of a field, a
|
|
69
|
+
* slider dragged past its own track and a splitter dragged across the pane
|
|
70
|
+
* it is resizing are all the pointer being somewhere the handler is not.
|
|
71
|
+
*/
|
|
72
|
+
private captured;
|
|
73
|
+
/**
|
|
74
|
+
* Everything under the pointer, innermost outwards.
|
|
75
|
+
*
|
|
76
|
+
* A chain rather than one node, because hover is inherited the way it is in
|
|
77
|
+
* a browser: a row lights up when the pointer is over the label inside it,
|
|
78
|
+
* and the label is what the hit test finds. Hover used to be a focus id
|
|
79
|
+
* compared against `props.id`, which meant only a focusable node could ever
|
|
80
|
+
* be hovered - so a tool call row, a list row and every other box that is
|
|
81
|
+
* clicked rather than focused had a `hover` style nothing could trigger.
|
|
82
|
+
*/
|
|
83
|
+
private hoveredChain;
|
|
63
84
|
/** Focus registrations created from `focusable` props, by focus id. */
|
|
64
85
|
private declaredFocus;
|
|
65
86
|
private lastFrame;
|
|
@@ -73,6 +94,13 @@ export declare class App implements TextUIApp {
|
|
|
73
94
|
get running(): boolean;
|
|
74
95
|
private publishEnvironment;
|
|
75
96
|
setTheme(id: string): void;
|
|
97
|
+
/**
|
|
98
|
+
* Ask the terminal for the theme's caret, when the theme states one.
|
|
99
|
+
*
|
|
100
|
+
* A theme that says nothing leaves the terminal's own setting alone, which
|
|
101
|
+
* is why this is not called with a default.
|
|
102
|
+
*/
|
|
103
|
+
private applyCursorShape;
|
|
76
104
|
setShell(id: string): void;
|
|
77
105
|
activeShell(): string;
|
|
78
106
|
setCapabilityOverrides(overrides: CapabilityOverrides): void;
|
|
@@ -166,6 +194,14 @@ export declare class App implements TextUIApp {
|
|
|
166
194
|
*/
|
|
167
195
|
private handleKey;
|
|
168
196
|
private handleMouse;
|
|
197
|
+
/**
|
|
198
|
+
* Who the pointer is over now, and who it has just left.
|
|
199
|
+
*
|
|
200
|
+
* `onHover` is called on the way in and the way out, once each - a handler
|
|
201
|
+
* that fires on every pixel of movement is a handler nobody can use for
|
|
202
|
+
* anything but a repaint.
|
|
203
|
+
*/
|
|
204
|
+
private updateHover;
|
|
169
205
|
/** Innermost box under the pointer first, then outward. */
|
|
170
206
|
private dispatchMouse;
|
|
171
207
|
private handleResize;
|
package/dist/app/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/app/app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAC3C,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAQ,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,KAAK,EAAE,UAAU,EAAwB,MAAM,mBAAmB,CAAC;AAM1E,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAa,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAS1D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAuBrD,qBAAa,GAAI,YAAW,SAAS;
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/app/app.ts"],"names":[],"mappings":"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"}
|
package/dist/app/app.js
CHANGED
|
@@ -76,6 +76,27 @@ export class App {
|
|
|
76
76
|
resolvedTheme;
|
|
77
77
|
bag = createBag();
|
|
78
78
|
hovered = null;
|
|
79
|
+
/**
|
|
80
|
+
* Whoever took the last button down, until it comes back up.
|
|
81
|
+
*
|
|
82
|
+
* Mouse dispatch is a hit test, so without this a drag stops the moment the
|
|
83
|
+
* pointer leaves the box it started in - which is precisely when a drag
|
|
84
|
+
* becomes interesting. A selection dragged off the bottom of a field, a
|
|
85
|
+
* slider dragged past its own track and a splitter dragged across the pane
|
|
86
|
+
* it is resizing are all the pointer being somewhere the handler is not.
|
|
87
|
+
*/
|
|
88
|
+
captured = null;
|
|
89
|
+
/**
|
|
90
|
+
* Everything under the pointer, innermost outwards.
|
|
91
|
+
*
|
|
92
|
+
* A chain rather than one node, because hover is inherited the way it is in
|
|
93
|
+
* a browser: a row lights up when the pointer is over the label inside it,
|
|
94
|
+
* and the label is what the hit test finds. Hover used to be a focus id
|
|
95
|
+
* compared against `props.id`, which meant only a focusable node could ever
|
|
96
|
+
* be hovered - so a tool call row, a list row and every other box that is
|
|
97
|
+
* clicked rather than focused had a `hover` style nothing could trigger.
|
|
98
|
+
*/
|
|
99
|
+
hoveredChain = new Set();
|
|
79
100
|
/** Focus registrations created from `focusable` props, by focus id. */
|
|
80
101
|
declaredFocus = new Map();
|
|
81
102
|
lastFrame = null;
|
|
@@ -209,10 +230,22 @@ export class App {
|
|
|
209
230
|
}
|
|
210
231
|
this.themeId = id;
|
|
211
232
|
this.resolvedTheme = this.themes.resolve(id, this.terminal.capabilities());
|
|
233
|
+
this.applyCursorShape();
|
|
212
234
|
this.store.set('$/modus/theme', id);
|
|
213
235
|
this.buffer_.invalidate();
|
|
214
236
|
this.requestRender(true);
|
|
215
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Ask the terminal for the theme's caret, when the theme states one.
|
|
240
|
+
*
|
|
241
|
+
* A theme that says nothing leaves the terminal's own setting alone, which
|
|
242
|
+
* is why this is not called with a default.
|
|
243
|
+
*/
|
|
244
|
+
applyCursorShape() {
|
|
245
|
+
const shape = this.resolvedTheme.cursor;
|
|
246
|
+
if (shape)
|
|
247
|
+
this.terminal.setCursorShape?.(shape);
|
|
248
|
+
}
|
|
216
249
|
setShell(id) {
|
|
217
250
|
if (!this.shells.get(id)) {
|
|
218
251
|
throw new Error(`[textui] no shell registered as "${id}"`);
|
|
@@ -231,6 +264,7 @@ export class App {
|
|
|
231
264
|
setCapabilityOverrides(overrides) {
|
|
232
265
|
this.terminal.setCapabilityOverrides(overrides);
|
|
233
266
|
this.resolvedTheme = this.themes.resolve(this.themeId, this.terminal.capabilities());
|
|
267
|
+
this.applyCursorShape();
|
|
234
268
|
this.publishEnvironment();
|
|
235
269
|
this.buffer_.invalidate();
|
|
236
270
|
this.requestRender(true);
|
|
@@ -270,6 +304,9 @@ export class App {
|
|
|
270
304
|
enhancedKeys: caps.kittyKeyboard,
|
|
271
305
|
...this.options.session,
|
|
272
306
|
});
|
|
307
|
+
// After `acquire`, never before: with no session there is nothing to put
|
|
308
|
+
// the shape back, so an early call is dropped rather than leaked.
|
|
309
|
+
this.applyCursorShape();
|
|
273
310
|
this.bag.add(this.terminal.onInput((event) => this.handleInput(event)));
|
|
274
311
|
this.bag.add(this.terminal.onResize((size) => this.handleResize(size)));
|
|
275
312
|
this.running_ = true;
|
|
@@ -546,7 +583,7 @@ export class App {
|
|
|
546
583
|
const focusedId = this.focus.focused();
|
|
547
584
|
return {
|
|
548
585
|
focused: focusedId === id || focusedId === `${instance.id}:focus`,
|
|
549
|
-
hovered: this.hovered === id,
|
|
586
|
+
hovered: this.hovered === id || this.hoveredChain.has(instance),
|
|
550
587
|
active: false,
|
|
551
588
|
selected: instance.props.selected === true,
|
|
552
589
|
disabled: instance.props.disabled === true,
|
|
@@ -811,6 +848,27 @@ export class App {
|
|
|
811
848
|
this.requestRender();
|
|
812
849
|
return;
|
|
813
850
|
}
|
|
851
|
+
/*
|
|
852
|
+
* A modal takes escape before any keybinding does.
|
|
853
|
+
*
|
|
854
|
+
* `dismissOnEscape` was unreachable in any application with a global
|
|
855
|
+
* escape binding, which most have: the binding matched first, the layer
|
|
856
|
+
* stayed open, and the key went to whatever "go back" means behind it.
|
|
857
|
+
* What that looks like is a confirm dialog you cannot leave, over a screen
|
|
858
|
+
* that has navigated somewhere else while you were reading it.
|
|
859
|
+
*
|
|
860
|
+
* The test is `trapFocus`, not `dismissOnEscape` alone. A layer that traps
|
|
861
|
+
* focus has claimed the keyboard, so nothing behind it should be acting on
|
|
862
|
+
* keys; a toast or a tooltip has not, and those keep the old order so that
|
|
863
|
+
* escape still reaches the application while one happens to be up.
|
|
864
|
+
*/
|
|
865
|
+
if (event.name === 'escape') {
|
|
866
|
+
const top = this.layers.topmostDismissible();
|
|
867
|
+
if (top && top.trapFocus) {
|
|
868
|
+
this.layers.close(top.id, 'escape');
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
814
872
|
if (this.keybindings.handle(event) !== 'unhandled') {
|
|
815
873
|
this.requestRender();
|
|
816
874
|
return;
|
|
@@ -831,14 +889,43 @@ export class App {
|
|
|
831
889
|
this.requestRender();
|
|
832
890
|
}
|
|
833
891
|
handleMouse(event) {
|
|
892
|
+
// The rest of the gesture belongs to whoever took the button down,
|
|
893
|
+
// wherever the pointer has got to since - and it is delivered whether or
|
|
894
|
+
// not the handler claims it, because during a drag there is nothing else
|
|
895
|
+
// it could be for.
|
|
896
|
+
if (this.captured && (event.action === 'drag' || event.action === 'up')) {
|
|
897
|
+
const target = this.captured;
|
|
898
|
+
if (event.action === 'up')
|
|
899
|
+
this.captured = null;
|
|
900
|
+
if (target.mounted) {
|
|
901
|
+
const onMouse = target.props.onMouse;
|
|
902
|
+
if (typeof onMouse === 'function') {
|
|
903
|
+
onMouse(event);
|
|
904
|
+
this.requestRender();
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
// Unmounted mid-drag, or it stopped taking the pointer: the gesture has
|
|
909
|
+
// nowhere to go, so let the hit test have it back.
|
|
910
|
+
this.captured = null;
|
|
911
|
+
}
|
|
834
912
|
const hit = this.focus.at(event.x, event.y);
|
|
835
913
|
if (event.action === 'move') {
|
|
914
|
+
const moved = this.updateHover(event);
|
|
836
915
|
if (hit !== this.hovered) {
|
|
837
916
|
this.hovered = hit;
|
|
838
917
|
this.requestRender();
|
|
839
918
|
}
|
|
919
|
+
else if (moved) {
|
|
920
|
+
this.requestRender();
|
|
921
|
+
}
|
|
840
922
|
return;
|
|
841
923
|
}
|
|
924
|
+
// A new press ends the last one, claimed or not: an `up` that never
|
|
925
|
+
// arrived - a terminal that lost focus mid-drag - must not leave a capture
|
|
926
|
+
// that eats the next gesture.
|
|
927
|
+
if (event.action === 'down')
|
|
928
|
+
this.captured = null;
|
|
842
929
|
if (event.action === 'down' && hit)
|
|
843
930
|
this.focus.focus(hit);
|
|
844
931
|
if (this.root) {
|
|
@@ -846,6 +933,46 @@ export class App {
|
|
|
846
933
|
}
|
|
847
934
|
this.requestRender();
|
|
848
935
|
}
|
|
936
|
+
/**
|
|
937
|
+
* Who the pointer is over now, and who it has just left.
|
|
938
|
+
*
|
|
939
|
+
* `onHover` is called on the way in and the way out, once each - a handler
|
|
940
|
+
* that fires on every pixel of movement is a handler nobody can use for
|
|
941
|
+
* anything but a repaint.
|
|
942
|
+
*/
|
|
943
|
+
updateHover(event) {
|
|
944
|
+
const next = new Set();
|
|
945
|
+
if (this.root)
|
|
946
|
+
collectHover(this.root, event.x, event.y, next);
|
|
947
|
+
let changed = next.size !== this.hoveredChain.size;
|
|
948
|
+
if (!changed) {
|
|
949
|
+
for (const instance of next) {
|
|
950
|
+
if (!this.hoveredChain.has(instance)) {
|
|
951
|
+
changed = true;
|
|
952
|
+
break;
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
if (!changed)
|
|
957
|
+
return false;
|
|
958
|
+
const previous = this.hoveredChain;
|
|
959
|
+
this.hoveredChain = next;
|
|
960
|
+
for (const instance of previous) {
|
|
961
|
+
if (next.has(instance) || !instance.mounted)
|
|
962
|
+
continue;
|
|
963
|
+
const onHover = instance.props.onHover;
|
|
964
|
+
if (typeof onHover === 'function')
|
|
965
|
+
onHover(false);
|
|
966
|
+
}
|
|
967
|
+
for (const instance of next) {
|
|
968
|
+
if (previous.has(instance))
|
|
969
|
+
continue;
|
|
970
|
+
const onHover = instance.props.onHover;
|
|
971
|
+
if (typeof onHover === 'function')
|
|
972
|
+
onHover(true);
|
|
973
|
+
}
|
|
974
|
+
return true;
|
|
975
|
+
}
|
|
849
976
|
/** Innermost box under the pointer first, then outward. */
|
|
850
977
|
dispatchMouse(instance, event) {
|
|
851
978
|
for (let i = instance.children.length - 1; i >= 0; i--) {
|
|
@@ -861,6 +988,9 @@ export class App {
|
|
|
861
988
|
return false;
|
|
862
989
|
const onMouse = instance.props.onMouse;
|
|
863
990
|
if (typeof onMouse === 'function' && onMouse(event) === true) {
|
|
991
|
+
// Taking the button down is what claims the drag that follows it.
|
|
992
|
+
if (event.action === 'down')
|
|
993
|
+
this.captured = instance;
|
|
864
994
|
return true;
|
|
865
995
|
}
|
|
866
996
|
if (event.action === 'down' && event.button === 'left') {
|
|
@@ -978,3 +1108,22 @@ export const WRITER_KEY = serviceKey('textui.writer');
|
|
|
978
1108
|
export function createApp(options = {}) {
|
|
979
1109
|
return new App(options);
|
|
980
1110
|
}
|
|
1111
|
+
/**
|
|
1112
|
+
* Every box containing the point, from the root down.
|
|
1113
|
+
*
|
|
1114
|
+
* The whole chain rather than the innermost one: a row is hovered when the
|
|
1115
|
+
* pointer is over the text inside it, and the text is what a hit test finds.
|
|
1116
|
+
* Only boxes with a laid-out rect count - a component that produced no box
|
|
1117
|
+
* occupies no space, so there is nothing to be over.
|
|
1118
|
+
*/
|
|
1119
|
+
function collectHover(instance, x, y, into) {
|
|
1120
|
+
const box = instance.box;
|
|
1121
|
+
if (box) {
|
|
1122
|
+
const { x: bx, y: by, width, height } = box.rect;
|
|
1123
|
+
if (x < bx || x >= bx + width || y < by || y >= by + height)
|
|
1124
|
+
return;
|
|
1125
|
+
into.add(instance);
|
|
1126
|
+
}
|
|
1127
|
+
for (const child of instance.children)
|
|
1128
|
+
collectHover(child, x, y, into);
|
|
1129
|
+
}
|
package/dist/core/focus.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"focus.d.ts","sourceRoot":"","sources":["../../src/core/focus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAClE,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AASzD,8EAA8E;AAC9E,eAAO,MAAM,YAAY,eAAe,CAAC;AAEzC;;;;;;;GAOG;AACH,qBAAa,KAAM,YAAW,YAAY;IAQ5B,OAAO,CAAC,QAAQ;IAP5B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,KAAK,CAAuC;IACpD,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,OAAO,CAAuB;gBAElB,QAAQ,GAAE,MAAM,IAAe;IAOnD,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU;IAQrD,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAe/B,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAgCjC,WAAW,IAAI,MAAM,GAAG,IAAI;IAK5B,qDAAqD;IACrD,OAAO,CAAC,aAAa;IAQrB,6EAA6E;IAC7E,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAM/B,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,UAAU;
|
|
1
|
+
{"version":3,"file":"focus.d.ts","sourceRoot":"","sources":["../../src/core/focus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAClE,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AASzD,8EAA8E;AAC9E,eAAO,MAAM,YAAY,eAAe,CAAC;AAEzC;;;;;;;GAOG;AACH,qBAAa,KAAM,YAAW,YAAY;IAQ5B,OAAO,CAAC,QAAQ;IAP5B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,KAAK,CAAuC;IACpD,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,OAAO,CAAuB;gBAElB,QAAQ,GAAE,MAAM,IAAe;IAOnD,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU;IAQrD,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAe/B,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAgCjC,WAAW,IAAI,MAAM,GAAG,IAAI;IAK5B,qDAAqD;IACrD,OAAO,CAAC,aAAa;IAQrB,6EAA6E;IAC7E,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAM/B,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,UAAU;IA4C/C,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAgB1D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAa1B,IAAI,IAAI,IAAI;IAQZ,OAAO,IAAI,MAAM,GAAG,IAAI;IAIxB,KAAK,IAAI,MAAM,EAAE;IAOjB,kEAAkE;IAClE,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAsBjC,IAAI,CAAC,SAAS,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI;IAe9C;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAwCvB,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAgBvC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO;IAiClC,0EAA0E;IAC1E,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI;CAItC;AAED,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,KAAK,CAExD"}
|
package/dist/core/focus.js
CHANGED
|
@@ -111,7 +111,18 @@ export class Focus {
|
|
|
111
111
|
// the screen this is for - pushed over whatever had focus, which the push
|
|
112
112
|
// unmounted, leaving none - and a dialog, which opens while its opener
|
|
113
113
|
// still holds focus and whose own controls say which of them wants it.
|
|
114
|
-
|
|
114
|
+
//
|
|
115
|
+
// And only onto something a person could have tabbed to. A `global`
|
|
116
|
+
// handler registers as a focusable - that is how a layer reads escape
|
|
117
|
+
// without holding focus - and it is `skipTab`, so it is not a place focus
|
|
118
|
+
// can land. Handed it anyway, focus sat on a node that consumes nothing:
|
|
119
|
+
// the keys fell through to whatever was behind, and every real control's
|
|
120
|
+
// own `autoFocus` stood down, because it claims focus only when the scope
|
|
121
|
+
// does not already hold it. A question with a text field in it was
|
|
122
|
+
// therefore unanswerable - the field was drawn, `required` beside it, and
|
|
123
|
+
// what was typed at it went into the composer underneath.
|
|
124
|
+
const focusable = options.disabled !== true && options.skipTab !== true && options.global !== true;
|
|
125
|
+
if (!existing && focusable && this.current === null) {
|
|
115
126
|
const scopeId = options.scopeId ?? GLOBAL_SCOPE;
|
|
116
127
|
if (this.scopes.get(scopeId)?.autoFocus === true && this.stack.includes(scopeId)) {
|
|
117
128
|
this.focus(options.id);
|
package/dist/core/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,sBAAsB,EACvE,UAAU,EAAE,kBAAkB,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB,EAC3E,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA0BzD;;;;GAIG;AACH,qBAAa,KAAM,YAAW,aAAa;IACzC,OAAO,CAAC,IAAI,CAA+B;IAC3C,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,aAAa,CAAoD;IAEzE,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,QAAQ,CAAS;IAEzB,6EAA6E;IAC7E,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAE9C;IAIF,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,CAAC,GAAG,SAAS;IAMlD,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC;IAK1C,GAAG,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO;IAI/B,OAAO,CAAC,OAAO;IAoBf,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAQ5C,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,KAAK,CAAC,GAAG,IAAI;IAI/E,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAMhE,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAQjD,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAgB/B,OAAO,CAAC,QAAQ;IAiChB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAUxB,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,MAAM;IAYd,OAAO,CAAC,UAAU;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,sBAAsB,EACvE,UAAU,EAAE,kBAAkB,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB,EAC3E,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA0BzD;;;;GAIG;AACH,qBAAa,KAAM,YAAW,aAAa;IACzC,OAAO,CAAC,IAAI,CAA+B;IAC3C,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,aAAa,CAAoD;IAEzE,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,QAAQ,CAAS;IAEzB,6EAA6E;IAC7E,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAE9C;IAIF,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,CAAC,GAAG,SAAS;IAMlD,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC;IAK1C,GAAG,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO;IAI/B,OAAO,CAAC,OAAO;IAoBf,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAQ5C,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,KAAK,CAAC,GAAG,IAAI;IAI/E,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAMhE,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAQjD,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAgB/B,OAAO,CAAC,QAAQ;IAiChB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAUxB,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,MAAM;IAYd,OAAO,CAAC,UAAU;IAOlB,SAAS,CACP,IAAI,EAAE,WAAW,EACjB,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,EAClD,OAAO,GAAE,gBAAqB,GAC7B,UAAU;IA0Bb,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM;IAQlD,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI;IAgB3C,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,UAAU;IAsChF,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,mBAAmB;IAgB3B,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC;IA2D5D,oBAAoB,CAAC,GAAG,EAAE,sBAAsB,GAAG,UAAU;IAY7D,iBAAiB,IAAI,sBAAsB,EAAE;IAI7C,yEAAyE;IACzE,OAAO,CAAC,aAAa;YAWP,YAAY;IAiB1B,OAAO,CAAC,mBAAmB;IAmB3B,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU;IAS9C,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,GAAG,UAAU;IAUtD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAe9B,OAAO,CAAC,eAAe;IAgCvB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAO7D,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAQhD,OAAO,IAAI,IAAI;CAmBhB;AAmDD,wBAAgB,WAAW,IAAI,KAAK,CAEnC"}
|
package/dist/core/store.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toDisposable } from '../util/disposable.js';
|
|
2
|
-
import {
|
|
2
|
+
import { hasWildcard, isDescendantKey, keysTouch, matchKey, pathKey, PathError, } from '../util/paths.js';
|
|
3
3
|
/**
|
|
4
4
|
* The store is one tree, and it is the only place state lives. A component
|
|
5
5
|
* that keeps a copy in its own state has created a second answer to a question
|
|
@@ -184,15 +184,7 @@ export class Store {
|
|
|
184
184
|
subMatches(sub, changedKey) {
|
|
185
185
|
if (sub.wildcard)
|
|
186
186
|
return matchKey(changedKey, sub.key, sub.subtree);
|
|
187
|
-
|
|
188
|
-
return true;
|
|
189
|
-
// A write below an exact subscription still changes that object's contents.
|
|
190
|
-
if (isDescendantKey(changedKey, sub.key))
|
|
191
|
-
return true;
|
|
192
|
-
// A write above it may have replaced the subtree the subscriber reads.
|
|
193
|
-
if (isDescendantKey(sub.key, changedKey))
|
|
194
|
-
return true;
|
|
195
|
-
return sub.subtree && ancestorKeys(changedKey).includes(sub.key);
|
|
187
|
+
return keysTouch(changedKey, sub.key);
|
|
196
188
|
}
|
|
197
189
|
// ---------------------------------------------------------- subscriptions
|
|
198
190
|
subscribe(path, fn, options = {}) {
|
package/dist/jsx/intrinsics.d.ts
CHANGED
|
@@ -38,8 +38,26 @@ export interface BaseProps extends Style {
|
|
|
38
38
|
onKey?(event: KeyEvent): boolean | void;
|
|
39
39
|
onFocus?(): void;
|
|
40
40
|
onBlur?(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Every mouse action on this node, innermost first.
|
|
43
|
+
*
|
|
44
|
+
* Returning `true` stops it going any further - and on a `down`, **claims
|
|
45
|
+
* the rest of the gesture**: the `drag`s and the `up` that follow come here
|
|
46
|
+
* whatever they are over, until the button comes back up. Dispatch is
|
|
47
|
+
* otherwise a hit test, so without that a drag would stop at the edge of the
|
|
48
|
+
* node it started in, which is where a drag starts being worth having.
|
|
49
|
+
*/
|
|
41
50
|
onMouse?(event: MouseEvent): boolean | void;
|
|
51
|
+
/** The left button going down - a third of a gesture. `onMouse` for the rest. */
|
|
42
52
|
onClick?: Action | ((event: MouseEvent) => void);
|
|
53
|
+
/**
|
|
54
|
+
* The pointer entered or left this node. Called once each way, not per cell.
|
|
55
|
+
*
|
|
56
|
+
* Hover is inherited the way it is in a browser: a row is hovered while the
|
|
57
|
+
* pointer is over the label inside it, because the label is what a hit test
|
|
58
|
+
* finds. A `style` with a `hover` overlay needs nothing else - this is for
|
|
59
|
+
* the cases where something other than a colour has to happen.
|
|
60
|
+
*/
|
|
43
61
|
onHover?(hovering: boolean): void;
|
|
44
62
|
/** OSC 8 link target, where the terminal supports hyperlinks. */
|
|
45
63
|
link?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intrinsics.d.ts","sourceRoot":"","sources":["../../src/jsx/intrinsics.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"intrinsics.d.ts","sourceRoot":"","sources":["../../src/jsx/intrinsics.ts"],"names":[],"mappings":"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"}
|
package/dist/render/layout.js
CHANGED
|
@@ -387,8 +387,16 @@ function layoutBox(box, rect) {
|
|
|
387
387
|
box.rect = { ...box.rect, width: 0, height: 0 };
|
|
388
388
|
return;
|
|
389
389
|
}
|
|
390
|
-
const flow =
|
|
391
|
-
const absolute =
|
|
390
|
+
const flow = [];
|
|
391
|
+
const absolute = [];
|
|
392
|
+
for (const child of box.children) {
|
|
393
|
+
if (isHidden(child))
|
|
394
|
+
continue;
|
|
395
|
+
if (isAbsolute(child))
|
|
396
|
+
absolute.push(child);
|
|
397
|
+
else
|
|
398
|
+
flow.push(child);
|
|
399
|
+
}
|
|
392
400
|
if (flow.length > 0)
|
|
393
401
|
layoutFlow(box, flow);
|
|
394
402
|
for (const child of absolute)
|
package/dist/themes/builtin.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export declare const LIGHT: ThemeDefinition;
|
|
|
14
14
|
export declare const CONSOLE: ThemeDefinition;
|
|
15
15
|
/** Borderless. Whitespace and alignment do the separating. */
|
|
16
16
|
export declare const PAPER: ThemeDefinition;
|
|
17
|
+
/** Borderless. Whitespace and alignment do the separating. */
|
|
18
|
+
export declare const PAPER_LIGHT: ThemeDefinition;
|
|
17
19
|
/** Rounded chrome around a persistent frame. */
|
|
18
20
|
export declare const WORKBENCH: ThemeDefinition;
|
|
19
21
|
/** No colour at all. What a `colorDepth: 0` terminal or a pipe gets. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtin.d.ts","sourceRoot":"","sources":["../../src/themes/builtin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;;;;;;GAQG;AAEH,eAAO,MAAM,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"builtin.d.ts","sourceRoot":"","sources":["../../src/themes/builtin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;;;;;;GAQG;AAEH,eAAO,MAAM,IAAI,EAAE,eA6ClB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,eA6CnB,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,OAAO,EAAE,eAqCrB,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,KAAK,EAAE,eAkDnB,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,WAAW,EAAE,eAkCzB,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,SAAS,EAAE,eAkCvB,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,IAAI,EAAE,eA6ClB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,EAAE,eA+BxB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,eAAe,EAE3C,CAAC"}
|