@textui/widgets 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/control/text-area.d.ts +2 -0
- package/dist/control/text-area.d.ts.map +1 -1
- package/dist/control/text-area.js +16 -8
- package/dist/data/code-viewer.d.ts +2 -0
- package/dist/data/code-viewer.d.ts.map +1 -1
- package/dist/data/code-viewer.js +9 -1
- package/dist/data/index.d.ts +9 -0
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js +8 -2
- package/dist/data/list.d.ts +9 -0
- package/dist/data/list.d.ts.map +1 -1
- package/dist/data/list.js +20 -3
- package/dist/data/markdown-view.d.ts.map +1 -1
- package/dist/data/markdown-view.js +4 -1
- package/dist/data/pagination.d.ts.map +1 -1
- package/dist/data/pagination.js +4 -1
- package/dist/data/tree.d.ts +2 -0
- package/dist/data/tree.d.ts.map +1 -1
- package/dist/data/tree.js +8 -2
- package/dist/display/card.d.ts.map +1 -1
- package/dist/display/card.js +12 -0
- package/dist/display/color-text.d.ts +13 -1
- package/dist/display/color-text.d.ts.map +1 -1
- package/dist/display/color-text.js +28 -6
- package/dist/display/font-text.d.ts +72 -0
- package/dist/display/font-text.d.ts.map +1 -0
- package/dist/display/font-text.js +35 -0
- package/dist/display/fonts.d.ts +138 -0
- package/dist/display/fonts.d.ts.map +1 -0
- package/dist/display/fonts.js +893 -0
- package/dist/display/gard.d.ts +26 -0
- package/dist/display/gard.d.ts.map +1 -0
- package/dist/display/gard.js +479 -0
- package/dist/display/index.d.ts +3 -0
- package/dist/display/index.d.ts.map +1 -1
- package/dist/display/index.js +7 -0
- package/dist/display/key-value.d.ts +25 -5
- package/dist/display/key-value.d.ts.map +1 -1
- package/dist/display/key-value.js +13 -3
- package/dist/display/pagga.d.ts +29 -0
- package/dist/display/pagga.d.ts.map +1 -0
- package/dist/display/pagga.js +101 -0
- package/dist/display/pattern.d.ts +117 -0
- package/dist/display/pattern.d.ts.map +1 -0
- package/dist/display/pattern.js +257 -0
- package/dist/display/spinner.d.ts +2 -0
- package/dist/display/spinner.d.ts.map +1 -1
- package/dist/display/spinner.js +3 -2
- package/dist/navigation/menu.d.ts +2 -0
- package/dist/navigation/menu.d.ts.map +1 -1
- package/dist/navigation/menu.js +19 -6
- package/dist/navigation/tabs.d.ts +2 -0
- package/dist/navigation/tabs.d.ts.map +1 -1
- package/dist/navigation/tabs.js +12 -2
- package/package.json +2 -2
- package/src/control/text-area.ts +18 -7
- package/src/data/code-viewer.ts +10 -1
- package/src/data/index.ts +9 -2
- package/src/data/list.ts +21 -3
- package/src/data/markdown-view.ts +7 -4
- package/src/data/pagination.ts +4 -1
- package/src/data/tree.ts +9 -2
- package/src/display/card.ts +12 -0
- package/src/display/color-text.ts +33 -10
- package/src/display/font-text.tsx +94 -0
- package/src/display/fonts.ts +990 -0
- package/src/display/gard.ts +475 -0
- package/src/display/index.ts +7 -0
- package/src/display/key-value.ts +44 -6
- package/src/display/pagga.ts +102 -0
- package/src/display/pattern.tsx +427 -0
- package/src/display/spinner.ts +5 -2
- package/src/navigation/menu.ts +20 -6
- package/src/navigation/tabs.ts +13 -2
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `pagga` table, transcribed.
|
|
3
|
+
*
|
|
4
|
+
* Three rows of half cells on a `░` ground - which is the difference between
|
|
5
|
+
* this and `half`, and the whole reason for it. `half` draws letters and
|
|
6
|
+
* leaves the space around them empty; this draws them *on* something, so the
|
|
7
|
+
* banner is a block of texture with the letters knocked out of it rather than
|
|
8
|
+
* strokes floating on the terminal's background.
|
|
9
|
+
*
|
|
10
|
+
* That ground is why the glyphs are four columns rather than three. The first
|
|
11
|
+
* column of every one is the `░` gutter, so the letters butt together and the
|
|
12
|
+
* ground runs unbroken between them - and why the space is a glyph of its own
|
|
13
|
+
* rather than a gap, because a gap would be a hole in it.
|
|
14
|
+
*
|
|
15
|
+
* One case: the source has one set of letters and lowercase folds to it.
|
|
16
|
+
*
|
|
17
|
+
* The punctuation comes from two places and the table says which is which. The
|
|
18
|
+
* marks above the divider are transcribed - and the brackets among them took a
|
|
19
|
+
* correction, because the source lists three pairs with nothing saying which is
|
|
20
|
+
* which and shape alone does not settle it: the square-cornered pair reads as
|
|
21
|
+
* `(` `)` just as happily as `[` `]`, and it was the wrong one of the two.
|
|
22
|
+
*
|
|
23
|
+
* The marks below it are drawn to match, because the source has none of them
|
|
24
|
+
* at all - no full stop, no comma, no slash. Which is worth knowing when one
|
|
25
|
+
* of them looks out of place: it is not a transcription error, it is a
|
|
26
|
+
* judgement, and a paste would replace it.
|
|
27
|
+
*/
|
|
28
|
+
export declare const PAGGA: Record<string, string[]>;
|
|
29
|
+
//# sourceMappingURL=pagga.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagga.d.ts","sourceRoot":"","sources":["../../src/display/pagga.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CA0E1C,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `pagga` table, transcribed.
|
|
3
|
+
*
|
|
4
|
+
* Three rows of half cells on a `░` ground - which is the difference between
|
|
5
|
+
* this and `half`, and the whole reason for it. `half` draws letters and
|
|
6
|
+
* leaves the space around them empty; this draws them *on* something, so the
|
|
7
|
+
* banner is a block of texture with the letters knocked out of it rather than
|
|
8
|
+
* strokes floating on the terminal's background.
|
|
9
|
+
*
|
|
10
|
+
* That ground is why the glyphs are four columns rather than three. The first
|
|
11
|
+
* column of every one is the `░` gutter, so the letters butt together and the
|
|
12
|
+
* ground runs unbroken between them - and why the space is a glyph of its own
|
|
13
|
+
* rather than a gap, because a gap would be a hole in it.
|
|
14
|
+
*
|
|
15
|
+
* One case: the source has one set of letters and lowercase folds to it.
|
|
16
|
+
*
|
|
17
|
+
* The punctuation comes from two places and the table says which is which. The
|
|
18
|
+
* marks above the divider are transcribed - and the brackets among them took a
|
|
19
|
+
* correction, because the source lists three pairs with nothing saying which is
|
|
20
|
+
* which and shape alone does not settle it: the square-cornered pair reads as
|
|
21
|
+
* `(` `)` just as happily as `[` `]`, and it was the wrong one of the two.
|
|
22
|
+
*
|
|
23
|
+
* The marks below it are drawn to match, because the source has none of them
|
|
24
|
+
* at all - no full stop, no comma, no slash. Which is worth knowing when one
|
|
25
|
+
* of them looks out of place: it is not a transcription error, it is a
|
|
26
|
+
* judgement, and a paste would replace it.
|
|
27
|
+
*/
|
|
28
|
+
export const PAGGA = {
|
|
29
|
+
0: ["░▄▀▄", "░█/█", "░░▀░"],
|
|
30
|
+
1: ["░▀█░", "░░█░", "░▀▀▀"],
|
|
31
|
+
2: ["░▀▀▄", "░▄▀░", "░▀▀▀"],
|
|
32
|
+
3: ["░▀▀█", "░░▀▄", "░▀▀░"],
|
|
33
|
+
4: ["░█░█", "░░▀█", "░░░▀"],
|
|
34
|
+
5: ["░█▀▀", "░▀▀▄", "░▀▀░"],
|
|
35
|
+
6: ["░▄▀▀", "░█▀▄", "░░▀░"],
|
|
36
|
+
7: ["░▀▀█", "░▄▀░", "░▀░░"],
|
|
37
|
+
8: ["░▄▀▄", "░▄▀▄", "░░▀░"],
|
|
38
|
+
9: ["░▄▀▄", "░░▀█", "░▀▀░"],
|
|
39
|
+
A: ["░█▀█", "░█▀█", "░▀░▀"],
|
|
40
|
+
B: ["░█▀▄", "░█▀▄", "░▀▀░"],
|
|
41
|
+
C: ["░█▀▀", "░█░░", "░▀▀▀"],
|
|
42
|
+
D: ["░█▀▄", "░█░█", "░▀▀░"],
|
|
43
|
+
E: ["░█▀▀", "░█▀▀", "░▀▀▀"],
|
|
44
|
+
F: ["░█▀▀", "░█▀▀", "░▀░░"],
|
|
45
|
+
G: ["░█▀▀", "░█░█", "░▀▀▀"],
|
|
46
|
+
H: ["░█░█", "░█▀█", "░▀░▀"],
|
|
47
|
+
I: ["░▀█▀", "░░█░", "░▀▀▀"],
|
|
48
|
+
J: ["░▀▀█", "░░░█", "░▀▀░"],
|
|
49
|
+
K: ["░█░█", "░█▀▄", "░▀░▀"],
|
|
50
|
+
L: ["░█░░", "░█░░", "░▀▀▀"],
|
|
51
|
+
M: ["░█▄█", "░█░█", "░▀░▀"],
|
|
52
|
+
N: ["░█▀█", "░█░█", "░▀░▀"],
|
|
53
|
+
O: ["░█▀█", "░█░█", "░▀▀▀"],
|
|
54
|
+
P: ["░█▀█", "░█▀▀", "░▀░░"],
|
|
55
|
+
Q: ["░▄▀▄", "░█\\█", "░░▀\\"],
|
|
56
|
+
R: ["░█▀▄", "░█▀▄", "░▀░▀"],
|
|
57
|
+
S: ["░█▀▀", "░▀▀█", "░▀▀▀"],
|
|
58
|
+
T: ["░▀█▀", "░░█░", "░░▀░"],
|
|
59
|
+
U: ["░█░█", "░█░█", "░▀▀▀"],
|
|
60
|
+
V: ["░█░█", "░▀▄▀", "░░▀░"],
|
|
61
|
+
W: ["░█░█", "░█▄█", "░▀░▀"],
|
|
62
|
+
X: ["░█░█", "░▄▀▄", "░▀░▀"],
|
|
63
|
+
Y: ["░█░█", "░░█░", "░░▀░"],
|
|
64
|
+
Z: ["░▀▀█", "░▄▀░", "░▀▀▀"],
|
|
65
|
+
"!": ["░█", "░▀", "░▀"],
|
|
66
|
+
"?": ["░▄▀▄", "░█▀▀", "░░▀░"],
|
|
67
|
+
"#": ["░▄█▄█▄", "░▄█▄█▄", "░░▀░▀░"],
|
|
68
|
+
"$": ["░▄█▀", "░▀██", "░▀▀░"],
|
|
69
|
+
"%": ["░▀░█", "░▄▀░", "░▀░▀"],
|
|
70
|
+
"&": ["░▄▀░", "░▄█▀", "░░▀▀"],
|
|
71
|
+
"*": ["░▄░▄", "░▄█▄", "░▄▀▄"],
|
|
72
|
+
"[": ["░█▀░", "░█░░", "░▀▀░"],
|
|
73
|
+
"]": ["░▀█░", "░░█░", "░▀▀░"],
|
|
74
|
+
"_": ["░░░░", "░░░░", "░▀▀▀"],
|
|
75
|
+
"+": ["░░░░", "░▄█▄", "░░▀░"],
|
|
76
|
+
"-": ["░░░░", "░▄▄▄", "░░░░"],
|
|
77
|
+
"=": ["░░░░", "░▀▀▀", "░▀▀▀"],
|
|
78
|
+
"\"": ["░▀░▀", "░░░░", "░░░░"],
|
|
79
|
+
"'": ["░▀", "░░", "░░"],
|
|
80
|
+
"(": ["░▄▀░", "░█░░", "░░▀░"],
|
|
81
|
+
")": ["░▀▄░", "░░█░", "░▀░░"],
|
|
82
|
+
"{": ["░░█▀", "░▀▄░", "░░▀▀"],
|
|
83
|
+
"}": ["░▀█░", "░░▄▀", "░▀▀░"],
|
|
84
|
+
"<": ["░░▄▀", "░▀▄░", "░░░▀"],
|
|
85
|
+
">": ["░▀▄░", "░░▄▀", "░▀░░"],
|
|
86
|
+
" ": ["░░░░", "░░░░", "░░░░"],
|
|
87
|
+
// Drawn to match, not transcribed: the source has none of these. A period
|
|
88
|
+
// is the top half of the last cell, sitting on the line, and a comma is the
|
|
89
|
+
// bottom half of it, hanging below - which is what those two marks are.
|
|
90
|
+
".": ["░░", "░░", "░▀"],
|
|
91
|
+
",": ["░░", "░░", "░▄"],
|
|
92
|
+
":": ["░░", "░▀", "░▀"],
|
|
93
|
+
";": ["░░", "░▀", "░▄"],
|
|
94
|
+
"/": ["░░▄▀", "░▄▀░", "░▀░░"],
|
|
95
|
+
"\\": ["░▀▄░", "░░▀▄", "░░░▀"],
|
|
96
|
+
"@": ["░▄▀▄", "░█▄█", "░░▀▀"],
|
|
97
|
+
"^": ["░▄▀▄", "░░░░", "░░░░"],
|
|
98
|
+
"`": ["░▀▄", "░░░", "░░░"],
|
|
99
|
+
"|": ["░█", "░█", "░▀"],
|
|
100
|
+
"~": ["░░░░", "░▄▀▄", "░░░░"],
|
|
101
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { BoxProps, RenderOutput } from '@textui/core';
|
|
2
|
+
import type { Ink } from './color-text.js';
|
|
3
|
+
/**
|
|
4
|
+
* A tile, repeated.
|
|
5
|
+
*
|
|
6
|
+
* A texture for a box, or a motif over one: the tile is stamped across and
|
|
7
|
+
* down until the box runs out, and `asBackground` (the default) or `asOverlay`
|
|
8
|
+
* says which side of the children it lands on.
|
|
9
|
+
*
|
|
10
|
+
* The two modes are document order and not much else. Painting walks the tree
|
|
11
|
+
* in the order components were written, so a layer emitted before the children
|
|
12
|
+
* ends up under them and one emitted after ends up over them. `zIndex` looks
|
|
13
|
+
* like it should decide this and does not: it sorts the layout boxes, while
|
|
14
|
+
* `paintTree` walks the instance children, so the property is inert for
|
|
15
|
+
* painting today. Relying on order is what actually works.
|
|
16
|
+
*/
|
|
17
|
+
export interface PatternProps extends BoxProps {
|
|
18
|
+
/** The tile. One string per row, or one string with newlines in it. */
|
|
19
|
+
tile: string | string[];
|
|
20
|
+
/**
|
|
21
|
+
* The tile to draw on a terminal that cannot manage the first one.
|
|
22
|
+
*
|
|
23
|
+
* A pattern is the one component whose whole content is glyphs, so it is the
|
|
24
|
+
* one that breaks worst on an `unicode: 'ascii'` terminal - and unlike a
|
|
25
|
+
* border, the library cannot guess a fallback for a tile it has never seen.
|
|
26
|
+
* Whoever picks the glyphs picks the substitute.
|
|
27
|
+
*/
|
|
28
|
+
ascii?: string | string[];
|
|
29
|
+
/**
|
|
30
|
+
* Repeats across.
|
|
31
|
+
*
|
|
32
|
+
* Unset or `0` draws the tile once. `-1` repeats until the box runs out.
|
|
33
|
+
* A positive number draws that many, and the box still clips it.
|
|
34
|
+
*/
|
|
35
|
+
x?: number;
|
|
36
|
+
/** Repeats down. Same rules as `x`. */
|
|
37
|
+
y?: number;
|
|
38
|
+
/** Stop short of the box, in cells. Unset means the box decides. */
|
|
39
|
+
limit?: {
|
|
40
|
+
width?: number;
|
|
41
|
+
height?: number;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Cells added after each copy, before the next one starts.
|
|
45
|
+
*
|
|
46
|
+
* Unset is flush, which is what a texture wants. Spacing turns the same tile
|
|
47
|
+
* into a motif with air around it - the difference between wrapping paper
|
|
48
|
+
* and a wallpaper: `10 + 10 = 20`, and `spacing.x = 5` makes it `25`.
|
|
49
|
+
*
|
|
50
|
+
* Not `gap`. A box already has one, it means the space between *children*,
|
|
51
|
+
* and a component that used the same word for the space between copies of
|
|
52
|
+
* its own tile would be two different distances under one name.
|
|
53
|
+
*/
|
|
54
|
+
spacing?: {
|
|
55
|
+
x?: number;
|
|
56
|
+
y?: number;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Up to this many extra cells between copies, chosen at random per step.
|
|
60
|
+
*
|
|
61
|
+
* The standard name for it: a jitter is a random displacement applied to
|
|
62
|
+
* positions that would otherwise be regular, and breaking a lattice is what
|
|
63
|
+
* it is for. Not a deviation, which in statistics is a spread about a mean,
|
|
64
|
+
* and not a factor, which is what it multiplied before it was a limit.
|
|
65
|
+
*
|
|
66
|
+
* A limit, not a factor: `jitter.x = 6` is "somewhere between flush and six
|
|
67
|
+
* cells further on", dealt again for every step. Unset or `0` is the grid,
|
|
68
|
+
* every copy exactly a tile from the last, which is what the default
|
|
69
|
+
* preserves.
|
|
70
|
+
*
|
|
71
|
+
* It stacks with `spacing` rather than replacing it. Spacing is the air you
|
|
72
|
+
* always want and this is how much more of it is left to chance, so
|
|
73
|
+
* `spacing.x = 4, jitter.x = 6` steps by a tile plus four to ten.
|
|
74
|
+
*
|
|
75
|
+
* A jitter on `x` also stops the copies lining up into columns - see
|
|
76
|
+
* `offsets`, and the screenshot that made it necessary.
|
|
77
|
+
*/
|
|
78
|
+
jitter?: {
|
|
79
|
+
x?: number;
|
|
80
|
+
y?: number;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* The deal, when there is a jitter.
|
|
84
|
+
*
|
|
85
|
+
* A pattern re-renders whenever its box changes, and one that reached for
|
|
86
|
+
* `Math.random()` while painting would shuffle itself on every frame - a
|
|
87
|
+
* texture that crawls. The seed makes the scatter a function of the props,
|
|
88
|
+
* so the same pattern is the same pattern until somebody changes the number.
|
|
89
|
+
*/
|
|
90
|
+
seed?: number;
|
|
91
|
+
/**
|
|
92
|
+
* Cells holding this character are left unpainted, so whatever is behind
|
|
93
|
+
* shows through. `null` paints every cell, spaces included.
|
|
94
|
+
*/
|
|
95
|
+
transparent?: string | null;
|
|
96
|
+
/**
|
|
97
|
+
* Colour the tile cell by cell, the way [`ColorText`](color-text.md) colours
|
|
98
|
+
* text: a ramp between stops, a palette walked in runs, or a function of the
|
|
99
|
+
* cell. The coordinates are the pattern's own - `col` and `line` count cells
|
|
100
|
+
* of the box it fills, not of one copy of the tile - so `{ gradient }` runs
|
|
101
|
+
* across the whole texture and `{ cycle, every }` walks it.
|
|
102
|
+
*
|
|
103
|
+
* Stated, the tile is painted on a canvas rather than drawn as text, and a
|
|
104
|
+
* canvas is not told what it was nested in: every cell takes this
|
|
105
|
+
* component's own `fg` where the ink declines one, not the colour of the row
|
|
106
|
+
* it happens to sit in. That is the trade `ColorText` makes for the same
|
|
107
|
+
* reason, and it is the only difference between an inked tile and a plain
|
|
108
|
+
* one.
|
|
109
|
+
*/
|
|
110
|
+
ink?: Ink;
|
|
111
|
+
/** Paint under the children. The default, and what a texture wants. */
|
|
112
|
+
asBackground?: boolean;
|
|
113
|
+
/** Paint over the children instead. */
|
|
114
|
+
asOverlay?: boolean;
|
|
115
|
+
}
|
|
116
|
+
export declare const Pattern: (props: PatternProps) => RenderOutput;
|
|
117
|
+
//# sourceMappingURL=pattern.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../../src/display/pattern.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAA+B,YAAY,EAAE,MAAM,cAAc,CAAC;AAExF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC5C,uEAAuE;IACvE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B;;;;;OAKG;IACH,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,uCAAuC;IACvC,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,MAAM,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;;;;;;;;;;OAaG;IACH,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,uEAAuE;IACvE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uCAAuC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA8HD,eAAO,MAAM,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,YA+L9C,CAAC"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { jsx as _jsx } from "@textui/core/jsx-runtime";
|
|
2
|
+
import { defineComponent, useCapabilities, useMeasure } from '@textui/core';
|
|
3
|
+
import { inkCellStyle, inkOwnStyle, painterOf } from './color-text.js';
|
|
4
|
+
/**
|
|
5
|
+
* The tile as equal-length rows. A ragged tile pads rather than tears.
|
|
6
|
+
*
|
|
7
|
+
* Only the blank rows at the ends go - those are how a string written across
|
|
8
|
+
* several lines begins and ends. A blank row in the middle is a row of
|
|
9
|
+
* transparent cells somebody drew on purpose, and dropping it silently
|
|
10
|
+
* shortens their tile.
|
|
11
|
+
*/
|
|
12
|
+
function rowsOf(tile) {
|
|
13
|
+
const rows = Array.isArray(tile) ? [...tile] : tile.split('\n');
|
|
14
|
+
while (rows.length > 0 && rows[0] === '')
|
|
15
|
+
rows.shift();
|
|
16
|
+
while (rows.length > 0 && rows[rows.length - 1] === '')
|
|
17
|
+
rows.pop();
|
|
18
|
+
const width = Math.max(0, ...rows.map((row) => [...row].length));
|
|
19
|
+
return rows.map((row) => row.padEnd(width, ' '));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* How many copies to draw along one axis.
|
|
23
|
+
*
|
|
24
|
+
* Unset and zero mean the same thing - once, no repetition - because "repeat
|
|
25
|
+
* it zero times" and "do not repeat it" are the same request, and treating
|
|
26
|
+
* zero as *nothing at all* makes an unset prop and a computed one behave
|
|
27
|
+
* differently for no reason anyone would want.
|
|
28
|
+
*
|
|
29
|
+
* `-1` is "as many as fit", which with a gap or a deviation is not arithmetic
|
|
30
|
+
* any more - it is however many the walk gets through. The count is an upper
|
|
31
|
+
* bound there rather than the answer.
|
|
32
|
+
*/
|
|
33
|
+
function repeats(count, tile, room) {
|
|
34
|
+
if (count === undefined || count === 0)
|
|
35
|
+
return 1;
|
|
36
|
+
if (count < 0)
|
|
37
|
+
return tile > 0 ? Math.ceil(room / tile) : 1;
|
|
38
|
+
return count;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A small deterministic generator, so a deviation is a deal rather than a
|
|
42
|
+
* shuffle. `mulberry32`: the point is repeatability, not statistics.
|
|
43
|
+
*/
|
|
44
|
+
function random(seed) {
|
|
45
|
+
let state = seed >>> 0;
|
|
46
|
+
return () => {
|
|
47
|
+
state = (state + 0x6d2b79f5) >>> 0;
|
|
48
|
+
let t = state;
|
|
49
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
50
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
51
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Where each copy starts along one axis.
|
|
56
|
+
*
|
|
57
|
+
* The step is a tile, plus whatever the gap and the deviation ask for:
|
|
58
|
+
*
|
|
59
|
+
* - neither - `tile`, which is the grid, and exactly what this drew before
|
|
60
|
+
* either of them existed
|
|
61
|
+
* - spacing - `tile + spacing`, the same grid with air in it
|
|
62
|
+
* - a deviation - `tile + rand * deviation * tile`, so `1` can skip a whole
|
|
63
|
+
* tile and land anywhere in the one after
|
|
64
|
+
* - both - `tile + rand * deviation * spacing`, because once there is a
|
|
65
|
+
* spacing it is the spacing being shared out rather than the tile
|
|
66
|
+
*
|
|
67
|
+
* A jitter also moves where the walk *starts*, backwards, by up to a step.
|
|
68
|
+
*
|
|
69
|
+
* Without that, a tile as wide as the box is drawn once at zero and the
|
|
70
|
+
* jitter has nothing to act on - there is no second copy for the step to
|
|
71
|
+
* be different from, so every seed deals the same picture. It is the case a
|
|
72
|
+
* sparse tile is most likely to be in: a big tile with two marks on it is
|
|
73
|
+
* somebody scattering by hand, and the whole point of the seed there is that
|
|
74
|
+
* the scatter moves.
|
|
75
|
+
*
|
|
76
|
+
* Backwards rather than forwards, so the phase shows as a different slice of
|
|
77
|
+
* the pattern rather than as a blank margin down the left. The walk then needs
|
|
78
|
+
* one more copy to reach the far edge, which is why `fill` extends the count.
|
|
79
|
+
*/
|
|
80
|
+
function offsets(count, tile, room, spacing,
|
|
81
|
+
/** Up to this many extra cells per step. */
|
|
82
|
+
jitter, next,
|
|
83
|
+
/** Repeating to fill, rather than drawing a stated number of copies. */
|
|
84
|
+
fill) {
|
|
85
|
+
if (tile <= 0)
|
|
86
|
+
return [];
|
|
87
|
+
const out = [];
|
|
88
|
+
const step = tile + spacing;
|
|
89
|
+
// Only when filling. A caller who asked for three copies put them there;
|
|
90
|
+
// sliding those off the edge would be answering a different question.
|
|
91
|
+
const phase = fill && jitter > 0
|
|
92
|
+
? -Math.round(next() * (step + jitter))
|
|
93
|
+
: 0;
|
|
94
|
+
let at = phase;
|
|
95
|
+
const total = phase < 0 ? count + 1 : count;
|
|
96
|
+
for (let i = 0; i < total && at < room; i++) {
|
|
97
|
+
out.push(at);
|
|
98
|
+
// A limit rather than a factor: the extra is somewhere in `0..jitter`,
|
|
99
|
+
// dealt again for every step.
|
|
100
|
+
at += step + (jitter > 0 ? Math.round(next() * jitter) : 0);
|
|
101
|
+
}
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
/** The runs of paintable cells in one row, so gaps stay see-through. */
|
|
105
|
+
function runs(row, transparent) {
|
|
106
|
+
const cells = [...row];
|
|
107
|
+
if (transparent === null)
|
|
108
|
+
return cells.length > 0 ? [{ at: 0, text: row }] : [];
|
|
109
|
+
const out = [];
|
|
110
|
+
let start = -1;
|
|
111
|
+
for (let i = 0; i <= cells.length; i++) {
|
|
112
|
+
const paint = i < cells.length && cells[i] !== transparent;
|
|
113
|
+
if (paint && start < 0)
|
|
114
|
+
start = i;
|
|
115
|
+
else if (!paint && start >= 0) {
|
|
116
|
+
out.push({ at: start, text: cells.slice(start, i).join('') });
|
|
117
|
+
start = -1;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
export const Pattern = defineComponent('Pattern', (props) => {
|
|
123
|
+
const { tile, ascii, x, y, limit, transparent = ' ', spacing, jitter, seed = 1, ink, asOverlay, asBackground: _asBackground, children, ...rest } = props;
|
|
124
|
+
const capabilities = useCapabilities();
|
|
125
|
+
// The box this pattern was given. Zero on the first pass, real on the
|
|
126
|
+
// second - which is why `-1` needs a frame to find its extent.
|
|
127
|
+
const measured = useMeasure();
|
|
128
|
+
const rows = rowsOf(capabilities.unicode === 'ascii' && ascii !== undefined ? ascii : tile);
|
|
129
|
+
const tileWidth = rows[0] ? [...rows[0]].length : 0;
|
|
130
|
+
const tileHeight = rows.length;
|
|
131
|
+
const room = {
|
|
132
|
+
width: Math.min(measured.width, limit?.width ?? Number.POSITIVE_INFINITY),
|
|
133
|
+
height: Math.min(measured.height, limit?.height ?? Number.POSITIVE_INFINITY),
|
|
134
|
+
};
|
|
135
|
+
const across = repeats(x, tileWidth, room.width);
|
|
136
|
+
const down = repeats(y, tileHeight, room.height);
|
|
137
|
+
// One generator for both axes, drawn from in a fixed order, so neither
|
|
138
|
+
// depends on the box's size.
|
|
139
|
+
const next = random(seed);
|
|
140
|
+
const lines = offsets(down, tileHeight, room.height, spacing?.y ?? 0, jitter?.y ?? 0, next, (y ?? 0) < 0);
|
|
141
|
+
/*
|
|
142
|
+
* A walk across for *each* row of copies, not one shared by all of them.
|
|
143
|
+
*
|
|
144
|
+
* This is what the difference between "irregular" and "not a lattice"
|
|
145
|
+
* turns out to be. With one set of column positions, every row starts its
|
|
146
|
+
* copies at the same offsets - so the copies still line up into columns,
|
|
147
|
+
* and a sky of stars drawn that way still has visible rows and columns no
|
|
148
|
+
* matter how uneven the spacing along each axis is. You can draw the grid
|
|
149
|
+
* on a screenshot with a ruler, which is exactly what happened.
|
|
150
|
+
*
|
|
151
|
+
* Re-dealing the walk per row costs one pass each and breaks the
|
|
152
|
+
* alignment, because row two's copies are nowhere near row one's.
|
|
153
|
+
* Without a jitter there is nothing to re-deal, so the walk is
|
|
154
|
+
* computed once and shared - and the output is the grid it always was.
|
|
155
|
+
*/
|
|
156
|
+
const shared = (jitter?.x ?? 0) === 0
|
|
157
|
+
? offsets(across, tileWidth, room.width, spacing?.x ?? 0, 0, next, (x ?? 0) < 0)
|
|
158
|
+
: null;
|
|
159
|
+
const columnsFor = () => shared ?? offsets(across, tileWidth, room.width, spacing?.x ?? 0, jitter?.x ?? 0, next, (x ?? 0) < 0);
|
|
160
|
+
/*
|
|
161
|
+
* Every copy placed on its own, not as a cell of a grid.
|
|
162
|
+
*
|
|
163
|
+
* Re-dealing the walk per row breaks the columns; it does not break the
|
|
164
|
+
* rows, because every copy in one row still shares a `top`. A sky drawn
|
|
165
|
+
* that way still has marks lined up in bands - which is visible the
|
|
166
|
+
* moment somebody puts a ruler on a screenshot.
|
|
167
|
+
*
|
|
168
|
+
* So a copy also wobbles up or down by its own amount, out of the same
|
|
169
|
+
* budget as the vertical step. That is the last thing holding the lattice
|
|
170
|
+
* together, and with it gone the placements are a scatter that happens to
|
|
171
|
+
* have been generated in reading order.
|
|
172
|
+
*/
|
|
173
|
+
const wobble = jitter?.y ?? 0;
|
|
174
|
+
const placements = lines.flatMap((top) => columnsFor().map((left) => ({
|
|
175
|
+
left,
|
|
176
|
+
top: wobble > 0 ? top + Math.round(next() * wobble) - Math.round(wobble / 2) : top,
|
|
177
|
+
})));
|
|
178
|
+
const widest = Math.max(0, ...placements.map(({ left }) => left + tileWidth));
|
|
179
|
+
const last = {
|
|
180
|
+
x: Math.max(0, widest),
|
|
181
|
+
y: Math.max(0, (lines[lines.length - 1] ?? 0) + tileHeight),
|
|
182
|
+
};
|
|
183
|
+
const painted = {
|
|
184
|
+
width: Math.min(last.x, room.width),
|
|
185
|
+
height: Math.min(last.y, room.height),
|
|
186
|
+
};
|
|
187
|
+
/*
|
|
188
|
+
* Stamped into a grid, then split into runs.
|
|
189
|
+
*
|
|
190
|
+
* The rows used to be built by repeating the tile's own string, which is
|
|
191
|
+
* shorter and only works while every copy is exactly a tile from the last.
|
|
192
|
+
* With a gap or a deviation the copies are at arbitrary offsets, so the
|
|
193
|
+
* grid is composed first and read off afterwards - and the reading is the
|
|
194
|
+
* same `runs` split as before, which is what keeps a transparent cell
|
|
195
|
+
* transparent and adjacent cells in one `text` rather than one apiece.
|
|
196
|
+
*
|
|
197
|
+
* With neither prop set the offsets come out as `0, tile, 2*tile, ...` and
|
|
198
|
+
* the composed rows are identical to what the repeat produced.
|
|
199
|
+
*/
|
|
200
|
+
const cells = [];
|
|
201
|
+
if (tileWidth > 0 && painted.width > 0 && painted.height > 0) {
|
|
202
|
+
const blank = transparent ?? ' ';
|
|
203
|
+
const grid = Array.from({ length: painted.height }, () => Array.from({ length: painted.width }, () => blank));
|
|
204
|
+
for (const { top, left } of placements) {
|
|
205
|
+
for (let r = 0; r < tileHeight; r++) {
|
|
206
|
+
// A phased or wobbled copy starts above and to the left of the box,
|
|
207
|
+
// so part of it is outside. Those cells are simply not written; the
|
|
208
|
+
// rest of the copy still lands.
|
|
209
|
+
const row = grid[top + r];
|
|
210
|
+
if (top + r < 0 || !row)
|
|
211
|
+
continue;
|
|
212
|
+
const source = [...rows[r]];
|
|
213
|
+
for (let c = 0; c < tileWidth; c++) {
|
|
214
|
+
const at = left + c;
|
|
215
|
+
if (at >= 0 && at < painted.width)
|
|
216
|
+
row[at] = source[c];
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (ink === undefined) {
|
|
221
|
+
grid.forEach((row, y1) => {
|
|
222
|
+
for (const run of runs(row.join(''), transparent)) {
|
|
223
|
+
cells.push(_jsx("text", { position: "absolute", top: y1, left: run.at, content: run.text }, `${y1}:${run.at}`));
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
// One cell at a time, because one colour at a time is the whole point
|
|
229
|
+
// of an ink. A cell the `transparent` character owns is skipped rather
|
|
230
|
+
// than painted over: it is not the tile's to draw.
|
|
231
|
+
cells.push(_jsx("canvas", { position: "absolute", top: 0, left: 0, width: painted.width, height: painted.height, draw: (surface, ctx) => {
|
|
232
|
+
const ownProps = props;
|
|
233
|
+
const base = inkCellStyle(inkOwnStyle(ownProps, ctx), ctx, props.link);
|
|
234
|
+
const paint = painterOf(ink, ctx);
|
|
235
|
+
for (let y1 = 0; y1 < grid.length; y1++) {
|
|
236
|
+
const row = grid[y1];
|
|
237
|
+
for (let x1 = 0; x1 < row.length; x1++) {
|
|
238
|
+
const char = row[x1];
|
|
239
|
+
if (transparent !== null && char === transparent)
|
|
240
|
+
continue;
|
|
241
|
+
const style = paint({
|
|
242
|
+
char, col: x1, line: y1, index: x1,
|
|
243
|
+
offset: y1 * painted.width + x1,
|
|
244
|
+
width: painted.width, height: painted.height,
|
|
245
|
+
blockWidth: painted.width,
|
|
246
|
+
});
|
|
247
|
+
surface.put(x1, y1, char, style ? { ...base, ...style } : base);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
} }, "ink"));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Absolute, so the pattern never pushes the children around, and hidden,
|
|
254
|
+
// so a partial tile at the edge is cut rather than allowed to overflow.
|
|
255
|
+
const layer = (_jsx("box", { position: "absolute", top: 0, left: 0, width: painted.width, height: painted.height, overflow: "hidden", children: cells }));
|
|
256
|
+
return (_jsx("box", { position: "relative", ...rest, children: asOverlay === true ? [children, layer] : [layer, children] }));
|
|
257
|
+
});
|
|
@@ -2,6 +2,8 @@ import type { BoxProps, SemanticVariant } from '@textui/core';
|
|
|
2
2
|
export interface SpinnerProps extends BoxProps {
|
|
3
3
|
label?: string;
|
|
4
4
|
tone?: SemanticVariant;
|
|
5
|
+
frames?: string[];
|
|
5
6
|
}
|
|
7
|
+
export declare const DEFAULT_FRAMES: string[];
|
|
6
8
|
export declare const Spinner: (props: SpinnerProps) => import("@textui/core").RenderOutput;
|
|
7
9
|
//# sourceMappingURL=spinner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/display/spinner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAI9D,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/display/spinner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAI9D,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,eAAO,MAAM,cAAc,UAAwB,CAAC;AAEpD,eAAO,MAAM,OAAO,8DAUlB,CAAC"}
|
package/dist/display/spinner.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { defineComponent, h, useFrame, useTheme } from '@textui/core';
|
|
2
2
|
import { TONE as TONE_COLOR } from '../tone.js';
|
|
3
|
-
export const
|
|
3
|
+
export const DEFAULT_FRAMES = ['-', '\\', '|', '/'];
|
|
4
|
+
export const Spinner = defineComponent('Spinner', ({ label, tone = 'accent', frames: customFrames, ...rest }) => {
|
|
4
5
|
const theme = useTheme();
|
|
5
6
|
const frame = useFrame(10);
|
|
6
|
-
const frames = theme.glyphs.spinner;
|
|
7
|
+
const frames = customFrames ?? theme.glyphs.spinner ?? DEFAULT_FRAMES;
|
|
7
8
|
const glyph = frames[frame % frames.length] ?? frames[0] ?? '*';
|
|
8
9
|
return h('box', { role: 'status', direction: 'row', gap: 1, ...rest }, h('text', { content: glyph, fg: TONE_COLOR[tone] }), label ? h('text', { content: label }) : null);
|
|
9
10
|
});
|
|
@@ -55,5 +55,7 @@ export interface MenuProps extends BoxProps {
|
|
|
55
55
|
*/
|
|
56
56
|
interactive?: boolean;
|
|
57
57
|
}
|
|
58
|
+
/** The name a theme styles a menu row under. See `LIST`. */
|
|
59
|
+
export declare const MENU = "Menu";
|
|
58
60
|
export declare const Menu: (props: MenuProps) => import("@textui/core").RenderOutput;
|
|
59
61
|
//# sourceMappingURL=menu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../src/navigation/menu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAK9D,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,SAAU,SAAQ,QAAQ;IACzC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,QAAQ,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC5C,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../src/navigation/menu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAK9D,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,SAAU,SAAQ,QAAQ;IACzC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,QAAQ,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC5C,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,4DAA4D;AAC5D,eAAO,MAAM,IAAI,SAAS,CAAC;AAE3B,eAAO,MAAM,IAAI,2DA8If,CAAC"}
|
package/dist/navigation/menu.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { defineComponent, h, stringWidth, useFocus, useI18n, useInput, useState, useTheme } from '@textui/core';
|
|
2
2
|
import { Marquee } from '../display/index.js';
|
|
3
3
|
import { TONE } from '../tone.js';
|
|
4
|
+
/** The name a theme styles a menu row under. See `LIST`. */
|
|
5
|
+
export const MENU = 'Menu';
|
|
4
6
|
export const Menu = defineComponent('Menu', (props) => {
|
|
5
7
|
const theme = useTheme();
|
|
6
8
|
const i18n = useI18n();
|
|
@@ -58,14 +60,19 @@ export const Menu = defineComponent('Menu', (props) => {
|
|
|
58
60
|
// The description yields first, and by a lot. It is the elaboration;
|
|
59
61
|
// the label is the thing being chosen, and a row reading "Accept ed…"
|
|
60
62
|
// beside a full sentence has given up the wrong half.
|
|
63
|
+
//
|
|
64
|
+
// On the row under the cursor the foreground is `undefined`, not a
|
|
65
|
+
// token: what is written on a selection is the theme's, and a hard
|
|
66
|
+
// `onSelected` here would be a second answer to the same question that
|
|
67
|
+
// a theme restating `Menu.focused.fg` could not reach.
|
|
61
68
|
item.description && !below
|
|
62
69
|
? h(Marquee, {
|
|
63
70
|
content: item.description,
|
|
64
71
|
active,
|
|
65
|
-
fg: active ?
|
|
72
|
+
fg: active ? undefined : 'muted',
|
|
66
73
|
shrink: 8,
|
|
67
74
|
})
|
|
68
|
-
: null, item.shortcut ? h('text', { content: item.shortcut, fg: active ?
|
|
75
|
+
: null, item.shortcut ? h('text', { content: item.shortcut, fg: active ? undefined : 'subtle' }) : null,
|
|
69
76
|
// Present but empty means "this opens something, contents unknown" -
|
|
70
77
|
// which is what the command palette knows about an argument whose
|
|
71
78
|
// choices it has not resolved yet.
|
|
@@ -74,12 +81,18 @@ export const Menu = defineComponent('Menu', (props) => {
|
|
|
74
81
|
key: item.id,
|
|
75
82
|
role: 'menuitem',
|
|
76
83
|
label: item.label,
|
|
84
|
+
styleAs: MENU,
|
|
77
85
|
selected: active,
|
|
86
|
+
// The keyboard is the menu's, so the row is told - which is what lets
|
|
87
|
+
// `Menu.selected` be the dimmer fill a menu shows when something else
|
|
88
|
+
// has taken the keyboard, and `Menu.focused` the one it shows while
|
|
89
|
+
// the reader is moving through it.
|
|
90
|
+
focused: active && focus.focused,
|
|
78
91
|
direction: 'column',
|
|
79
92
|
// One background over both lines: a highlight that stopped after the
|
|
80
|
-
// label would split the row it is highlighting in two.
|
|
81
|
-
|
|
82
|
-
fg: item.disabled ? 'disabled' : active ?
|
|
93
|
+
// label would split the row it is highlighting in two. What it is
|
|
94
|
+
// filled with is the theme's to say.
|
|
95
|
+
fg: item.disabled ? 'disabled' : active ? undefined : item.tone ? TONE[item.tone] : undefined,
|
|
83
96
|
onClick: () => { if (!item.disabled)
|
|
84
97
|
onSelect?.(item.id, item); },
|
|
85
98
|
}, head,
|
|
@@ -94,7 +107,7 @@ export const Menu = defineComponent('Menu', (props) => {
|
|
|
94
107
|
h(Marquee, {
|
|
95
108
|
content: item.description,
|
|
96
109
|
active,
|
|
97
|
-
fg: active ?
|
|
110
|
+
fg: active ? undefined : 'muted',
|
|
98
111
|
flex: 1,
|
|
99
112
|
}))
|
|
100
113
|
: null);
|
|
@@ -16,5 +16,7 @@ export interface TabsProps extends BoxProps {
|
|
|
16
16
|
/** Take focus on mount, so the keyboard has somewhere to be. */
|
|
17
17
|
autoFocus?: boolean;
|
|
18
18
|
}
|
|
19
|
+
/** The name a theme styles a tab under. See `LIST`. */
|
|
20
|
+
export declare const TABS = "Tabs";
|
|
19
21
|
export declare const Tabs: (props: TabsProps) => import("@textui/core").RenderOutput;
|
|
20
22
|
//# sourceMappingURL=tabs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/navigation/tabs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAI7C,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,SAAU,SAAQ,QAAQ;IACzC,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,wDAAwD;IACxD,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,GAAG,OAAO,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/navigation/tabs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAI7C,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,SAAU,SAAQ,QAAQ;IACzC,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,wDAAwD;IACxD,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,GAAG,OAAO,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,uDAAuD;AACvD,eAAO,MAAM,IAAI,SAAS,CAAC;AAE3B,eAAO,MAAM,IAAI,2DAyDf,CAAC"}
|