@plures/design-dojo 0.5.2 → 0.7.1

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 (250) hide show
  1. package/dist/app/CanvasBreadcrumb.svelte +146 -0
  2. package/dist/app/CanvasBreadcrumb.svelte.d.ts +19 -0
  3. package/dist/app/CanvasBreadcrumb.types.js +1 -0
  4. package/dist/app/ChatInput.svelte +296 -0
  5. package/dist/app/ChatInput.svelte.d.ts +15 -0
  6. package/dist/app/ChatView.svelte +542 -0
  7. package/dist/app/ChatView.svelte.d.ts +19 -0
  8. package/dist/app/ChatView.types.js +1 -0
  9. package/dist/app/ConversationGraph.svelte +471 -0
  10. package/dist/app/ConversationGraph.svelte.d.ts +20 -0
  11. package/dist/app/FirstRunWizard.svelte +542 -0
  12. package/dist/app/FirstRunWizard.svelte.d.ts +10 -0
  13. package/dist/app/FirstRunWizard.types.js +1 -0
  14. package/dist/app/MemorySidebar.svelte +258 -0
  15. package/dist/app/MemorySidebar.svelte.d.ts +9 -0
  16. package/dist/app/MemorySidebar.types.js +1 -0
  17. package/dist/app/PeerStatusPanel.svelte +464 -0
  18. package/dist/app/PeerStatusPanel.svelte.d.ts +16 -0
  19. package/dist/app/ProcedureCanvas.svelte +994 -0
  20. package/dist/app/ProcedureCanvas.svelte.d.ts +12 -0
  21. package/dist/app/ProcedureCanvas.types.js +1 -0
  22. package/dist/app/ProcedureEditor.svelte +494 -0
  23. package/dist/app/ProcedureEditor.svelte.d.ts +11 -0
  24. package/dist/app/ProcedureEditor.types.js +1 -0
  25. package/dist/app/ProcedureInspector.svelte +520 -0
  26. package/dist/app/ProcedureInspector.svelte.d.ts +15 -0
  27. package/dist/app/ProcedureNode.svelte +283 -0
  28. package/dist/app/ProcedureNode.svelte.d.ts +26 -0
  29. package/dist/app/Realm.types.js +1 -0
  30. package/dist/app/RealmIndicator.svelte +81 -0
  31. package/dist/app/RealmIndicator.svelte.d.ts +10 -0
  32. package/dist/app/RealmSwitcher.svelte +354 -0
  33. package/dist/app/RealmSwitcher.svelte.d.ts +16 -0
  34. package/dist/app/SemanticConversation.types.js +1 -0
  35. package/dist/app/SemanticSearchInput.svelte +630 -0
  36. package/dist/app/SemanticSearchInput.svelte.d.ts +20 -0
  37. package/dist/app/SemanticSearchInput.types.js +1 -0
  38. package/dist/app/SemanticTimeline.svelte +426 -0
  39. package/dist/app/SemanticTimeline.svelte.d.ts +13 -0
  40. package/dist/app/SettingsPanel.svelte +330 -0
  41. package/dist/app/SettingsPanel.svelte.d.ts +12 -0
  42. package/dist/app/SettingsPanel.types.js +1 -0
  43. package/dist/app/SubCanvas.svelte +457 -0
  44. package/dist/app/SubCanvas.svelte.d.ts +48 -0
  45. package/dist/app/SubCanvas.types.js +1 -0
  46. package/dist/app/Sync.types.js +1 -0
  47. package/dist/app/SyncIndicator.svelte +219 -0
  48. package/dist/app/SyncIndicator.svelte.d.ts +15 -0
  49. package/dist/app/SyncTimeline.svelte +299 -0
  50. package/dist/app/SyncTimeline.svelte.d.ts +12 -0
  51. package/dist/app/TagCloud.svelte +287 -0
  52. package/dist/app/TagCloud.svelte.d.ts +12 -0
  53. package/dist/app/WorkModeToggle.svelte +188 -0
  54. package/dist/app/WorkModeToggle.svelte.d.ts +17 -0
  55. package/dist/data/List.svelte +104 -0
  56. package/dist/data/List.svelte.d.ts +18 -0
  57. package/dist/data/ListItem.svelte +130 -0
  58. package/dist/data/ListItem.svelte.d.ts +12 -0
  59. package/dist/data/Table.svelte +241 -0
  60. package/dist/data/Table.svelte.d.ts +17 -0
  61. package/dist/data/index.d.ts +3 -0
  62. package/dist/data/index.js +3 -0
  63. package/dist/disclosure/Accordion.svelte +48 -0
  64. package/dist/disclosure/Accordion.svelte.d.ts +15 -0
  65. package/dist/feedback/Badge.svelte +60 -0
  66. package/dist/feedback/Badge.svelte.d.ts +14 -0
  67. package/dist/feedback/Callout.svelte +52 -0
  68. package/dist/feedback/Callout.svelte.d.ts +12 -0
  69. package/dist/feedback/EmptyState.svelte +47 -0
  70. package/dist/feedback/EmptyState.svelte.d.ts +12 -0
  71. package/dist/feedback/ProgressBar.svelte +95 -0
  72. package/dist/feedback/ProgressBar.svelte.d.ts +16 -0
  73. package/dist/forms/FileUpload.svelte +99 -0
  74. package/dist/forms/FileUpload.svelte.d.ts +18 -0
  75. package/dist/forms/RadioGroup.svelte +84 -0
  76. package/dist/forms/RadioGroup.svelte.d.ts +19 -0
  77. package/dist/icons/NerdFont.svelte +44 -0
  78. package/dist/icons/NerdFont.svelte.d.ts +13 -0
  79. package/dist/icons/index.d.ts +1 -0
  80. package/dist/icons/index.js +1 -0
  81. package/dist/index.d.ts +76 -0
  82. package/dist/index.js +70 -6212
  83. package/dist/layout/Box.svelte +207 -0
  84. package/dist/layout/Box.svelte.d.ts +22 -0
  85. package/dist/layout/Sidebar.svelte +210 -0
  86. package/dist/layout/Sidebar.svelte.d.ts +22 -0
  87. package/dist/layout/SplitPane.svelte +64 -0
  88. package/dist/layout/SplitPane.svelte.d.ts +12 -0
  89. package/dist/layout/StatusBar.svelte +83 -0
  90. package/dist/layout/StatusBar.svelte.d.ts +12 -0
  91. package/dist/layout/StatusBarItem.svelte +146 -0
  92. package/dist/layout/StatusBarItem.svelte.d.ts +15 -0
  93. package/dist/layout/StatusBarSpacer.svelte +38 -0
  94. package/dist/layout/StatusBarSpacer.svelte.d.ts +3 -0
  95. package/dist/layout/Tabs.svelte +254 -0
  96. package/dist/layout/Tabs.svelte.d.ts +21 -0
  97. package/dist/layout/Tabs.types.js +1 -0
  98. package/dist/layout/TitleBar.svelte +422 -0
  99. package/dist/layout/TitleBar.svelte.d.ts +22 -0
  100. package/dist/layout/index.d.ts +9 -0
  101. package/dist/layout/index.js +8 -0
  102. package/dist/motion/index.d.ts +1 -0
  103. package/dist/motion/index.js +1 -0
  104. package/dist/motion/spring.js +116 -0
  105. package/dist/overlays/ContextMenu.svelte +268 -0
  106. package/dist/overlays/ContextMenu.svelte.d.ts +17 -0
  107. package/dist/overlays/Dialog.svelte +264 -0
  108. package/dist/overlays/Dialog.svelte.d.ts +20 -0
  109. package/dist/overlays/Menu.svelte +274 -0
  110. package/dist/overlays/Menu.svelte.d.ts +26 -0
  111. package/dist/overlays/Menu.types.js +1 -0
  112. package/dist/overlays/Popover.svelte +158 -0
  113. package/dist/overlays/Popover.svelte.d.ts +21 -0
  114. package/dist/overlays/Toast.svelte +179 -0
  115. package/dist/overlays/Toast.svelte.d.ts +19 -0
  116. package/dist/overlays/Tooltip.svelte +114 -0
  117. package/dist/overlays/Tooltip.svelte.d.ts +17 -0
  118. package/dist/overlays/index.d.ts +7 -0
  119. package/dist/overlays/index.js +6 -0
  120. package/dist/primitives/Button.svelte +217 -0
  121. package/dist/primitives/Button.svelte.d.ts +13 -0
  122. package/dist/primitives/ContextMenu.svelte +242 -0
  123. package/dist/primitives/ContextMenu.svelte.d.ts +18 -0
  124. package/dist/primitives/ContextMenu.types.js +1 -0
  125. package/dist/primitives/Input.svelte +468 -0
  126. package/dist/primitives/Input.svelte.d.ts +21 -0
  127. package/dist/primitives/MarkdownEditor.svelte +781 -0
  128. package/dist/primitives/MarkdownEditor.svelte.d.ts +21 -0
  129. package/dist/primitives/MarkdownEditor.types.js +1 -0
  130. package/dist/primitives/SearchInput.svelte +623 -0
  131. package/dist/primitives/SearchInput.svelte.d.ts +24 -0
  132. package/dist/primitives/Select.svelte +336 -0
  133. package/dist/primitives/Select.svelte.d.ts +18 -0
  134. package/dist/primitives/Text.svelte +177 -0
  135. package/dist/primitives/Text.svelte.d.ts +26 -0
  136. package/dist/primitives/Toggle.svelte +138 -0
  137. package/dist/primitives/Toggle.svelte.d.ts +9 -0
  138. package/dist/primitives/index.d.ts +9 -0
  139. package/dist/primitives/index.js +7 -0
  140. package/dist/primitives/search-input-types.js +1 -0
  141. package/dist/surfaces/ChatPane.svelte +520 -0
  142. package/dist/surfaces/ChatPane.svelte.d.ts +15 -0
  143. package/dist/surfaces/ChatPane.types.js +1 -0
  144. package/dist/surfaces/GlassPanel.svelte +118 -0
  145. package/dist/surfaces/GlassPanel.svelte.d.ts +19 -0
  146. package/dist/surfaces/Pane.svelte +172 -0
  147. package/dist/surfaces/Pane.svelte.d.ts +25 -0
  148. package/dist/surfaces/index.d.ts +4 -0
  149. package/dist/surfaces/index.js +3 -0
  150. package/dist/telemetry/correlation.js +26 -0
  151. package/dist/telemetry/index.d.ts +4 -4
  152. package/dist/telemetry/index.js +20 -101
  153. package/dist/telemetry/sampling.js +58 -0
  154. package/dist/telemetry/tracer.d.ts +16 -1
  155. package/dist/telemetry/tracer.js +112 -0
  156. package/dist/tokens.css +123 -0
  157. package/dist/tui-tokens.css +36 -0
  158. package/dist/useTui.js +31 -0
  159. package/package.json +32 -22
  160. package/dist/design-dojo.css +0 -1
  161. package/dist/enforce/index.d.ts +0 -75
  162. package/dist/enforce/known-components.d.ts +0 -7
  163. package/dist/enforce/rules/no-local-components.d.ts +0 -29
  164. package/dist/enforce/rules/prefer-design-dojo-imports.d.ts +0 -27
  165. package/dist/enforce.js +0 -132
  166. package/dist/lib/app/CanvasBreadcrumb.svelte.d.ts +0 -1
  167. package/dist/lib/app/ChatInput.svelte.d.ts +0 -1
  168. package/dist/lib/app/ChatView.svelte.d.ts +0 -1
  169. package/dist/lib/app/ConversationGraph.svelte.d.ts +0 -1
  170. package/dist/lib/app/FirstRunWizard.svelte.d.ts +0 -1
  171. package/dist/lib/app/MemorySidebar.svelte.d.ts +0 -1
  172. package/dist/lib/app/PeerStatusPanel.svelte.d.ts +0 -1
  173. package/dist/lib/app/ProcedureCanvas.svelte.d.ts +0 -1
  174. package/dist/lib/app/ProcedureEditor.svelte.d.ts +0 -1
  175. package/dist/lib/app/ProcedureInspector.svelte.d.ts +0 -1
  176. package/dist/lib/app/ProcedureNode.svelte.d.ts +0 -1
  177. package/dist/lib/app/RealmIndicator.svelte.d.ts +0 -1
  178. package/dist/lib/app/RealmSwitcher.svelte.d.ts +0 -1
  179. package/dist/lib/app/SemanticSearchInput.svelte.d.ts +0 -1
  180. package/dist/lib/app/SemanticTimeline.svelte.d.ts +0 -1
  181. package/dist/lib/app/SettingsPanel.svelte.d.ts +0 -1
  182. package/dist/lib/app/SubCanvas.svelte.d.ts +0 -1
  183. package/dist/lib/app/SyncIndicator.svelte.d.ts +0 -1
  184. package/dist/lib/app/SyncTimeline.svelte.d.ts +0 -1
  185. package/dist/lib/app/TagCloud.svelte.d.ts +0 -1
  186. package/dist/lib/app/WorkModeToggle.svelte.d.ts +0 -1
  187. package/dist/lib/data/List.svelte.d.ts +0 -1
  188. package/dist/lib/data/ListItem.svelte.d.ts +0 -1
  189. package/dist/lib/data/Table.svelte.d.ts +0 -1
  190. package/dist/lib/data/index.d.ts +0 -3
  191. package/dist/lib/disclosure/Accordion.svelte.d.ts +0 -1
  192. package/dist/lib/feedback/Badge.svelte.d.ts +0 -1
  193. package/dist/lib/feedback/Callout.svelte.d.ts +0 -1
  194. package/dist/lib/feedback/EmptyState.svelte.d.ts +0 -1
  195. package/dist/lib/feedback/ProgressBar.svelte.d.ts +0 -1
  196. package/dist/lib/forms/FileUpload.svelte.d.ts +0 -1
  197. package/dist/lib/forms/RadioGroup.svelte.d.ts +0 -1
  198. package/dist/lib/icons/NerdFont.svelte.d.ts +0 -1
  199. package/dist/lib/icons/index.d.ts +0 -1
  200. package/dist/lib/index.d.ts +0 -76
  201. package/dist/lib/layout/Box.svelte.d.ts +0 -1
  202. package/dist/lib/layout/Sidebar.svelte.d.ts +0 -1
  203. package/dist/lib/layout/SplitPane.svelte.d.ts +0 -1
  204. package/dist/lib/layout/StatusBar.svelte.d.ts +0 -1
  205. package/dist/lib/layout/StatusBarItem.svelte.d.ts +0 -1
  206. package/dist/lib/layout/StatusBarSpacer.svelte.d.ts +0 -1
  207. package/dist/lib/layout/Tabs.svelte.d.ts +0 -1
  208. package/dist/lib/layout/TitleBar.svelte.d.ts +0 -1
  209. package/dist/lib/layout/index.d.ts +0 -9
  210. package/dist/lib/motion/index.d.ts +0 -1
  211. package/dist/lib/overlays/ContextMenu.svelte.d.ts +0 -1
  212. package/dist/lib/overlays/Dialog.svelte.d.ts +0 -1
  213. package/dist/lib/overlays/Menu.svelte.d.ts +0 -1
  214. package/dist/lib/overlays/Popover.svelte.d.ts +0 -1
  215. package/dist/lib/overlays/Toast.svelte.d.ts +0 -1
  216. package/dist/lib/overlays/Tooltip.svelte.d.ts +0 -1
  217. package/dist/lib/overlays/index.d.ts +0 -7
  218. package/dist/lib/primitives/Button.svelte.d.ts +0 -1
  219. package/dist/lib/primitives/ContextMenu.svelte.d.ts +0 -1
  220. package/dist/lib/primitives/Input.svelte.d.ts +0 -1
  221. package/dist/lib/primitives/MarkdownEditor.svelte.d.ts +0 -1
  222. package/dist/lib/primitives/SearchInput.svelte.d.ts +0 -1
  223. package/dist/lib/primitives/Select.svelte.d.ts +0 -1
  224. package/dist/lib/primitives/Text.svelte.d.ts +0 -1
  225. package/dist/lib/primitives/Toggle.svelte.d.ts +0 -1
  226. package/dist/lib/primitives/index.d.ts +0 -9
  227. package/dist/lib/surfaces/ChatPane.svelte.d.ts +0 -1
  228. package/dist/lib/surfaces/GlassPanel.svelte.d.ts +0 -1
  229. package/dist/lib/surfaces/Pane.svelte.d.ts +0 -1
  230. package/dist/lib/surfaces/index.d.ts +0 -4
  231. /package/dist/{lib/app → app}/CanvasBreadcrumb.types.d.ts +0 -0
  232. /package/dist/{lib/app → app}/ChatView.types.d.ts +0 -0
  233. /package/dist/{lib/app → app}/FirstRunWizard.types.d.ts +0 -0
  234. /package/dist/{lib/app → app}/MemorySidebar.types.d.ts +0 -0
  235. /package/dist/{lib/app → app}/ProcedureCanvas.types.d.ts +0 -0
  236. /package/dist/{lib/app → app}/ProcedureEditor.types.d.ts +0 -0
  237. /package/dist/{lib/app → app}/Realm.types.d.ts +0 -0
  238. /package/dist/{lib/app → app}/SemanticConversation.types.d.ts +0 -0
  239. /package/dist/{lib/app → app}/SemanticSearchInput.types.d.ts +0 -0
  240. /package/dist/{lib/app → app}/SettingsPanel.types.d.ts +0 -0
  241. /package/dist/{lib/app → app}/SubCanvas.types.d.ts +0 -0
  242. /package/dist/{lib/app → app}/Sync.types.d.ts +0 -0
  243. /package/dist/{lib/layout → layout}/Tabs.types.d.ts +0 -0
  244. /package/dist/{lib/motion → motion}/spring.d.ts +0 -0
  245. /package/dist/{lib/overlays → overlays}/Menu.types.d.ts +0 -0
  246. /package/dist/{lib/primitives → primitives}/ContextMenu.types.d.ts +0 -0
  247. /package/dist/{lib/primitives → primitives}/MarkdownEditor.types.d.ts +0 -0
  248. /package/dist/{lib/primitives → primitives}/search-input-types.d.ts +0 -0
  249. /package/dist/{lib/surfaces → surfaces}/ChatPane.types.d.ts +0 -0
  250. /package/dist/{lib/useTui.d.ts → useTui.d.ts} +0 -0
