@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
|
@@ -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 };
|