@zaly/tui 0.0.4

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.
Files changed (228) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/assets/schemas/theme.schema.json +899 -0
  4. package/assets/themes/LICENSE-tokyonight.txt +201 -0
  5. package/assets/themes/NOTICES.md +69 -0
  6. package/assets/themes/ayu-dark.json +119 -0
  7. package/assets/themes/catppuccin-frappe.json +124 -0
  8. package/assets/themes/catppuccin-latte.json +124 -0
  9. package/assets/themes/catppuccin-macchiato.json +124 -0
  10. package/assets/themes/catppuccin-mocha.json +124 -0
  11. package/assets/themes/dracula-soft.json +119 -0
  12. package/assets/themes/dracula.json +119 -0
  13. package/assets/themes/everforest-dark.json +118 -0
  14. package/assets/themes/everforest-light.json +118 -0
  15. package/assets/themes/github-dark.json +123 -0
  16. package/assets/themes/github-light.json +123 -0
  17. package/assets/themes/gruvbox-dark-medium.json +112 -0
  18. package/assets/themes/kanagawa-dragon.json +115 -0
  19. package/assets/themes/kanagawa-wave.json +115 -0
  20. package/assets/themes/material-theme-palenight.json +114 -0
  21. package/assets/themes/min-dark.json +55 -0
  22. package/assets/themes/min-light.json +59 -0
  23. package/assets/themes/monokai.json +116 -0
  24. package/assets/themes/night-owl.json +116 -0
  25. package/assets/themes/nord.json +101 -0
  26. package/assets/themes/one-dark-pro.json +110 -0
  27. package/assets/themes/one-light.json +108 -0
  28. package/assets/themes/poimandres.json +123 -0
  29. package/assets/themes/rose-pine.json +98 -0
  30. package/assets/themes/solarized-dark.json +116 -0
  31. package/assets/themes/solarized-light.json +116 -0
  32. package/assets/themes/synthwave-84.json +100 -0
  33. package/assets/themes/tokyonight-day.json +157 -0
  34. package/assets/themes/tokyonight-moon.json +157 -0
  35. package/assets/themes/tokyonight-night.json +157 -0
  36. package/assets/themes/tokyonight-storm.json +157 -0
  37. package/assets/themes/vesper.json +103 -0
  38. package/assets/themes/vitesse-dark.json +126 -0
  39. package/assets/themes/vitesse-light.json +126 -0
  40. package/dist/ansi-Clq0ozyA.mjs +206 -0
  41. package/dist/ansi-Clq0ozyA.mjs.map +1 -0
  42. package/dist/ansi.d.mts +48 -0
  43. package/dist/ansi.d.mts.map +1 -0
  44. package/dist/ansi.mjs +2 -0
  45. package/dist/autocomplete-Dfw-yQDa.d.mts +100 -0
  46. package/dist/autocomplete-Dfw-yQDa.d.mts.map +1 -0
  47. package/dist/box-DyaByEiG.mjs +386 -0
  48. package/dist/box-DyaByEiG.mjs.map +1 -0
  49. package/dist/builder-D49ECBEf.mjs +385 -0
  50. package/dist/builder-D49ECBEf.mjs.map +1 -0
  51. package/dist/callbacks-CNjGNxVw.mjs +279 -0
  52. package/dist/callbacks-CNjGNxVw.mjs.map +1 -0
  53. package/dist/client-D6C_uczF.mjs +142 -0
  54. package/dist/client-D6C_uczF.mjs.map +1 -0
  55. package/dist/clipboard.d.mts +104 -0
  56. package/dist/clipboard.d.mts.map +1 -0
  57. package/dist/clipboard.mjs +404 -0
  58. package/dist/clipboard.mjs.map +1 -0
  59. package/dist/flex-Bguo-fUe.mjs +202 -0
  60. package/dist/flex-Bguo-fUe.mjs.map +1 -0
  61. package/dist/image-Cm5T-uw-.mjs +108 -0
  62. package/dist/image-Cm5T-uw-.mjs.map +1 -0
  63. package/dist/image.d.mts +123 -0
  64. package/dist/image.d.mts.map +1 -0
  65. package/dist/image.mjs +2 -0
  66. package/dist/index.d.mts +64 -0
  67. package/dist/index.d.mts.map +1 -0
  68. package/dist/index.mjs +222 -0
  69. package/dist/index.mjs.map +1 -0
  70. package/dist/input-B5Vy-iaa.d.mts +141 -0
  71. package/dist/input-B5Vy-iaa.d.mts.map +1 -0
  72. package/dist/inspect-D1d9t-ni.mjs +101 -0
  73. package/dist/inspect-D1d9t-ni.mjs.map +1 -0
  74. package/dist/inspect-D6FW_QUo.d.mts +67 -0
  75. package/dist/inspect-D6FW_QUo.d.mts.map +1 -0
  76. package/dist/kitty-JbCJC0iQ.mjs +673 -0
  77. package/dist/kitty-JbCJC0iQ.mjs.map +1 -0
  78. package/dist/markdown.d.mts +24 -0
  79. package/dist/markdown.d.mts.map +1 -0
  80. package/dist/markdown.mjs +2 -0
  81. package/dist/md.bun.d.mts +14 -0
  82. package/dist/md.bun.d.mts.map +1 -0
  83. package/dist/md.bun.mjs +28 -0
  84. package/dist/md.bun.mjs.map +1 -0
  85. package/dist/md.node.d.mts +14 -0
  86. package/dist/md.node.d.mts.map +1 -0
  87. package/dist/md.node.mjs +126 -0
  88. package/dist/md.node.mjs.map +1 -0
  89. package/dist/node-BZ7f6HzU.mjs +316 -0
  90. package/dist/node-BZ7f6HzU.mjs.map +1 -0
  91. package/dist/picker-D8OLb6kZ.d.mts +36 -0
  92. package/dist/picker-D8OLb6kZ.d.mts.map +1 -0
  93. package/dist/picker-ndVVt6qF.mjs +621 -0
  94. package/dist/picker-ndVVt6qF.mjs.map +1 -0
  95. package/dist/queries-DH3bj74K.d.mts +1963 -0
  96. package/dist/queries-DH3bj74K.d.mts.map +1 -0
  97. package/dist/reactive-f7NpAi69.mjs +623 -0
  98. package/dist/reactive-f7NpAi69.mjs.map +1 -0
  99. package/dist/registry-U654j61Y.mjs +356 -0
  100. package/dist/registry-U654j61Y.mjs.map +1 -0
  101. package/dist/render-DxVLqqB9.mjs +74 -0
  102. package/dist/render-DxVLqqB9.mjs.map +1 -0
  103. package/dist/renderer-CdLCkJB-.mjs +42 -0
  104. package/dist/renderer-CdLCkJB-.mjs.map +1 -0
  105. package/dist/renderer-CxL4xbkl.mjs +2644 -0
  106. package/dist/renderer-CxL4xbkl.mjs.map +1 -0
  107. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  108. package/dist/search-FvGnswRl.d.mts +49 -0
  109. package/dist/search-FvGnswRl.d.mts.map +1 -0
  110. package/dist/select-CbmAZdpt.d.mts +116 -0
  111. package/dist/select-CbmAZdpt.d.mts.map +1 -0
  112. package/dist/services/logger.d.mts +2 -0
  113. package/dist/services/logger.mjs +71 -0
  114. package/dist/services/logger.mjs.map +1 -0
  115. package/dist/services/notifier.d.mts +17 -0
  116. package/dist/services/notifier.d.mts.map +1 -0
  117. package/dist/services/notifier.mjs +71 -0
  118. package/dist/services/notifier.mjs.map +1 -0
  119. package/dist/services/picker.d.mts +36 -0
  120. package/dist/services/picker.d.mts.map +1 -0
  121. package/dist/services/picker.mjs +137 -0
  122. package/dist/services/picker.mjs.map +1 -0
  123. package/dist/services/prompt.d.mts +30 -0
  124. package/dist/services/prompt.d.mts.map +1 -0
  125. package/dist/services/prompt.mjs +83 -0
  126. package/dist/services/prompt.mjs.map +1 -0
  127. package/dist/shiki-BrjVUkeh.mjs +423 -0
  128. package/dist/shiki-BrjVUkeh.mjs.map +1 -0
  129. package/dist/size-D8JogYLy.mjs +34 -0
  130. package/dist/size-D8JogYLy.mjs.map +1 -0
  131. package/dist/style.d.mts +10 -0
  132. package/dist/style.d.mts.map +1 -0
  133. package/dist/style.mjs +4 -0
  134. package/dist/text.d.mts +33 -0
  135. package/dist/text.d.mts.map +1 -0
  136. package/dist/text.mjs +111 -0
  137. package/dist/text.mjs.map +1 -0
  138. package/dist/theme.config-CU3B50HN.mjs +832 -0
  139. package/dist/theme.config-CU3B50HN.mjs.map +1 -0
  140. package/dist/themes.d.mts +113 -0
  141. package/dist/themes.d.mts.map +1 -0
  142. package/dist/themes.mjs +2 -0
  143. package/dist/tree-C28QOVIK.d.mts +23 -0
  144. package/dist/tree-C28QOVIK.d.mts.map +1 -0
  145. package/dist/types-B9Eh7k2v.d.mts +212 -0
  146. package/dist/types-B9Eh7k2v.d.mts.map +1 -0
  147. package/dist/types-D3jk1rtk.d.mts +140 -0
  148. package/dist/types-D3jk1rtk.d.mts.map +1 -0
  149. package/dist/utils-3M4D_AXZ.mjs +40 -0
  150. package/dist/utils-3M4D_AXZ.mjs.map +1 -0
  151. package/dist/widgets/autocomplete.d.mts +2 -0
  152. package/dist/widgets/autocomplete.mjs +165 -0
  153. package/dist/widgets/autocomplete.mjs.map +1 -0
  154. package/dist/widgets/box.d.mts +2 -0
  155. package/dist/widgets/box.mjs +2 -0
  156. package/dist/widgets/code.d.mts +48 -0
  157. package/dist/widgets/code.d.mts.map +1 -0
  158. package/dist/widgets/code.mjs +59 -0
  159. package/dist/widgets/code.mjs.map +1 -0
  160. package/dist/widgets/completions/actions.d.mts +41 -0
  161. package/dist/widgets/completions/actions.d.mts.map +1 -0
  162. package/dist/widgets/completions/actions.mjs +48 -0
  163. package/dist/widgets/completions/actions.mjs.map +1 -0
  164. package/dist/widgets/completions/files.d.mts +29 -0
  165. package/dist/widgets/completions/files.d.mts.map +1 -0
  166. package/dist/widgets/completions/files.mjs +42 -0
  167. package/dist/widgets/completions/files.mjs.map +1 -0
  168. package/dist/widgets/completions/github.d.mts +64 -0
  169. package/dist/widgets/completions/github.d.mts.map +1 -0
  170. package/dist/widgets/completions/github.mjs +137 -0
  171. package/dist/widgets/completions/github.mjs.map +1 -0
  172. package/dist/widgets/completions/index.d.mts +4 -0
  173. package/dist/widgets/completions/index.mjs +4 -0
  174. package/dist/widgets/diff.d.mts +57 -0
  175. package/dist/widgets/diff.d.mts.map +1 -0
  176. package/dist/widgets/diff.mjs +199 -0
  177. package/dist/widgets/diff.mjs.map +1 -0
  178. package/dist/widgets/divider.d.mts +11 -0
  179. package/dist/widgets/divider.d.mts.map +1 -0
  180. package/dist/widgets/divider.mjs +9 -0
  181. package/dist/widgets/divider.mjs.map +1 -0
  182. package/dist/widgets/image.d.mts +37 -0
  183. package/dist/widgets/image.d.mts.map +1 -0
  184. package/dist/widgets/image.mjs +77 -0
  185. package/dist/widgets/image.mjs.map +1 -0
  186. package/dist/widgets/input.d.mts +2 -0
  187. package/dist/widgets/input.mjs +497 -0
  188. package/dist/widgets/input.mjs.map +1 -0
  189. package/dist/widgets/log.d.mts +2 -0
  190. package/dist/widgets/log.mjs +130 -0
  191. package/dist/widgets/log.mjs.map +1 -0
  192. package/dist/widgets/markdown.d.mts +45 -0
  193. package/dist/widgets/markdown.d.mts.map +1 -0
  194. package/dist/widgets/markdown.mjs +124 -0
  195. package/dist/widgets/markdown.mjs.map +1 -0
  196. package/dist/widgets/overlay.d.mts +2 -0
  197. package/dist/widgets/overlay.mjs +18 -0
  198. package/dist/widgets/overlay.mjs.map +1 -0
  199. package/dist/widgets/picker.d.mts +2 -0
  200. package/dist/widgets/picker.mjs +2 -0
  201. package/dist/widgets/progress.d.mts +48 -0
  202. package/dist/widgets/progress.d.mts.map +1 -0
  203. package/dist/widgets/progress.mjs +48 -0
  204. package/dist/widgets/progress.mjs.map +1 -0
  205. package/dist/widgets/select.d.mts +2 -0
  206. package/dist/widgets/select.mjs +195 -0
  207. package/dist/widgets/select.mjs.map +1 -0
  208. package/dist/widgets/show.d.mts +55 -0
  209. package/dist/widgets/show.d.mts.map +1 -0
  210. package/dist/widgets/show.mjs +85 -0
  211. package/dist/widgets/show.mjs.map +1 -0
  212. package/dist/widgets/spinner.d.mts +65 -0
  213. package/dist/widgets/spinner.d.mts.map +1 -0
  214. package/dist/widgets/spinner.mjs +147 -0
  215. package/dist/widgets/spinner.mjs.map +1 -0
  216. package/dist/widgets/text.d.mts +2 -0
  217. package/dist/widgets/text.mjs +32 -0
  218. package/dist/widgets/text.mjs.map +1 -0
  219. package/dist/widgets/tree.d.mts +2 -0
  220. package/dist/widgets/tree.mjs +73 -0
  221. package/dist/widgets/tree.mjs.map +1 -0
  222. package/dist/widgets/widget.d.mts +49 -0
  223. package/dist/widgets/widget.d.mts.map +1 -0
  224. package/dist/widgets/widget.mjs +40 -0
  225. package/dist/widgets/widget.mjs.map +1 -0
  226. package/dist/worker-DjHuQSbY.mjs +27 -0
  227. package/dist/worker-DjHuQSbY.mjs.map +1 -0
  228. package/package.json +117 -0
