@silvery/examples 0.17.3 → 0.17.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/UPNG-ShUlaTDh.mjs +5074 -0
  2. package/dist/__vite-browser-external-2447137e-Bopa5BFR.mjs +4 -0
  3. package/dist/_banner-A70_y2Vi.mjs +43 -0
  4. package/dist/ansi-0VXlUmNn.mjs +16397 -0
  5. package/dist/apng-B0gRaDVT.mjs +3 -0
  6. package/dist/apng-BTRDTfDW.mjs +68 -0
  7. package/dist/apps/aichat/index.mjs +1298 -0
  8. package/dist/apps/app-todo.mjs +138 -0
  9. package/dist/apps/async-data.mjs +203 -0
  10. package/dist/apps/cli-wizard.mjs +338 -0
  11. package/dist/apps/clipboard.mjs +197 -0
  12. package/dist/apps/components.mjs +863 -0
  13. package/dist/apps/data-explorer.mjs +482 -0
  14. package/dist/apps/dev-tools.mjs +396 -0
  15. package/dist/apps/explorer.mjs +697 -0
  16. package/dist/apps/gallery.mjs +765 -0
  17. package/dist/apps/inline-bench.mjs +115 -0
  18. package/dist/apps/kanban.mjs +279 -0
  19. package/dist/apps/layout-ref.mjs +186 -0
  20. package/dist/apps/outline.mjs +202 -0
  21. package/dist/apps/paste-demo.mjs +188 -0
  22. package/dist/apps/scroll.mjs +85 -0
  23. package/dist/apps/search-filter.mjs +286 -0
  24. package/dist/apps/selection.mjs +354 -0
  25. package/dist/apps/spatial-focus-demo.mjs +387 -0
  26. package/dist/apps/task-list.mjs +257 -0
  27. package/dist/apps/terminal-caps-demo.mjs +314 -0
  28. package/dist/apps/terminal.mjs +871 -0
  29. package/dist/apps/text-selection-demo.mjs +253 -0
  30. package/dist/apps/textarea.mjs +177 -0
  31. package/dist/apps/theme.mjs +660 -0
  32. package/dist/apps/transform.mjs +214 -0
  33. package/dist/apps/virtual-10k.mjs +421 -0
  34. package/dist/assets/resvgjs.darwin-arm64-BtufyGW1.node +0 -0
  35. package/dist/backends-Dj-11kZF.mjs +1179 -0
  36. package/dist/backends-U3QwStfO.mjs +3 -0
  37. package/dist/{cli.mjs → bin/cli.mjs} +15 -19
  38. package/dist/chunk-BSw8zbkd.mjs +37 -0
  39. package/dist/components/counter.mjs +47 -0
  40. package/dist/components/hello.mjs +30 -0
  41. package/dist/components/progress-bar.mjs +58 -0
  42. package/dist/components/select-list.mjs +84 -0
  43. package/dist/components/spinner.mjs +56 -0
  44. package/dist/components/text-input.mjs +61 -0
  45. package/dist/components/virtual-list.mjs +50 -0
  46. package/dist/flexily-zero-adapter-ByVzLTFP.mjs +3374 -0
  47. package/dist/gif-B6NGH5gs.mjs +3 -0
  48. package/dist/gif-CfkOF-iG.mjs +71 -0
  49. package/dist/gifenc-BI4ihP_T.mjs +728 -0
  50. package/dist/key-mapping-5oYQdAQE.mjs +3 -0
  51. package/dist/key-mapping-D4LR1go6.mjs +130 -0
  52. package/dist/layout/dashboard.mjs +1203 -0
  53. package/dist/layout/live-resize.mjs +302 -0
  54. package/dist/layout/overflow.mjs +69 -0
  55. package/dist/layout/text-layout.mjs +334 -0
  56. package/dist/node-nsrAOjH4.mjs +1083 -0
  57. package/dist/plugins-CT0DdV_E.mjs +3056 -0
  58. package/dist/resvg-js-Cnk2o49d.mjs +201 -0
  59. package/dist/src-9ZhfQyzD.mjs +814 -0
  60. package/dist/src-CUUOuRH6.mjs +5322 -0
  61. package/dist/src-jO3Zuzjj.mjs +23538 -0
  62. package/dist/usingCtx-CsEf0xO3.mjs +57 -0
  63. package/dist/yoga-adapter-BSQHuMV9.mjs +237 -0
  64. package/package.json +21 -14
  65. package/_banner.tsx +0 -60
  66. package/apps/aichat/components.tsx +0 -469
  67. package/apps/aichat/index.tsx +0 -220
  68. package/apps/aichat/script.ts +0 -460
  69. package/apps/aichat/state.ts +0 -325
  70. package/apps/aichat/types.ts +0 -19
  71. package/apps/app-todo.tsx +0 -201
  72. package/apps/async-data.tsx +0 -196
  73. package/apps/cli-wizard.tsx +0 -332
  74. package/apps/clipboard.tsx +0 -183
  75. package/apps/components.tsx +0 -658
  76. package/apps/data-explorer.tsx +0 -490
  77. package/apps/dev-tools.tsx +0 -395
  78. package/apps/explorer.tsx +0 -731
  79. package/apps/gallery.tsx +0 -653
  80. package/apps/inline-bench.tsx +0 -138
  81. package/apps/kanban.tsx +0 -265
  82. package/apps/layout-ref.tsx +0 -173
  83. package/apps/outline.tsx +0 -160
  84. package/apps/panes/index.tsx +0 -203
  85. package/apps/paste-demo.tsx +0 -185
  86. package/apps/scroll.tsx +0 -80
  87. package/apps/search-filter.tsx +0 -240
  88. package/apps/selection.tsx +0 -346
  89. package/apps/spatial-focus-demo.tsx +0 -372
  90. package/apps/task-list.tsx +0 -271
  91. package/apps/terminal-caps-demo.tsx +0 -317
  92. package/apps/terminal.tsx +0 -784
  93. package/apps/text-selection-demo.tsx +0 -193
  94. package/apps/textarea.tsx +0 -155
  95. package/apps/theme.tsx +0 -515
  96. package/apps/transform.tsx +0 -229
  97. package/apps/virtual-10k.tsx +0 -405
  98. package/apps/vterm-demo/index.tsx +0 -216
  99. package/components/counter.tsx +0 -49
  100. package/components/hello.tsx +0 -38
  101. package/components/progress-bar.tsx +0 -52
  102. package/components/select-list.tsx +0 -54
  103. package/components/spinner.tsx +0 -44
  104. package/components/text-input.tsx +0 -61
  105. package/components/virtual-list.tsx +0 -56
  106. package/dist/cli.d.mts +0 -1
  107. package/dist/cli.mjs.map +0 -1
  108. package/layout/dashboard.tsx +0 -953
  109. package/layout/live-resize.tsx +0 -282
  110. package/layout/overflow.tsx +0 -51
  111. package/layout/text-layout.tsx +0 -283