@@ -0,0 +1,207 @@
1
+ <!--
2
+ Box — Foundational container component.
3
+
4
+ Maps to ratatui::widgets::Block in TUI mode.
5
+ Surface panel (or glassmorphism) in GUI mode.
6
+
7
+ TUI mode:
8
+ Box-drawing borders with optional title. Supports single, double, bold,
9
+ dashed, rounded, and none border styles.
10
+
11
+ GUI mode:
12
+ Surface panel using --surface-1 background, --radius-md, --shadow-md.
13
+ If glass=true, uses GlassPanel (backdrop blur) internally.
14
+ -->
15
+ <script lang="ts">
16
+ import { useTui, provideTui } from "../useTui.js";
17
+ import GlassPanel from "../surfaces/GlassPanel.svelte";
18
+ import type { Snippet } from "svelte";
19
+
20
+ interface Props {
21
+ /** Enable TUI mode: box-drawing borders, terminal-safe colors. */
22
+ tui?: boolean;
23
+ /** Border style. Default: "rounded" (GUI), "single" (TUI). */
24
+ border?: "none" | "single" | "double" | "bold" | "dashed" | "rounded";
25
+ /** Title displayed in the top border (TUI) or as a header (GUI). */
26
+ title?: string;
27
+ /** Uniform padding. Multiples of 4px in GUI; character cells in TUI. */
28
+ padding?: number;
29
+ /** Width: CSS string in GUI mode, character columns as number in TUI mode (strings ignored in TUI). */
30
+ width?: string | number;
31
+ /** Height: CSS string in GUI mode. Ignored in TUI (content-driven). */
32
+ height?: string | number;
33
+ /** GUI only: use glassmorphism (GlassPanel) instead of flat surface. */
34
+ glass?: boolean;
35
+ class?: string;
36
+ children: Snippet;
37
+ }
38
+
39
+ let {
40
+ tui = false,
41
+ border,
42
+ title,
43
+ padding,
44
+ width,
45
+ height,
46
+ glass = false,
47
+ class: className = "",
48
+ children: renderChildren,
49
+ }: Props = $props();
50
+
51
+ const getTuiCtx = useTui();
52
+ const isTui = $derived(tui || getTuiCtx());
53
+
54
+ // Propagate TUI mode to all descendant components.
55
+ provideTui(() => isTui);
56
+
57
+ const effectiveBorder = $derived(border ?? (isTui ? "single" : "rounded"));
58
+
59
+ // Border character sets: [h, v, top-left, top-right, bottom-left, bottom-right]
60
+ const BORDERS: Record<string, readonly [string, string, string, string, string, string]> = {
61
+ single: ["─", "│", "┌", "┐", "└", "┘"],
62
+ rounded: ["─", "│", "╭", "╮", "╰", "╯"],
63
+ double: ["═", "║", "╔", "╗", "╚", "╝"],
64
+ bold: ["━", "┃", "┏", "┓", "┗", "┛"],
65
+ dashed: ["╌", "╎", "┌", "┐", "└", "┘"],
66
+ none: ["", "", "", "", "", ""],
67
+ };
68
+
69
+ // In TUI mode, width as number = inner character columns.
70
+ const tuiCols = $derived(typeof width === "number" ? width : 30);
71
+ const bchars = $derived(BORDERS[effectiveBorder] ?? BORDERS["single"]);
72
+
73
+ function buildTopBorder(
74
+ chars: readonly [string, string, string, string, string, string],
75
+ cols: number,
76
+ t: string | undefined,
77
+ ): string {
78
+ const [h, , tl, tr] = chars;
79
+ if (!tl) return ""; // "none" border
80
+ if (t) {
81
+ const titleStr = ` ${t} `;
82
+ const remaining = Math.max(0, cols - titleStr.length - 1);
83
+ return `${tl}${h}${titleStr}${h.repeat(remaining)}${tr}`;
84
+ }
85
+ return `${tl}${h.repeat(cols)}${tr}`;
86
+ }
87
+
88
+ function buildBottomBorder(
89
+ chars: readonly [string, string, string, string, string, string],
90
+ cols: number,
91
+ ): string {
92
+ const [h, , , , bl, br] = chars;
93
+ if (!bl) return ""; // "none" border
94
+ return `${bl}${h.repeat(cols)}${br}`;
95
+ }
96
+
97
+ // GUI mode styles
98
+ const guiWidth = $derived(
99
+ typeof width === "number" ? `${width}px` : (width ?? undefined),
100
+ );
101
+ const guiHeight = $derived(
102
+ typeof height === "number" ? `${height}px` : (height ?? undefined),
103
+ );
104
+ const guiPadding = $derived(
105
+ padding !== undefined ? `${padding * 4}px` : "var(--space-4, 16px)",
106
+ );
107
+
108
+ // Map border style to CSS border + border-radius for GUI mode
109
+ const guiBorderStyle = $derived(
110
+ ({
111
+ none: { border: "none", radius: "0" },
112
+ single: { border: "1px solid var(--color-border, #2a2a2a)", radius: "0" },
113
+ rounded: { border: "1px solid var(--color-border, #2a2a2a)", radius: "var(--radius-md, 10px)" },
114
+ double: { border: "3px double var(--color-border, #2a2a2a)", radius: "0" },
115
+ bold: { border: "2px solid var(--color-border, #2a2a2a)", radius: "0" },
116
+ dashed: { border: "1px dashed var(--color-border, #2a2a2a)", radius: "0" },
117
+ } as Record<string, { border: string; radius: string }>)[effectiveBorder] ??
118
+ { border: "1px solid var(--color-border, #2a2a2a)", radius: "var(--radius-md, 10px)" },
119
+ );
120
+
121
+ // TUI padding: horizontal = padding ch, vertical = padding * 0.5em
122
+ const tuiContentPadding = $derived(
123
+ padding !== undefined && padding > 0 ? `${padding * 0.5}em ${padding}ch` : "0",
124
+ );
125
+ </script>
126
+
127
+ {#if isTui}
128
+ <div
129
+ class="tui-box {className}"
130
+ style:width={typeof width === "number" ? `${width}ch` : undefined}
131
+ >
132
+ {#if effectiveBorder !== "none"}
133
+ <div class="tui-border" aria-hidden="true">{buildTopBorder(bchars, tuiCols, title)}</div>
134
+ {/if}
135
+ <div class="tui-body">
136
+ {#if effectiveBorder !== "none"}
137
+ <span class="tui-side" aria-hidden="true">{bchars[1]}</span>
138
+ {/if}
139
+ <div class="tui-content" style:padding={tuiContentPadding}>
140
+ {@render renderChildren()}
141
+ </div>
142
+ {#if effectiveBorder !== "none"}
143
+ <span class="tui-side" aria-hidden="true">{bchars[1]}</span>
144
+ {/if}
145
+ </div>
146
+ {#if effectiveBorder !== "none"}
147
+ <div class="tui-border" aria-hidden="true">{buildBottomBorder(bchars, tuiCols)}</div>
148
+ {/if}
149
+ </div>
150
+ {:else if glass}
151
+ <div class="box {className}">
152
+ <GlassPanel padding={guiPadding}>
153
+ {#snippet children()}
154
+ {@render renderChildren()}
155
+ {/snippet}
156
+ </GlassPanel>
157
+ </div>
158
+ {:else}
159
+ <div
160
+ class="box {className}"
161
+ style:width={guiWidth}
162
+ style:height={guiHeight}
163
+ style:padding={guiPadding}
164
+ style:border={guiBorderStyle.border}
165
+ style:border-radius={guiBorderStyle.radius}
166
+ >
167
+ {@render renderChildren()}
168
+ </div>
169
+ {/if}
170
+
171
+ <style>
172
+ /* ===== GUI mode ===== */
173
+ .box {
174
+ background: var(--surface-1, #141414);
175
+ box-shadow: var(--shadow-md, 0 4px 6px rgba(0,0,0,0.05), 0 10px 15px rgba(0,0,0,0.1));
176
+ }
177
+
178
+ /* ===== TUI mode ===== */
179
+ .tui-box {
180
+ display: inline-block;
181
+ font-family: var(--font-mono, monospace);
182
+ color: var(--tui-text, #e0e0e0);
183
+ background: var(--tui-surface, #16213e);
184
+ }
185
+
186
+ .tui-border {
187
+ color: var(--tui-border, #0f3460);
188
+ white-space: pre;
189
+ line-height: 1;
190
+ }
191
+
192
+ .tui-body {
193
+ display: flex;
194
+ align-items: stretch;
195
+ }
196
+
197
+ .tui-side {
198
+ color: var(--tui-border, #0f3460);
199
+ user-select: none;
200
+ line-height: 1;
201
+ }
202
+
203
+ .tui-content {
204
+ flex: 1;
205
+ min-width: 0;
206
+ }
207
+ </style>
@@ -0,0 +1,22 @@
1
+ import type { Snippet } from "svelte";
2
+ interface Props {
3
+ /** Enable TUI mode: box-drawing borders, terminal-safe colors. */
4
+ tui?: boolean;
5
+ /** Border style. Default: "rounded" (GUI), "single" (TUI). */
6
+ border?: "none" | "single" | "double" | "bold" | "dashed" | "rounded";
7
+ /** Title displayed in the top border (TUI) or as a header (GUI). */
8
+ title?: string;
9
+ /** Uniform padding. Multiples of 4px in GUI; character cells in TUI. */
10
+ padding?: number;
11
+ /** Width: CSS string in GUI mode, character columns as number in TUI mode (strings ignored in TUI). */
12
+ width?: string | number;
13
+ /** Height: CSS string in GUI mode. Ignored in TUI (content-driven). */
14
+ height?: string | number;
15
+ /** GUI only: use glassmorphism (GlassPanel) instead of flat surface. */
16
+ glass?: boolean;
17
+ class?: string;
18
+ children: Snippet;
19
+ }
20
+ declare const Box: import("svelte").Component<Props, {}, "">;
21
+ type Box = ReturnType<typeof Box>;
22
+ export default Box;
@@ -0,0 +1,210 @@
1
+ <!--
2
+ Sidebar — Collapsible side panel for navigation or context.
3
+
4
+ GUI mode: slide-in/out with width transition, respects prefers-reduced-motion.
5
+ TUI mode: fixed-width column with box-drawing border on the open edge.
6
+ -->
7
+ <script lang="ts">
8
+ import { useTui } from "../useTui.js";
9
+ import type { Snippet } from "svelte";
10
+
11
+ interface Props {
12
+ /** Side the sidebar is attached to. Default: "left". */
13
+ side?: "left" | "right";
14
+ /** Width in px when expanded (GUI only). Default: 240. */
15
+ width?: number;
16
+ /** Width in character columns when expanded (TUI only). Default: 24. */
17
+ cols?: number;
18
+ /** Whether the sidebar is collapsed. */
19
+ collapsed?: boolean;
20
+ /** Called when the user toggles the sidebar. */
21
+ ontoggle?: (collapsed: boolean) => void;
22
+ /** Enable TUI mode. */
23
+ tui?: boolean;
24
+ /** Sidebar content. */
25
+ children: Snippet;
26
+ /** Main content area to the right/left of the sidebar. */
27
+ main?: Snippet;
28
+ }
29
+
30
+ let {
31
+ side = "left",
32
+ width = 240,
33
+ cols = 24,
34
+ collapsed = $bindable(false),
35
+ ontoggle,
36
+ tui = false,
37
+ children,
38
+ main,
39
+ }: Props = $props();
40
+
41
+ const getTuiCtx = useTui();
42
+ const isTui = $derived(tui || getTuiCtx());
43
+
44
+ function toggle() {
45
+ collapsed = !collapsed;
46
+ ontoggle?.(collapsed);
47
+ }
48
+ </script>
49
+
50
+ <div class="sidebar-layout" class:sidebar-layout--tui={isTui} class:sidebar-layout--right={side === "right"}>
51
+ {#if isTui}
52
+ {#if !collapsed}
53
+ <div
54
+ class="tui-sidebar"
55
+ style:width="{cols}ch"
56
+ aria-label="Sidebar"
57
+ style:border-right={side === "left" ? "1px solid var(--tui-border, #0f3460)" : undefined}
58
+ style:border-left={side === "right" ? "1px solid var(--tui-border, #0f3460)" : undefined}
59
+ >
60
+ <button type="button" class="tui-toggle" aria-label={collapsed ? "Expand sidebar" : "Collapse sidebar"} onclick={toggle}>
61
+ {side === "left" ? "◀" : "▶"}
62
+ </button>
63
+ <div class="tui-sidebar-content">{@render children()}</div>
64
+ </div>
65
+ {:else}
66
+ <button type="button" class="tui-toggle tui-toggle--collapsed" aria-label="Expand sidebar" onclick={toggle}>
67
+ {side === "left" ? "▶" : "◀"}
68
+ </button>
69
+ {/if}
70
+ {:else}
71
+ <div
72
+ class="sidebar"
73
+ class:sidebar--collapsed={collapsed}
74
+ style:width={collapsed ? "0px" : `${width}px`}
75
+ aria-label="Sidebar"
76
+ aria-hidden={collapsed}
77
+ >
78
+ <div class="sidebar-inner">{@render children()}</div>
79
+ </div>
80
+ <button
81
+ type="button"
82
+ class="sidebar-toggle"
83
+ class:sidebar-toggle--right={side === "right"}
84
+ aria-label={collapsed ? "Expand sidebar" : "Collapse sidebar"}
85
+ aria-expanded={!collapsed}
86
+ onclick={toggle}
87
+ >
88
+ {#if side === "left"}
89
+ {collapsed ? "›" : "‹"}
90
+ {:else}
91
+ {collapsed ? "‹" : "›"}
92
+ {/if}
93
+ </button>
94
+ {/if}
95
+
96
+ {#if main}
97
+ <div class="sidebar-main" class:sidebar-main--tui={isTui}>
98
+ {@render main()}
99
+ </div>
100
+ {/if}
101
+ </div>
102
+
103
+ <style>
104
+ .sidebar-layout {
105
+ display: flex;
106
+ flex-direction: row;
107
+ height: 100%;
108
+ min-height: 0;
109
+ overflow: hidden;
110
+ position: relative;
111
+ }
112
+
113
+ .sidebar-layout--right { flex-direction: row-reverse; }
114
+
115
+ /* ===== GUI mode ===== */
116
+ .sidebar {
117
+ flex-shrink: 0;
118
+ overflow: hidden;
119
+ transition: width 0.2s ease;
120
+ background: var(--surface-1, #141414);
121
+ border-right: 1px solid var(--color-border, #2a2a2a);
122
+ }
123
+
124
+ .sidebar-layout--right .sidebar {
125
+ border-right: none;
126
+ border-left: 1px solid var(--color-border, #2a2a2a);
127
+ }
128
+
129
+ .sidebar-inner {
130
+ width: 100%;
131
+ padding: var(--space-3, 12px);
132
+ height: 100%;
133
+ overflow-y: auto;
134
+ }
135
+
136
+ .sidebar--collapsed { pointer-events: none; }
137
+
138
+ .sidebar-toggle {
139
+ position: absolute;
140
+ top: 50%;
141
+ left: 0;
142
+ transform: translateY(-50%);
143
+ z-index: 10;
144
+ background: var(--surface-2, #1e1e1e);
145
+ border: 1px solid var(--color-border, #2a2a2a);
146
+ border-radius: 0 var(--radius-sm, 6px) var(--radius-sm, 6px) 0;
147
+ color: var(--color-text-muted, #888);
148
+ cursor: pointer;
149
+ padding: var(--space-2, 8px) var(--space-1, 4px);
150
+ font-size: 12px;
151
+ line-height: 1;
152
+ outline: none;
153
+ }
154
+
155
+ .sidebar-toggle--right {
156
+ left: auto;
157
+ right: 0;
158
+ border-radius: var(--radius-sm, 6px) 0 0 var(--radius-sm, 6px);
159
+ }
160
+
161
+ .sidebar-toggle:hover { color: var(--color-text, #e8e8e8); }
162
+
163
+ .sidebar-toggle:focus-visible {
164
+ outline: var(--focus-ring-width, 3px) solid var(--color-focus-ring, #818cf8);
165
+ outline-offset: var(--focus-ring-offset, 2px);
166
+ }
167
+
168
+ .sidebar-main {
169
+ flex: 1;
170
+ min-width: 0;
171
+ overflow: auto;
172
+ }
173
+
174
+ /* ===== TUI mode ===== */
175
+ .tui-sidebar {
176
+ flex-shrink: 0;
177
+ display: flex;
178
+ flex-direction: column;
179
+ background: var(--tui-surface, #16213e);
180
+ font-family: var(--font-mono, monospace);
181
+ font-size: var(--text-sm, 14px);
182
+ color: var(--tui-text, #e0e0e0);
183
+ }
184
+
185
+ .tui-toggle {
186
+ background: none;
187
+ border: none;
188
+ cursor: pointer;
189
+ color: var(--tui-border, #0f3460);
190
+ font-family: var(--font-mono, monospace);
191
+ padding: 2px var(--space-1, 4px);
192
+ text-align: right;
193
+ outline: none;
194
+ }
195
+
196
+ .tui-toggle:hover { color: var(--tui-accent, #00d4ff); }
197
+ .tui-toggle:focus-visible { outline: 1px solid var(--tui-accent, #00d4ff); }
198
+
199
+ .tui-toggle--collapsed {
200
+ display: block;
201
+ padding: 2px var(--space-1, 4px);
202
+ }
203
+
204
+ .tui-sidebar-content { flex: 1; overflow-y: auto; padding: var(--space-1, 4px); }
205
+
206
+ .sidebar-main--tui {
207
+ background: var(--tui-bg, #1a1a2e);
208
+ color: var(--tui-text, #e0e0e0);
209
+ }
210
+ </style>
@@ -0,0 +1,22 @@
1
+ import type { Snippet } from "svelte";
2
+ interface Props {
3
+ /** Side the sidebar is attached to. Default: "left". */
4
+ side?: "left" | "right";
5
+ /** Width in px when expanded (GUI only). Default: 240. */
6
+ width?: number;
7
+ /** Width in character columns when expanded (TUI only). Default: 24. */
8
+ cols?: number;
9
+ /** Whether the sidebar is collapsed. */
10
+ collapsed?: boolean;
11
+ /** Called when the user toggles the sidebar. */
12
+ ontoggle?: (collapsed: boolean) => void;
13
+ /** Enable TUI mode. */
14
+ tui?: boolean;
15
+ /** Sidebar content. */
16
+ children: Snippet;
17
+ /** Main content area to the right/left of the sidebar. */
18
+ main?: Snippet;
19
+ }
20
+ declare const Sidebar: import("svelte").Component<Props, {}, "collapsed">;
21
+ type Sidebar = ReturnType<typeof Sidebar>;
22
+ export default Sidebar;
@@ -0,0 +1,64 @@
1
+ <!--
2
+ SplitPane — Divides the terminal/window into named Pane regions.
3
+
4
+ GUI mode: CSS flexbox container (flex-direction: row|column).
5
+ Child Panes use flex-grow for proportional sizing.
6
+ TUI mode: Same flexbox layout, styled with TUI tokens.
7
+ Maps to ratatui Layout::default().direction(…).constraints([…]).split(area)
8
+
9
+ Example — horizontal split:
10
+ <SplitPane direction="horizontal">
11
+ <Pane title="Sidebar" flex={3}>…</Pane>
12
+ <Pane title="Main" flex={7}>…</Pane>
13
+ </SplitPane>
14
+ -->
15
+ <script lang="ts">
16
+ import { provideTui, useTui } from "../useTui.js";
17
+ import type { Snippet } from "svelte";
18
+
19
+ interface Props {
20
+ /** Enable TUI mode: terminal-safe colors, no decorative CSS. */
21
+ tui?: boolean;
22
+ /** Split direction. Default: "horizontal". */
23
+ direction?: "horizontal" | "vertical";
24
+ class?: string;
25
+ children: Snippet;
26
+ }
27
+
28
+ let { tui = false, direction = "horizontal", class: className = "", children }: Props = $props();
29
+
30
+ const getTuiCtx = useTui();
31
+ const isTui = $derived(tui || getTuiCtx());
32
+
33
+ // Propagate TUI mode to all child Panes
34
+ provideTui(() => isTui);
35
+
36
+ const flexDir = $derived(direction === "vertical" ? "column" : "row");
37
+ </script>
38
+
39
+ <div
40
+ class="split-pane {className}"
41
+ class:split-pane--tui={isTui}
42
+ style:flex-direction={flexDir}
43
+ >
44
+ {@render children()}
45
+ </div>
46
+
47
+ <style>
48
+ .split-pane {
49
+ display: flex;
50
+ flex: 1;
51
+ width: 100%;
52
+ height: 100%;
53
+ min-width: 0;
54
+ min-height: 0;
55
+ overflow: hidden;
56
+ }
57
+
58
+ /* ===== TUI mode ===== */
59
+ .split-pane--tui {
60
+ background: var(--tui-bg, #1a1a2e);
61
+ font-family: var(--font-mono, monospace);
62
+ color: var(--tui-text, #e0e0e0);
63
+ }
64
+ </style>
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from "svelte";
2
+ interface Props {
3
+ /** Enable TUI mode: terminal-safe colors, no decorative CSS. */
4
+ tui?: boolean;
5
+ /** Split direction. Default: "horizontal". */
6
+ direction?: "horizontal" | "vertical";
7
+ class?: string;
8
+ children: Snippet;
9
+ }
10
+ declare const SplitPane: import("svelte").Component<Props, {}, "">;
11
+ type SplitPane = ReturnType<typeof SplitPane>;
12
+ export default SplitPane;
@@ -0,0 +1,83 @@
1
+ <!--
2
+ StatusBar — Fixed single-row bar for displaying status, labels, and indicators.
3
+
4
+ Maps to ratatui::widgets::Paragraph (styled row) or a row of Spans in TUI mode.
5
+
6
+ GUI mode: sticky position:fixed bar (top or bottom), flex row, --surface-1 background.
7
+ TUI mode: full-width row, --tui-bg background, │ separators between items.
8
+ -->
9
+ <script lang="ts">
10
+ import { provideTui, useTui } from "../useTui.js";
11
+ import type { Snippet } from "svelte";
12
+
13
+ interface Props {
14
+ /** Enable TUI mode: flat surface, terminal-safe colors, box-drawing separators. */
15
+ tui?: boolean;
16
+ /** Sticky position for GUI mode. Default: "bottom" */
17
+ position?: "top" | "bottom";
18
+ class?: string;
19
+ children: Snippet;
20
+ }
21
+
22
+ let { tui = false, position = "bottom", class: className = "", children }: Props = $props();
23
+
24
+ const getTuiCtx = useTui();
25
+ const isTui = $derived(tui || getTuiCtx());
26
+
27
+ provideTui(() => isTui);
28
+ </script>
29
+
30
+ <div
31
+ class="statusbar {className}"
32
+ class:tui={isTui}
33
+ class:gui={!isTui}
34
+ class:top={!isTui && position === "top"}
35
+ class:bottom={!isTui && position === "bottom"}
36
+ role="status"
37
+ aria-label="Status bar"
38
+ >
39
+ {@render children()}
40
+ </div>
41
+
42
+ <style>
43
+ .statusbar {
44
+ display: flex;
45
+ align-items: center;
46
+ width: 100%;
47
+ overflow: hidden;
48
+ white-space: nowrap;
49
+ box-sizing: border-box;
50
+ }
51
+
52
+ /* ===== GUI mode ===== */
53
+ .gui {
54
+ position: fixed;
55
+ left: 0;
56
+ right: 0;
57
+ height: 28px;
58
+ background: var(--surface-1, #141414);
59
+ z-index: 100;
60
+ padding: 0 var(--space-2, 8px);
61
+ gap: var(--space-1, 4px);
62
+ }
63
+
64
+ .gui.top {
65
+ top: 0;
66
+ border-bottom: 1px solid var(--color-border, #2a2a2a);
67
+ }
68
+
69
+ .gui.bottom {
70
+ bottom: 0;
71
+ border-top: 1px solid var(--color-border, #2a2a2a);
72
+ }
73
+
74
+ /* ===== TUI mode ===== */
75
+ .tui {
76
+ background: var(--tui-bg, #1a1a2e);
77
+ font-family: var(--font-mono, monospace);
78
+ font-size: var(--text-sm, 14px);
79
+ color: var(--tui-text, #e0e0e0);
80
+ line-height: 1.5;
81
+ align-items: stretch;
82
+ }
83
+ </style>
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from "svelte";
2
+ interface Props {
3
+ /** Enable TUI mode: flat surface, terminal-safe colors, box-drawing separators. */
4
+ tui?: boolean;
5
+ /** Sticky position for GUI mode. Default: "bottom" */
6
+ position?: "top" | "bottom";
7
+ class?: string;
8
+ children: Snippet;
9
+ }
10
+ declare const StatusBar: import("svelte").Component<Props, {}, "">;
11
+ type StatusBar = ReturnType<typeof StatusBar>;
12
+ export default StatusBar;