@silvery/examples 0.17.3 → 0.17.5

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 (111) hide show
  1. package/dist/UPNG-ShUlaTDh.mjs +5074 -0
  2. package/dist/__vite-browser-external-2447137e-Bopa5BFR.mjs +4 -0
  3. package/dist/_banner-A70_y2Vi.mjs +43 -0
  4. package/dist/ansi-0VXlUmNn.mjs +16397 -0
  5. package/dist/apng-B0gRaDVT.mjs +3 -0
  6. package/dist/apng-BTRDTfDW.mjs +68 -0
  7. package/dist/apps/aichat/index.mjs +1298 -0
  8. package/dist/apps/app-todo.mjs +138 -0
  9. package/dist/apps/async-data.mjs +203 -0
  10. package/dist/apps/cli-wizard.mjs +338 -0
  11. package/dist/apps/clipboard.mjs +197 -0
  12. package/dist/apps/components.mjs +863 -0
  13. package/dist/apps/data-explorer.mjs +482 -0
  14. package/dist/apps/dev-tools.mjs +396 -0
  15. package/dist/apps/explorer.mjs +697 -0
  16. package/dist/apps/gallery.mjs +765 -0
  17. package/dist/apps/inline-bench.mjs +115 -0
  18. package/dist/apps/kanban.mjs +279 -0
  19. package/dist/apps/layout-ref.mjs +186 -0
  20. package/dist/apps/outline.mjs +202 -0
  21. package/dist/apps/paste-demo.mjs +188 -0
  22. package/dist/apps/scroll.mjs +85 -0
  23. package/dist/apps/search-filter.mjs +286 -0
  24. package/dist/apps/selection.mjs +354 -0
  25. package/dist/apps/spatial-focus-demo.mjs +387 -0
  26. package/dist/apps/task-list.mjs +257 -0
  27. package/dist/apps/terminal-caps-demo.mjs +314 -0
  28. package/dist/apps/terminal.mjs +871 -0
  29. package/dist/apps/text-selection-demo.mjs +253 -0
  30. package/dist/apps/textarea.mjs +177 -0
  31. package/dist/apps/theme.mjs +660 -0
  32. package/dist/apps/transform.mjs +214 -0
  33. package/dist/apps/virtual-10k.mjs +421 -0
  34. package/dist/assets/resvgjs.darwin-arm64-BtufyGW1.node +0 -0
  35. package/dist/backends-Dj-11kZF.mjs +1179 -0
  36. package/dist/backends-U3QwStfO.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 +47 -0
  40. package/dist/components/hello.mjs +30 -0
  41. package/dist/components/progress-bar.mjs +58 -0
  42. package/dist/components/select-list.mjs +84 -0
  43. package/dist/components/spinner.mjs +56 -0
  44. package/dist/components/text-input.mjs +61 -0
  45. package/dist/components/virtual-list.mjs +50 -0
  46. package/dist/flexily-zero-adapter-ByVzLTFP.mjs +3374 -0
  47. package/dist/gif-B6NGH5gs.mjs +3 -0
  48. package/dist/gif-CfkOF-iG.mjs +71 -0
  49. package/dist/gifenc-BI4ihP_T.mjs +728 -0
  50. package/dist/key-mapping-5oYQdAQE.mjs +3 -0
  51. package/dist/key-mapping-D4LR1go6.mjs +130 -0
  52. package/dist/layout/dashboard.mjs +1203 -0
  53. package/dist/layout/live-resize.mjs +302 -0
  54. package/dist/layout/overflow.mjs +69 -0
  55. package/dist/layout/text-layout.mjs +334 -0
  56. package/dist/node-nsrAOjH4.mjs +1083 -0
  57. package/dist/plugins-CT0DdV_E.mjs +3056 -0
  58. package/dist/resvg-js-Cnk2o49d.mjs +201 -0
  59. package/dist/src-9ZhfQyzD.mjs +814 -0
  60. package/dist/src-CUUOuRH6.mjs +5322 -0
  61. package/dist/src-jO3Zuzjj.mjs +23538 -0
  62. package/dist/usingCtx-CsEf0xO3.mjs +57 -0
  63. package/dist/yoga-adapter-BSQHuMV9.mjs +237 -0
  64. package/package.json +21 -14
  65. package/_banner.tsx +0 -60
  66. package/apps/aichat/components.tsx +0 -469
  67. package/apps/aichat/index.tsx +0 -220
  68. package/apps/aichat/script.ts +0 -460
  69. package/apps/aichat/state.ts +0 -325
  70. package/apps/aichat/types.ts +0 -19
  71. package/apps/app-todo.tsx +0 -201
  72. package/apps/async-data.tsx +0 -196
  73. package/apps/cli-wizard.tsx +0 -332
  74. package/apps/clipboard.tsx +0 -183
  75. package/apps/components.tsx +0 -658
  76. package/apps/data-explorer.tsx +0 -490
  77. package/apps/dev-tools.tsx +0 -395
  78. package/apps/explorer.tsx +0 -731
  79. package/apps/gallery.tsx +0 -653
  80. package/apps/inline-bench.tsx +0 -138
  81. package/apps/kanban.tsx +0 -265
  82. package/apps/layout-ref.tsx +0 -173
  83. package/apps/outline.tsx +0 -160
  84. package/apps/panes/index.tsx +0 -203
  85. package/apps/paste-demo.tsx +0 -185
  86. package/apps/scroll.tsx +0 -80
  87. package/apps/search-filter.tsx +0 -240
  88. package/apps/selection.tsx +0 -346
  89. package/apps/spatial-focus-demo.tsx +0 -372
  90. package/apps/task-list.tsx +0 -271
  91. package/apps/terminal-caps-demo.tsx +0 -317
  92. package/apps/terminal.tsx +0 -784
  93. package/apps/text-selection-demo.tsx +0 -193
  94. package/apps/textarea.tsx +0 -155
  95. package/apps/theme.tsx +0 -515
  96. package/apps/transform.tsx +0 -229
  97. package/apps/virtual-10k.tsx +0 -405
  98. package/apps/vterm-demo/index.tsx +0 -216
  99. package/components/counter.tsx +0 -49
  100. package/components/hello.tsx +0 -38
  101. package/components/progress-bar.tsx +0 -52
  102. package/components/select-list.tsx +0 -54
  103. package/components/spinner.tsx +0 -44
  104. package/components/text-input.tsx +0 -61
  105. package/components/virtual-list.tsx +0 -56
  106. package/dist/cli.d.mts +0 -1
  107. package/dist/cli.mjs.map +0 -1
  108. package/layout/dashboard.tsx +0 -953
  109. package/layout/live-resize.tsx +0 -282
  110. package/layout/overflow.tsx +0 -51
  111. package/layout/text-layout.tsx +0 -283