@@ -0,0 +1,302 @@
1
+ import { t as ExampleBanner } from "../_banner-A70_y2Vi.mjs";
2
+ import { useCallback } from "react";
3
+ import { Box, H1, H3, Kbd, Muted, Small, Text, useBoxRect } from "silvery";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { run, useInput as useInput$1 } from "silvery/runtime";
6
+ //#region layout/live-resize.tsx
7
+ const meta = {
8
+ name: "Live Resize",
9
+ description: "Responsive multi-column grid that reflows based on terminal width",
10
+ features: [
11
+ "useBoxRect()",
12
+ "responsive breakpoints",
13
+ "Box flexDirection"
14
+ ]
15
+ };
16
+ const CARDS = [
17
+ {
18
+ title: "CPU Usage",
19
+ icon: "💻",
20
+ value: "42%",
21
+ detail: "4 cores, 2.4 GHz base",
22
+ color: "green",
23
+ sparkline: "▂▃▅▇▆▄▃▅▇█▆▄▃▂▃▅"
24
+ },
25
+ {
26
+ title: "Memory",
27
+ icon: "🧠",
28
+ value: "8.2 GB",
29
+ detail: "of 16 GB (51% used)",
30
+ color: "cyan",
31
+ sparkline: "▄▄▅▅▅▆▆▆▅▅▆▆▇▇▆▆"
32
+ },
33
+ {
34
+ title: "Disk I/O",
35
+ icon: "💾",
36
+ value: "234 MB/s",
37
+ detail: "Read: 180 MB/s Write: 54 MB/s",
38
+ color: "yellow",
39
+ sparkline: "▁▂▃▇█▇▄▂▁▂▅▇▆▃▂▁"
40
+ },
41
+ {
42
+ title: "Network",
43
+ icon: "🌐",
44
+ value: "1.2 Gb/s",
45
+ detail: "In: 800 Mb/s Out: 400 Mb/s",
46
+ color: "magenta",
47
+ sparkline: "▃▄▅▆▇▆▅▄▅▆▇█▇▆▅▄"
48
+ },
49
+ {
50
+ title: "Processes",
51
+ icon: "⚙️",
52
+ value: "247",
53
+ detail: "12 running, 235 sleeping",
54
+ color: "blue",
55
+ sparkline: "▅▅▅▆▅▅▅▅▆▅▅▅▆▅▅▅"
56
+ },
57
+ {
58
+ title: "Temperature",
59
+ icon: "🌡️",
60
+ value: "62 C",
61
+ detail: "Max: 85 C (safe range)",
62
+ color: "red",
63
+ sparkline: "▃▃▄▄▅▅▆▆▅▅▄▄▃▄▅▅"
64
+ }
65
+ ];
66
+ function MetricCard({ card, compact }) {
67
+ if (compact) return /* @__PURE__ */ jsxs(Box, {
68
+ borderStyle: "round",
69
+ borderColor: card.color,
70
+ paddingX: 1,
71
+ flexDirection: "row",
72
+ justifyContent: "space-between",
73
+ children: [/* @__PURE__ */ jsx(H1, {
74
+ color: card.color,
75
+ children: card.title
76
+ }), /* @__PURE__ */ jsx(H3, { children: card.value })]
77
+ });
78
+ return /* @__PURE__ */ jsxs(Box, {
79
+ borderStyle: "round",
80
+ borderColor: card.color,
81
+ paddingX: 1,
82
+ flexDirection: "column",
83
+ flexGrow: 1,
84
+ children: [
85
+ /* @__PURE__ */ jsxs(Box, {
86
+ justifyContent: "space-between",
87
+ children: [/* @__PURE__ */ jsx(H1, {
88
+ color: card.color,
89
+ children: card.title
90
+ }), /* @__PURE__ */ jsx(H1, {
91
+ color: card.color,
92
+ children: card.value
93
+ })]
94
+ }),
95
+ /* @__PURE__ */ jsx(Text, {
96
+ color: card.color,
97
+ children: card.sparkline
98
+ }),
99
+ /* @__PURE__ */ jsx(Small, { children: card.detail })
100
+ ]
101
+ });
102
+ }
103
+ function BreakpointIndicator({ width, columns }) {
104
+ return /* @__PURE__ */ jsx(Box, {
105
+ gap: 2,
106
+ paddingX: 1,
107
+ children: [
108
+ {
109
+ threshold: 0,
110
+ cols: 1,
111
+ label: "< 60"
112
+ },
113
+ {
114
+ threshold: 60,
115
+ cols: 2,
116
+ label: "60-99"
117
+ },
118
+ {
119
+ threshold: 100,
120
+ cols: 3,
121
+ label: "100+"
122
+ }
123
+ ].map((bp) => {
124
+ const isActive = bp.cols === columns;
125
+ return /* @__PURE__ */ jsxs(Box, {
126
+ gap: 1,
127
+ children: [/* @__PURE__ */ jsx(Text, {
128
+ color: isActive ? "green" : "gray",
129
+ bold: isActive,
130
+ children: isActive ? "●" : "○"
131
+ }), /* @__PURE__ */ jsxs(Text, {
132
+ color: isActive ? "white" : "gray",
133
+ bold: isActive,
134
+ children: [
135
+ bp.cols,
136
+ " col",
137
+ bp.cols > 1 ? "s" : " ",
138
+ " (",
139
+ bp.label,
140
+ ")"
141
+ ]
142
+ })]
143
+ }, bp.cols);
144
+ })
145
+ });
146
+ }
147
+ function GridLayout({ cards, columns, compact }) {
148
+ if (columns === 1) return /* @__PURE__ */ jsx(Box, {
149
+ flexDirection: "column",
150
+ gap: compact ? 0 : 1,
151
+ flexGrow: 1,
152
+ children: cards.map((card) => /* @__PURE__ */ jsx(MetricCard, {
153
+ card,
154
+ compact
155
+ }, card.title))
156
+ });
157
+ const rows = [];
158
+ for (let i = 0; i < cards.length; i += columns) rows.push(cards.slice(i, i + columns));
159
+ return /* @__PURE__ */ jsx(Box, {
160
+ flexDirection: "column",
161
+ gap: 1,
162
+ flexGrow: 1,
163
+ children: rows.map((row, rowIndex) => /* @__PURE__ */ jsxs(Box, {
164
+ flexDirection: "row",
165
+ gap: 1,
166
+ children: [row.map((card) => /* @__PURE__ */ jsx(Box, {
167
+ flexGrow: 1,
168
+ flexBasis: 0,
169
+ children: /* @__PURE__ */ jsx(MetricCard, {
170
+ card,
171
+ compact: false
172
+ })
173
+ }, card.title)), row.length < columns && Array.from({ length: columns - row.length }, (_, i) => /* @__PURE__ */ jsx(Box, {
174
+ flexGrow: 1,
175
+ flexBasis: 0
176
+ }, `spacer-${i}`))]
177
+ }, rowIndex))
178
+ });
179
+ }
180
+ function CodeSnippet({ width }) {
181
+ if (!(width >= 60)) return /* @__PURE__ */ jsx(Box, {
182
+ paddingX: 1,
183
+ children: /* @__PURE__ */ jsx(Text, {
184
+ dim: true,
185
+ italic: true,
186
+ children: "(Widen terminal to see the code that powers this)"
187
+ })
188
+ });
189
+ return /* @__PURE__ */ jsxs(Box, {
190
+ flexDirection: "column",
191
+ borderStyle: "single",
192
+ borderColor: "$border",
193
+ paddingX: 1,
194
+ children: [
195
+ /* @__PURE__ */ jsx(H1, {
196
+ color: "yellow",
197
+ children: "How it works:"
198
+ }),
199
+ /* @__PURE__ */ jsxs(Text, {
200
+ color: "gray",
201
+ children: [
202
+ " ",
203
+ /* @__PURE__ */ jsx(Text, {
204
+ color: "magenta",
205
+ children: "const"
206
+ }),
207
+ " ",
208
+ "{",
209
+ " width ",
210
+ "}",
211
+ " = ",
212
+ /* @__PURE__ */ jsx(Text, {
213
+ color: "cyan",
214
+ children: "useBoxRect"
215
+ }),
216
+ "()"
217
+ ]
218
+ }),
219
+ /* @__PURE__ */ jsxs(Text, {
220
+ color: "gray",
221
+ children: [
222
+ " ",
223
+ /* @__PURE__ */ jsx(Text, {
224
+ color: "magenta",
225
+ children: "const"
226
+ }),
227
+ " columns = width ",
228
+ ">",
229
+ " 100 ? ",
230
+ /* @__PURE__ */ jsx(Text, {
231
+ color: "green",
232
+ children: "3"
233
+ }),
234
+ " : width ",
235
+ ">",
236
+ " 60 ?",
237
+ " ",
238
+ /* @__PURE__ */ jsx(Text, {
239
+ color: "green",
240
+ children: "2"
241
+ }),
242
+ " : ",
243
+ /* @__PURE__ */ jsx(Text, {
244
+ color: "green",
245
+ children: "1"
246
+ })
247
+ ]
248
+ }),
249
+ /* @__PURE__ */ jsxs(Text, {
250
+ dim: true,
251
+ italic: true,
252
+ children: [" ", "// No useEffect, no layout thrashing. Synchronous."]
253
+ })
254
+ ]
255
+ });
256
+ }
257
+ function LiveResize() {
258
+ const { width, height } = useBoxRect();
259
+ const columns = width >= 100 ? 3 : width >= 60 ? 2 : 1;
260
+ const compact = height < 20 || width < 40;
261
+ useInput$1(useCallback((input, key) => {
262
+ if (input === "q" || key.escape || key.ctrl && input === "c") return "exit";
263
+ }, []));
264
+ return /* @__PURE__ */ jsxs(Box, {
265
+ flexDirection: "column",
266
+ width: "100%",
267
+ height: "100%",
268
+ padding: 1,
269
+ children: [
270
+ /* @__PURE__ */ jsx(BreakpointIndicator, {
271
+ width,
272
+ columns
273
+ }),
274
+ /* @__PURE__ */ jsx(Box, {
275
+ flexGrow: 1,
276
+ flexDirection: "column",
277
+ marginTop: 1,
278
+ children: /* @__PURE__ */ jsx(GridLayout, {
279
+ cards: CARDS,
280
+ columns,
281
+ compact
282
+ })
283
+ }),
284
+ !compact && /* @__PURE__ */ jsx(CodeSnippet, { width }),
285
+ /* @__PURE__ */ jsxs(Box, {
286
+ justifyContent: "space-between",
287
+ paddingX: 1,
288
+ children: [/* @__PURE__ */ jsx(Muted, { children: "Resize your terminal to see the layout reflow" }), /* @__PURE__ */ jsxs(Muted, { children: [/* @__PURE__ */ jsx(Kbd, { children: "Esc/q" }), " quit"] })]
289
+ })
290
+ ]
291
+ });
292
+ }
293
+ async function main() {
294
+ await (await run(/* @__PURE__ */ jsx(ExampleBanner, {
295
+ meta,
296
+ controls: "Resize terminal to see reflow Esc/q quit",
297
+ children: /* @__PURE__ */ jsx(LiveResize, {})
298
+ }))).waitUntilExit();
299
+ }
300
+ if (import.meta.main) await main();
301
+ //#endregion
302
+ export { main, meta };
@@ -0,0 +1,69 @@
1
+ import { t as _usingCtx } from "../usingCtx-CsEf0xO3.mjs";
2
+ import { t as ExampleBanner } from "../_banner-A70_y2Vi.mjs";
3
+ import "react";
4
+ import { Box, Text, createTerm, render, useApp, useInput } from "silvery";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ //#region layout/overflow.tsx
7
+ const meta = {
8
+ name: "Overflow",
9
+ description: "overflow=\"hidden\" content clipping demonstration",
10
+ features: ["overflow=\"hidden\"", "Box height"]
11
+ };
12
+ function OverflowApp() {
13
+ const { exit } = useApp();
14
+ useInput((input, key) => {
15
+ if (input === "q" || key.escape) exit();
16
+ });
17
+ return /* @__PURE__ */ jsxs(Box, {
18
+ flexDirection: "column",
19
+ padding: 1,
20
+ children: [
21
+ /* @__PURE__ */ jsx(Text, {
22
+ color: "yellow",
23
+ children: "Title"
24
+ }),
25
+ /* @__PURE__ */ jsx(Box, {
26
+ borderStyle: "single",
27
+ borderColor: "$primary",
28
+ height: 5,
29
+ overflow: "hidden",
30
+ children: /* @__PURE__ */ jsxs(Box, {
31
+ flexDirection: "column",
32
+ flexGrow: 1,
33
+ children: [
34
+ /* @__PURE__ */ jsx(Text, { children: "Line 1" }),
35
+ /* @__PURE__ */ jsx(Text, { children: "Line 2" }),
36
+ /* @__PURE__ */ jsx(Text, { children: "Line 3" }),
37
+ /* @__PURE__ */ jsx(Text, { children: "Line 4" }),
38
+ /* @__PURE__ */ jsx(Text, { children: "Line 5" }),
39
+ /* @__PURE__ */ jsx(Text, { children: "Line 6 - should NOT appear" }),
40
+ /* @__PURE__ */ jsx(Text, { children: "Line 7 - should NOT appear" })
41
+ ]
42
+ })
43
+ }),
44
+ /* @__PURE__ */ jsx(Text, {
45
+ color: "$success",
46
+ children: "This should NOT be corrupted"
47
+ })
48
+ ]
49
+ });
50
+ }
51
+ async function main() {
52
+ try {
53
+ var _usingCtx$1 = _usingCtx();
54
+ const term = _usingCtx$1.u(createTerm());
55
+ const { waitUntilExit } = await render(/* @__PURE__ */ jsx(ExampleBanner, {
56
+ meta,
57
+ controls: "Esc/q quit",
58
+ children: /* @__PURE__ */ jsx(OverflowApp, {})
59
+ }), term);
60
+ await waitUntilExit();
61
+ } catch (_) {
62
+ _usingCtx$1.e = _;
63
+ } finally {
64
+ _usingCtx$1.d();
65
+ }
66
+ }
67
+ if (import.meta.main) await main();
68
+ //#endregion
69
+ export { OverflowApp, main, meta };
@@ -0,0 +1,334 @@
1
+ import { t as ExampleBanner } from "../_banner-A70_y2Vi.mjs";
2
+ import { useCallback, useState } from "react";
3
+ import { Box, Divider, H2, Kbd, Muted, Small, Text } from "silvery";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { run, useInput as useInput$1 } from "silvery/runtime";
6
+ //#region layout/text-layout.tsx
7
+ /**
8
+ * Pretext Demo — snug-content bubbles + even wrapping comparison
9
+ *
10
+ * Interactive demo showcasing Silvery's Pretext-inspired text layout:
11
+ * - width="snug-content" — tightest box width for same line count (shrinkwrap)
12
+ * - wrap="even" — minimum-raggedness line breaking (Knuth-Plass)
13
+ *
14
+ * Inspired by https://chenglou.me/pretext/
15
+ *
16
+ * Usage: bun examples/pretext-demo.tsx
17
+ *
18
+ * Controls:
19
+ * j/k - Cycle demo sections
20
+ * Esc/q - Quit
21
+ */
22
+ const meta = {
23
+ name: "text layout",
24
+ description: "Snug-content bubbles + even wrapping — inspired by chenglou/pretext",
25
+ demo: true,
26
+ features: [
27
+ "width=\"snug-content\"",
28
+ "wrap=\"even\"",
29
+ "chat bubbles",
30
+ "paragraph layout"
31
+ ]
32
+ };
33
+ const CHAT_MESSAGES = [
34
+ {
35
+ sender: "Alice",
36
+ text: "Hey!"
37
+ },
38
+ {
39
+ sender: "Bob",
40
+ text: "What are you working on?"
41
+ },
42
+ {
43
+ sender: "Alice",
44
+ text: "Building a terminal UI framework with beautiful text layout."
45
+ },
46
+ {
47
+ sender: "Bob",
48
+ text: "That sounds interesting. Does it handle word wrapping well? Most terminal apps have really ugly ragged text."
49
+ },
50
+ {
51
+ sender: "Alice",
52
+ text: "Yes! It uses Pretext-inspired algorithms for snug bubbles and even line breaking."
53
+ }
54
+ ];
55
+ const PARAGRAPH = "The quick brown fox jumps over the lazy dog. Typography in terminal applications has always been limited by the character grid, but modern algorithms can distribute text across lines for minimum raggedness, producing results that rival print-quality typesetting. Silvery brings these techniques to the terminal.";
56
+ /** A single chat bubble with configurable width and wrap mode. */
57
+ function Bubble({ sender, text, width, wrap, align }) {
58
+ return /* @__PURE__ */ jsxs(Box, {
59
+ flexDirection: "column",
60
+ alignItems: align ?? "flex-start",
61
+ children: [/* @__PURE__ */ jsxs(Small, { children: [" ", sender] }), /* @__PURE__ */ jsx(Box, {
62
+ width,
63
+ borderStyle: "round",
64
+ borderColor: "$border",
65
+ paddingX: 1,
66
+ maxWidth: 48,
67
+ children: /* @__PURE__ */ jsx(Text, {
68
+ wrap: wrap ?? "wrap",
69
+ children: text
70
+ })
71
+ })]
72
+ });
73
+ }
74
+ /** Column of chat bubbles with a label. */
75
+ function BubbleColumn({ label, sublabel, width, wrap }) {
76
+ return /* @__PURE__ */ jsxs(Box, {
77
+ flexDirection: "column",
78
+ flexGrow: 1,
79
+ flexBasis: 0,
80
+ children: [
81
+ /* @__PURE__ */ jsx(Text, {
82
+ bold: true,
83
+ color: "$accent",
84
+ children: label
85
+ }),
86
+ /* @__PURE__ */ jsx(Muted, { children: sublabel }),
87
+ /* @__PURE__ */ jsx(Text, { children: " " }),
88
+ /* @__PURE__ */ jsx(Box, {
89
+ flexDirection: "column",
90
+ gap: 1,
91
+ children: CHAT_MESSAGES.map((msg, i) => /* @__PURE__ */ jsx(Bubble, {
92
+ sender: msg.sender,
93
+ text: msg.text,
94
+ width,
95
+ wrap,
96
+ align: msg.sender === "Bob" ? "flex-end" : "flex-start"
97
+ }, i))
98
+ })
99
+ ]
100
+ });
101
+ }
102
+ /** Side-by-side paragraph comparison. */
103
+ function ParagraphComparison({ label, sublabel, wrap }) {
104
+ return /* @__PURE__ */ jsxs(Box, {
105
+ flexDirection: "column",
106
+ flexGrow: 1,
107
+ flexBasis: 0,
108
+ children: [
109
+ /* @__PURE__ */ jsx(Text, {
110
+ bold: true,
111
+ color: "$accent",
112
+ children: label
113
+ }),
114
+ /* @__PURE__ */ jsx(Muted, { children: sublabel }),
115
+ /* @__PURE__ */ jsx(Text, { children: " " }),
116
+ /* @__PURE__ */ jsx(Box, {
117
+ width: 52,
118
+ borderStyle: "single",
119
+ borderColor: "$border",
120
+ paddingX: 1,
121
+ children: /* @__PURE__ */ jsx(Text, {
122
+ wrap,
123
+ children: PARAGRAPH
124
+ })
125
+ })
126
+ ]
127
+ });
128
+ }
129
+ function Demo1Bubbles() {
130
+ return /* @__PURE__ */ jsxs(Box, {
131
+ flexDirection: "column",
132
+ children: [
133
+ /* @__PURE__ */ jsx(H2, { children: "Chat Bubbles: fit-content vs snug-content" }),
134
+ /* @__PURE__ */ jsxs(Muted, { children: [" ", "fit-content sizes to the widest wrapped line (dead space on short lines)."] }),
135
+ /* @__PURE__ */ jsxs(Muted, { children: [" ", "snug-content binary-searches for the tightest width with the same line count."] }),
136
+ /* @__PURE__ */ jsx(Text, { children: " " }),
137
+ /* @__PURE__ */ jsxs(Box, {
138
+ flexDirection: "row",
139
+ gap: 3,
140
+ paddingX: 1,
141
+ children: [/* @__PURE__ */ jsx(BubbleColumn, {
142
+ label: "width=\"fit-content\"",
143
+ sublabel: "CSS default — dead space",
144
+ width: "fit-content"
145
+ }), /* @__PURE__ */ jsx(BubbleColumn, {
146
+ label: "width=\"snug-content\"",
147
+ sublabel: "Pretext shrinkwrap — tight",
148
+ width: "snug-content"
149
+ })]
150
+ })
151
+ ]
152
+ });
153
+ }
154
+ function Demo2EvenWrap() {
155
+ return /* @__PURE__ */ jsxs(Box, {
156
+ flexDirection: "column",
157
+ children: [
158
+ /* @__PURE__ */ jsx(H2, { children: "Paragraph Layout: greedy vs even wrapping" }),
159
+ /* @__PURE__ */ jsxs(Muted, { children: [" ", "Greedy fills each line left-to-right, leaving a ragged right edge."] }),
160
+ /* @__PURE__ */ jsxs(Muted, { children: [" ", "Even uses minimum-raggedness DP to distribute words across all lines."] }),
161
+ /* @__PURE__ */ jsx(Text, { children: " " }),
162
+ /* @__PURE__ */ jsxs(Box, {
163
+ flexDirection: "row",
164
+ gap: 3,
165
+ paddingX: 1,
166
+ children: [/* @__PURE__ */ jsx(ParagraphComparison, {
167
+ label: "wrap=\"wrap\"",
168
+ sublabel: "Greedy — ragged right edge",
169
+ wrap: "wrap"
170
+ }), /* @__PURE__ */ jsx(ParagraphComparison, {
171
+ label: "wrap=\"even\"",
172
+ sublabel: "Min-raggedness — balanced lines",
173
+ wrap: "even"
174
+ })]
175
+ })
176
+ ]
177
+ });
178
+ }
179
+ function Demo3Combined() {
180
+ return /* @__PURE__ */ jsxs(Box, {
181
+ flexDirection: "column",
182
+ children: [
183
+ /* @__PURE__ */ jsx(H2, { children: "Combined: snug-content + even wrapping" }),
184
+ /* @__PURE__ */ jsxs(Muted, { children: [" ", "The tightest, most beautiful text layout — both features together."] }),
185
+ /* @__PURE__ */ jsx(Text, { children: " " }),
186
+ /* @__PURE__ */ jsxs(Box, {
187
+ flexDirection: "row",
188
+ gap: 3,
189
+ paddingX: 1,
190
+ children: [/* @__PURE__ */ jsxs(Box, {
191
+ flexDirection: "column",
192
+ flexGrow: 1,
193
+ flexBasis: 0,
194
+ children: [
195
+ /* @__PURE__ */ jsx(Text, {
196
+ bold: true,
197
+ color: "$accent",
198
+ children: "Default (fit-content + greedy)"
199
+ }),
200
+ /* @__PURE__ */ jsx(Muted, { children: "Widest line sets width, lines fill greedily" }),
201
+ /* @__PURE__ */ jsx(Text, { children: " " }),
202
+ /* @__PURE__ */ jsxs(Box, {
203
+ flexDirection: "column",
204
+ gap: 1,
205
+ children: [/* @__PURE__ */ jsx(Box, {
206
+ width: "fit-content",
207
+ borderStyle: "round",
208
+ borderColor: "$border",
209
+ paddingX: 1,
210
+ maxWidth: 48,
211
+ children: /* @__PURE__ */ jsx(Text, {
212
+ wrap: "wrap",
213
+ children: "Typography in terminal applications has always been limited by the character grid, but modern algorithms change that."
214
+ })
215
+ }), /* @__PURE__ */ jsx(Box, {
216
+ width: "fit-content",
217
+ borderStyle: "round",
218
+ borderColor: "$border",
219
+ paddingX: 1,
220
+ maxWidth: 48,
221
+ children: /* @__PURE__ */ jsx(Text, {
222
+ wrap: "wrap",
223
+ children: "Silvery brings Pretext-inspired layout to the terminal with two simple props."
224
+ })
225
+ })]
226
+ })
227
+ ]
228
+ }), /* @__PURE__ */ jsxs(Box, {
229
+ flexDirection: "column",
230
+ flexGrow: 1,
231
+ flexBasis: 0,
232
+ children: [
233
+ /* @__PURE__ */ jsx(Text, {
234
+ bold: true,
235
+ color: "$accent",
236
+ children: "Pretext (snug-content + even)"
237
+ }),
238
+ /* @__PURE__ */ jsx(Muted, { children: "Tightest width, balanced line lengths" }),
239
+ /* @__PURE__ */ jsx(Text, { children: " " }),
240
+ /* @__PURE__ */ jsxs(Box, {
241
+ flexDirection: "column",
242
+ gap: 1,
243
+ children: [/* @__PURE__ */ jsx(Box, {
244
+ width: "snug-content",
245
+ borderStyle: "round",
246
+ borderColor: "$primary",
247
+ paddingX: 1,
248
+ maxWidth: 48,
249
+ children: /* @__PURE__ */ jsx(Text, {
250
+ wrap: "even",
251
+ children: "Typography in terminal applications has always been limited by the character grid, but modern algorithms change that."
252
+ })
253
+ }), /* @__PURE__ */ jsx(Box, {
254
+ width: "snug-content",
255
+ borderStyle: "round",
256
+ borderColor: "$primary",
257
+ paddingX: 1,
258
+ maxWidth: 48,
259
+ children: /* @__PURE__ */ jsx(Text, {
260
+ wrap: "even",
261
+ children: "Silvery brings Pretext-inspired layout to the terminal with two simple props."
262
+ })
263
+ })]
264
+ })
265
+ ]
266
+ })]
267
+ })
268
+ ]
269
+ });
270
+ }
271
+ const DEMOS = [
272
+ Demo1Bubbles,
273
+ Demo2EvenWrap,
274
+ Demo3Combined
275
+ ];
276
+ const DEMO_LABELS = [
277
+ "Chat Bubbles",
278
+ "Even Wrapping",
279
+ "Combined"
280
+ ];
281
+ function PretextDemo() {
282
+ const [demoIndex, setDemoIndex] = useState(0);
283
+ useInput$1(useCallback((input, key) => {
284
+ if (input === "q" || key.escape) return "exit";
285
+ if (input === "j" || key.downArrow || key.rightArrow) setDemoIndex((i) => Math.min(i + 1, DEMOS.length - 1));
286
+ if (input === "k" || key.upArrow || key.leftArrow) setDemoIndex((i) => Math.max(i - 1, 0));
287
+ if (input === "1") setDemoIndex(0);
288
+ if (input === "2") setDemoIndex(1);
289
+ if (input === "3") setDemoIndex(2);
290
+ }, []));
291
+ const Demo = DEMOS[demoIndex];
292
+ return /* @__PURE__ */ jsxs(Box, {
293
+ flexDirection: "column",
294
+ padding: 1,
295
+ gap: 1,
296
+ children: [
297
+ /* @__PURE__ */ jsx(Box, {
298
+ gap: 2,
299
+ children: DEMO_LABELS.map((label, i) => /* @__PURE__ */ jsxs(Text, {
300
+ bold: i === demoIndex,
301
+ color: i === demoIndex ? "$primary" : "$muted",
302
+ children: [
303
+ i === demoIndex ? "▸ " : " ",
304
+ i + 1,
305
+ ". ",
306
+ label
307
+ ]
308
+ }, i))
309
+ }),
310
+ /* @__PURE__ */ jsx(Divider, {}),
311
+ /* @__PURE__ */ jsx(Demo, {}),
312
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Muted, { children: [
313
+ " ",
314
+ /* @__PURE__ */ jsx(Kbd, { children: "j/k" }),
315
+ " or ",
316
+ /* @__PURE__ */ jsx(Kbd, { children: "1-3" }),
317
+ " switch demo",
318
+ " ",
319
+ /* @__PURE__ */ jsx(Kbd, { children: "Esc/q" }),
320
+ " quit"
321
+ ] }) })
322
+ ]
323
+ });
324
+ }
325
+ async function main() {
326
+ await (await run(/* @__PURE__ */ jsx(ExampleBanner, {
327
+ meta,
328
+ controls: "j/k switch demo 1-3 jump Esc/q quit",
329
+ children: /* @__PURE__ */ jsx(PretextDemo, {})
330
+ }))).waitUntilExit();
331
+ }
332
+ if (import.meta.main) await main();
333
+ //#endregion
334
+ export { main, meta };