@silvery/examples 0.17.3 → 0.17.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 (112) hide show
  1. package/dist/UPNG-Cy7ViL8f.mjs +5074 -0
  2. package/dist/__vite-browser-external-2447137e-BML7CYau.mjs +4 -0
  3. package/dist/_banner-DLPxCqVy.mjs +44 -0
  4. package/dist/ansi-CCE2pVS0.mjs +16397 -0
  5. package/dist/apng-HhhBjRGt.mjs +68 -0
  6. package/dist/apng-mwUQbTTF.mjs +3 -0
  7. package/dist/apps/aichat/index.mjs +1299 -0
  8. package/dist/apps/app-todo.mjs +139 -0
  9. package/dist/apps/async-data.mjs +204 -0
  10. package/dist/apps/cli-wizard.mjs +339 -0
  11. package/dist/apps/clipboard.mjs +198 -0
  12. package/dist/apps/components.mjs +864 -0
  13. package/dist/apps/data-explorer.mjs +483 -0
  14. package/dist/apps/dev-tools.mjs +397 -0
  15. package/dist/apps/explorer.mjs +698 -0
  16. package/dist/apps/gallery.mjs +766 -0
  17. package/dist/apps/inline-bench.mjs +115 -0
  18. package/dist/apps/kanban.mjs +280 -0
  19. package/dist/apps/layout-ref.mjs +187 -0
  20. package/dist/apps/outline.mjs +203 -0
  21. package/dist/apps/paste-demo.mjs +189 -0
  22. package/dist/apps/scroll.mjs +86 -0
  23. package/dist/apps/search-filter.mjs +287 -0
  24. package/dist/apps/selection.mjs +355 -0
  25. package/dist/apps/spatial-focus-demo.mjs +388 -0
  26. package/dist/apps/task-list.mjs +258 -0
  27. package/dist/apps/terminal-caps-demo.mjs +315 -0
  28. package/dist/apps/terminal.mjs +872 -0
  29. package/dist/apps/text-selection-demo.mjs +254 -0
  30. package/dist/apps/textarea.mjs +178 -0
  31. package/dist/apps/theme.mjs +661 -0
  32. package/dist/apps/transform.mjs +215 -0
  33. package/dist/apps/virtual-10k.mjs +422 -0
  34. package/dist/assets/resvgjs.darwin-arm64-BtufyGW1.node +0 -0
  35. package/dist/backends-Bahh9mKN.mjs +1179 -0
  36. package/dist/backends-CCtCDQ94.mjs +3 -0
  37. package/dist/{cli.mjs → bin/cli.mjs} +15 -19
  38. package/dist/chunk-BSw8zbkd.mjs +37 -0
  39. package/dist/components/counter.mjs +48 -0
  40. package/dist/components/hello.mjs +31 -0
  41. package/dist/components/progress-bar.mjs +59 -0
  42. package/dist/components/select-list.mjs +85 -0
  43. package/dist/components/spinner.mjs +57 -0
  44. package/dist/components/text-input.mjs +62 -0
  45. package/dist/components/virtual-list.mjs +51 -0
  46. package/dist/flexily-zero-adapter-UB-ra8fR.mjs +3374 -0
  47. package/dist/gif-BZaqPPVX.mjs +3 -0
  48. package/dist/gif-BtnXuxLF.mjs +71 -0
  49. package/dist/gifenc-CLRW41dk.mjs +728 -0
  50. package/dist/jsx-runtime-dMs_8fNu.mjs +241 -0
  51. package/dist/key-mapping-5oYQdAQE.mjs +3 -0
  52. package/dist/key-mapping-D4LR1go6.mjs +130 -0
  53. package/dist/layout/dashboard.mjs +1204 -0
  54. package/dist/layout/live-resize.mjs +303 -0
  55. package/dist/layout/overflow.mjs +70 -0
  56. package/dist/layout/text-layout.mjs +335 -0
  57. package/dist/node-NuJ94BWl.mjs +1083 -0
  58. package/dist/plugins-D1KtkT4a.mjs +3057 -0
  59. package/dist/resvg-js-C_8Wps1F.mjs +201 -0
  60. package/dist/src-BTEVGpd9.mjs +23538 -0
  61. package/dist/src-CUUOuRH6.mjs +5322 -0
  62. package/dist/src-CzfRafCQ.mjs +814 -0
  63. package/dist/usingCtx-CsEf0xO3.mjs +57 -0
  64. package/dist/yoga-adapter-BVtQ5OJR.mjs +237 -0
  65. package/package.json +18 -13
  66. package/_banner.tsx +0 -60
  67. package/apps/aichat/components.tsx +0 -469
  68. package/apps/aichat/index.tsx +0 -220
  69. package/apps/aichat/script.ts +0 -460
  70. package/apps/aichat/state.ts +0 -325
  71. package/apps/aichat/types.ts +0 -19
  72. package/apps/app-todo.tsx +0 -201
  73. package/apps/async-data.tsx +0 -196
  74. package/apps/cli-wizard.tsx +0 -332
  75. package/apps/clipboard.tsx +0 -183
  76. package/apps/components.tsx +0 -658
  77. package/apps/data-explorer.tsx +0 -490
  78. package/apps/dev-tools.tsx +0 -395
  79. package/apps/explorer.tsx +0 -731
  80. package/apps/gallery.tsx +0 -653
  81. package/apps/inline-bench.tsx +0 -138
  82. package/apps/kanban.tsx +0 -265
  83. package/apps/layout-ref.tsx +0 -173
  84. package/apps/outline.tsx +0 -160
  85. package/apps/panes/index.tsx +0 -203
  86. package/apps/paste-demo.tsx +0 -185
  87. package/apps/scroll.tsx +0 -80
  88. package/apps/search-filter.tsx +0 -240
  89. package/apps/selection.tsx +0 -346
  90. package/apps/spatial-focus-demo.tsx +0 -372
  91. package/apps/task-list.tsx +0 -271
  92. package/apps/terminal-caps-demo.tsx +0 -317
  93. package/apps/terminal.tsx +0 -784
  94. package/apps/text-selection-demo.tsx +0 -193
  95. package/apps/textarea.tsx +0 -155
  96. package/apps/theme.tsx +0 -515
  97. package/apps/transform.tsx +0 -229
  98. package/apps/virtual-10k.tsx +0 -405
  99. package/apps/vterm-demo/index.tsx +0 -216
  100. package/components/counter.tsx +0 -49
  101. package/components/hello.tsx +0 -38
  102. package/components/progress-bar.tsx +0 -52
  103. package/components/select-list.tsx +0 -54
  104. package/components/spinner.tsx +0 -44
  105. package/components/text-input.tsx +0 -61
  106. package/components/virtual-list.tsx +0 -56
  107. package/dist/cli.d.mts +0 -1
  108. package/dist/cli.mjs.map +0 -1
  109. package/layout/dashboard.tsx +0 -953
  110. package/layout/live-resize.tsx +0 -282
  111. package/layout/overflow.tsx +0 -51
  112. package/layout/text-layout.tsx +0 -283
