@silvery/examples 0.5.6 → 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.
- package/dist/UPNG-Cy7ViL8f.mjs +5074 -0
- package/dist/__vite-browser-external-2447137e-BML7CYau.mjs +4 -0
- package/dist/_banner-DLPxCqVy.mjs +44 -0
- package/dist/ansi-CCE2pVS0.mjs +16397 -0
- package/dist/apng-HhhBjRGt.mjs +68 -0
- package/dist/apng-mwUQbTTF.mjs +3 -0
- package/dist/apps/aichat/index.mjs +1299 -0
- package/dist/apps/app-todo.mjs +139 -0
- package/dist/apps/async-data.mjs +204 -0
- package/dist/apps/cli-wizard.mjs +339 -0
- package/dist/apps/clipboard.mjs +198 -0
- package/dist/apps/components.mjs +864 -0
- package/dist/apps/data-explorer.mjs +483 -0
- package/dist/apps/dev-tools.mjs +397 -0
- package/dist/apps/explorer.mjs +698 -0
- package/dist/apps/gallery.mjs +766 -0
- package/dist/apps/inline-bench.mjs +115 -0
- package/dist/apps/kanban.mjs +280 -0
- package/dist/apps/layout-ref.mjs +187 -0
- package/dist/apps/outline.mjs +203 -0
- package/dist/apps/paste-demo.mjs +189 -0
- package/dist/apps/scroll.mjs +86 -0
- package/dist/apps/search-filter.mjs +287 -0
- package/dist/apps/selection.mjs +355 -0
- package/dist/apps/spatial-focus-demo.mjs +388 -0
- package/dist/apps/task-list.mjs +258 -0
- package/dist/apps/terminal-caps-demo.mjs +315 -0
- package/dist/apps/terminal.mjs +872 -0
- package/dist/apps/text-selection-demo.mjs +254 -0
- package/dist/apps/textarea.mjs +178 -0
- package/dist/apps/theme.mjs +661 -0
- package/dist/apps/transform.mjs +215 -0
- package/dist/apps/virtual-10k.mjs +422 -0
- package/dist/assets/resvgjs.darwin-arm64-BtufyGW1.node +0 -0
- package/dist/backends-Bahh9mKN.mjs +1179 -0
- package/dist/backends-CCtCDQ94.mjs +3 -0
- package/dist/{cli.mjs → bin/cli.mjs} +21 -25
- package/dist/chunk-BSw8zbkd.mjs +37 -0
- package/dist/components/counter.mjs +48 -0
- package/dist/components/hello.mjs +31 -0
- package/dist/components/progress-bar.mjs +59 -0
- package/dist/components/select-list.mjs +85 -0
- package/dist/components/spinner.mjs +57 -0
- package/dist/components/text-input.mjs +62 -0
- package/dist/components/virtual-list.mjs +51 -0
- package/dist/flexily-zero-adapter-UB-ra8fR.mjs +3374 -0
- package/dist/gif-BZaqPPVX.mjs +3 -0
- package/dist/gif-BtnXuxLF.mjs +71 -0
- package/dist/gifenc-CLRW41dk.mjs +728 -0
- package/dist/jsx-runtime-dMs_8fNu.mjs +241 -0
- package/dist/key-mapping-5oYQdAQE.mjs +3 -0
- package/dist/key-mapping-D4LR1go6.mjs +130 -0
- package/dist/layout/dashboard.mjs +1204 -0
- package/dist/layout/live-resize.mjs +303 -0
- package/dist/layout/overflow.mjs +70 -0
- package/dist/layout/text-layout.mjs +335 -0
- package/dist/node-NuJ94BWl.mjs +1083 -0
- package/dist/plugins-D1KtkT4a.mjs +3057 -0
- package/dist/resvg-js-C_8Wps1F.mjs +201 -0
- package/dist/src-BTEVGpd9.mjs +23538 -0
- package/dist/src-CUUOuRH6.mjs +5322 -0
- package/dist/src-CzfRafCQ.mjs +814 -0
- package/dist/usingCtx-CsEf0xO3.mjs +57 -0
- package/dist/yoga-adapter-BVtQ5OJR.mjs +237 -0
- package/package.json +19 -14
- package/_banner.tsx +0 -60
- package/apps/aichat/components.tsx +0 -469
- package/apps/aichat/index.tsx +0 -220
- package/apps/aichat/script.ts +0 -460
- package/apps/aichat/state.ts +0 -325
- package/apps/aichat/types.ts +0 -19
- package/apps/app-todo.tsx +0 -201
- package/apps/async-data.tsx +0 -196
- package/apps/cli-wizard.tsx +0 -332
- package/apps/clipboard.tsx +0 -183
- package/apps/components.tsx +0 -658
- package/apps/data-explorer.tsx +0 -490
- package/apps/dev-tools.tsx +0 -395
- package/apps/explorer.tsx +0 -731
- package/apps/gallery.tsx +0 -653
- package/apps/inline-bench.tsx +0 -138
- package/apps/kanban.tsx +0 -265
- package/apps/layout-ref.tsx +0 -173
- package/apps/outline.tsx +0 -160
- package/apps/panes/index.tsx +0 -203
- package/apps/paste-demo.tsx +0 -185
- package/apps/scroll.tsx +0 -77
- package/apps/search-filter.tsx +0 -240
- package/apps/selection.tsx +0 -342
- package/apps/spatial-focus-demo.tsx +0 -368
- package/apps/task-list.tsx +0 -271
- package/apps/terminal-caps-demo.tsx +0 -334
- package/apps/terminal.tsx +0 -800
- package/apps/text-selection-demo.tsx +0 -189
- package/apps/textarea.tsx +0 -155
- package/apps/theme.tsx +0 -515
- package/apps/transform.tsx +0 -229
- package/apps/virtual-10k.tsx +0 -405
- package/apps/vterm-demo/index.tsx +0 -216
- package/components/counter.tsx +0 -45
- package/components/hello.tsx +0 -34
- package/components/progress-bar.tsx +0 -48
- package/components/select-list.tsx +0 -50
- package/components/spinner.tsx +0 -40
- package/components/text-input.tsx +0 -57
- package/components/virtual-list.tsx +0 -52
- package/dist/cli.d.mts +0 -1
- package/dist/cli.mjs.map +0 -1
- package/layout/dashboard.tsx +0 -953
- package/layout/live-resize.tsx +0 -282
- package/layout/overflow.tsx +0 -51
- package/layout/text-layout.tsx +0 -283
|
@@ -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
|
|
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(
|
|
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
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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;
|
|
@@ -151,12 +149,12 @@ async function exampleCommand(args) {
|
|
|
151
149
|
process.exit(1);
|
|
152
150
|
}
|
|
153
151
|
console.log(`${DIM}Running ${BOLD}${match.name}${RESET}${DIM}...${RESET}\n`);
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
152
|
+
const mod = await import(match.file);
|
|
153
|
+
if (typeof mod.main === "function") await mod.main();
|
|
154
|
+
else {
|
|
155
|
+
console.error(`${RED}Error:${RESET} Example does not export a main() function`);
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
160
158
|
}
|
|
161
159
|
async function main() {
|
|
162
160
|
const args = process.argv.slice(2);
|
|
@@ -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,48 @@
|
|
|
1
|
+
import { t as require_jsx_runtime } from "../jsx-runtime-dMs_8fNu.mjs";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Box, Text } from "silvery";
|
|
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
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
15
|
+
function Counter() {
|
|
16
|
+
const [count, setCount] = useState(0);
|
|
17
|
+
useInput$1((input, key) => {
|
|
18
|
+
if (input === "j" || key.downArrow) setCount((c) => c + 1);
|
|
19
|
+
if (input === "k" || key.upArrow) setCount((c) => c - 1);
|
|
20
|
+
if (input === "r") setCount(0);
|
|
21
|
+
if (input === "q" || key.escape) return "exit";
|
|
22
|
+
});
|
|
23
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
|
|
24
|
+
flexDirection: "column",
|
|
25
|
+
padding: 1,
|
|
26
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
|
|
27
|
+
gap: 1,
|
|
28
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "Count:" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
29
|
+
bold: true,
|
|
30
|
+
color: count >= 0 ? "$success" : "$error",
|
|
31
|
+
children: count
|
|
32
|
+
})]
|
|
33
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
34
|
+
color: "$muted",
|
|
35
|
+
children: "j/k: +/- r: reset q: quit"
|
|
36
|
+
})]
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const meta = {
|
|
40
|
+
name: "Counter",
|
|
41
|
+
description: "Interactive counter with useState + useInput"
|
|
42
|
+
};
|
|
43
|
+
async function main() {
|
|
44
|
+
await (await run(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Counter, {}))).waitUntilExit();
|
|
45
|
+
}
|
|
46
|
+
if (import.meta.main) await main();
|
|
47
|
+
//#endregion
|
|
48
|
+
export { main, meta };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { t as require_jsx_runtime } from "../jsx-runtime-dMs_8fNu.mjs";
|
|
2
|
+
import "react";
|
|
3
|
+
import { Box, Text } from "silvery";
|
|
4
|
+
import { run, useInput as useInput$1 } from "silvery/runtime";
|
|
5
|
+
//#region components/hello.tsx
|
|
6
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
7
|
+
function Hello() {
|
|
8
|
+
useInput$1(() => "exit");
|
|
9
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
|
|
10
|
+
flexDirection: "column",
|
|
11
|
+
padding: 1,
|
|
12
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
13
|
+
bold: true,
|
|
14
|
+
color: "$primary",
|
|
15
|
+
children: "Hello, Silvery!"
|
|
16
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
17
|
+
color: "$muted",
|
|
18
|
+
children: "Press any key to exit."
|
|
19
|
+
})]
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
const meta = {
|
|
23
|
+
name: "Hello",
|
|
24
|
+
description: "The simplest silvery app — styled text, exit on keypress"
|
|
25
|
+
};
|
|
26
|
+
async function main() {
|
|
27
|
+
await (await run(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Hello, {}))).waitUntilExit();
|
|
28
|
+
}
|
|
29
|
+
if (import.meta.main) await main();
|
|
30
|
+
//#endregion
|
|
31
|
+
export { main, meta };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { t as require_jsx_runtime } from "../jsx-runtime-dMs_8fNu.mjs";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Box, ProgressBar, Text } from "silvery";
|
|
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
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
15
|
+
function ProgressBarDemo() {
|
|
16
|
+
const [progress, setProgress] = useState(.4);
|
|
17
|
+
useInput$1((input, key) => {
|
|
18
|
+
if (input === "j" || key.rightArrow) setProgress((p) => Math.min(1, p + .05));
|
|
19
|
+
if (input === "k" || key.leftArrow) setProgress((p) => Math.max(0, p - .05));
|
|
20
|
+
if (input === "q" || key.escape) return "exit";
|
|
21
|
+
});
|
|
22
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
|
|
23
|
+
flexDirection: "column",
|
|
24
|
+
padding: 1,
|
|
25
|
+
gap: 1,
|
|
26
|
+
children: [
|
|
27
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
28
|
+
bold: true,
|
|
29
|
+
children: "Determinate"
|
|
30
|
+
}),
|
|
31
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
|
|
32
|
+
width: 40,
|
|
33
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProgressBar, { value: progress })
|
|
34
|
+
}),
|
|
35
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
36
|
+
bold: true,
|
|
37
|
+
children: "Indeterminate"
|
|
38
|
+
}),
|
|
39
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
|
|
40
|
+
width: 40,
|
|
41
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProgressBar, {})
|
|
42
|
+
}),
|
|
43
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
44
|
+
color: "$muted",
|
|
45
|
+
children: "j/k: adjust q: quit"
|
|
46
|
+
})
|
|
47
|
+
]
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const meta = {
|
|
51
|
+
name: "Progress Bar",
|
|
52
|
+
description: "Determinate and indeterminate progress bars"
|
|
53
|
+
};
|
|
54
|
+
async function main() {
|
|
55
|
+
await (await run(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProgressBarDemo, {}))).waitUntilExit();
|
|
56
|
+
}
|
|
57
|
+
if (import.meta.main) await main();
|
|
58
|
+
//#endregion
|
|
59
|
+
export { main, meta };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { t as require_jsx_runtime } from "../jsx-runtime-dMs_8fNu.mjs";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Box, SelectList, Text } from "silvery";
|
|
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
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
15
|
+
const languages = [
|
|
16
|
+
{
|
|
17
|
+
label: "TypeScript",
|
|
18
|
+
value: "ts"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
label: "Rust",
|
|
22
|
+
value: "rs"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
label: "Go",
|
|
26
|
+
value: "go"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
label: "Python",
|
|
30
|
+
value: "py"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
label: "COBOL",
|
|
34
|
+
value: "cob",
|
|
35
|
+
disabled: true
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
label: "Elixir",
|
|
39
|
+
value: "ex"
|
|
40
|
+
}
|
|
41
|
+
];
|
|
42
|
+
function SelectListDemo() {
|
|
43
|
+
const [selected, setSelected] = useState(null);
|
|
44
|
+
useInput$1((_, key) => {
|
|
45
|
+
if (key.escape) return "exit";
|
|
46
|
+
});
|
|
47
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
|
|
48
|
+
flexDirection: "column",
|
|
49
|
+
padding: 1,
|
|
50
|
+
gap: 1,
|
|
51
|
+
children: [
|
|
52
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
53
|
+
bold: true,
|
|
54
|
+
children: "Pick a language:"
|
|
55
|
+
}),
|
|
56
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
|
|
57
|
+
borderStyle: "round",
|
|
58
|
+
borderColor: "$border",
|
|
59
|
+
paddingX: 1,
|
|
60
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectList, {
|
|
61
|
+
items: languages,
|
|
62
|
+
onSelect: (opt) => setSelected(opt.value)
|
|
63
|
+
})
|
|
64
|
+
}),
|
|
65
|
+
selected && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
|
|
66
|
+
color: "$success",
|
|
67
|
+
children: ["Selected: ", selected]
|
|
68
|
+
}),
|
|
69
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
70
|
+
color: "$muted",
|
|
71
|
+
children: "j/k: navigate Enter: select Esc: quit"
|
|
72
|
+
})
|
|
73
|
+
]
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const meta = {
|
|
77
|
+
name: "Select List",
|
|
78
|
+
description: "Keyboard-navigable single-select list"
|
|
79
|
+
};
|
|
80
|
+
async function main() {
|
|
81
|
+
await (await run(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectListDemo, {}))).waitUntilExit();
|
|
82
|
+
}
|
|
83
|
+
if (import.meta.main) await main();
|
|
84
|
+
//#endregion
|
|
85
|
+
export { main, meta };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { t as require_jsx_runtime } from "../jsx-runtime-dMs_8fNu.mjs";
|
|
2
|
+
import "react";
|
|
3
|
+
import { Box, Spinner, Text } from "silvery";
|
|
4
|
+
import { run, useInput as useInput$1 } from "silvery/runtime";
|
|
5
|
+
//#region components/spinner.tsx
|
|
6
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
7
|
+
function SpinnerDemo() {
|
|
8
|
+
useInput$1((input, key) => {
|
|
9
|
+
if (input === "q" || key.escape) return "exit";
|
|
10
|
+
});
|
|
11
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
|
|
12
|
+
flexDirection: "column",
|
|
13
|
+
padding: 1,
|
|
14
|
+
gap: 1,
|
|
15
|
+
children: [
|
|
16
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
17
|
+
bold: true,
|
|
18
|
+
children: "Spinner Styles"
|
|
19
|
+
}),
|
|
20
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
|
|
21
|
+
flexDirection: "column",
|
|
22
|
+
children: [
|
|
23
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
|
|
24
|
+
type: "dots",
|
|
25
|
+
label: "Loading packages..."
|
|
26
|
+
}),
|
|
27
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
|
|
28
|
+
type: "line",
|
|
29
|
+
label: "Compiling..."
|
|
30
|
+
}),
|
|
31
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
|
|
32
|
+
type: "arc",
|
|
33
|
+
label: "Optimizing..."
|
|
34
|
+
}),
|
|
35
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
|
|
36
|
+
type: "bounce",
|
|
37
|
+
label: "Connecting..."
|
|
38
|
+
})
|
|
39
|
+
]
|
|
40
|
+
}),
|
|
41
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
42
|
+
color: "$muted",
|
|
43
|
+
children: "q: quit"
|
|
44
|
+
})
|
|
45
|
+
]
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const meta = {
|
|
49
|
+
name: "Spinner",
|
|
50
|
+
description: "Four animated loading spinner styles"
|
|
51
|
+
};
|
|
52
|
+
async function main() {
|
|
53
|
+
await (await run(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SpinnerDemo, {}))).waitUntilExit();
|
|
54
|
+
}
|
|
55
|
+
if (import.meta.main) await main();
|
|
56
|
+
//#endregion
|
|
57
|
+
export { main, meta };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { t as require_jsx_runtime } from "../jsx-runtime-dMs_8fNu.mjs";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Box, Text, TextInput } from "silvery";
|
|
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
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
15
|
+
function TextInputDemo() {
|
|
16
|
+
const [value, setValue] = useState("");
|
|
17
|
+
const [submitted, setSubmitted] = useState([]);
|
|
18
|
+
useInput$1((_, key) => {
|
|
19
|
+
if (key.escape) return "exit";
|
|
20
|
+
});
|
|
21
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
|
|
22
|
+
flexDirection: "column",
|
|
23
|
+
padding: 1,
|
|
24
|
+
gap: 1,
|
|
25
|
+
children: [
|
|
26
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextInput, {
|
|
27
|
+
value,
|
|
28
|
+
onChange: setValue,
|
|
29
|
+
onSubmit: (val) => {
|
|
30
|
+
setSubmitted((prev) => [...prev, val]);
|
|
31
|
+
setValue("");
|
|
32
|
+
},
|
|
33
|
+
placeholder: "Type something and press Enter...",
|
|
34
|
+
prompt: "> "
|
|
35
|
+
}),
|
|
36
|
+
submitted.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
|
|
37
|
+
flexDirection: "column",
|
|
38
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
39
|
+
color: "$muted",
|
|
40
|
+
children: "Submitted:"
|
|
41
|
+
}), submitted.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
42
|
+
color: "$success",
|
|
43
|
+
children: s
|
|
44
|
+
}, i))]
|
|
45
|
+
}),
|
|
46
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
47
|
+
color: "$muted",
|
|
48
|
+
children: "Enter: submit Esc: quit"
|
|
49
|
+
})
|
|
50
|
+
]
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
const meta = {
|
|
54
|
+
name: "Text Input",
|
|
55
|
+
description: "Single-line text entry with readline keybindings"
|
|
56
|
+
};
|
|
57
|
+
async function main() {
|
|
58
|
+
await (await run(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextInputDemo, {}))).waitUntilExit();
|
|
59
|
+
}
|
|
60
|
+
if (import.meta.main) await main();
|
|
61
|
+
//#endregion
|
|
62
|
+
export { main, meta };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { t as require_jsx_runtime } from "../jsx-runtime-dMs_8fNu.mjs";
|
|
2
|
+
import "react";
|
|
3
|
+
import { Box, ListView, Text } from "silvery";
|
|
4
|
+
import { run, useInput as useInput$1 } from "silvery/runtime";
|
|
5
|
+
//#region components/virtual-list.tsx
|
|
6
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
7
|
+
const items = Array.from({ length: 200 }, (_, i) => ({
|
|
8
|
+
id: i,
|
|
9
|
+
name: `Item ${i + 1}`
|
|
10
|
+
}));
|
|
11
|
+
function ListViewDemo() {
|
|
12
|
+
useInput$1((input, key) => {
|
|
13
|
+
if (input === "q" || key.escape) return "exit";
|
|
14
|
+
});
|
|
15
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
|
|
16
|
+
flexDirection: "column",
|
|
17
|
+
padding: 1,
|
|
18
|
+
gap: 1,
|
|
19
|
+
children: [
|
|
20
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
21
|
+
bold: true,
|
|
22
|
+
children: "200 items (virtualized)"
|
|
23
|
+
}),
|
|
24
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ListView, {
|
|
25
|
+
items,
|
|
26
|
+
height: 12,
|
|
27
|
+
estimateHeight: 1,
|
|
28
|
+
nav: true,
|
|
29
|
+
renderItem: (item, _index, meta) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
|
|
30
|
+
color: meta.isCursor ? "$primary" : void 0,
|
|
31
|
+
bold: meta.isCursor,
|
|
32
|
+
children: [meta.isCursor ? "> " : " ", item.name]
|
|
33
|
+
}, item.id)
|
|
34
|
+
}),
|
|
35
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
36
|
+
color: "$muted",
|
|
37
|
+
children: "j/k: navigate q: quit"
|
|
38
|
+
})
|
|
39
|
+
]
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const meta = {
|
|
43
|
+
name: "Virtual List",
|
|
44
|
+
description: "Efficient scrollable list with 200 virtualized items"
|
|
45
|
+
};
|
|
46
|
+
async function main() {
|
|
47
|
+
await (await run(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ListViewDemo, {}))).waitUntilExit();
|
|
48
|
+
}
|
|
49
|
+
if (import.meta.main) await main();
|
|
50
|
+
//#endregion
|
|
51
|
+
export { main, meta };
|