@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,203 @@
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 { useState } from "react";
5
+ import { Box, Kbd, Muted, Text, createTerm, render, useApp, useBoxRect, useInput } from "silvery";
6
+ //#region apps/outline.tsx
7
+ /**
8
+ * Outline vs Border Comparison
9
+ *
10
+ * Side-by-side demonstration of outlineStyle vs borderStyle.
11
+ * Borders push content inward (adding to layout dimensions), while
12
+ * outlines overlap the content edge without affecting layout.
13
+ *
14
+ * Features:
15
+ * - Left panel: Box with borderStyle — content area is smaller
16
+ * - Right panel: Box with outlineStyle — content starts at edge
17
+ * - Toggle between styles with Tab
18
+ * - Live content dimensions via useBoxRect()
19
+ *
20
+ * Run: bun vendor/silvery/examples/apps/outline.tsx
21
+ */
22
+ var import_jsx_runtime = require_jsx_runtime();
23
+ const meta = {
24
+ name: "Outline vs Border",
25
+ description: "Side-by-side comparison showing outline (no layout impact) vs border",
26
+ features: [
27
+ "outlineStyle",
28
+ "borderStyle",
29
+ "useBoxRect()",
30
+ "layout dimensions"
31
+ ]
32
+ };
33
+ const STYLES = [
34
+ "single",
35
+ "double",
36
+ "round",
37
+ "bold"
38
+ ];
39
+ function ContentWithSize({ label }) {
40
+ const { width, height } = useBoxRect();
41
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
42
+ flexDirection: "column",
43
+ children: [
44
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
45
+ bold: true,
46
+ children: label
47
+ }),
48
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
49
+ "Content area:",
50
+ " ",
51
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
52
+ color: "$success",
53
+ bold: true,
54
+ children: width
55
+ }),
56
+ "x",
57
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
58
+ color: "$success",
59
+ bold: true,
60
+ children: height
61
+ })
62
+ ] }),
63
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
64
+ dim: true,
65
+ children: "The quick brown fox"
66
+ }),
67
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
68
+ dim: true,
69
+ children: "jumps over the lazy"
70
+ }),
71
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
72
+ dim: true,
73
+ children: "dog on a sunny day."
74
+ })
75
+ ]
76
+ });
77
+ }
78
+ function BorderPanel({ style, highlight }) {
79
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
80
+ flexDirection: "column",
81
+ flexGrow: 1,
82
+ gap: 1,
83
+ children: [
84
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
85
+ bold: true,
86
+ color: highlight ? "$primary" : void 0,
87
+ children: [
88
+ "borderStyle=\"",
89
+ style,
90
+ "\""
91
+ ]
92
+ }),
93
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
94
+ borderStyle: style,
95
+ borderColor: highlight ? "$primary" : "$border",
96
+ width: 30,
97
+ height: 9,
98
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContentWithSize, { label: "Border Box" })
99
+ }),
100
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "Border adds to layout." }),
101
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "Content is pushed inward." })
102
+ ]
103
+ });
104
+ }
105
+ function OutlinePanel({ style, highlight }) {
106
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
107
+ flexDirection: "column",
108
+ flexGrow: 1,
109
+ gap: 1,
110
+ children: [
111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
112
+ bold: true,
113
+ color: highlight ? "$warning" : void 0,
114
+ children: [
115
+ "outlineStyle=\"",
116
+ style,
117
+ "\""
118
+ ]
119
+ }),
120
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
121
+ outlineStyle: style,
122
+ outlineColor: highlight ? "$warning" : "$border",
123
+ width: 30,
124
+ height: 9,
125
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContentWithSize, { label: "Outline Box" })
126
+ }),
127
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "Outline overlaps content." }),
128
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "No layout impact at all." })
129
+ ]
130
+ });
131
+ }
132
+ function OutlineDemo() {
133
+ const { exit } = useApp();
134
+ const [styleIndex, setStyleIndex] = useState(0);
135
+ const [focusedSide, setFocusedSide] = useState("border");
136
+ const currentStyle = STYLES[styleIndex];
137
+ useInput((input, key) => {
138
+ if (input === "q" || key.escape) {
139
+ exit();
140
+ return;
141
+ }
142
+ if (key.tab || input === " ") setFocusedSide((prev) => prev === "border" ? "outline" : "border");
143
+ if (key.rightArrow || input === "l") setStyleIndex((prev) => (prev + 1) % STYLES.length);
144
+ if (key.leftArrow || input === "h") setStyleIndex((prev) => (prev - 1 + STYLES.length) % STYLES.length);
145
+ });
146
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
147
+ flexDirection: "column",
148
+ padding: 1,
149
+ gap: 1,
150
+ children: [
151
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
152
+ gap: 1,
153
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
154
+ bold: true,
155
+ children: "Style:"
156
+ }), STYLES.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
157
+ color: i === styleIndex ? "$primary" : "$muted",
158
+ bold: i === styleIndex,
159
+ children: i === styleIndex ? `[${s}]` : s
160
+ }, s))]
161
+ }),
162
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
163
+ flexDirection: "row",
164
+ gap: 2,
165
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(BorderPanel, {
166
+ style: currentStyle,
167
+ highlight: focusedSide === "border"
168
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OutlinePanel, {
169
+ style: currentStyle,
170
+ highlight: focusedSide === "outline"
171
+ })]
172
+ }),
173
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
174
+ " ",
175
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "Tab" }),
176
+ " toggle focus ",
177
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "h/l" }),
178
+ " change style ",
179
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "Esc/q" }),
180
+ " quit"
181
+ ] })
182
+ ]
183
+ });
184
+ }
185
+ async function main() {
186
+ try {
187
+ var _usingCtx$1 = _usingCtx();
188
+ const term = _usingCtx$1.u(createTerm());
189
+ const { waitUntilExit } = await render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExampleBanner, {
190
+ meta,
191
+ controls: "Tab toggle h/l style Esc/q quit",
192
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OutlineDemo, {})
193
+ }), term);
194
+ await waitUntilExit();
195
+ } catch (_) {
196
+ _usingCtx$1.e = _;
197
+ } finally {
198
+ _usingCtx$1.d();
199
+ }
200
+ }
201
+ if (import.meta.main) await main();
202
+ //#endregion
203
+ export { OutlineDemo, main, meta };
@@ -0,0 +1,189 @@
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 { useState } from "react";
5
+ import { Box, H1, Kbd, Lead, Muted, Small, Text, createTerm, render, useApp, useInput } from "silvery";
6
+ //#region apps/paste-demo.tsx
7
+ /**
8
+ * Bracketed Paste Demo
9
+ *
10
+ * Demonstrates bracketed paste mode — when text is pasted into the terminal,
11
+ * it arrives as a single event rather than individual keystrokes. This prevents
12
+ * pasted text from being interpreted as commands.
13
+ *
14
+ * Features:
15
+ * - Shows paste mode status (always enabled with render())
16
+ * - Displays pasted text as a single block event
17
+ * - Shows character count and line count of pasted text
18
+ * - Maintains a history of paste events
19
+ *
20
+ * Run: bun vendor/silvery/examples/apps/paste-demo.tsx
21
+ */
22
+ var import_jsx_runtime = require_jsx_runtime();
23
+ const meta = {
24
+ name: "Bracketed Paste",
25
+ description: "Receive pasted text as a single event via bracketed paste mode",
26
+ features: [
27
+ "onPaste",
28
+ "useInput",
29
+ "bracketed paste mode"
30
+ ]
31
+ };
32
+ function PasteIndicator() {
33
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
34
+ gap: 1,
35
+ paddingX: 1,
36
+ children: [
37
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
38
+ color: "$success",
39
+ bold: true,
40
+ children: "●"
41
+ }),
42
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "Paste mode:" }),
43
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
44
+ color: "$success",
45
+ bold: true,
46
+ children: "ENABLED"
47
+ }),
48
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "(bracketed paste is automatic with render())" })
49
+ ]
50
+ });
51
+ }
52
+ function PasteEventCard({ event, isLatest }) {
53
+ const displayText = (event.text.length > 60 ? event.text.slice(0, 57) + "..." : event.text).replace(/\n/g, "\\n").replace(/\t/g, "\\t");
54
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
55
+ flexDirection: "column",
56
+ borderStyle: "round",
57
+ borderColor: isLatest ? "$primary" : "$border",
58
+ paddingX: 1,
59
+ marginBottom: 0,
60
+ children: [
61
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
62
+ justifyContent: "space-between",
63
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(H1, {
64
+ color: isLatest ? "$primary" : void 0,
65
+ children: ["Paste #", event.id]
66
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Small, { children: event.timestamp })]
67
+ }),
68
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
69
+ gap: 2,
70
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Small, { children: [
71
+ event.charCount,
72
+ " char",
73
+ event.charCount !== 1 ? "s" : ""
74
+ ] }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Small, { children: [
75
+ event.lineCount,
76
+ " line",
77
+ event.lineCount !== 1 ? "s" : ""
78
+ ] })]
79
+ }),
80
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
81
+ marginTop: 1,
82
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
83
+ color: "$warning",
84
+ children: displayText
85
+ })
86
+ })
87
+ ]
88
+ });
89
+ }
90
+ function EmptyState() {
91
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
92
+ flexDirection: "column",
93
+ padding: 2,
94
+ alignItems: "center",
95
+ children: [
96
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "No paste events yet." }),
97
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Lead, { children: "Try pasting some text from your clipboard!" }),
98
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Lead, { children: "(Cmd+V on macOS, Ctrl+Shift+V on Linux)" })
99
+ ]
100
+ });
101
+ }
102
+ function PasteDemo() {
103
+ const { exit } = useApp();
104
+ const [pasteHistory, setPasteHistory] = useState([]);
105
+ const [nextId, setNextId] = useState(1);
106
+ useInput((input, key) => {
107
+ if (input === "q" || key.escape) {
108
+ exit();
109
+ return;
110
+ }
111
+ if (input === "x") {
112
+ setPasteHistory([]);
113
+ setNextId(1);
114
+ }
115
+ }, { onPaste: (text) => {
116
+ const now = /* @__PURE__ */ new Date();
117
+ const timestamp = `${now.getHours().toString().padStart(2, "0")}:${now.getMinutes().toString().padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}`;
118
+ const event = {
119
+ id: nextId,
120
+ text,
121
+ charCount: text.length,
122
+ lineCount: text.split("\n").length,
123
+ timestamp
124
+ };
125
+ setPasteHistory((prev) => [event, ...prev].slice(0, 10));
126
+ setNextId((prev) => prev + 1);
127
+ } });
128
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
129
+ flexDirection: "column",
130
+ padding: 1,
131
+ gap: 1,
132
+ children: [
133
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PasteIndicator, {}),
134
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
135
+ flexDirection: "column",
136
+ borderStyle: "round",
137
+ borderColor: "$primary",
138
+ paddingX: 1,
139
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
140
+ marginBottom: 1,
141
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(H1, { children: "Paste History" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Small, { children: [
142
+ " ",
143
+ "— ",
144
+ pasteHistory.length,
145
+ " event",
146
+ pasteHistory.length !== 1 ? "s" : ""
147
+ ] })]
148
+ }), pasteHistory.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyState, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
149
+ flexDirection: "column",
150
+ overflow: "scroll",
151
+ height: 12,
152
+ gap: 1,
153
+ children: pasteHistory.map((event, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PasteEventCard, {
154
+ event,
155
+ isLatest: index === 0
156
+ }, event.id))
157
+ })]
158
+ }),
159
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
160
+ " ",
161
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "Paste text" }),
162
+ " to see events ",
163
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "x" }),
164
+ " clear ",
165
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "Esc/q" }),
166
+ " quit"
167
+ ] })
168
+ ]
169
+ });
170
+ }
171
+ async function main() {
172
+ try {
173
+ var _usingCtx$1 = _usingCtx();
174
+ const term = _usingCtx$1.u(createTerm());
175
+ const { waitUntilExit } = await render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExampleBanner, {
176
+ meta,
177
+ controls: "Paste text to see events x clear Esc/q quit",
178
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PasteDemo, {})
179
+ }), term);
180
+ await waitUntilExit();
181
+ } catch (_) {
182
+ _usingCtx$1.e = _;
183
+ } finally {
184
+ _usingCtx$1.d();
185
+ }
186
+ }
187
+ if (import.meta.main) await main();
188
+ //#endregion
189
+ export { PasteDemo, main, meta };
@@ -0,0 +1,86 @@
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 { useState } from "react";
5
+ import { Box, Kbd, Muted, Text, createTerm, render, useApp, useInput } from "silvery";
6
+ //#region apps/scroll.tsx
7
+ /**
8
+ * Scroll Example
9
+ *
10
+ * Demonstrates overflow="scroll" with keyboard navigation.
11
+ */
12
+ var import_jsx_runtime = require_jsx_runtime();
13
+ const meta = {
14
+ name: "Scroll",
15
+ description: "Native overflow=\"scroll\" with automatic scroll-to-selected",
16
+ features: [
17
+ "overflow=\"scroll\"",
18
+ "scrollTo",
19
+ "useInput"
20
+ ]
21
+ };
22
+ const items = Array.from({ length: 50 }, (_, i) => ({
23
+ id: i,
24
+ title: `Item ${i + 1}`,
25
+ description: `This is the description for item number ${i + 1}`
26
+ }));
27
+ function ScrollExample() {
28
+ const { exit } = useApp();
29
+ const [selectedIndex, setSelectedIndex] = useState(0);
30
+ useInput((input, key) => {
31
+ if (input === "q" || key.escape) exit();
32
+ if (key.upArrow || input === "k") setSelectedIndex((prev) => Math.max(0, prev - 1));
33
+ if (key.downArrow || input === "j") setSelectedIndex((prev) => Math.min(items.length - 1, prev + 1));
34
+ });
35
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
36
+ flexDirection: "column",
37
+ padding: 1,
38
+ width: 60,
39
+ height: 20,
40
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
41
+ flexGrow: 1,
42
+ flexDirection: "column",
43
+ borderStyle: "round",
44
+ borderColor: "$primary",
45
+ overflow: "scroll",
46
+ scrollTo: selectedIndex,
47
+ height: 10,
48
+ children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
49
+ paddingX: 1,
50
+ backgroundColor: index === selectedIndex ? "$primary" : void 0,
51
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
52
+ color: index === selectedIndex ? "$primary-fg" : void 0,
53
+ bold: index === selectedIndex,
54
+ children: item.title
55
+ })
56
+ }, item.id))
57
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
58
+ " ",
59
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "j/k" }),
60
+ " navigate ",
61
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "Esc/q" }),
62
+ " quit | Selected: ",
63
+ selectedIndex + 1,
64
+ "/",
65
+ items.length
66
+ ] })]
67
+ });
68
+ }
69
+ async function main() {
70
+ try {
71
+ var _usingCtx$1 = _usingCtx();
72
+ const term = _usingCtx$1.u(createTerm());
73
+ await render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExampleBanner, {
74
+ meta,
75
+ controls: "j/k navigate Esc/q quit",
76
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollExample, {})
77
+ }), term);
78
+ } catch (_) {
79
+ _usingCtx$1.e = _;
80
+ } finally {
81
+ _usingCtx$1.d();
82
+ }
83
+ }
84
+ if (import.meta.main) await main();
85
+ //#endregion
86
+ export { ScrollExample, main, meta };