@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,65 @@
|
|
|
1
|
+
import type { TextWrap } from '../types/style.js';
|
|
2
|
+
/**
|
|
3
|
+
* Split into grapheme clusters. Falls back to code points without Intl.
|
|
4
|
+
*
|
|
5
|
+
* The ASCII path skips `Intl.Segmenter` entirely. It is not a micro-tweak:
|
|
6
|
+
* painting walks the graphemes of every string on screen every frame, and
|
|
7
|
+
* segmentation was measuring at about a sixth of the frame in a list of plain
|
|
8
|
+
* ASCII rows - all of it spent proving that `r`, `o` and `w` are one character
|
|
9
|
+
* each.
|
|
10
|
+
*/
|
|
11
|
+
export declare function graphemes(text: string): string[];
|
|
12
|
+
/**
|
|
13
|
+
* Width of one grapheme cluster in cells. A cluster is measured by its base
|
|
14
|
+
* character; an emoji followed by VS16 counts as wide.
|
|
15
|
+
*/
|
|
16
|
+
export declare function graphemeWidth(cluster: string): number;
|
|
17
|
+
/** Width of a string in terminal cells. */
|
|
18
|
+
export declare function stringWidth(text: string): number;
|
|
19
|
+
/** Take at most `width` cells from the front. Never splits a wide grapheme. */
|
|
20
|
+
export declare function sliceByWidth(text: string, width: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* The slice of `text` covering display columns `[start, start + width)`.
|
|
23
|
+
*
|
|
24
|
+
* Cutting by index is wrong the moment a line contains a wide character: the
|
|
25
|
+
* horizontal scroll would drift against the gutter, one cell per CJK glyph.
|
|
26
|
+
* A wide grapheme straddling either edge is dropped rather than split, because
|
|
27
|
+
* half of one cannot be drawn.
|
|
28
|
+
*/
|
|
29
|
+
export declare function sliceColumns(text: string, start: number, width: number): string;
|
|
30
|
+
/**
|
|
31
|
+
* Replace tabs with spaces to the next tab stop.
|
|
32
|
+
*
|
|
33
|
+
* A terminal cell is one column, so a raw tab is one blank cell and every
|
|
34
|
+
* indented line lands in a different place than it does in an editor. Doing
|
|
35
|
+
* this before highlighting keeps token offsets and screen columns the same
|
|
36
|
+
* number.
|
|
37
|
+
*/
|
|
38
|
+
export declare function expandTabs(text: string, tabWidth?: number): string;
|
|
39
|
+
export type TruncateSide = 'end' | 'start' | 'middle';
|
|
40
|
+
/** Fit into `width` cells, marking the cut with `ellipsis`. */
|
|
41
|
+
export declare function truncate(text: string, width: number, ellipsis?: string, side?: TruncateSide): string;
|
|
42
|
+
/** Pad to exactly `width` cells. Over-long input is returned unchanged. */
|
|
43
|
+
export declare function padTo(text: string, width: number, align?: 'left' | 'center' | 'right', fill?: string): string;
|
|
44
|
+
/** Fit to exactly `width`: truncate when long, pad when short. */
|
|
45
|
+
export declare function fitTo(text: string, width: number, align?: 'left' | 'center' | 'right', ellipsis?: string): string;
|
|
46
|
+
export type WrapMode = 'none' | 'word' | 'char';
|
|
47
|
+
/**
|
|
48
|
+
* The end a `TextWrap` cuts at, or `undefined` when it wraps instead.
|
|
49
|
+
*
|
|
50
|
+
* The wrapping modes and the truncating ones live in one union because they
|
|
51
|
+
* answer one question - what happens at the edge - and a component that had to
|
|
52
|
+
* take both a `wrap` and a `truncate` prop could be handed the two answers at
|
|
53
|
+
* once. These two helpers are how the union is taken apart again.
|
|
54
|
+
*/
|
|
55
|
+
export declare function truncateSideOf(wrap: TextWrap | undefined): TruncateSide | undefined;
|
|
56
|
+
/** The mode `wrapText` should run in. A truncating text does not wrap at all. */
|
|
57
|
+
export declare function wrapModeOf(wrap: TextWrap | undefined): WrapMode;
|
|
58
|
+
/** Break into lines of at most `width` cells. Honours existing newlines. */
|
|
59
|
+
export declare function wrapText(text: string, width: number, mode?: WrapMode): string[];
|
|
60
|
+
export declare function stripAnsi(text: string): string;
|
|
61
|
+
/** Remove control characters that would corrupt the frame. Keeps newlines. */
|
|
62
|
+
export declare function sanitize(text: string): string;
|
|
63
|
+
/** Repeat a grapheme to exactly `width` cells (wide chars land short). */
|
|
64
|
+
export declare function repeatToWidth(char: string, width: number): string;
|
|
65
|
+
//# sourceMappingURL=text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/util/text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AA8BlD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAShD;AA8ED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAsBrD;AAED,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQhD;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAYhE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAgC/E;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,MAAM,CAuB7D;AAED,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEtD,+DAA+D;AAC/D,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,SAAM,EACd,IAAI,GAAE,YAAoB,GACzB,MAAM,CAkCR;AAED,2EAA2E;AAC3E,wBAAgB,KAAK,CACnB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAM,GAAG,QAAQ,GAAG,OAAgB,EAC3C,IAAI,SAAM,GACT,MAAM,CAQR;AAED,kEAAkE;AAClE,wBAAgB,KAAK,CACnB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAM,GAAG,QAAQ,GAAG,OAAgB,EAC3C,QAAQ,SAAM,GACb,MAAM,CAER;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAOnF;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAE/D;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,QAAiB,GAAG,MAAM,EAAE,CAuDvF;AAOD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjE"}
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal text measurement.
|
|
3
|
+
*
|
|
4
|
+
* Everything the layout engine knows about size comes from here, so the rules
|
|
5
|
+
* are worth stating: a cell holds one grapheme cluster, a grapheme is 0, 1 or
|
|
6
|
+
* 2 cells wide, and a string's width is the sum - never its `.length`.
|
|
7
|
+
*/
|
|
8
|
+
const segmenter = typeof Intl !== 'undefined' && 'Segmenter' in Intl
|
|
9
|
+
? new Intl.Segmenter(undefined, { granularity: 'grapheme' })
|
|
10
|
+
: null;
|
|
11
|
+
/**
|
|
12
|
+
* True for a string that is entirely printable ASCII.
|
|
13
|
+
*
|
|
14
|
+
* Worth asking, because the answer is yes for very nearly all of it: source
|
|
15
|
+
* code, file names, labels, key hints. Every character is then one grapheme
|
|
16
|
+
* one cell wide, and none of the Unicode machinery below has anything to do.
|
|
17
|
+
*/
|
|
18
|
+
function isAscii(text) {
|
|
19
|
+
for (let i = 0; i < text.length; i++) {
|
|
20
|
+
const c = text.charCodeAt(i);
|
|
21
|
+
if (c < 0x20 || c > 0x7e)
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Split into grapheme clusters. Falls back to code points without Intl.
|
|
28
|
+
*
|
|
29
|
+
* The ASCII path skips `Intl.Segmenter` entirely. It is not a micro-tweak:
|
|
30
|
+
* painting walks the graphemes of every string on screen every frame, and
|
|
31
|
+
* segmentation was measuring at about a sixth of the frame in a list of plain
|
|
32
|
+
* ASCII rows - all of it spent proving that `r`, `o` and `w` are one character
|
|
33
|
+
* each.
|
|
34
|
+
*/
|
|
35
|
+
export function graphemes(text) {
|
|
36
|
+
if (text === '')
|
|
37
|
+
return [];
|
|
38
|
+
if (isAscii(text))
|
|
39
|
+
return text.split('');
|
|
40
|
+
if (segmenter) {
|
|
41
|
+
const out = [];
|
|
42
|
+
for (const { segment } of segmenter.segment(text))
|
|
43
|
+
out.push(segment);
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
return Array.from(text);
|
|
47
|
+
}
|
|
48
|
+
// Zero-width: combining marks, variation selectors, ZWJ, control chars.
|
|
49
|
+
function isZeroWidth(cp) {
|
|
50
|
+
return (cp === 0x200b || cp === 0x200c || cp === 0x200d || cp === 0xfeff ||
|
|
51
|
+
(cp >= 0x0300 && cp <= 0x036f) ||
|
|
52
|
+
(cp >= 0x0483 && cp <= 0x0489) ||
|
|
53
|
+
(cp >= 0x0591 && cp <= 0x05bd) ||
|
|
54
|
+
(cp >= 0x0610 && cp <= 0x061a) ||
|
|
55
|
+
(cp >= 0x064b && cp <= 0x065f) ||
|
|
56
|
+
(cp >= 0x0e31 && cp <= 0x0e3a) ||
|
|
57
|
+
(cp >= 0x1ab0 && cp <= 0x1aff) ||
|
|
58
|
+
(cp >= 0x1dc0 && cp <= 0x1dff) ||
|
|
59
|
+
(cp >= 0x20d0 && cp <= 0x20f0) ||
|
|
60
|
+
(cp >= 0xfe00 && cp <= 0xfe0f) ||
|
|
61
|
+
(cp >= 0xfe20 && cp <= 0xfe2f) ||
|
|
62
|
+
(cp >= 0xe0100 && cp <= 0xe01ef));
|
|
63
|
+
}
|
|
64
|
+
// East Asian Wide + Fullwidth, and the emoji ranges that render double-width.
|
|
65
|
+
function isWide(cp) {
|
|
66
|
+
return ((cp >= 0x1100 && cp <= 0x115f) ||
|
|
67
|
+
(cp >= 0x2e80 && cp <= 0x303e) ||
|
|
68
|
+
(cp >= 0x3041 && cp <= 0x33ff) ||
|
|
69
|
+
(cp >= 0x3400 && cp <= 0x4dbf) ||
|
|
70
|
+
(cp >= 0x4e00 && cp <= 0x9fff) ||
|
|
71
|
+
(cp >= 0xa000 && cp <= 0xa4cf) ||
|
|
72
|
+
(cp >= 0xac00 && cp <= 0xd7a3) ||
|
|
73
|
+
(cp >= 0xf900 && cp <= 0xfaff) ||
|
|
74
|
+
(cp >= 0xfe10 && cp <= 0xfe19) ||
|
|
75
|
+
(cp >= 0xfe30 && cp <= 0xfe6f) ||
|
|
76
|
+
(cp >= 0xff00 && cp <= 0xff60) ||
|
|
77
|
+
(cp >= 0xffe0 && cp <= 0xffe6) ||
|
|
78
|
+
// The pictograph blocks are *mostly* wide, and the exceptions matter.
|
|
79
|
+
// `1F300..1F64F` as one range called U+1F5C0 FOLDER two cells; Unicode
|
|
80
|
+
// says East Asian Width Neutral, and a terminal following wcwidth draws
|
|
81
|
+
// it in one. Those blocks are full of such symbols - the whole
|
|
82
|
+
// `1F5A5..1F5FA` run of them - and a glyph measured as two and drawn as
|
|
83
|
+
// one leaves the rest of the row shifted by a column.
|
|
84
|
+
//
|
|
85
|
+
// Generated from EastAsianWidth (Unicode 15.1), W and F only. A symbol
|
|
86
|
+
// that takes emoji presentation is handled by the VS16 rule below, which
|
|
87
|
+
// is the thing that actually makes one of these wide when it is wide.
|
|
88
|
+
(cp >= 0x1f300 && cp <= 0x1f320) ||
|
|
89
|
+
(cp >= 0x1f32d && cp <= 0x1f335) ||
|
|
90
|
+
(cp >= 0x1f337 && cp <= 0x1f37c) ||
|
|
91
|
+
(cp >= 0x1f37e && cp <= 0x1f393) ||
|
|
92
|
+
(cp >= 0x1f3a0 && cp <= 0x1f3ca) ||
|
|
93
|
+
(cp >= 0x1f3cf && cp <= 0x1f3d3) ||
|
|
94
|
+
(cp >= 0x1f3e0 && cp <= 0x1f3f0) ||
|
|
95
|
+
cp === 0x1f3f4 ||
|
|
96
|
+
(cp >= 0x1f3f8 && cp <= 0x1f43e) ||
|
|
97
|
+
cp === 0x1f440 ||
|
|
98
|
+
(cp >= 0x1f442 && cp <= 0x1f4fc) ||
|
|
99
|
+
(cp >= 0x1f4ff && cp <= 0x1f53d) ||
|
|
100
|
+
(cp >= 0x1f54b && cp <= 0x1f54e) ||
|
|
101
|
+
(cp >= 0x1f550 && cp <= 0x1f567) ||
|
|
102
|
+
cp === 0x1f57a ||
|
|
103
|
+
(cp >= 0x1f595 && cp <= 0x1f596) ||
|
|
104
|
+
cp === 0x1f5a4 ||
|
|
105
|
+
(cp >= 0x1f5fb && cp <= 0x1f64f) ||
|
|
106
|
+
(cp >= 0x1f90c && cp <= 0x1f93a) ||
|
|
107
|
+
(cp >= 0x1f93c && cp <= 0x1f945) ||
|
|
108
|
+
(cp >= 0x1f947 && cp <= 0x1f9ff) ||
|
|
109
|
+
(cp >= 0x1fa70 && cp <= 0x1fa7c) ||
|
|
110
|
+
(cp >= 0x1fa80 && cp <= 0x1fa88) ||
|
|
111
|
+
(cp >= 0x1fa90 && cp <= 0x1fabd) ||
|
|
112
|
+
(cp >= 0x1fabf && cp <= 0x1fac5) ||
|
|
113
|
+
(cp >= 0x1face && cp <= 0x1fadb) ||
|
|
114
|
+
(cp >= 0x1fae0 && cp <= 0x1fae8) ||
|
|
115
|
+
(cp >= 0x1faf0 && cp <= 0x1faf8) ||
|
|
116
|
+
(cp >= 0x20000 && cp <= 0x3fffd));
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Width of one grapheme cluster in cells. A cluster is measured by its base
|
|
120
|
+
* character; an emoji followed by VS16 counts as wide.
|
|
121
|
+
*/
|
|
122
|
+
export function graphemeWidth(cluster) {
|
|
123
|
+
if (cluster === '')
|
|
124
|
+
return 0;
|
|
125
|
+
/*
|
|
126
|
+
* One printable ASCII character is one cell, and that is the overwhelming
|
|
127
|
+
* majority of every cluster this is ever asked about.
|
|
128
|
+
*
|
|
129
|
+
* The general path below builds two arrays - `Array.from` then `.map` - for
|
|
130
|
+
* every cluster, which is two allocations per cell per frame. Answering the
|
|
131
|
+
* common case from the character code costs nothing and allocates nothing.
|
|
132
|
+
*/
|
|
133
|
+
if (cluster.length === 1) {
|
|
134
|
+
const only = cluster.charCodeAt(0);
|
|
135
|
+
if (only >= 0x20 && only <= 0x7e)
|
|
136
|
+
return 1;
|
|
137
|
+
}
|
|
138
|
+
const cps = Array.from(cluster).map((c) => c.codePointAt(0));
|
|
139
|
+
const base = cps[0];
|
|
140
|
+
if (base < 0x20 || base === 0x7f)
|
|
141
|
+
return 0;
|
|
142
|
+
if (isZeroWidth(base))
|
|
143
|
+
return 0;
|
|
144
|
+
// VS16 promotes a text-presentation symbol to emoji presentation.
|
|
145
|
+
if (cps.includes(0xfe0f))
|
|
146
|
+
return 2;
|
|
147
|
+
if (isWide(base))
|
|
148
|
+
return 2;
|
|
149
|
+
return 1;
|
|
150
|
+
}
|
|
151
|
+
/** Width of a string in terminal cells. */
|
|
152
|
+
export function stringWidth(text) {
|
|
153
|
+
if (text === '')
|
|
154
|
+
return 0;
|
|
155
|
+
// Fast path: pure ASCII printable.
|
|
156
|
+
if (isAscii(text))
|
|
157
|
+
return text.length;
|
|
158
|
+
let w = 0;
|
|
159
|
+
for (const g of graphemes(text))
|
|
160
|
+
w += graphemeWidth(g);
|
|
161
|
+
return w;
|
|
162
|
+
}
|
|
163
|
+
/** Take at most `width` cells from the front. Never splits a wide grapheme. */
|
|
164
|
+
export function sliceByWidth(text, width) {
|
|
165
|
+
if (width <= 0)
|
|
166
|
+
return '';
|
|
167
|
+
if (stringWidth(text) <= width)
|
|
168
|
+
return text;
|
|
169
|
+
let out = '';
|
|
170
|
+
let w = 0;
|
|
171
|
+
for (const g of graphemes(text)) {
|
|
172
|
+
const gw = graphemeWidth(g);
|
|
173
|
+
if (w + gw > width)
|
|
174
|
+
break;
|
|
175
|
+
out += g;
|
|
176
|
+
w += gw;
|
|
177
|
+
}
|
|
178
|
+
return out;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* The slice of `text` covering display columns `[start, start + width)`.
|
|
182
|
+
*
|
|
183
|
+
* Cutting by index is wrong the moment a line contains a wide character: the
|
|
184
|
+
* horizontal scroll would drift against the gutter, one cell per CJK glyph.
|
|
185
|
+
* A wide grapheme straddling either edge is dropped rather than split, because
|
|
186
|
+
* half of one cannot be drawn.
|
|
187
|
+
*/
|
|
188
|
+
export function sliceColumns(text, start, width) {
|
|
189
|
+
if (width <= 0)
|
|
190
|
+
return '';
|
|
191
|
+
const end = start + width;
|
|
192
|
+
let column = 0;
|
|
193
|
+
let out = '';
|
|
194
|
+
for (const g of graphemes(text)) {
|
|
195
|
+
const gw = graphemeWidth(g);
|
|
196
|
+
if (gw === 0) {
|
|
197
|
+
// A combining mark belongs to the grapheme before it, if that survived.
|
|
198
|
+
if (out !== '')
|
|
199
|
+
out += g;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
const next = column + gw;
|
|
203
|
+
if (next <= start) {
|
|
204
|
+
column = next;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (column >= end)
|
|
208
|
+
break;
|
|
209
|
+
if (column >= start && next <= end) {
|
|
210
|
+
out += g;
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
// A wide grapheme half inside the window becomes blanks for the half
|
|
214
|
+
// that shows. Splitting it is impossible and dropping it silently would
|
|
215
|
+
// slide the rest of the line one cell against the gutter.
|
|
216
|
+
out += ' '.repeat(Math.min(next, end) - Math.max(column, start));
|
|
217
|
+
}
|
|
218
|
+
column = next;
|
|
219
|
+
}
|
|
220
|
+
return out;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Replace tabs with spaces to the next tab stop.
|
|
224
|
+
*
|
|
225
|
+
* A terminal cell is one column, so a raw tab is one blank cell and every
|
|
226
|
+
* indented line lands in a different place than it does in an editor. Doing
|
|
227
|
+
* this before highlighting keeps token offsets and screen columns the same
|
|
228
|
+
* number.
|
|
229
|
+
*/
|
|
230
|
+
export function expandTabs(text, tabWidth = 4) {
|
|
231
|
+
if (!text.includes('\t'))
|
|
232
|
+
return text;
|
|
233
|
+
const width = Math.max(1, tabWidth);
|
|
234
|
+
return text
|
|
235
|
+
.split('\n')
|
|
236
|
+
.map((line) => {
|
|
237
|
+
if (!line.includes('\t'))
|
|
238
|
+
return line;
|
|
239
|
+
let out = '';
|
|
240
|
+
let column = 0;
|
|
241
|
+
for (const g of graphemes(line)) {
|
|
242
|
+
if (g === '\t') {
|
|
243
|
+
const advance = width - (column % width);
|
|
244
|
+
out += ' '.repeat(advance);
|
|
245
|
+
column += advance;
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
out += g;
|
|
249
|
+
column += graphemeWidth(g);
|
|
250
|
+
}
|
|
251
|
+
return out;
|
|
252
|
+
})
|
|
253
|
+
.join('\n');
|
|
254
|
+
}
|
|
255
|
+
/** Fit into `width` cells, marking the cut with `ellipsis`. */
|
|
256
|
+
export function truncate(text, width, ellipsis = '…', side = 'end') {
|
|
257
|
+
const total = stringWidth(text);
|
|
258
|
+
if (total <= width)
|
|
259
|
+
return text;
|
|
260
|
+
if (width <= 0)
|
|
261
|
+
return '';
|
|
262
|
+
const ew = stringWidth(ellipsis);
|
|
263
|
+
if (width <= ew)
|
|
264
|
+
return sliceByWidth(ellipsis, width);
|
|
265
|
+
// A space either side of the ellipsis is a typographic mistake, not a cell
|
|
266
|
+
// of content, so the cut is tidied before the mark goes on. It also means a
|
|
267
|
+
// truncated string can come back narrower than `width`, which is correct:
|
|
268
|
+
// `width` is a limit, and nothing here is padding.
|
|
269
|
+
const keep = width - ew;
|
|
270
|
+
if (side === 'end')
|
|
271
|
+
return sliceByWidth(text, keep).trimEnd() + ellipsis;
|
|
272
|
+
const gs = graphemes(text);
|
|
273
|
+
if (side === 'start') {
|
|
274
|
+
let w = 0;
|
|
275
|
+
let i = gs.length;
|
|
276
|
+
while (i > 0 && w + graphemeWidth(gs[i - 1]) <= keep) {
|
|
277
|
+
i--;
|
|
278
|
+
w += graphemeWidth(gs[i]);
|
|
279
|
+
}
|
|
280
|
+
return ellipsis + gs.slice(i).join('').trimStart();
|
|
281
|
+
}
|
|
282
|
+
const left = Math.ceil(keep / 2);
|
|
283
|
+
const right = keep - left;
|
|
284
|
+
let w = 0;
|
|
285
|
+
let j = gs.length;
|
|
286
|
+
while (j > 0 && w + graphemeWidth(gs[j - 1]) <= right) {
|
|
287
|
+
j--;
|
|
288
|
+
w += graphemeWidth(gs[j]);
|
|
289
|
+
}
|
|
290
|
+
return sliceByWidth(text, left).trimEnd() + ellipsis + gs.slice(j).join('').trimStart();
|
|
291
|
+
}
|
|
292
|
+
/** Pad to exactly `width` cells. Over-long input is returned unchanged. */
|
|
293
|
+
export function padTo(text, width, align = 'left', fill = ' ') {
|
|
294
|
+
const w = stringWidth(text);
|
|
295
|
+
if (w >= width)
|
|
296
|
+
return text;
|
|
297
|
+
const pad = width - w;
|
|
298
|
+
if (align === 'left')
|
|
299
|
+
return text + fill.repeat(pad);
|
|
300
|
+
if (align === 'right')
|
|
301
|
+
return fill.repeat(pad) + text;
|
|
302
|
+
const left = Math.floor(pad / 2);
|
|
303
|
+
return fill.repeat(left) + text + fill.repeat(pad - left);
|
|
304
|
+
}
|
|
305
|
+
/** Fit to exactly `width`: truncate when long, pad when short. */
|
|
306
|
+
export function fitTo(text, width, align = 'left', ellipsis = '…') {
|
|
307
|
+
return padTo(truncate(text, width, ellipsis), width, align);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* The end a `TextWrap` cuts at, or `undefined` when it wraps instead.
|
|
311
|
+
*
|
|
312
|
+
* The wrapping modes and the truncating ones live in one union because they
|
|
313
|
+
* answer one question - what happens at the edge - and a component that had to
|
|
314
|
+
* take both a `wrap` and a `truncate` prop could be handed the two answers at
|
|
315
|
+
* once. These two helpers are how the union is taken apart again.
|
|
316
|
+
*/
|
|
317
|
+
export function truncateSideOf(wrap) {
|
|
318
|
+
switch (wrap) {
|
|
319
|
+
case 'truncate':
|
|
320
|
+
case 'truncate-end': return 'end';
|
|
321
|
+
case 'truncate-start': return 'start';
|
|
322
|
+
case 'truncate-middle': return 'middle';
|
|
323
|
+
default: return undefined;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
/** The mode `wrapText` should run in. A truncating text does not wrap at all. */
|
|
327
|
+
export function wrapModeOf(wrap) {
|
|
328
|
+
return wrap === 'word' || wrap === 'char' ? wrap : 'none';
|
|
329
|
+
}
|
|
330
|
+
/** Break into lines of at most `width` cells. Honours existing newlines. */
|
|
331
|
+
export function wrapText(text, width, mode = 'word') {
|
|
332
|
+
if (width <= 0)
|
|
333
|
+
return [];
|
|
334
|
+
const paragraphs = text.split('\n');
|
|
335
|
+
if (mode === 'none')
|
|
336
|
+
return paragraphs;
|
|
337
|
+
const out = [];
|
|
338
|
+
for (const para of paragraphs) {
|
|
339
|
+
if (para === '') {
|
|
340
|
+
out.push('');
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
if (stringWidth(para) <= width) {
|
|
344
|
+
out.push(para);
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
if (mode === 'char') {
|
|
348
|
+
let rest = para;
|
|
349
|
+
while (stringWidth(rest) > width) {
|
|
350
|
+
const head = sliceByWidth(rest, width);
|
|
351
|
+
out.push(head);
|
|
352
|
+
rest = rest.slice(head.length);
|
|
353
|
+
}
|
|
354
|
+
if (rest !== '')
|
|
355
|
+
out.push(rest);
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
// word wrap; a word longer than the line falls back to char wrap
|
|
359
|
+
let line = '';
|
|
360
|
+
let lineW = 0;
|
|
361
|
+
for (const word of para.split(/(\s+)/)) {
|
|
362
|
+
if (word === '')
|
|
363
|
+
continue;
|
|
364
|
+
const ww = stringWidth(word);
|
|
365
|
+
const isSpace = /^\s+$/.test(word);
|
|
366
|
+
if (lineW + ww <= width) {
|
|
367
|
+
line += word;
|
|
368
|
+
lineW += ww;
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
if (isSpace) {
|
|
372
|
+
out.push(line.trimEnd());
|
|
373
|
+
line = '';
|
|
374
|
+
lineW = 0;
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
if (line !== '') {
|
|
378
|
+
out.push(line.trimEnd());
|
|
379
|
+
line = '';
|
|
380
|
+
lineW = 0;
|
|
381
|
+
}
|
|
382
|
+
if (ww <= width) {
|
|
383
|
+
line = word;
|
|
384
|
+
lineW = ww;
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
let rest = word;
|
|
388
|
+
while (stringWidth(rest) > width) {
|
|
389
|
+
const head = sliceByWidth(rest, width);
|
|
390
|
+
out.push(head);
|
|
391
|
+
rest = rest.slice(head.length);
|
|
392
|
+
}
|
|
393
|
+
line = rest;
|
|
394
|
+
lineW = stringWidth(rest);
|
|
395
|
+
}
|
|
396
|
+
if (line !== '')
|
|
397
|
+
out.push(line.trimEnd());
|
|
398
|
+
}
|
|
399
|
+
return out;
|
|
400
|
+
}
|
|
401
|
+
// CSI / OSC / SS2 / SS3 and friends. Input sanitation only, never output.
|
|
402
|
+
const ANSI_RE =
|
|
403
|
+
// eslint-disable-next-line no-control-regex
|
|
404
|
+
/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~]|\][^\x07\x1B]*(?:\x07|\x1B\\))/g;
|
|
405
|
+
export function stripAnsi(text) {
|
|
406
|
+
return text.replace(ANSI_RE, '');
|
|
407
|
+
}
|
|
408
|
+
/** Remove control characters that would corrupt the frame. Keeps newlines. */
|
|
409
|
+
export function sanitize(text) {
|
|
410
|
+
// eslint-disable-next-line no-control-regex
|
|
411
|
+
return stripAnsi(text).replace(/[\x00-\x08\x0B-\x1F\x7F]/g, '');
|
|
412
|
+
}
|
|
413
|
+
/** Repeat a grapheme to exactly `width` cells (wide chars land short). */
|
|
414
|
+
export function repeatToWidth(char, width) {
|
|
415
|
+
if (width <= 0)
|
|
416
|
+
return '';
|
|
417
|
+
const w = graphemeWidth(char) || 1;
|
|
418
|
+
return char.repeat(Math.max(0, Math.floor(width / w)));
|
|
419
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@textui/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Graph-mounted terminal UI runtime - store, registries, renderer, host primitives",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"terminal",
|
|
7
|
+
"tui",
|
|
8
|
+
"cli",
|
|
9
|
+
"jsx",
|
|
10
|
+
"ui",
|
|
11
|
+
"runtime",
|
|
12
|
+
"ansi",
|
|
13
|
+
"text-ui",
|
|
14
|
+
"console",
|
|
15
|
+
"no-dependencies"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://softov.github.io/textui/",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/softov/textui/issues"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/softov/textui.git",
|
|
24
|
+
"directory": "packages/core"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"author": "Softov <softov@brbyte.com>",
|
|
28
|
+
"type": "module",
|
|
29
|
+
"sideEffects": false,
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=22"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"src",
|
|
36
|
+
"README.md",
|
|
37
|
+
"LICENSE"
|
|
38
|
+
],
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"types": "./dist/index.d.ts",
|
|
42
|
+
"import": "./dist/index.js"
|
|
43
|
+
},
|
|
44
|
+
"./types": {
|
|
45
|
+
"types": "./dist/types/index.d.ts",
|
|
46
|
+
"import": "./dist/types/index.js"
|
|
47
|
+
},
|
|
48
|
+
"./jsx-runtime": {
|
|
49
|
+
"types": "./dist/jsx/jsx-runtime.d.ts",
|
|
50
|
+
"import": "./dist/jsx/jsx-runtime.js"
|
|
51
|
+
},
|
|
52
|
+
"./jsx-dev-runtime": {
|
|
53
|
+
"types": "./dist/jsx/jsx-dev-runtime.d.ts",
|
|
54
|
+
"import": "./dist/jsx/jsx-dev-runtime.js"
|
|
55
|
+
},
|
|
56
|
+
"./themes": {
|
|
57
|
+
"types": "./dist/themes/index.d.ts",
|
|
58
|
+
"import": "./dist/themes/index.js"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public"
|
|
63
|
+
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"build": "tsc -p tsconfig.json",
|
|
66
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json",
|
|
67
|
+
"test": "vitest run",
|
|
68
|
+
"test:watch": "vitest"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapters.
|
|
3
|
+
*
|
|
4
|
+
* Nothing here is registered by default. An adapter is a choice - what a kind
|
|
5
|
+
* means, what opens it, what can be done to it - and choices belong to the
|
|
6
|
+
* application, not to the library that ships them.
|
|
7
|
+
*
|
|
8
|
+
* The adapters that have an opinion about *content* live in
|
|
9
|
+
* `@textui/documents`, beside the buffers they read and write.
|
|
10
|
+
*/
|
|
11
|
+
export {};
|