@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,254 @@
1
+ import { W as CapabilityRegistryContext } from "../src-BTEVGpd9.mjs";
2
+ import { t as _usingCtx } from "../usingCtx-CsEf0xO3.mjs";
3
+ import { a as createApp, i as pipe, n as withTerminal, r as withReact, t as withDomEvents } from "../plugins-D1KtkT4a.mjs";
4
+ import { t as require_jsx_runtime } from "../jsx-runtime-dMs_8fNu.mjs";
5
+ import { t as ExampleBanner } from "../_banner-DLPxCqVy.mjs";
6
+ import { useContext, useSyncExternalStore } from "react";
7
+ import { Box, H1, H2, HR, Kbd, Muted, Small, Strong, Text } from "silvery";
8
+ //#region ../packages/ag-react/src/hooks/useSelection.ts
9
+ /**
10
+ * useSelection — React hook for accessing the selection feature from the capability registry.
11
+ *
12
+ * Reads SELECTION_CAPABILITY from the app's CapabilityRegistry via context.
13
+ * Returns `undefined` when the selection feature is not installed (e.g., simple
14
+ * run() apps without pipe() composition, or when withDomEvents is not used).
15
+ *
16
+ * When installed, returns the current TerminalSelectionState and re-renders
17
+ * reactively on selection changes via useSyncExternalStore.
18
+ *
19
+ * This is the recommended hook for reading selection state. It replaces the
20
+ * older useTerminalSelection/TerminalSelectionProvider pattern with a simpler
21
+ * capability-based lookup.
22
+ */
23
+ const SELECTION_CAPABILITY = Symbol.for("silvery.selection");
24
+ const noopSubscribe = (_listener) => () => {};
25
+ const getUndefined = () => void 0;
26
+ /**
27
+ * Access the current selection state from the capability registry.
28
+ *
29
+ * Returns `undefined` when:
30
+ * - No CapabilityRegistryContext is provided (simple run() apps)
31
+ * - SELECTION_CAPABILITY is not registered (withDomEvents not used or selection disabled)
32
+ *
33
+ * Returns `TerminalSelectionState` when selection is installed:
34
+ * - `state.range` — current SelectionRange or null (idle)
35
+ * - `state.selecting` — true while mouse button is held
36
+ * - `state.source` — "mouse" | "keyboard" | null
37
+ */
38
+ function useSelection() {
39
+ const feature = useContext(CapabilityRegistryContext)?.get(SELECTION_CAPABILITY);
40
+ return useSyncExternalStore(feature ? (listener) => feature.subscribe(listener) : noopSubscribe, feature ? () => feature.state : getUndefined);
41
+ }
42
+ //#endregion
43
+ //#region apps/text-selection-demo.tsx
44
+ var import_jsx_runtime = require_jsx_runtime();
45
+ const meta = {
46
+ name: "Text Selection",
47
+ description: "Real selection via useSelection hook, userSelect modes, live state readout",
48
+ demo: true,
49
+ features: [
50
+ "useSelection()",
51
+ "userSelect prop",
52
+ "CapabilityRegistry",
53
+ "mouse drag selection"
54
+ ]
55
+ };
56
+ function SelectableTextPanel() {
57
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
58
+ flexDirection: "column",
59
+ borderStyle: "round",
60
+ borderColor: "$border",
61
+ paddingX: 1,
62
+ flexGrow: 1,
63
+ children: [
64
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, { children: "Selectable Text" }),
65
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Small, { children: "userSelect=\"text\" (default)" }),
66
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
67
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "Drag your mouse over this text to select it." }),
68
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "Multi-line selections work across paragraphs." }),
69
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
70
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
71
+ color: "$muted",
72
+ children: "The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs."
73
+ })
74
+ ]
75
+ });
76
+ }
77
+ function NonSelectablePanel() {
78
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
79
+ flexDirection: "column",
80
+ borderStyle: "round",
81
+ borderColor: "$border",
82
+ paddingX: 1,
83
+ flexGrow: 1,
84
+ userSelect: "none",
85
+ children: [
86
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, { children: "Non-Selectable" }),
87
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Small, { children: "userSelect=\"none\"" }),
88
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
89
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "This area cannot be selected by mouse drag." }),
90
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "Click events still work normally here." }),
91
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
92
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "Hold Alt and drag to override and select anyway." })
93
+ ]
94
+ });
95
+ }
96
+ function ContainedPanel() {
97
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
98
+ flexDirection: "column",
99
+ borderStyle: "round",
100
+ borderColor: "$warning",
101
+ paddingX: 1,
102
+ flexGrow: 1,
103
+ children: [
104
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, {
105
+ color: "$warning",
106
+ children: "Contained Selection"
107
+ }),
108
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Small, { children: "userSelect=\"contain\"" }),
109
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
110
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
111
+ flexDirection: "column",
112
+ borderStyle: "round",
113
+ borderColor: "$primary",
114
+ paddingX: 1,
115
+ userSelect: "contain",
116
+ children: [
117
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
118
+ bold: true,
119
+ color: "$primary",
120
+ children: "Selection Boundary"
121
+ }),
122
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
123
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "Selection cannot escape this container." }),
124
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "Try dragging past the border — it clips." }),
125
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
126
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
127
+ color: "$success",
128
+ children: "Useful for modals, side panes, overlays."
129
+ })
130
+ ]
131
+ })
132
+ ]
133
+ });
134
+ }
135
+ function SelectionStatePanel() {
136
+ const selection = useSelection();
137
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
138
+ flexDirection: "column",
139
+ borderStyle: "round",
140
+ borderColor: "$info",
141
+ paddingX: 1,
142
+ flexGrow: 1,
143
+ children: [
144
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(H2, {
145
+ color: "$info",
146
+ children: "Selection State"
147
+ }),
148
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Small, { children: "Live readout from useSelection()" }),
149
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, { height: 1 }),
150
+ !selection ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
151
+ color: "$muted",
152
+ children: "useSelection() returned undefined — feature not installed"
153
+ }) : selection.range ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
154
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
155
+ gap: 1,
156
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Strong, { children: "Status:" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
157
+ color: "$success",
158
+ children: selection.selecting ? "Selecting..." : "Selected"
159
+ })]
160
+ }),
161
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
162
+ gap: 1,
163
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Strong, { children: "Source:" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: selection.source ?? "unknown" })]
164
+ }),
165
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
166
+ gap: 1,
167
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Strong, { children: "Anchor:" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
168
+ "(",
169
+ selection.range.anchor.col,
170
+ ", ",
171
+ selection.range.anchor.row,
172
+ ")"
173
+ ] })]
174
+ }),
175
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
176
+ gap: 1,
177
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Strong, { children: "Head:" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
178
+ "(",
179
+ selection.range.head.col,
180
+ ", ",
181
+ selection.range.head.row,
182
+ ")"
183
+ ] })]
184
+ })
185
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
186
+ color: "$muted",
187
+ children: "No active selection — drag to select text"
188
+ })
189
+ ]
190
+ });
191
+ }
192
+ function StatusBar() {
193
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
194
+ flexDirection: "row",
195
+ gap: 2,
196
+ paddingX: 1,
197
+ flexShrink: 0,
198
+ userSelect: "none",
199
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
200
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "Drag" }),
201
+ " select ",
202
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "Alt+Drag" }),
203
+ " force select ",
204
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: "Ctrl+C" }),
205
+ " quit"
206
+ ] })
207
+ });
208
+ }
209
+ function TextSelectionDemo() {
210
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
211
+ flexDirection: "column",
212
+ padding: 1,
213
+ gap: 1,
214
+ height: "100%",
215
+ children: [
216
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(H1, {
217
+ color: "$primary",
218
+ children: "Text Selection Demo"
219
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: " — real selection via useSelection()" })] }),
220
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
221
+ flexDirection: "row",
222
+ gap: 1,
223
+ flexGrow: 1,
224
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectableTextPanel, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NonSelectablePanel, {})]
225
+ }),
226
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
227
+ flexDirection: "row",
228
+ gap: 1,
229
+ flexGrow: 1,
230
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContainedPanel, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectionStatePanel, {})]
231
+ }),
232
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HR, {}),
233
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatusBar, {})
234
+ ]
235
+ });
236
+ }
237
+ async function main() {
238
+ try {
239
+ var _usingCtx$1 = _usingCtx();
240
+ const app = pipe(createApp(() => () => ({})), withReact(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExampleBanner, {
241
+ meta,
242
+ controls: "Drag select Alt+Drag force select Ctrl+C quit",
243
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextSelectionDemo, {})
244
+ })), withTerminal(process, { mouse: true }), withDomEvents());
245
+ await _usingCtx$1.u(await app.run()).waitUntilExit();
246
+ } catch (_) {
247
+ _usingCtx$1.e = _;
248
+ } finally {
249
+ _usingCtx$1.d();
250
+ }
251
+ }
252
+ if (import.meta.main) await main();
253
+ //#endregion
254
+ export { main, meta };
@@ -0,0 +1,178 @@
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, Muted, Strong, Text, TextArea, createTerm, render, useApp, useInput } from "silvery";
6
+ //#region apps/textarea.tsx
7
+ /**
8
+ * TextArea Example — Split-Pane Note Editor
9
+ *
10
+ * A note-taking app demonstrating:
11
+ * - Multi-line text input with word wrapping and pre-filled content
12
+ * - Split-pane layout: editor (2/3) + saved notes sidebar (1/3)
13
+ * - Tab focus cycling between panes
14
+ * - Cursor movement (arrow keys, Home/End, Ctrl+A/E)
15
+ * - Kill operations (Ctrl+K, Ctrl+U)
16
+ * - Word/character stats in the header
17
+ * - Submit with Ctrl+Enter to collect notes
18
+ */
19
+ var import_jsx_runtime = require_jsx_runtime();
20
+ const meta = {
21
+ name: "TextArea",
22
+ description: "Split-pane note editor with word wrap, kill ring, and note collection",
23
+ features: [
24
+ "TextArea",
25
+ "Split pane layout",
26
+ "Ctrl+Enter submit",
27
+ "Tab focus cycling"
28
+ ]
29
+ };
30
+ const INITIAL_CONTENT = `# Release Notes — Silvery v0.1
31
+
32
+ ## New Features
33
+
34
+ - **Flexbox layout engine** — CSS-compatible sizing,
35
+ wrapping, and gap support via Flexily
36
+ - **38 built-in color palettes** — from Dracula
37
+ to Solarized, Nord to Catppuccin
38
+ - **Incremental rendering** — only changed cells
39
+ are repainted, no full-screen flicker
40
+
41
+ ## Breaking Changes
42
+
43
+ - Dropped Node.js 18 support (now requires >=20)
44
+ - Renamed \`useTerminal()\` to \`useTerm()\`
45
+
46
+ ## Performance
47
+
48
+ Benchmark results on an M4 MacBook Pro:
49
+ Initial render: 2.1ms (80x24)
50
+ Incremental: 0.3ms (typical diff)
51
+ Layout: 0.8ms (1000 nodes)
52
+
53
+ Thanks to all contributors!`;
54
+ function NoteEditor() {
55
+ const { exit } = useApp();
56
+ const [notes, setNotes] = useState([]);
57
+ const [value, setValue] = useState(INITIAL_CONTENT);
58
+ const [focusIndex, setFocusIndex] = useState(0);
59
+ useInput((input, key) => {
60
+ if (key.escape) exit();
61
+ if (key.tab && !key.shift) setFocusIndex((prev) => (prev + 1) % 2);
62
+ if (key.tab && key.shift) setFocusIndex((prev) => (prev - 1 + 2) % 2);
63
+ });
64
+ function handleSubmit(text) {
65
+ if (text.trim()) {
66
+ setNotes((prev) => [...prev, text.trim()]);
67
+ setValue("");
68
+ }
69
+ }
70
+ const lines = value.split("\n").length;
71
+ const chars = value.length;
72
+ const words = value.split(/\s+/).filter(Boolean).length;
73
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
74
+ flexDirection: "column",
75
+ flexGrow: 1,
76
+ padding: 1,
77
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
78
+ flexDirection: "row",
79
+ gap: 1,
80
+ flexGrow: 1,
81
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
82
+ borderStyle: "round",
83
+ borderColor: focusIndex === 0 ? "$primary" : "$border",
84
+ flexDirection: "column",
85
+ flexGrow: 3,
86
+ flexBasis: 0,
87
+ children: [
88
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
89
+ paddingX: 1,
90
+ justifyContent: "space-between",
91
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(H1, { children: "Editor" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
92
+ lines,
93
+ " lines, ",
94
+ words,
95
+ " words, ",
96
+ chars,
97
+ " chars"
98
+ ] })]
99
+ }),
100
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: " " }),
101
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
102
+ paddingX: 1,
103
+ flexGrow: 1,
104
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextArea, {
105
+ value,
106
+ onChange: setValue,
107
+ onSubmit: handleSubmit,
108
+ height: 16,
109
+ isActive: focusIndex === 0
110
+ })
111
+ })
112
+ ]
113
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
114
+ borderStyle: "round",
115
+ borderColor: focusIndex === 1 ? "$primary" : "$border",
116
+ flexDirection: "column",
117
+ flexGrow: 2,
118
+ flexBasis: 0,
119
+ children: [
120
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
121
+ paddingX: 1,
122
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(H1, { children: "Notes" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
123
+ " (",
124
+ notes.length,
125
+ ")"
126
+ ] })]
127
+ }),
128
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: " " }),
129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
130
+ flexDirection: "column",
131
+ paddingX: 1,
132
+ overflow: "scroll",
133
+ flexGrow: 1,
134
+ children: notes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "No notes yet." }) : notes.map((note, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
135
+ flexDirection: "column",
136
+ marginBottom: 1,
137
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
138
+ wrap: "truncate",
139
+ children: [
140
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Strong, {
141
+ color: "$success",
142
+ children: ["#", i + 1]
143
+ }),
144
+ " ",
145
+ note.split("\n")[0]
146
+ ]
147
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
148
+ note.split("\n").length,
149
+ " lines, ",
150
+ note.length,
151
+ " chars"
152
+ ] })]
153
+ }, i))
154
+ })
155
+ ]
156
+ })]
157
+ })
158
+ });
159
+ }
160
+ async function main() {
161
+ try {
162
+ var _usingCtx$1 = _usingCtx();
163
+ const term = _usingCtx$1.u(createTerm());
164
+ const { waitUntilExit } = await render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExampleBanner, {
165
+ meta,
166
+ controls: "Tab switch pane Ctrl+Enter submit Esc quit",
167
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NoteEditor, {})
168
+ }), term);
169
+ await waitUntilExit();
170
+ } catch (_) {
171
+ _usingCtx$1.e = _;
172
+ } finally {
173
+ _usingCtx$1.d();
174
+ }
175
+ }
176
+ if (import.meta.main) await main();
177
+ //#endregion
178
+ export { NoteEditor, main, meta };