@@ -0,0 +1,126 @@
1
+ {
2
+ "$schema": "file:./../schemas/theme.schema.json",
3
+ "id": "vitesse-light",
4
+ "name": "Vitesse Light",
5
+ "shiki": "vitesse-light",
6
+ "text": "#393a34",
7
+ "subtle": "#aaaaaa",
8
+ "ui": {
9
+ "bg": "#ffffff",
10
+ "fg": "#393a34"
11
+ },
12
+ "primary": "#1c6b48",
13
+ "accent": "#1c6b48",
14
+ "success": "#1e754f",
15
+ "info": "#2993a3",
16
+ "warn": "#a65e2b",
17
+ "error": "#ab5959",
18
+ "muted": "#aaaaaa",
19
+ "border": "#f0f0f0",
20
+ "code": {
21
+ "bg": "#ffffff"
22
+ },
23
+ "mdCodeBlock": {
24
+ "bg": "#ffffff"
25
+ },
26
+ "overlay": {
27
+ "bg": "#ffffff"
28
+ },
29
+ "highlight": {
30
+ "bg": "#eaeaea"
31
+ },
32
+ "selection": {
33
+ "bg": "#eaeaea"
34
+ },
35
+ "diffAdd": {
36
+ "bg": "#d4e3dd",
37
+ "fg": "#22863a"
38
+ },
39
+ "diffDel": {
40
+ "bg": "#ead5d5",
41
+ "fg": "#b31d28"
42
+ },
43
+ "diffTitle": {
44
+ "fg": "#b31d28",
45
+ "bg": "#ffeef0"
46
+ },
47
+ "comment": {
48
+ "fg": "#a0ada0"
49
+ },
50
+ "syntaxNumber": {
51
+ "fg": "#2f798a"
52
+ },
53
+ "syntaxString": {
54
+ "fg": "#b56959"
55
+ },
56
+ "syntaxBoolean": {
57
+ "fg": "#1e754f"
58
+ },
59
+ "syntaxFunction": {
60
+ "fg": "#59873a"
61
+ },
62
+ "syntaxField": {
63
+ "fg": "#b07d48"
64
+ },
65
+ "syntaxConstant": {
66
+ "fg": "#a65e2b"
67
+ },
68
+ "syntaxSpecial": {
69
+ "fg": "#1e754f"
70
+ },
71
+ "syntaxDelimiter": {
72
+ "fg": "#999999"
73
+ },
74
+ "syntaxBracket": {
75
+ "fg": "#999999"
76
+ },
77
+ "mdHeading": {
78
+ "bold": true,
79
+ "fg": "#1c6b48"
80
+ },
81
+ "mdHeading1": {
82
+ "bold": true,
83
+ "fg": "#1c6b48"
84
+ },
85
+ "mdHeading2": {
86
+ "bold": true,
87
+ "fg": "#1c6b48"
88
+ },
89
+ "mdHeading3": {
90
+ "bold": true,
91
+ "fg": "#1c6b48"
92
+ },
93
+ "mdHeading4": {
94
+ "bold": true,
95
+ "fg": "#1c6b48"
96
+ },
97
+ "mdHeading5": {
98
+ "bold": true,
99
+ "fg": "#1c6b48"
100
+ },
101
+ "mdHeading6": {
102
+ "bold": true,
103
+ "fg": "#1c6b48"
104
+ },
105
+ "mdBold": {
106
+ "bold": true,
107
+ "fg": "#393a34"
108
+ },
109
+ "mdItalic": {
110
+ "italic": true,
111
+ "fg": "#393a34"
112
+ },
113
+ "mdLink": {
114
+ "fg": "#b56959"
115
+ },
116
+ "mdQuote": {
117
+ "fg": "#2e808f"
118
+ },
119
+ "mdCode": {
120
+ "fg": "#1c6b48"
121
+ },
122
+ "mdHr": {
123
+ "bold": true,
124
+ "fg": "#005cc5"
125
+ }
126
+ }
@@ -0,0 +1,206 @@
1
+ import { clamp } from "@zaly/shared";
2
+ import { sliceAnsi } from "@zaly/shared/ansi";
3
+ import { hasColors } from "@zaly/shared/env";
4
+ //#region src/style/color.ts
5
+ const hexByte = (n) => clamp(Math.round(n), 0, 255).toString(16).padStart(2, "0");
6
+ function toHex(x, y, z) {
7
+ const [r, g, b] = Array.isArray(x) ? x : [
8
+ x,
9
+ y,
10
+ z
11
+ ];
12
+ return `#${hexByte(r)}${hexByte(g)}${hexByte(b)}`;
13
+ }
14
+ function parseHex(hex) {
15
+ let s = hex.charCodeAt(0) === 35 ? hex.slice(1) : hex;
16
+ if (s.length === 4) s = s.slice(0, 3);
17
+ if (s.length === 8) s = s.slice(0, 6);
18
+ if (s.length === 3) s = s[0] + s[0] + s[1] + s[1] + s[2] + s[2];
19
+ if (s.length !== 6) throw new Error(`invalid hex color: ${hex}`);
20
+ const n = Number.parseInt(s, 16);
21
+ if (Number.isNaN(n)) throw new Error(`invalid hex color: ${hex}`);
22
+ return [
23
+ n >> 16 & 255,
24
+ n >> 8 & 255,
25
+ n & 255
26
+ ];
27
+ }
28
+ function isHexColor(s) {
29
+ return /^#[0-9a-fA-F]{3,8}$/.test(s);
30
+ }
31
+ //#endregion
32
+ //#region src/style/ansi.ts
33
+ const OSC8 = "\x1B]8;;";
34
+ const ST = "\x1B\\";
35
+ const RESET = "\x1B[0m";
36
+ const ATTRS = [
37
+ ["bold", 1],
38
+ ["dim", 2],
39
+ ["italic", 3],
40
+ ["underline", 4],
41
+ ["inverse", 7],
42
+ ["strikethrough", 9]
43
+ ];
44
+ const ANSI_OFFSET = {
45
+ black: 0,
46
+ blue: 4,
47
+ cyan: 6,
48
+ green: 2,
49
+ magenta: 5,
50
+ red: 1,
51
+ white: 7,
52
+ yellow: 3
53
+ };
54
+ const ANSI_BG = {
55
+ 100: "gray",
56
+ 101: "brightRed",
57
+ 102: "brightGreen",
58
+ 103: "brightYellow",
59
+ 104: "brightBlue",
60
+ 105: "brightMagenta",
61
+ 106: "brightCyan",
62
+ 107: "brightWhite",
63
+ 40: "black",
64
+ 41: "red",
65
+ 42: "green",
66
+ 43: "yellow",
67
+ 44: "blue",
68
+ 45: "magenta",
69
+ 46: "cyan",
70
+ 47: "white"
71
+ };
72
+ const notFound = Symbol("not found");
73
+ const colorCache = /* @__PURE__ */ new Map();
74
+ /**
75
+ * Wrap `text` in an OSC 8 hyperlink pointing at `url`. Modern terminals
76
+ * (iTerm2, kitty, WezTerm, VS Code, Ghostty, …) render the text as
77
+ * clickable while falling back gracefully to plain text elsewhere.
78
+ *
79
+ * Safe to nest ANSI SGR styling inside the `text` argument — OSC 8 is a
80
+ * separate escape category and doesn't conflict.
81
+ *
82
+ * An empty `url` short-circuits and returns `text` unchanged, so callers
83
+ * can unconditionally pipe link text through this helper.
84
+ *
85
+ * @internal
86
+ */
87
+ function hyperlink(url, text) {
88
+ if (url === "") return text;
89
+ return `${OSC8}${url}${ST}${text}${OSC8}${ST}`;
90
+ }
91
+ function ansiColor(color, kind) {
92
+ if (!hasColors) return;
93
+ const key = `${color}-${kind}`;
94
+ let cached = colorCache.get(key);
95
+ if (cached === void 0) colorCache.set(key, (cached = _ansiColor(color, kind)) ?? notFound);
96
+ return cached === notFound ? void 0 : cached;
97
+ }
98
+ function _ansiColor(color, kind) {
99
+ if (color === "inherit") return;
100
+ if (color === "gray" || color === "grey") return String(kind === "fg" ? 90 : 100);
101
+ const base = color in ANSI_OFFSET ? color : void 0;
102
+ if (base !== void 0) return String((kind === "fg" ? 30 : 40) + ANSI_OFFSET[base]);
103
+ if (color.startsWith("bright")) {
104
+ const rest = color.slice(6).toLowerCase();
105
+ if (rest in ANSI_OFFSET) return String((kind === "fg" ? 90 : 100) + ANSI_OFFSET[rest]);
106
+ }
107
+ const rgb = isHexColor(color) ? parseHex(color) : void 0;
108
+ if (rgb) return `${kind === "fg" ? 38 : 48};2;${rgb[0]};${rgb[1]};${rgb[2]}`;
109
+ }
110
+ function openAnsi(style) {
111
+ if (!hasColors) return "";
112
+ const params = [];
113
+ for (const [key, code] of ATTRS) if (style[key]) params.push(code);
114
+ if (style.fg !== void 0) params.push(ansiColor(style.fg, "fg"));
115
+ if (style.bg !== void 0) params.push(ansiColor(style.bg, "bg"));
116
+ const attrs = params.filter((p) => p !== void 0);
117
+ if (attrs.length === 0) return "";
118
+ return `\x1b[${attrs.join(";")}m`;
119
+ }
120
+ function styleAnsi(text, style) {
121
+ if (!style) return text;
122
+ const open = openAnsi(style);
123
+ if (open === "") return text;
124
+ return `${open}${text}${RESET}`;
125
+ }
126
+ /**
127
+ * Post-process a styled string so an outer style is re-applied after any
128
+ * inner full-reset (`\x1b[0m`). Without this, a child's reset clobbers
129
+ * the parent's bg/fg/attrs for the remainder of the line.
130
+ *
131
+ * `escape` is the already-built SGR run to re-emit after each reset
132
+ * (typically the return value of `openStyle(parentStyle, theme)`). If
133
+ * empty, the input is returned unchanged.
134
+ *
135
+ * Inlined indexOf loop rather than `String.prototype.replaceAll` — the
136
+ * manual version avoids the regex/object allocation overhead of
137
+ * `replaceAll` and runs meaningfully faster on short strings (hot in
138
+ * the builder's `apply`, called once per styled span). Pattern taken
139
+ * from ansis's nested-style resolver.
140
+ *
141
+ * @internal
142
+ */
143
+ function reapplyStyle(s, escape) {
144
+ if (escape === "" || !s.includes("\x1B[0m")) return s;
145
+ const replacement = RESET + escape;
146
+ const searchLength = 4;
147
+ let result = "";
148
+ let lastPos = 0;
149
+ let pos = s.indexOf(RESET);
150
+ while (pos !== -1) {
151
+ result += s.slice(lastPos, pos) + replacement;
152
+ lastPos = pos + searchLength;
153
+ pos = s.indexOf(RESET, lastPos);
154
+ }
155
+ return result + s.slice(lastPos);
156
+ }
157
+ function stripAnsiBg(s) {
158
+ return s.replaceAll(/\x1b\[([0-9;]*)m/g, (match, raw) => {
159
+ const next = stripBgParams(raw);
160
+ if (next === raw) return match;
161
+ return next === "" ? "" : `\x1b[${next}m`;
162
+ });
163
+ }
164
+ function stripBgParams(raw) {
165
+ if (raw === "") return raw;
166
+ const params = raw.split(";").map(Number);
167
+ const ret = [];
168
+ for (let i = 0; i < params.length; i++) {
169
+ const p = params[i];
170
+ if (p >= 40 && p <= 47 || p >= 100 && p <= 107 || p === 49) continue;
171
+ if (p === 48) {
172
+ const mode = params[i + 1];
173
+ if (mode === 2) {
174
+ i += 4;
175
+ continue;
176
+ }
177
+ if (mode === 5) {
178
+ i += 2;
179
+ continue;
180
+ }
181
+ continue;
182
+ }
183
+ ret.push(p);
184
+ }
185
+ return ret.join(";");
186
+ }
187
+ function ansiBg(str, idx) {
188
+ const cell = sliceAnsi(str, idx, idx + 1);
189
+ let bg;
190
+ for (const match of cell.matchAll(/\x1b\[([0-9;]*)m/g)) {
191
+ const params = match[1].split(";").map(Number);
192
+ for (let i = 0; i < params.length; i++) {
193
+ const p = params[i];
194
+ if (p >= 40 && p <= 47 || p >= 100 && p <= 107) bg = ANSI_BG[p];
195
+ else if (p === 48 && params[i + 1] === 2) {
196
+ bg = toHex(params[i + 2], params[i + 3], params[i + 4]);
197
+ i += 4;
198
+ }
199
+ }
200
+ }
201
+ return bg;
202
+ }
203
+ //#endregion
204
+ export { openAnsi as a, styleAnsi as c, toHex as d, hyperlink as i, isHexColor as l, ansiBg as n, reapplyStyle as o, ansiColor as r, stripAnsiBg as s, RESET as t, parseHex as u };
205
+
206
+ //# sourceMappingURL=ansi-Clq0ozyA.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ansi-Clq0ozyA.mjs","names":[],"sources":["../src/style/color.ts","../src/style/ansi.ts"],"sourcesContent":["import type { HexColor, RGB } from \"./types.ts\"\n\nimport { clamp } from \"@zaly/shared\"\n\nconst hexByte = (n: number): string => clamp(Math.round(n), 0, 255).toString(16).padStart(2, \"0\")\n\nexport function toHex(c: RGB): HexColor\nexport function toHex(r: number, g: number, b: number): HexColor\nexport function toHex(x: number | RGB, y?: number, z?: number): HexColor {\n const [r, g, b] = Array.isArray(x) ? x : [x, y!, z!]\n return `#${hexByte(r)}${hexByte(g)}${hexByte(b)}`\n}\n\nexport function parseHex(hex: string): RGB {\n let s = hex.charCodeAt(0) === 0x23 ? hex.slice(1) : hex // strip leading #\n if (s.length === 4) s = s.slice(0, 3) // strip alpha\n if (s.length === 8) s = s.slice(0, 6) // strip alpha\n if (s.length === 3) {\n // Expand \"abc\" → \"aabbcc\" without allocating an array.\n s = s[0] + s[0] + s[1] + s[1] + s[2] + s[2]\n }\n if (s.length !== 6) throw new Error(`invalid hex color: ${hex}`)\n const n = Number.parseInt(s, 16)\n if (Number.isNaN(n)) throw new Error(`invalid hex color: ${hex}`)\n return [(n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]\n}\n\nexport function isHexColor(s: string): s is HexColor {\n return /^#[0-9a-fA-F]{3,8}$/.test(s)\n}\n","import type { AnsiColor, AnsiStyle } from \"./types.ts\"\n\nimport { sliceAnsi } from \"@zaly/shared/ansi\"\nimport { hasColors } from \"@zaly/shared/env\"\nimport { isHexColor, parseHex, toHex } from \"./color.ts\"\n\n/** Optional wrap mode: `\"word\"` (default) breaks at word boundaries;\n * `\"char\"` hard-wraps mid-word. */\nexport interface WrapOpts {\n mode?: \"word\" | \"char\"\n}\n\n// ---- ANSI escape categories -------------------------------------------\n// OSC 8 hyperlink sequence. ESC + backslash is the \"string terminator\" (ST)\n// that closes the OSC. Format: `ESC]8;;URL ST TEXT ESC]8;; ST`.\nconst OSC8 = \"\\x1b]8;;\"\nconst ST = \"\\x1b\\\\\"\nexport const RESET = \"\\x1b[0m\"\n\n// Attribute → SGR code. Order matters for stable output.\nconst ATTRS = [\n [\"bold\", 1],\n [\"dim\", 2],\n [\"italic\", 3],\n [\"underline\", 4],\n [\"inverse\", 7],\n [\"strikethrough\", 9],\n] as const satisfies readonly (readonly [keyof AnsiStyle, number])[]\n\n// Standard 8-color ANSI palette. Offsets from SGR 30 (fg) and 40 (bg).\nconst ANSI_OFFSET: Record<string, number> = {\n black: 0,\n blue: 4,\n cyan: 6,\n green: 2,\n magenta: 5,\n red: 1,\n white: 7,\n yellow: 3,\n}\n\nconst ANSI_BG: Record<number, AnsiColor> = {\n 100: \"gray\", // or \"brightBlack\" if that exists\n 101: \"brightRed\",\n 102: \"brightGreen\",\n 103: \"brightYellow\",\n 104: \"brightBlue\",\n 105: \"brightMagenta\",\n 106: \"brightCyan\",\n 107: \"brightWhite\",\n 40: \"black\",\n 41: \"red\",\n 42: \"green\",\n 43: \"yellow\",\n 44: \"blue\",\n 45: \"magenta\",\n 46: \"cyan\",\n 47: \"white\",\n}\n\nconst notFound = Symbol(\"not found\")\nconst colorCache = new Map<string, string | typeof notFound>()\n\n/**\n * Wrap `text` in an OSC 8 hyperlink pointing at `url`. Modern terminals\n * (iTerm2, kitty, WezTerm, VS Code, Ghostty, …) render the text as\n * clickable while falling back gracefully to plain text elsewhere.\n *\n * Safe to nest ANSI SGR styling inside the `text` argument — OSC 8 is a\n * separate escape category and doesn't conflict.\n *\n * An empty `url` short-circuits and returns `text` unchanged, so callers\n * can unconditionally pipe link text through this helper.\n *\n * @internal\n */\nexport function hyperlink(url: string, text: string): string {\n if (url === \"\") return text\n return `${OSC8}${url}${ST}${text}${OSC8}${ST}`\n}\n\nexport function ansiColor(color: AnsiColor, kind: \"fg\" | \"bg\"): string | undefined {\n if (!hasColors) return\n const key = `${color}-${kind}`\n let cached = colorCache.get(key)\n if (cached === undefined) colorCache.set(key, (cached = _ansiColor(color, kind)) ?? notFound)\n return cached === notFound ? undefined : cached\n}\n\nfunction _ansiColor(color: AnsiColor, kind: \"fg\" | \"bg\"): string | undefined {\n if (color === \"inherit\") return\n // Gray aliases to brightBlack.\n if (color === \"gray\" || color === \"grey\") return String(kind === \"fg\" ? 90 : 100)\n\n const base = color in ANSI_OFFSET ? color : undefined\n if (base !== undefined) return String((kind === \"fg\" ? 30 : 40) + ANSI_OFFSET[base])\n\n if (color.startsWith(\"bright\")) {\n const rest = color.slice(\"bright\".length).toLowerCase()\n if (rest in ANSI_OFFSET) return String((kind === \"fg\" ? 90 : 100) + ANSI_OFFSET[rest])\n }\n\n const rgb = isHexColor(color) ? parseHex(color) : undefined\n if (rgb) {\n const indicator = kind === \"fg\" ? 38 : 48\n return `${indicator};2;${rgb[0]};${rgb[1]};${rgb[2]}`\n }\n}\n\nexport function openAnsi(style: AnsiStyle) {\n if (!hasColors) return \"\"\n const params: (number | string | undefined)[] = []\n for (const [key, code] of ATTRS) if (style[key]) params.push(code)\n if (style.fg !== undefined) params.push(ansiColor(style.fg, \"fg\"))\n if (style.bg !== undefined) params.push(ansiColor(style.bg, \"bg\"))\n const attrs = params.filter((p) => p !== undefined)\n if (attrs.length === 0) return \"\"\n return `\\x1b[${attrs.join(\";\")}m`\n}\n\nexport function styleAnsi(text: string, style?: AnsiStyle): string {\n if (!style) return text\n const open = openAnsi(style)\n if (open === \"\") return text\n return `${open}${text}${RESET}`\n}\n\n/**\n * Post-process a styled string so an outer style is re-applied after any\n * inner full-reset (`\\x1b[0m`). Without this, a child's reset clobbers\n * the parent's bg/fg/attrs for the remainder of the line.\n *\n * `escape` is the already-built SGR run to re-emit after each reset\n * (typically the return value of `openStyle(parentStyle, theme)`). If\n * empty, the input is returned unchanged.\n *\n * Inlined indexOf loop rather than `String.prototype.replaceAll` — the\n * manual version avoids the regex/object allocation overhead of\n * `replaceAll` and runs meaningfully faster on short strings (hot in\n * the builder's `apply`, called once per styled span). Pattern taken\n * from ansis's nested-style resolver.\n *\n * @internal\n */\nexport function reapplyStyle(s: string, escape: string): string {\n if (escape === \"\" || !s.includes(RESET)) return s\n const replacement = RESET + escape\n const searchLength = RESET.length\n let result = \"\"\n let lastPos = 0\n let pos = s.indexOf(RESET)\n while (pos !== -1) {\n result += s.slice(lastPos, pos) + replacement\n lastPos = pos + searchLength\n pos = s.indexOf(RESET, lastPos)\n }\n return result + s.slice(lastPos)\n}\n\nexport function stripAnsiBg(s: string): string {\n return s.replaceAll(/\\x1b\\[([0-9;]*)m/g, (match, raw: string) => {\n const next = stripBgParams(raw)\n if (next === raw) return match\n return next === \"\" ? \"\" : `\\x1b[${next}m`\n })\n}\n\nfunction stripBgParams(raw: string): string {\n if (raw === \"\") return raw\n const params = raw.split(\";\").map(Number)\n const ret: number[] = []\n for (let i = 0; i < params.length; i++) {\n const p = params[i]\n if ((p >= 40 && p <= 47) || (p >= 100 && p <= 107) || p === 49) continue\n if (p === 48) {\n const mode = params[i + 1]\n if (mode === 2) {\n i += 4\n continue\n }\n if (mode === 5) {\n i += 2\n continue\n }\n continue\n }\n ret.push(p)\n }\n return ret.join(\";\")\n}\n\nexport function ansiBg(str: string, idx: number): AnsiColor | undefined {\n const cell = sliceAnsi(str, idx, idx + 1)\n\n let bg: AnsiColor | undefined\n\n for (const match of cell.matchAll(/\\x1b\\[([0-9;]*)m/g)) {\n const params = match[1].split(\";\").map(Number)\n\n for (let i = 0; i < params.length; i++) {\n const p = params[i]\n\n if ((p >= 40 && p <= 47) || (p >= 100 && p <= 107)) {\n bg = ANSI_BG[p]\n } else if (p === 48 && params[i + 1] === 2) {\n bg = toHex(params[i + 2], params[i + 3], params[i + 4])\n i += 4\n }\n }\n }\n\n return bg\n}\n"],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { a as AnsiStyle, r as AnsiColor } from "./types-B9Eh7k2v.mjs";
2
+ //#region src/style/ansi.d.ts
3
+ /** Optional wrap mode: `"word"` (default) breaks at word boundaries;
4
+ * `"char"` hard-wraps mid-word. */
5
+ interface WrapOpts {
6
+ mode?: "word" | "char";
7
+ }
8
+ declare const RESET = "";
9
+ /**
10
+ * Wrap `text` in an OSC 8 hyperlink pointing at `url`. Modern terminals
11
+ * (iTerm2, kitty, WezTerm, VS Code, Ghostty, …) render the text as
12
+ * clickable while falling back gracefully to plain text elsewhere.
13
+ *
14
+ * Safe to nest ANSI SGR styling inside the `text` argument — OSC 8 is a
15
+ * separate escape category and doesn't conflict.
16
+ *
17
+ * An empty `url` short-circuits and returns `text` unchanged, so callers
18
+ * can unconditionally pipe link text through this helper.
19
+ *
20
+ * @internal
21
+ */
22
+ declare function hyperlink(url: string, text: string): string;
23
+ declare function ansiColor(color: AnsiColor, kind: "fg" | "bg"): string | undefined;
24
+ declare function openAnsi(style: AnsiStyle): string;
25
+ declare function styleAnsi(text: string, style?: AnsiStyle): string;
26
+ /**
27
+ * Post-process a styled string so an outer style is re-applied after any
28
+ * inner full-reset (`\x1b[0m`). Without this, a child's reset clobbers
29
+ * the parent's bg/fg/attrs for the remainder of the line.
30
+ *
31
+ * `escape` is the already-built SGR run to re-emit after each reset
32
+ * (typically the return value of `openStyle(parentStyle, theme)`). If
33
+ * empty, the input is returned unchanged.
34
+ *
35
+ * Inlined indexOf loop rather than `String.prototype.replaceAll` — the
36
+ * manual version avoids the regex/object allocation overhead of
37
+ * `replaceAll` and runs meaningfully faster on short strings (hot in
38
+ * the builder's `apply`, called once per styled span). Pattern taken
39
+ * from ansis's nested-style resolver.
40
+ *
41
+ * @internal
42
+ */
43
+ declare function reapplyStyle(s: string, escape: string): string;
44
+ declare function stripAnsiBg(s: string): string;
45
+ declare function ansiBg(str: string, idx: number): AnsiColor | undefined;
46
+ //#endregion
47
+ export { RESET, WrapOpts, ansiBg, ansiColor, hyperlink, openAnsi, reapplyStyle, stripAnsiBg, styleAnsi };
48
+ //# sourceMappingURL=ansi.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ansi.d.mts","names":[],"sources":["../src/style/ansi.ts"],"mappings":";;;;UAQiB;EACf;;cAQW;;;;;;;;;;;;;;iBA2DG,UAAU,aAAa;iBAKvB,UAAU,OAAO,WAAW;iBA4B5B,SAAS,OAAO;iBAWhB,UAAU,cAAc,QAAQ;;;;;;;;;;;;;;;;;;iBAwBhC,aAAa,WAAW;iBAexB,YAAY;iBAgCZ,OAAO,aAAa,cAAc"}
package/dist/ansi.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { a as openAnsi, c as styleAnsi, i as hyperlink, n as ansiBg, o as reapplyStyle, r as ansiColor, s as stripAnsiBg, t as RESET } from "./ansi-Clq0ozyA.mjs";
2
+ export { RESET, ansiBg, ansiColor, hyperlink, openAnsi, reapplyStyle, stripAnsiBg, styleAnsi };
@@ -0,0 +1,100 @@
1
+ import { P as RenderCtx, Z as StyleState, f as BaseEvents, nt as Reactive, p as Node, rt as Ref } from "./queries-DH3bj74K.mjs";
2
+ import { t as Input } from "./input-B5Vy-iaa.mjs";
3
+ import { n as SearchOptions, t as SearchItems } from "./search-FvGnswRl.mjs";
4
+ import { i as Select, n as OptionRender, t as Option } from "./select-CbmAZdpt.mjs";
5
+ //#region src/widgets/autocomplete.d.ts
6
+ /** Called when the user picks `item` from this source. Return a string
7
+ * to insert in place of the trigger + query range, or `undefined`
8
+ * when the source handled the selection itself (dispatched an action,
9
+ * opened a modal, …) and the trigger range should just be removed. */
10
+ type AcceptFn<T> = (item: T, query: string) => string | undefined;
11
+ /** Single completion source. `triggers` are regexes run against the text
12
+ * *before the cursor*; the first regex whose match ends in the trailing
13
+ * word wins. The slice between match-end and the cursor becomes the
14
+ * `query` passed to `complete`.
15
+ *
16
+ * `complete` receives a `match` helper bound to `query` — call it on
17
+ * whatever string the source considers the matching field (action id,
18
+ * file basename, contact email, etc.) and either filter or rank.
19
+ *
20
+ * `accept` controls what happens on selection. Default: insert
21
+ * `item.value + " "`. Return `undefined` to have the source do its own
22
+ * side effect (dispatch an action, open a picker, …) and just clear
23
+ * the trigger range in the input.
24
+ *
25
+ * `render` is forwarded to the internal `Menu` so the source can carry
26
+ * its own row presentation — handy when `T` isn't a plain `MenuItem`. */
27
+ interface CompletionSource<T extends Option = Option> {
28
+ triggers: readonly RegExp[];
29
+ complete: Reactive<SearchItems<T>>;
30
+ accept?: AcceptFn<T>;
31
+ render?: OptionRender<T>;
32
+ }
33
+ interface AutocompleteState extends StyleState {}
34
+ interface AutocompleteOptions extends SearchOptions {
35
+ /** The `Input` to watch. Pass the node directly, or a `Ref<Input>`
36
+ * populated by `node.ref(ref)` elsewhere in the tree — the latter
37
+ * enables fully inline composition where the input doesn't need a
38
+ * local binding. The ref is dereferenced on mount, so wiring is
39
+ * type-safe and ordering-flexible (autocomplete can be constructed
40
+ * before the Input is). */
41
+ input: Input | Ref<Input>;
42
+ sources: Record<string, CompletionSource<any>>;
43
+ /** Cap on rows the popup shows at once. Default: 8. */
44
+ maxHeight?: Reactive<number>;
45
+ enabled?: Reactive<boolean>;
46
+ reverse?: boolean;
47
+ }
48
+ interface AutocompleteEvents extends BaseEvents {
49
+ /** Fired after an item is inserted into the input. Payload item type
50
+ * is `unknown` because sources may have different `T`; discriminate
51
+ * by source name and cast. */
52
+ complete: {
53
+ source: string;
54
+ item: Option;
55
+ };
56
+ }
57
+ /**
58
+ * Autocomplete popup bound to an `Input`. Watches the input's value and
59
+ * cursor; when one of the configured sources' trigger regexes matches
60
+ * the text before the cursor, the source's `complete(query)` is called
61
+ * and the resulting items are shown in a `Menu` child.
62
+ *
63
+ * Selecting an item replaces the matched trigger-prefix + query with
64
+ * the item's `value` and fires `"complete"` for apps that want to react
65
+ * beyond plain text insertion.
66
+ *
67
+ * ```ts
68
+ * autocomplete({
69
+ * input: "chat-input",
70
+ * sources: {
71
+ * slash: {
72
+ * triggers: [/^\s*\//],
73
+ * complete: (q) => slashCommands.filter((c) => c.startsWith(q)),
74
+ * },
75
+ * },
76
+ * }).on("complete", (src, item) => { ... })
77
+ * ```
78
+ *
79
+ * Positioning is layout-based — place the `Autocomplete` in your tree
80
+ * (typically directly above the input inside the UI footer) and it
81
+ * takes as many rows as it has items (up to `maxHeight`). When no
82
+ * source matches, `visible` flips to `false` and the widget takes
83
+ * zero rows, so the footer naturally collapses.
84
+ */
85
+ declare class Autocomplete extends Node<AutocompleteState, AutocompleteEvents> {
86
+ #private;
87
+ static readonly type = "autocomplete";
88
+ readonly type = "autocomplete";
89
+ readonly select: Select;
90
+ constructor(opts: AutocompleteOptions);
91
+ get enabled(): boolean;
92
+ protected _render(ctx: RenderCtx): string[] | Promise<string[]>;
93
+ }
94
+ /**
95
+ * Factory for `Autocomplete`. See the class doc for the full API.
96
+ */
97
+ declare function autocomplete(opts: AutocompleteOptions): Autocomplete;
98
+ //#endregion
99
+ export { AutocompleteState as a, AutocompleteOptions as i, Autocomplete as n, CompletionSource as o, AutocompleteEvents as r, autocomplete as s, AcceptFn as t };
100
+ //# sourceMappingURL=autocomplete-Dfw-yQDa.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autocomplete-Dfw-yQDa.d.mts","names":[],"sources":["../src/widgets/autocomplete.ts"],"mappings":";;;;;;;;;KAgBY,SAAS,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;UAkBnB,iBAAiB,UAAU,SAAS;EACnD,mBAAmB;EACnB,UAAU,SAAS,YAAY;EAC/B,SAAS,SAAS;EAClB,SAAS,aAAa;;UAIP,0BAA0B;UAE1B,4BAA4B;;;;;;;EAO3C,OAAO,QAAQ,IAAI;EAMnB,SAAS,eAAe;;EAExB,YAAY;EACZ,UAAU;EACV;;UAGe,2BAA2B;;;;EAI1C;IAAY;IAAgB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA6CvB,qBAAqB,KAAK,mBAAmB;;kBACxC;WACE;WAET,QAAQ;EAKjB,YAAY,MAAM;MAoDd;YAiFM,QAAQ,KAAK,uBAAuB;;;;;iBAmBhC,aAAa,MAAM,sBAAsB"}