@@ -0,0 +1,3 @@
1
+ import { s as init_backends, t as backend } from "./backends-Dj-11kZF.mjs";
2
+ init_backends();
3
+ export { backend };
@@ -46,18 +46,21 @@ const CATEGORY_COLOR = {
46
46
  "Kitty Protocol": BLUE
47
47
  };
48
48
  async function discoverExamples() {
49
- const { resolve, dirname } = await import("node:path");
49
+ const { resolve, dirname, extname } = await import("node:path");
50
50
  const { fileURLToPath } = await import("node:url");
51
- const { readdirSync } = await import("node:fs");
52
- const examplesDir = resolve(dirname(fileURLToPath(import.meta.url)), "..");
51
+ const { readdirSync, existsSync } = await import("node:fs");
52
+ const __dirname = dirname(fileURLToPath(import.meta.url));
53
+ const examplesDir = resolve(__dirname, "..");
54
+ const isBuilt = __dirname.endsWith("/dist/bin") || __dirname.endsWith("/dist\\bin");
55
+ const ext = isBuilt ? ".mjs" : ".tsx";
53
56
  const results = [];
54
57
  for (const dir of CATEGORY_DIRS) {
55
58
  const category = CATEGORY_DISPLAY[dir] ?? dir.charAt(0).toUpperCase() + dir.slice(1);
56
59
  const dirPath = resolve(examplesDir, dir);
57
60
  try {
58
- const files = readdirSync(dirPath).filter((f) => f.endsWith(".tsx") && !f.startsWith("_"));
61
+ const files = readdirSync(dirPath).filter((f) => f.endsWith(ext) && !f.startsWith("_"));
59
62
  for (const file of files) {
60
- const name = file.replace(/\.tsx$/, "").replace(/-/g, " ");
63
+ const name = file.replace(/\.(tsx|mjs)$/, "").replace(/-/g, " ");
61
64
  results.push({
62
65
  name,
63
66
  description: "",
@@ -67,18 +70,13 @@ async function discoverExamples() {
67
70
  }
68
71
  } catch {}
69
72
  }
70
- const aichatDir = resolve(examplesDir, "apps/aichat");
71
- try {
72
- const indexFile = resolve(aichatDir, "index.tsx");
73
- const { stat } = await import("node:fs/promises");
74
- await stat(indexFile);
75
- results.push({
76
- name: "aichat",
77
- description: "AI Coding Agent demo",
78
- file: indexFile,
79
- category: "Apps"
80
- });
81
- } catch {}
73
+ const aichatPath = isBuilt ? resolve(examplesDir, "apps/aichat/index.mjs") : resolve(examplesDir, "apps/aichat/index.tsx");
74
+ if (existsSync(aichatPath)) results.push({
75
+ name: "aichat",
76
+ description: "AI Coding Agent demo",
77
+ file: aichatPath,
78
+ category: "Apps"
79
+ });
82
80
  results.sort((a, b) => {
83
81
  const catDiff = (CATEGORY_ORDER[a.category] ?? 99) - (CATEGORY_ORDER[b.category] ?? 99);
84
82
  if (catDiff !== 0) return catDiff;
@@ -189,5 +187,3 @@ main().catch((err) => {
189
187
  });
190
188
  //#endregion
191
189
  export {};
192
-
193
- //# sourceMappingURL=cli.mjs.map
@@ -0,0 +1,37 @@
1
+ import { createRequire } from "node:module";
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
10
+ var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
11
+ var __exportAll = (all, no_symbols) => {
12
+ let target = {};
13
+ for (var name in all) __defProp(target, name, {
14
+ get: all[name],
15
+ enumerable: true
16
+ });
17
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
18
+ return target;
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
22
+ key = keys[i];
23
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
24
+ get: ((k) => from[k]).bind(null, key),
25
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
26
+ });
27
+ }
28
+ return to;
29
+ };
30
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
31
+ value: mod,
32
+ enumerable: true
33
+ }) : target, mod));
34
+ var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
35
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
36
+ //#endregion
37
+ export { __toCommonJS as a, __require as i, __esmMin as n, __toESM as o, __exportAll as r, __commonJSMin as t };
@@ -0,0 +1,47 @@
1
+ import { useState } from "react";
2
+ import { Box, Text } from "silvery";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { run, useInput as useInput$1 } from "silvery/runtime";
5
+ //#region components/counter.tsx
6
+ /**
7
+ * Counter — Interactive state with useInput
8
+ *
9
+ * The "Hello World" of interactive TUIs: a counter you
10
+ * increment/decrement with j/k.
11
+ *
12
+ * Usage: bun examples/components/counter.tsx
13
+ */
14
+ function Counter() {
15
+ const [count, setCount] = useState(0);
16
+ useInput$1((input, key) => {
17
+ if (input === "j" || key.downArrow) setCount((c) => c + 1);
18
+ if (input === "k" || key.upArrow) setCount((c) => c - 1);
19
+ if (input === "r") setCount(0);
20
+ if (input === "q" || key.escape) return "exit";
21
+ });
22
+ return /* @__PURE__ */ jsxs(Box, {
23
+ flexDirection: "column",
24
+ padding: 1,
25
+ children: [/* @__PURE__ */ jsxs(Box, {
26
+ gap: 1,
27
+ children: [/* @__PURE__ */ jsx(Text, { children: "Count:" }), /* @__PURE__ */ jsx(Text, {
28
+ bold: true,
29
+ color: count >= 0 ? "$success" : "$error",
30
+ children: count
31
+ })]
32
+ }), /* @__PURE__ */ jsx(Text, {
33
+ color: "$muted",
34
+ children: "j/k: +/- r: reset q: quit"
35
+ })]
36
+ });
37
+ }
38
+ const meta = {
39
+ name: "Counter",
40
+ description: "Interactive counter with useState + useInput"
41
+ };
42
+ async function main() {
43
+ await (await run(/* @__PURE__ */ jsx(Counter, {}))).waitUntilExit();
44
+ }
45
+ if (import.meta.main) await main();
46
+ //#endregion
47
+ export { main, meta };
@@ -0,0 +1,30 @@
1
+ import "react";
2
+ import { Box, Text } from "silvery";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { run, useInput as useInput$1 } from "silvery/runtime";
5
+ //#region components/hello.tsx
6
+ function Hello() {
7
+ useInput$1(() => "exit");
8
+ return /* @__PURE__ */ jsxs(Box, {
9
+ flexDirection: "column",
10
+ padding: 1,
11
+ children: [/* @__PURE__ */ jsx(Text, {
12
+ bold: true,
13
+ color: "$primary",
14
+ children: "Hello, Silvery!"
15
+ }), /* @__PURE__ */ jsx(Text, {
16
+ color: "$muted",
17
+ children: "Press any key to exit."
18
+ })]
19
+ });
20
+ }
21
+ const meta = {
22
+ name: "Hello",
23
+ description: "The simplest silvery app — styled text, exit on keypress"
24
+ };
25
+ async function main() {
26
+ await (await run(/* @__PURE__ */ jsx(Hello, {}))).waitUntilExit();
27
+ }
28
+ if (import.meta.main) await main();
29
+ //#endregion
30
+ export { main, meta };
@@ -0,0 +1,58 @@
1
+ import { useState } from "react";
2
+ import { Box, ProgressBar, Text } from "silvery";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { run, useInput as useInput$1 } from "silvery/runtime";
5
+ //#region components/progress-bar.tsx
6
+ /**
7
+ * ProgressBar — Determinate and indeterminate progress
8
+ *
9
+ * Press j/k to adjust progress. Shows determinate bars with
10
+ * percentage labels and an indeterminate animated bar.
11
+ *
12
+ * Usage: bun examples/components/progress-bar.tsx
13
+ */
14
+ function ProgressBarDemo() {
15
+ const [progress, setProgress] = useState(.4);
16
+ useInput$1((input, key) => {
17
+ if (input === "j" || key.rightArrow) setProgress((p) => Math.min(1, p + .05));
18
+ if (input === "k" || key.leftArrow) setProgress((p) => Math.max(0, p - .05));
19
+ if (input === "q" || key.escape) return "exit";
20
+ });
21
+ return /* @__PURE__ */ jsxs(Box, {
22
+ flexDirection: "column",
23
+ padding: 1,
24
+ gap: 1,
25
+ children: [
26
+ /* @__PURE__ */ jsx(Text, {
27
+ bold: true,
28
+ children: "Determinate"
29
+ }),
30
+ /* @__PURE__ */ jsx(Box, {
31
+ width: 40,
32
+ children: /* @__PURE__ */ jsx(ProgressBar, { value: progress })
33
+ }),
34
+ /* @__PURE__ */ jsx(Text, {
35
+ bold: true,
36
+ children: "Indeterminate"
37
+ }),
38
+ /* @__PURE__ */ jsx(Box, {
39
+ width: 40,
40
+ children: /* @__PURE__ */ jsx(ProgressBar, {})
41
+ }),
42
+ /* @__PURE__ */ jsx(Text, {
43
+ color: "$muted",
44
+ children: "j/k: adjust q: quit"
45
+ })
46
+ ]
47
+ });
48
+ }
49
+ const meta = {
50
+ name: "Progress Bar",
51
+ description: "Determinate and indeterminate progress bars"
52
+ };
53
+ async function main() {
54
+ await (await run(/* @__PURE__ */ jsx(ProgressBarDemo, {}))).waitUntilExit();
55
+ }
56
+ if (import.meta.main) await main();
57
+ //#endregion
58
+ export { main, meta };
@@ -0,0 +1,84 @@
1
+ import { useState } from "react";
2
+ import { Box, SelectList, Text } from "silvery";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { run, useInput as useInput$1 } from "silvery/runtime";
5
+ //#region components/select-list.tsx
6
+ /**
7
+ * SelectList — Keyboard-navigable single-select
8
+ *
9
+ * Navigate with j/k or arrows, confirm with Enter.
10
+ * Disabled items are automatically skipped.
11
+ *
12
+ * Usage: bun examples/components/select-list.tsx
13
+ */
14
+ const languages = [
15
+ {
16
+ label: "TypeScript",
17
+ value: "ts"
18
+ },
19
+ {
20
+ label: "Rust",
21
+ value: "rs"
22
+ },
23
+ {
24
+ label: "Go",
25
+ value: "go"
26
+ },
27
+ {
28
+ label: "Python",
29
+ value: "py"
30
+ },
31
+ {
32
+ label: "COBOL",
33
+ value: "cob",
34
+ disabled: true
35
+ },
36
+ {
37
+ label: "Elixir",
38
+ value: "ex"
39
+ }
40
+ ];
41
+ function SelectListDemo() {
42
+ const [selected, setSelected] = useState(null);
43
+ useInput$1((_, key) => {
44
+ if (key.escape) return "exit";
45
+ });
46
+ return /* @__PURE__ */ jsxs(Box, {
47
+ flexDirection: "column",
48
+ padding: 1,
49
+ gap: 1,
50
+ children: [
51
+ /* @__PURE__ */ jsx(Text, {
52
+ bold: true,
53
+ children: "Pick a language:"
54
+ }),
55
+ /* @__PURE__ */ jsx(Box, {
56
+ borderStyle: "round",
57
+ borderColor: "$border",
58
+ paddingX: 1,
59
+ children: /* @__PURE__ */ jsx(SelectList, {
60
+ items: languages,
61
+ onSelect: (opt) => setSelected(opt.value)
62
+ })
63
+ }),
64
+ selected && /* @__PURE__ */ jsxs(Text, {
65
+ color: "$success",
66
+ children: ["Selected: ", selected]
67
+ }),
68
+ /* @__PURE__ */ jsx(Text, {
69
+ color: "$muted",
70
+ children: "j/k: navigate Enter: select Esc: quit"
71
+ })
72
+ ]
73
+ });
74
+ }
75
+ const meta = {
76
+ name: "Select List",
77
+ description: "Keyboard-navigable single-select list"
78
+ };
79
+ async function main() {
80
+ await (await run(/* @__PURE__ */ jsx(SelectListDemo, {}))).waitUntilExit();
81
+ }
82
+ if (import.meta.main) await main();
83
+ //#endregion
84
+ export { main, meta };
@@ -0,0 +1,56 @@
1
+ import "react";
2
+ import { Box, Spinner, Text } from "silvery";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { run, useInput as useInput$1 } from "silvery/runtime";
5
+ //#region components/spinner.tsx
6
+ function SpinnerDemo() {
7
+ useInput$1((input, key) => {
8
+ if (input === "q" || key.escape) return "exit";
9
+ });
10
+ return /* @__PURE__ */ jsxs(Box, {
11
+ flexDirection: "column",
12
+ padding: 1,
13
+ gap: 1,
14
+ children: [
15
+ /* @__PURE__ */ jsx(Text, {
16
+ bold: true,
17
+ children: "Spinner Styles"
18
+ }),
19
+ /* @__PURE__ */ jsxs(Box, {
20
+ flexDirection: "column",
21
+ children: [
22
+ /* @__PURE__ */ jsx(Spinner, {
23
+ type: "dots",
24
+ label: "Loading packages..."
25
+ }),
26
+ /* @__PURE__ */ jsx(Spinner, {
27
+ type: "line",
28
+ label: "Compiling..."
29
+ }),
30
+ /* @__PURE__ */ jsx(Spinner, {
31
+ type: "arc",
32
+ label: "Optimizing..."
33
+ }),
34
+ /* @__PURE__ */ jsx(Spinner, {
35
+ type: "bounce",
36
+ label: "Connecting..."
37
+ })
38
+ ]
39
+ }),
40
+ /* @__PURE__ */ jsx(Text, {
41
+ color: "$muted",
42
+ children: "q: quit"
43
+ })
44
+ ]
45
+ });
46
+ }
47
+ const meta = {
48
+ name: "Spinner",
49
+ description: "Four animated loading spinner styles"
50
+ };
51
+ async function main() {
52
+ await (await run(/* @__PURE__ */ jsx(SpinnerDemo, {}))).waitUntilExit();
53
+ }
54
+ if (import.meta.main) await main();
55
+ //#endregion
56
+ export { main, meta };
@@ -0,0 +1,61 @@
1
+ import { useState } from "react";
2
+ import { Box, Text, TextInput } from "silvery";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { run, useInput as useInput$1 } from "silvery/runtime";
5
+ //#region components/text-input.tsx
6
+ /**
7
+ * TextInput — Single-line text entry
8
+ *
9
+ * Shows TextInput with placeholder, prompt, and submit handler.
10
+ * Full readline keybindings (Ctrl+A/E/K/U, Alt+B/F) are built in.
11
+ *
12
+ * Usage: bun examples/components/text-input.tsx
13
+ */
14
+ function TextInputDemo() {
15
+ const [value, setValue] = useState("");
16
+ const [submitted, setSubmitted] = useState([]);
17
+ useInput$1((_, key) => {
18
+ if (key.escape) return "exit";
19
+ });
20
+ return /* @__PURE__ */ jsxs(Box, {
21
+ flexDirection: "column",
22
+ padding: 1,
23
+ gap: 1,
24
+ children: [
25
+ /* @__PURE__ */ jsx(TextInput, {
26
+ value,
27
+ onChange: setValue,
28
+ onSubmit: (val) => {
29
+ setSubmitted((prev) => [...prev, val]);
30
+ setValue("");
31
+ },
32
+ placeholder: "Type something and press Enter...",
33
+ prompt: "> "
34
+ }),
35
+ submitted.length > 0 && /* @__PURE__ */ jsxs(Box, {
36
+ flexDirection: "column",
37
+ children: [/* @__PURE__ */ jsx(Text, {
38
+ color: "$muted",
39
+ children: "Submitted:"
40
+ }), submitted.map((s, i) => /* @__PURE__ */ jsx(Text, {
41
+ color: "$success",
42
+ children: s
43
+ }, i))]
44
+ }),
45
+ /* @__PURE__ */ jsx(Text, {
46
+ color: "$muted",
47
+ children: "Enter: submit Esc: quit"
48
+ })
49
+ ]
50
+ });
51
+ }
52
+ const meta = {
53
+ name: "Text Input",
54
+ description: "Single-line text entry with readline keybindings"
55
+ };
56
+ async function main() {
57
+ await (await run(/* @__PURE__ */ jsx(TextInputDemo, {}))).waitUntilExit();
58
+ }
59
+ if (import.meta.main) await main();
60
+ //#endregion
61
+ export { main, meta };
@@ -0,0 +1,50 @@
1
+ import "react";
2
+ import { Box, ListView, Text } from "silvery";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { run, useInput as useInput$1 } from "silvery/runtime";
5
+ //#region components/virtual-list.tsx
6
+ const items = Array.from({ length: 200 }, (_, i) => ({
7
+ id: i,
8
+ name: `Item ${i + 1}`
9
+ }));
10
+ function ListViewDemo() {
11
+ useInput$1((input, key) => {
12
+ if (input === "q" || key.escape) return "exit";
13
+ });
14
+ return /* @__PURE__ */ jsxs(Box, {
15
+ flexDirection: "column",
16
+ padding: 1,
17
+ gap: 1,
18
+ children: [
19
+ /* @__PURE__ */ jsx(Text, {
20
+ bold: true,
21
+ children: "200 items (virtualized)"
22
+ }),
23
+ /* @__PURE__ */ jsx(ListView, {
24
+ items,
25
+ height: 12,
26
+ estimateHeight: 1,
27
+ nav: true,
28
+ renderItem: (item, _index, meta) => /* @__PURE__ */ jsxs(Text, {
29
+ color: meta.isCursor ? "$primary" : void 0,
30
+ bold: meta.isCursor,
31
+ children: [meta.isCursor ? "> " : " ", item.name]
32
+ }, item.id)
33
+ }),
34
+ /* @__PURE__ */ jsx(Text, {
35
+ color: "$muted",
36
+ children: "j/k: navigate q: quit"
37
+ })
38
+ ]
39
+ });
40
+ }
41
+ const meta = {
42
+ name: "Virtual List",
43
+ description: "Efficient scrollable list with 200 virtualized items"
44
+ };
45
+ async function main() {
46
+ await (await run(/* @__PURE__ */ jsx(ListViewDemo, {}))).waitUntilExit();
47
+ }
48
+ if (import.meta.main) await main();
49
+ //#endregion
50
+ export { main, meta };