@@ -0,0 +1,872 @@
1
+ import { t as _usingCtx } from "../usingCtx-CsEf0xO3.mjs";
2
+ import { t as require_jsx_runtime } from "../jsx-runtime-dMs_8fNu.mjs";
3
+ import { t as ExampleBanner } from "../_banner-DLPxCqVy.mjs";
4
+ import { useEffect, useRef, useState } from "react";
5
+ import { Box, H2, Kbd, KittyFlags, Muted, Small, Tab, TabList, TabPanel, Tabs, Text, copyToClipboard, createTerm, detectKittyFromStdio, disableFocusReporting, disableKittyKeyboard, disableMouse, enableFocusReporting, enableKittyKeyboard, enableMouse, isMouseSequence, parseClipboardResponse, parseFocusEvent, parseKeypress, parseMouseSequence, render, requestClipboard, useApp, useInput, useStdout } from "silvery";
6
+ //#region apps/terminal.tsx
7
+ /**
8
+ * Terminal Kitchensink
9
+ *
10
+ * A tabbed demo showcasing terminal interaction capabilities:
11
+ * keyboard events, mouse tracking, clipboard (OSC 52), and
12
+ * terminal focus detection.
13
+ *
14
+ * Features:
15
+ * - Key event tester with color-coded modifier badges
16
+ * - Mouse position tracking, button state, scroll events
17
+ * - OSC 52 clipboard copy/paste
18
+ * - Terminal focus/blur tracking with event log
19
+ * - Kitty keyboard protocol auto-detection
20
+ *
21
+ * Run: bun vendor/silvery/examples/apps/terminal.tsx
22
+ */
23
+ var import_jsx_runtime = require_jsx_runtime();
24
+ const meta = {
25
+ name: "Terminal",
26
+ description: "Keyboard, mouse, clipboard, focus, and terminal capabilities",
27
+ demo: true,
28
+ features: [
29
+ "useInput",
30
+ "useMouse",
31
+ "clipboard",
32
+ "focus",
33
+ "Kitty protocol"
34
+ ]
35
+ };
36
+ const MODIFIER_DEFS = [
37
+ {
38
+ symbol: "⌃",
39
+ label: "Ctrl",
40
+ color: "$color1"
41
+ },
42
+ {
43
+ symbol: "⇧",
44
+ label: "Shift",
45
+ color: "$color3"
46
+ },
47
+ {
48
+ symbol: "⌥",
49
+ label: "Alt",
50
+ color: "$color4"
51
+ },
52
+ {
53
+ symbol: "⌘",
54
+ label: "Super",
55
+ color: "$color2"
56
+ },
57
+ {
58
+ symbol: "✦",
59
+ label: "Hyper",
60
+ color: "$color5"
61
+ }
62
+ ];
63
+ function now() {
64
+ const d = /* @__PURE__ */ new Date();
65
+ return `${d.getHours().toString().padStart(2, "0")}:${d.getMinutes().toString().padStart(2, "0")}:${d.getSeconds().toString().padStart(2, "0")}`;
66
+ }
67
+ function KeysTab({ kittySupported }) {
68
+ const [events, setEvents] = useState([]);
69
+ const [latest, setLatest] = useState(null);
70
+ const counterRef = useRef(0);
71
+ const stdin = process.stdin;
72
+ useEffect(() => {
73
+ const onData = (data) => {
74
+ const raw = data.toString();
75
+ if (raw.startsWith("\x1B[<")) return;
76
+ if (raw.startsWith("\x1B[I") || raw.startsWith("\x1B[O")) return;
77
+ const parsed = parseKeypress(raw);
78
+ if (parsed.name === "escape") return;
79
+ if (raw === "q" && !parsed.ctrl && !parsed.meta) return;
80
+ if (parsed.name === "left" || parsed.name === "right") return;
81
+ if (raw === "h" || raw === "l") return;
82
+ counterRef.current++;
83
+ const key = {
84
+ upArrow: parsed.name === "up",
85
+ downArrow: parsed.name === "down",
86
+ leftArrow: parsed.name === "left",
87
+ rightArrow: parsed.name === "right",
88
+ pageDown: parsed.name === "pagedown",
89
+ pageUp: parsed.name === "pageup",
90
+ home: parsed.name === "home",
91
+ end: parsed.name === "end",
92
+ return: parsed.name === "return",
93
+ escape: parsed.name === "escape",
94
+ ctrl: parsed.ctrl,
95
+ shift: parsed.shift,
96
+ tab: parsed.name === "tab",
97
+ backspace: parsed.name === "backspace",
98
+ delete: parsed.name === "delete",
99
+ meta: parsed.meta || parsed.option,
100
+ super: parsed.super,
101
+ hyper: parsed.hyper,
102
+ capsLock: parsed.capsLock ?? false,
103
+ numLock: parsed.numLock ?? false,
104
+ eventType: parsed.eventType
105
+ };
106
+ const input = parsed.name.length === 1 ? parsed.name : "";
107
+ const event = {
108
+ index: counterRef.current,
109
+ input,
110
+ key,
111
+ parsed,
112
+ raw
113
+ };
114
+ setLatest(event);
115
+ setEvents((prev) => [...prev.slice(-11), event]);
116
+ };
117
+ stdin.on("data", onData);
118
+ return () => {
119
+ stdin.off("data", onData);
120
+ };
121
+ }, [stdin]);
122
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
123
+ gap: 3,
124
+ paddingX: 1,
125
+ paddingTop: 1,
126
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
127
+ flexDirection: "column",
128
+ width: 46,
129
+ children: [
130
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, { children: "Last Key Pressed" }),
131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
132
+ latest ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KeyDetails, { event: latest }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KeyPlaceholder, { kittySupported })
133
+ ]
134
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
135
+ flexDirection: "column",
136
+ flexGrow: 1,
137
+ children: [
138
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(H2, { children: [
139
+ "Event Log",
140
+ " ",
141
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Small, { children: [
142
+ "(",
143
+ counterRef.current,
144
+ " ",
145
+ counterRef.current === 1 ? "event" : "events",
146
+ ")"
147
+ ] })
148
+ ] }),
149
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
150
+ events.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "Waiting for input..." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
151
+ flexDirection: "column",
152
+ overflow: "scroll",
153
+ scrollTo: events.length - 1,
154
+ children: events.map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
155
+ dimColor: i < events.length - 1,
156
+ children: [
157
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
158
+ color: "$muted",
159
+ children: ["#", String(e.index).padStart(3)]
160
+ }),
161
+ " ",
162
+ formatKeyEventSummary(e)
163
+ ]
164
+ }, e.index))
165
+ })
166
+ ]
167
+ })]
168
+ });
169
+ }
170
+ function KeyPlaceholder({ kittySupported }) {
171
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
172
+ flexDirection: "column",
173
+ children: [
174
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "Try pressing some key combinations:" }),
175
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
176
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: " Ctrl+A, Shift+Tab, Alt+Enter..." }),
177
+ kittySupported && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: " Cmd+S, Hyper+X (Kitty-only)" }),
178
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
179
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "Each keypress shows its full breakdown here." })
180
+ ]
181
+ });
182
+ }
183
+ function KeyDetails({ event }) {
184
+ const { parsed, raw } = event;
185
+ const modActive = [
186
+ parsed.ctrl,
187
+ parsed.shift,
188
+ parsed.meta || parsed.option,
189
+ parsed.super,
190
+ parsed.hyper
191
+ ];
192
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
193
+ flexDirection: "column",
194
+ children: [
195
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
196
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
197
+ bold: true,
198
+ children: "Name:"
199
+ }),
200
+ " ",
201
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
202
+ bold: true,
203
+ color: "$primary",
204
+ children: parsed.name || "(none)"
205
+ })
206
+ ] }),
207
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
208
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
209
+ bold: true,
210
+ children: "Input:"
211
+ }),
212
+ " ",
213
+ JSON.stringify(event.input)
214
+ ] }),
215
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
216
+ marginTop: 1,
217
+ gap: 1,
218
+ children: MODIFIER_DEFS.map((mod, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ModBadge, {
219
+ mod,
220
+ active: modActive[i]
221
+ }, mod.symbol))
222
+ }),
223
+ parsed.eventType && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
224
+ marginTop: 1,
225
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
226
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
227
+ bold: true,
228
+ children: "Event type:"
229
+ }),
230
+ " ",
231
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
232
+ color: "$accent",
233
+ children: parsed.eventType
234
+ })
235
+ ] })
236
+ }),
237
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
238
+ flexDirection: "column",
239
+ marginTop: 1,
240
+ children: [
241
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
242
+ bold: true,
243
+ color: "$muted",
244
+ children: "Kitty Extensions"
245
+ }),
246
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KittyField, {
247
+ label: "shiftedKey",
248
+ value: parsed.shiftedKey
249
+ }),
250
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KittyField, {
251
+ label: "baseLayoutKey",
252
+ value: parsed.baseLayoutKey
253
+ }),
254
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KittyField, {
255
+ label: "associatedText",
256
+ value: parsed.associatedText
257
+ }),
258
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KittyField, {
259
+ label: "capsLock",
260
+ value: parsed.capsLock
261
+ }),
262
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KittyField, {
263
+ label: "numLock",
264
+ value: parsed.numLock
265
+ })
266
+ ]
267
+ }),
268
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
269
+ marginTop: 1,
270
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
271
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
272
+ bold: true,
273
+ children: "Raw:"
274
+ }),
275
+ " ",
276
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: [...raw].map((c) => c.charCodeAt(0) < 32 || c.charCodeAt(0) === 127 ? `\\x${c.charCodeAt(0).toString(16).padStart(2, "0")}` : c).join("") })
277
+ ] })
278
+ })
279
+ ]
280
+ });
281
+ }
282
+ function ModBadge({ mod, active }) {
283
+ if (active) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
284
+ backgroundColor: mod.color,
285
+ color: "$inversebg",
286
+ bold: true,
287
+ children: ` ${mod.symbol} ${mod.label} `
288
+ });
289
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
290
+ color: "$muted",
291
+ children: ` ${mod.symbol} `
292
+ });
293
+ }
294
+ function KittyField({ label, value }) {
295
+ if (value === void 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
296
+ label,
297
+ ": ",
298
+ "--"
299
+ ] });
300
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
301
+ label,
302
+ ": ",
303
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
304
+ color: "$warning",
305
+ children: String(value)
306
+ })
307
+ ] });
308
+ }
309
+ function formatKeyEventSummary(event) {
310
+ const parts = [];
311
+ const { parsed } = event;
312
+ if (parsed.ctrl) parts.push("⌃");
313
+ if (parsed.shift) parts.push("⇧");
314
+ if (parsed.meta || parsed.option) parts.push("⌥");
315
+ if (parsed.super) parts.push("⌘");
316
+ if (parsed.hyper) parts.push("✦");
317
+ parts.push(parsed.name || JSON.stringify(event.input));
318
+ if (parsed.eventType) parts.push(` (${parsed.eventType})`);
319
+ return parts.join("");
320
+ }
321
+ function MouseTab() {
322
+ const [mousePos, setMousePos] = useState(null);
323
+ const [events, setEvents] = useState([]);
324
+ const [clicks, setClicks] = useState({
325
+ left: 0,
326
+ middle: 0,
327
+ right: 0
328
+ });
329
+ const [scrollTotal, setScrollTotal] = useState(0);
330
+ const counterRef = useRef(0);
331
+ const stdin = process.stdin;
332
+ useEffect(() => {
333
+ const onData = (data) => {
334
+ const raw = data.toString();
335
+ if (!isMouseSequence(raw)) return;
336
+ const parsed = parseMouseSequence(raw);
337
+ if (!parsed) return;
338
+ setMousePos({
339
+ x: parsed.x,
340
+ y: parsed.y
341
+ });
342
+ const mods = [];
343
+ if (parsed.ctrl) mods.push("Ctrl");
344
+ if (parsed.shift) mods.push("Shift");
345
+ if (parsed.meta) mods.push("Alt");
346
+ const modStr = mods.join("+");
347
+ if (parsed.action === "down") {
348
+ const btn = [
349
+ "Left",
350
+ "Middle",
351
+ "Right"
352
+ ][parsed.button] ?? `Btn${parsed.button}`;
353
+ counterRef.current++;
354
+ setEvents((prev) => [...prev.slice(-11), {
355
+ index: counterRef.current,
356
+ action: "click",
357
+ button: btn,
358
+ x: parsed.x,
359
+ y: parsed.y,
360
+ mods: modStr,
361
+ timestamp: now()
362
+ }]);
363
+ if (parsed.button === 0) setClicks((c) => ({
364
+ ...c,
365
+ left: c.left + 1
366
+ }));
367
+ else if (parsed.button === 1) setClicks((c) => ({
368
+ ...c,
369
+ middle: c.middle + 1
370
+ }));
371
+ else if (parsed.button === 2) setClicks((c) => ({
372
+ ...c,
373
+ right: c.right + 1
374
+ }));
375
+ } else if (parsed.action === "wheel") {
376
+ counterRef.current++;
377
+ const dir = parsed.delta < 0 ? "up" : "down";
378
+ setEvents((prev) => [...prev.slice(-11), {
379
+ index: counterRef.current,
380
+ action: `scroll ${dir}`,
381
+ button: "wheel",
382
+ x: parsed.x,
383
+ y: parsed.y,
384
+ mods: modStr,
385
+ timestamp: now()
386
+ }]);
387
+ setScrollTotal((s) => s + 1);
388
+ } else if (parsed.action === "move") {}
389
+ };
390
+ stdin.on("data", onData);
391
+ return () => {
392
+ stdin.off("data", onData);
393
+ };
394
+ }, [stdin]);
395
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
396
+ gap: 3,
397
+ paddingX: 1,
398
+ paddingTop: 1,
399
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
400
+ flexDirection: "column",
401
+ width: 36,
402
+ children: [
403
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, { children: "Position" }),
404
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
405
+ marginTop: 1,
406
+ children: mousePos ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
407
+ flexDirection: "column",
408
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
409
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
410
+ bold: true,
411
+ children: "X:"
412
+ }),
413
+ " ",
414
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
415
+ color: "$primary",
416
+ bold: true,
417
+ children: String(mousePos.x).padStart(4)
418
+ })
419
+ ] }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
420
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
421
+ bold: true,
422
+ children: "Y:"
423
+ }),
424
+ " ",
425
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
426
+ color: "$primary",
427
+ bold: true,
428
+ children: String(mousePos.y).padStart(4)
429
+ })
430
+ ] })]
431
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "Move mouse to track position" })
432
+ }),
433
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
434
+ marginTop: 1,
435
+ flexDirection: "column",
436
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, { children: "Click Counts" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
437
+ marginTop: 1,
438
+ flexDirection: "column",
439
+ children: [
440
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
441
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
442
+ bold: true,
443
+ children: "Left:"
444
+ }),
445
+ " ",
446
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
447
+ color: "$info",
448
+ children: clicks.left
449
+ })
450
+ ] }),
451
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
452
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
453
+ bold: true,
454
+ children: "Middle:"
455
+ }),
456
+ " ",
457
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
458
+ color: "$info",
459
+ children: clicks.middle
460
+ })
461
+ ] }),
462
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
463
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
464
+ bold: true,
465
+ children: "Right:"
466
+ }),
467
+ " ",
468
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
469
+ color: "$info",
470
+ children: clicks.right
471
+ })
472
+ ] }),
473
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
474
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
475
+ bold: true,
476
+ children: "Scroll:"
477
+ }),
478
+ " ",
479
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
480
+ color: "$info",
481
+ children: scrollTotal
482
+ })
483
+ ] })
484
+ ]
485
+ })]
486
+ })
487
+ ]
488
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
489
+ flexDirection: "column",
490
+ flexGrow: 1,
491
+ children: [
492
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(H2, { children: ["Mouse Events ", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Small, { children: [
493
+ "(",
494
+ counterRef.current,
495
+ ")"
496
+ ] })] }),
497
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
498
+ events.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "Click or scroll to see events..." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
499
+ flexDirection: "column",
500
+ overflow: "scroll",
501
+ scrollTo: events.length - 1,
502
+ children: events.map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
503
+ dimColor: i < events.length - 1,
504
+ children: [
505
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Small, { children: e.timestamp }),
506
+ " ",
507
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
508
+ color: e.action.startsWith("scroll") ? "$accent" : "$primary",
509
+ bold: true,
510
+ children: e.action
511
+ }),
512
+ " ",
513
+ e.button !== "wheel" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [e.button, " "] }),
514
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
515
+ "(",
516
+ e.x,
517
+ ",",
518
+ e.y,
519
+ ")"
520
+ ] }),
521
+ e.mods ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
522
+ color: "$warning",
523
+ children: [" +", e.mods]
524
+ }) : null
525
+ ]
526
+ }, e.index))
527
+ })
528
+ ]
529
+ })]
530
+ });
531
+ }
532
+ function ClipboardTab() {
533
+ const { stdout } = useStdout();
534
+ const [selectedIndex, setSelectedIndex] = useState(0);
535
+ const [lastCopied, setLastCopied] = useState(null);
536
+ const [lastPasted, setLastPasted] = useState(null);
537
+ const [history, setHistory] = useState([]);
538
+ const snippets = [
539
+ "Hello, world!",
540
+ "The quick brown fox jumps over the lazy dog",
541
+ "OSC 52 clipboard protocol",
542
+ "npx silvery examples",
543
+ "console.log('silvery')",
544
+ "https://silvery.dev"
545
+ ];
546
+ useInput((input, key) => {
547
+ if (key.upArrow || input === "k") setSelectedIndex((i) => Math.max(0, i - 1));
548
+ if (key.downArrow || input === "j") setSelectedIndex((i) => Math.min(snippets.length - 1, i + 1));
549
+ if (input === "c") {
550
+ const text = snippets[selectedIndex];
551
+ copyToClipboard(stdout, text);
552
+ setLastCopied(text);
553
+ setHistory((h) => [...h.slice(-7), {
554
+ action: "copy",
555
+ text,
556
+ time: now()
557
+ }]);
558
+ }
559
+ if (input === "v") {
560
+ requestClipboard(stdout);
561
+ setHistory((h) => [...h.slice(-7), {
562
+ action: "request",
563
+ text: "(paste requested)",
564
+ time: now()
565
+ }]);
566
+ }
567
+ const parsed = parseClipboardResponse(input);
568
+ if (parsed) {
569
+ setLastPasted(parsed);
570
+ setHistory((h) => [...h.slice(-7), {
571
+ action: "paste",
572
+ text: parsed,
573
+ time: now()
574
+ }]);
575
+ }
576
+ });
577
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
578
+ flexDirection: "column",
579
+ paddingX: 1,
580
+ paddingTop: 1,
581
+ gap: 1,
582
+ children: [
583
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
584
+ flexDirection: "column",
585
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(H2, { children: [
586
+ "Snippets",
587
+ " ",
588
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Small, { children: [
589
+ selectedIndex + 1,
590
+ "/",
591
+ snippets.length
592
+ ] })
593
+ ] }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
594
+ flexDirection: "column",
595
+ marginTop: 1,
596
+ overflow: "scroll",
597
+ scrollTo: selectedIndex,
598
+ children: snippets.map((text, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
599
+ paddingX: 1,
600
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
601
+ color: i === selectedIndex ? "$bg" : void 0,
602
+ backgroundColor: i === selectedIndex ? "$primary" : void 0,
603
+ bold: i === selectedIndex,
604
+ children: [i === selectedIndex ? " > " : " ", text]
605
+ })
606
+ }, i))
607
+ })]
608
+ }),
609
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
610
+ gap: 4,
611
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
612
+ flexDirection: "column",
613
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
614
+ bold: true,
615
+ children: "Last Copied:"
616
+ }), lastCopied ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
617
+ color: "$success",
618
+ children: ["✓ ", lastCopied]
619
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "nothing" })]
620
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
621
+ flexDirection: "column",
622
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
623
+ bold: true,
624
+ children: "Last Pasted:"
625
+ }), lastPasted ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
626
+ color: "$warning",
627
+ children: lastPasted
628
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "nothing" })]
629
+ })]
630
+ }),
631
+ history.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
632
+ flexDirection: "column",
633
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, { children: "History" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
634
+ flexDirection: "column",
635
+ overflow: "scroll",
636
+ scrollTo: history.length - 1,
637
+ children: history.map((h, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
638
+ dimColor: i < history.length - 1,
639
+ children: [
640
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Small, { children: h.time }),
641
+ " ",
642
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
643
+ color: h.action === "copy" ? "$success" : h.action === "paste" ? "$warning" : "$muted",
644
+ bold: true,
645
+ children: h.action
646
+ }),
647
+ " ",
648
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: h.text.length > 40 ? h.text.slice(0, 37) + "..." : h.text })
649
+ ]
650
+ }, i))
651
+ })]
652
+ }),
653
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
654
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "j/k" }),
655
+ " navigate ",
656
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "c" }),
657
+ " copy ",
658
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "v" }),
659
+ " paste (OSC 52)"
660
+ ] })
661
+ ]
662
+ });
663
+ }
664
+ function FocusTab() {
665
+ const [focused, setFocused] = useState(true);
666
+ const [events, setEvents] = useState([]);
667
+ const counterRef = useRef(0);
668
+ const stdin = process.stdin;
669
+ useEffect(() => {
670
+ const onData = (data) => {
671
+ const focusEvt = parseFocusEvent(data.toString());
672
+ if (!focusEvt) return;
673
+ const isFocused = focusEvt.type === "focus-in";
674
+ setFocused(isFocused);
675
+ counterRef.current++;
676
+ setEvents((prev) => [...prev.slice(-14), {
677
+ index: counterRef.current,
678
+ focused: isFocused,
679
+ timestamp: now()
680
+ }]);
681
+ };
682
+ stdin.on("data", onData);
683
+ return () => {
684
+ stdin.off("data", onData);
685
+ };
686
+ }, [stdin]);
687
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
688
+ gap: 3,
689
+ paddingX: 1,
690
+ paddingTop: 1,
691
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
692
+ flexDirection: "column",
693
+ width: 36,
694
+ children: [
695
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, { children: "Terminal Focus" }),
696
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
697
+ marginTop: 1,
698
+ flexDirection: "column",
699
+ alignItems: "center",
700
+ gap: 1,
701
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
702
+ bold: true,
703
+ color: focused ? "$success" : "$error",
704
+ children: focused ? " FOCUSED " : " UNFOCUSED "
705
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
706
+ color: focused ? "$success" : "$error",
707
+ children: focused ? "Terminal window is active" : "Terminal window lost focus"
708
+ })]
709
+ }),
710
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
711
+ marginTop: 2,
712
+ flexDirection: "column",
713
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "Switch to another window and back to see focus events. Uses CSI I/O terminal focus reporting protocol." })
714
+ }),
715
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
716
+ marginTop: 1,
717
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
718
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
719
+ bold: true,
720
+ children: "Protocol:"
721
+ }),
722
+ " ",
723
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
724
+ color: "$info",
725
+ children: "CSI ?1004h (DECRPM focus events)"
726
+ })
727
+ ] })
728
+ })
729
+ ]
730
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
731
+ flexDirection: "column",
732
+ flexGrow: 1,
733
+ children: [
734
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(H2, { children: ["Focus Events ", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Small, { children: [
735
+ "(",
736
+ counterRef.current,
737
+ ")"
738
+ ] })] }),
739
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
740
+ events.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "Switch windows to generate focus events..." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
741
+ flexDirection: "column",
742
+ overflow: "scroll",
743
+ scrollTo: events.length - 1,
744
+ children: events.map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
745
+ dimColor: i < events.length - 1,
746
+ children: [
747
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Small, { children: e.timestamp }),
748
+ " ",
749
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
750
+ color: e.focused ? "$success" : "$error",
751
+ bold: true,
752
+ children: e.focused ? "focus-in " : "focus-out"
753
+ }),
754
+ " ",
755
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
756
+ color: e.focused ? "$success" : "$error",
757
+ children: e.focused ? "Terminal gained focus" : "Terminal lost focus"
758
+ })
759
+ ]
760
+ }, e.index))
761
+ })
762
+ ]
763
+ })]
764
+ });
765
+ }
766
+ function TerminalDemo({ kittySupported }) {
767
+ const { exit } = useApp();
768
+ useInput((input, key) => {
769
+ if (input === "q" || key.escape) exit();
770
+ });
771
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
772
+ flexDirection: "column",
773
+ flexGrow: 1,
774
+ children: [
775
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
776
+ paddingX: 1,
777
+ gap: 2,
778
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
779
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
780
+ bold: true,
781
+ children: "Kitty:"
782
+ }),
783
+ " ",
784
+ kittySupported ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
785
+ color: "$success",
786
+ children: "enabled"
787
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
788
+ color: "$warning",
789
+ children: "legacy mode"
790
+ })
791
+ ] })
792
+ }),
793
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Tabs, {
794
+ defaultValue: "keys",
795
+ children: [
796
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TabList, { children: [
797
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tab, {
798
+ value: "keys",
799
+ children: "Keys"
800
+ }),
801
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tab, {
802
+ value: "mouse",
803
+ children: "Mouse"
804
+ }),
805
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tab, {
806
+ value: "clipboard",
807
+ children: "Clipboard"
808
+ }),
809
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tab, {
810
+ value: "focus",
811
+ children: "Focus"
812
+ })
813
+ ] }),
814
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabPanel, {
815
+ value: "keys",
816
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KeysTab, { kittySupported })
817
+ }),
818
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabPanel, {
819
+ value: "mouse",
820
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MouseTab, {})
821
+ }),
822
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabPanel, {
823
+ value: "clipboard",
824
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClipboardTab, {})
825
+ }),
826
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabPanel, {
827
+ value: "focus",
828
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FocusTab, {})
829
+ })
830
+ ]
831
+ }),
832
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
833
+ paddingX: 1,
834
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
835
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "h/l" }),
836
+ " switch tabs ",
837
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "Esc/q" }),
838
+ " quit"
839
+ ] })
840
+ })
841
+ ]
842
+ });
843
+ }
844
+ async function main() {
845
+ try {
846
+ var _usingCtx$1 = _usingCtx();
847
+ const kittyResult = await detectKittyFromStdio(process.stdout, process.stdin);
848
+ if (kittyResult.supported) {
849
+ const flags = KittyFlags.DISAMBIGUATE | KittyFlags.REPORT_EVENTS | KittyFlags.REPORT_ALTERNATE | KittyFlags.REPORT_ALL_KEYS | KittyFlags.REPORT_TEXT;
850
+ process.stdout.write(enableKittyKeyboard(flags));
851
+ }
852
+ const term = _usingCtx$1.u(createTerm());
853
+ process.stdout.write(enableMouse());
854
+ enableFocusReporting((s) => process.stdout.write(s));
855
+ const { waitUntilExit } = await render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExampleBanner, {
856
+ meta,
857
+ controls: "h/l tabs Esc/q quit",
858
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TerminalDemo, { kittySupported: kittyResult.supported })
859
+ }), term);
860
+ await waitUntilExit();
861
+ process.stdout.write(disableMouse());
862
+ disableFocusReporting((s) => process.stdout.write(s));
863
+ if (kittyResult.supported) process.stdout.write(disableKittyKeyboard());
864
+ } catch (_) {
865
+ _usingCtx$1.e = _;
866
+ } finally {
867
+ _usingCtx$1.d();
868
+ }
869
+ }
870
+ if (import.meta.main) await main();
871
+ //#endregion
872
+ export { TerminalDemo, main, meta };