termcast 1.3.32 → 1.3.34

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 (327) hide show
  1. package/dist/action-utils.d.ts.map +1 -1
  2. package/dist/action-utils.js +8 -0
  3. package/dist/action-utils.js.map +1 -1
  4. package/dist/apis/cache.d.ts +1 -2
  5. package/dist/apis/cache.d.ts.map +1 -1
  6. package/dist/apis/cache.js +138 -54
  7. package/dist/apis/cache.js.map +1 -1
  8. package/dist/apis/clipboard.d.ts.map +1 -1
  9. package/dist/apis/clipboard.js +4 -0
  10. package/dist/apis/clipboard.js.map +1 -1
  11. package/dist/apis/oauth.d.ts.map +1 -1
  12. package/dist/apis/oauth.js +31 -4
  13. package/dist/apis/oauth.js.map +1 -1
  14. package/dist/build.d.ts +0 -1
  15. package/dist/build.d.ts.map +1 -1
  16. package/dist/build.js +30 -51
  17. package/dist/build.js.map +1 -1
  18. package/dist/cli.js +31 -14
  19. package/dist/cli.js.map +1 -1
  20. package/dist/compile.d.ts.map +1 -1
  21. package/dist/compile.js +5 -1
  22. package/dist/compile.js.map +1 -1
  23. package/dist/components/actions.d.ts +14 -0
  24. package/dist/components/actions.d.ts.map +1 -1
  25. package/dist/components/actions.js +151 -59
  26. package/dist/components/actions.js.map +1 -1
  27. package/dist/components/alert.d.ts.map +1 -1
  28. package/dist/components/alert.js +6 -5
  29. package/dist/components/alert.js.map +1 -1
  30. package/dist/components/animation-tick.d.ts +1 -1
  31. package/dist/components/animation-tick.js +1 -1
  32. package/dist/components/animation-tick.js.map +1 -1
  33. package/dist/components/detail.d.ts +5 -31
  34. package/dist/components/detail.d.ts.map +1 -1
  35. package/dist/components/detail.js +36 -52
  36. package/dist/components/detail.js.map +1 -1
  37. package/dist/components/dropdown.d.ts +1 -1
  38. package/dist/components/dropdown.d.ts.map +1 -1
  39. package/dist/components/dropdown.js +50 -22
  40. package/dist/components/dropdown.js.map +1 -1
  41. package/dist/components/footer.d.ts.map +1 -1
  42. package/dist/components/footer.js +19 -18
  43. package/dist/components/footer.js.map +1 -1
  44. package/dist/components/form/checkbox.d.ts.map +1 -1
  45. package/dist/components/form/checkbox.js +12 -11
  46. package/dist/components/form/checkbox.js.map +1 -1
  47. package/dist/components/form/date-picker.d.ts.map +1 -1
  48. package/dist/components/form/date-picker.js +7 -22
  49. package/dist/components/form/date-picker.js.map +1 -1
  50. package/dist/components/form/description.d.ts +1 -1
  51. package/dist/components/form/description.d.ts.map +1 -1
  52. package/dist/components/form/description.js +6 -5
  53. package/dist/components/form/description.js.map +1 -1
  54. package/dist/components/form/dropdown.d.ts.map +1 -1
  55. package/dist/components/form/dropdown.js +53 -50
  56. package/dist/components/form/dropdown.js.map +1 -1
  57. package/dist/components/form/file-autocomplete.d.ts.map +1 -1
  58. package/dist/components/form/file-autocomplete.js +5 -4
  59. package/dist/components/form/file-autocomplete.js.map +1 -1
  60. package/dist/components/form/file-picker.d.ts.map +1 -1
  61. package/dist/components/form/file-picker.js +23 -22
  62. package/dist/components/form/file-picker.js.map +1 -1
  63. package/dist/components/form/form-end.d.ts.map +1 -1
  64. package/dist/components/form/form-end.js +6 -4
  65. package/dist/components/form/form-end.js.map +1 -1
  66. package/dist/components/form/form-field-wrapper.d.ts +15 -0
  67. package/dist/components/form/form-field-wrapper.d.ts.map +1 -0
  68. package/dist/components/form/form-field-wrapper.js +29 -0
  69. package/dist/components/form/form-field-wrapper.js.map +1 -0
  70. package/dist/components/form/index.d.ts.map +1 -1
  71. package/dist/components/form/index.js +31 -30
  72. package/dist/components/form/index.js.map +1 -1
  73. package/dist/components/form/password-field.d.ts.map +1 -1
  74. package/dist/components/form/password-field.js +7 -6
  75. package/dist/components/form/password-field.js.map +1 -1
  76. package/dist/components/form/separator.d.ts.map +1 -1
  77. package/dist/components/form/separator.js +3 -2
  78. package/dist/components/form/separator.js.map +1 -1
  79. package/dist/components/form/tagpicker.d.ts.map +1 -1
  80. package/dist/components/form/tagpicker.js +2 -1
  81. package/dist/components/form/tagpicker.js.map +1 -1
  82. package/dist/components/form/text-area.d.ts.map +1 -1
  83. package/dist/components/form/text-area.js +7 -6
  84. package/dist/components/form/text-area.js.map +1 -1
  85. package/dist/components/form/text-field.d.ts.map +1 -1
  86. package/dist/components/form/text-field.js +7 -6
  87. package/dist/components/form/text-field.js.map +1 -1
  88. package/dist/components/form/use-form-navigation.d.ts.map +1 -1
  89. package/dist/components/form/use-form-navigation.js +4 -4
  90. package/dist/components/form/use-form-navigation.js.map +1 -1
  91. package/dist/components/form/with-left-border.d.ts +15 -0
  92. package/dist/components/form/with-left-border.d.ts.map +1 -1
  93. package/dist/components/form/with-left-border.js +21 -9
  94. package/dist/components/form/with-left-border.js.map +1 -1
  95. package/dist/components/icon.d.ts +14 -0
  96. package/dist/components/icon.d.ts.map +1 -1
  97. package/dist/components/icon.js +60 -0
  98. package/dist/components/icon.js.map +1 -1
  99. package/dist/components/image.d.ts +47 -2
  100. package/dist/components/image.d.ts.map +1 -1
  101. package/dist/components/image.js +46 -7
  102. package/dist/components/image.js.map +1 -1
  103. package/dist/components/list.d.ts +5 -0
  104. package/dist/components/list.d.ts.map +1 -1
  105. package/dist/components/list.js +188 -132
  106. package/dist/components/list.js.map +1 -1
  107. package/dist/components/loading-bar.d.ts.map +1 -1
  108. package/dist/components/loading-bar.js +4 -3
  109. package/dist/components/loading-bar.js.map +1 -1
  110. package/dist/components/metadata.d.ts +70 -0
  111. package/dist/components/metadata.d.ts.map +1 -0
  112. package/dist/components/metadata.js +82 -0
  113. package/dist/components/metadata.js.map +1 -0
  114. package/dist/components/theme-picker.d.ts.map +1 -1
  115. package/dist/components/theme-picker.js +3 -2
  116. package/dist/components/theme-picker.js.map +1 -1
  117. package/dist/descendants-v2.d.ts +60 -0
  118. package/dist/descendants-v2.d.ts.map +1 -0
  119. package/dist/descendants-v2.js +144 -0
  120. package/dist/descendants-v2.js.map +1 -0
  121. package/dist/examples/actions-context.d.ts +2 -0
  122. package/dist/examples/actions-context.d.ts.map +1 -0
  123. package/dist/examples/actions-context.js +33 -0
  124. package/dist/examples/actions-context.js.map +1 -0
  125. package/dist/examples/form-basic.d.ts.map +1 -1
  126. package/dist/examples/form-basic.js +1 -1
  127. package/dist/examples/form-basic.js.map +1 -1
  128. package/dist/examples/form-dropdown.js +1 -1
  129. package/dist/examples/form-dropdown.js.map +1 -1
  130. package/dist/examples/internal/custom-action-renderables.d.ts +70 -0
  131. package/dist/examples/internal/custom-action-renderables.d.ts.map +1 -0
  132. package/dist/examples/internal/custom-action-renderables.js +163 -0
  133. package/dist/examples/internal/custom-action-renderables.js.map +1 -0
  134. package/dist/examples/internal/custom-dropdown.d.ts +99 -0
  135. package/dist/examples/internal/custom-dropdown.d.ts.map +1 -0
  136. package/dist/examples/internal/custom-dropdown.js +270 -0
  137. package/dist/examples/internal/custom-dropdown.js.map +1 -0
  138. package/dist/examples/internal/custom-renderable-form.d.ts +43 -0
  139. package/dist/examples/internal/custom-renderable-form.d.ts.map +1 -0
  140. package/dist/examples/internal/custom-renderable-form.js +284 -0
  141. package/dist/examples/internal/custom-renderable-form.js.map +1 -0
  142. package/dist/examples/internal/custom-renderable-list-default-search.d.ts +2 -0
  143. package/dist/examples/internal/custom-renderable-list-default-search.d.ts.map +1 -0
  144. package/dist/examples/internal/custom-renderable-list-default-search.js +16 -0
  145. package/dist/examples/internal/custom-renderable-list-default-search.js.map +1 -0
  146. package/dist/examples/internal/custom-renderable-list-v2-default-search.d.ts +2 -0
  147. package/dist/examples/internal/custom-renderable-list-v2-default-search.d.ts.map +1 -0
  148. package/dist/examples/internal/custom-renderable-list-v2-default-search.js +24 -0
  149. package/dist/examples/internal/custom-renderable-list-v2-default-search.js.map +1 -0
  150. package/dist/examples/internal/custom-renderable-list-v2.d.ts +189 -0
  151. package/dist/examples/internal/custom-renderable-list-v2.d.ts.map +1 -0
  152. package/dist/examples/internal/custom-renderable-list-v2.js +708 -0
  153. package/dist/examples/internal/custom-renderable-list-v2.js.map +1 -0
  154. package/dist/examples/internal/custom-renderable-list.d.ts +72 -0
  155. package/dist/examples/internal/custom-renderable-list.d.ts.map +1 -0
  156. package/dist/examples/internal/custom-renderable-list.js +544 -0
  157. package/dist/examples/internal/custom-renderable-list.js.map +1 -0
  158. package/dist/examples/internal/rhf-custom-ref.js +5 -4
  159. package/dist/examples/internal/rhf-custom-ref.js.map +1 -1
  160. package/dist/examples/internal/scrollbox-with-descendants.js +4 -2
  161. package/dist/examples/internal/scrollbox-with-descendants.js.map +1 -1
  162. package/dist/examples/list-controlled-search.d.ts +2 -0
  163. package/dist/examples/list-controlled-search.d.ts.map +1 -0
  164. package/dist/examples/list-controlled-search.js +12 -0
  165. package/dist/examples/list-controlled-search.js.map +1 -0
  166. package/dist/examples/list-detail-metadata.js +1 -1
  167. package/dist/examples/list-detail-metadata.js.map +1 -1
  168. package/dist/examples/simple-image-mask.d.ts +8 -0
  169. package/dist/examples/simple-image-mask.d.ts.map +1 -0
  170. package/dist/examples/simple-image-mask.js +12 -0
  171. package/dist/examples/simple-image-mask.js.map +1 -0
  172. package/dist/examples/toast-variations.js +1 -1
  173. package/dist/examples/toast-variations.js.map +1 -1
  174. package/dist/extensions/dev.d.ts.map +1 -1
  175. package/dist/extensions/dev.js +3 -2
  176. package/dist/extensions/dev.js.map +1 -1
  177. package/dist/extensions/react-refresh-init.d.ts.map +1 -1
  178. package/dist/extensions/react-refresh-init.js +4 -3
  179. package/dist/extensions/react-refresh-init.js.map +1 -1
  180. package/dist/index.d.ts +3 -2
  181. package/dist/index.d.ts.map +1 -1
  182. package/dist/index.js +1 -1
  183. package/dist/index.js.map +1 -1
  184. package/dist/internal/date-picker-widget.d.ts.map +1 -1
  185. package/dist/internal/date-picker-widget.js +2 -1
  186. package/dist/internal/date-picker-widget.js.map +1 -1
  187. package/dist/internal/dialog.d.ts +6 -0
  188. package/dist/internal/dialog.d.ts.map +1 -1
  189. package/dist/internal/dialog.js +59 -18
  190. package/dist/internal/dialog.js.map +1 -1
  191. package/dist/internal/navigation.d.ts.map +1 -1
  192. package/dist/internal/navigation.js +8 -1
  193. package/dist/internal/navigation.js.map +1 -1
  194. package/dist/internal/offscreen.d.ts +3 -0
  195. package/dist/internal/offscreen.d.ts.map +1 -1
  196. package/dist/internal/offscreen.js +5 -0
  197. package/dist/internal/offscreen.js.map +1 -1
  198. package/dist/internal/providers.d.ts.map +1 -1
  199. package/dist/internal/providers.js +20 -3
  200. package/dist/internal/providers.js.map +1 -1
  201. package/dist/internal/scrollbox.d.ts.map +1 -1
  202. package/dist/internal/scrollbox.js +3 -2
  203. package/dist/internal/scrollbox.js.map +1 -1
  204. package/dist/logger.d.ts.map +1 -1
  205. package/dist/logger.js +4 -0
  206. package/dist/logger.js.map +1 -1
  207. package/dist/preload.js +5 -17
  208. package/dist/preload.js.map +1 -1
  209. package/dist/state.d.ts +4 -0
  210. package/dist/state.d.ts.map +1 -1
  211. package/dist/state.js +4 -0
  212. package/dist/state.js.map +1 -1
  213. package/dist/test-border-overlay.d.ts +2 -0
  214. package/dist/test-border-overlay.d.ts.map +1 -0
  215. package/dist/test-border-overlay.js +7 -0
  216. package/dist/test-border-overlay.js.map +1 -0
  217. package/dist/test-layout-2.d.ts +2 -0
  218. package/dist/test-layout-2.d.ts.map +1 -0
  219. package/dist/test-layout-2.js +5 -0
  220. package/dist/test-layout-2.js.map +1 -0
  221. package/dist/test-layout.d.ts +2 -0
  222. package/dist/test-layout.d.ts.map +1 -0
  223. package/dist/test-layout.js +7 -0
  224. package/dist/test-layout.js.map +1 -0
  225. package/dist/theme.d.ts +1 -2
  226. package/dist/theme.d.ts.map +1 -1
  227. package/dist/theme.js +5 -9
  228. package/dist/theme.js.map +1 -1
  229. package/dist/utils/run-command.d.ts +1 -1
  230. package/dist/utils/run-command.d.ts.map +1 -1
  231. package/dist/utils/run-command.js +27 -7
  232. package/dist/utils/run-command.js.map +1 -1
  233. package/dist/utils.d.ts +1 -0
  234. package/dist/utils.d.ts.map +1 -1
  235. package/dist/utils.js +44 -23
  236. package/dist/utils.js.map +1 -1
  237. package/dist/watcher.d.ts.map +1 -1
  238. package/dist/watcher.js +24 -4
  239. package/dist/watcher.js.map +1 -1
  240. package/package.json +14 -12
  241. package/src/action-utils.tsx +10 -0
  242. package/src/apis/cache.test.ts +35 -3
  243. package/src/apis/cache.tsx +184 -59
  244. package/src/apis/clipboard.tsx +5 -0
  245. package/src/apis/oauth.tsx +33 -4
  246. package/src/build.tsx +35 -58
  247. package/src/cli.tsx +156 -134
  248. package/src/compile.tsx +6 -3
  249. package/src/compile.vitest.tsx +33 -15
  250. package/src/components/actions.tsx +230 -99
  251. package/src/components/alert.tsx +11 -10
  252. package/src/components/animation-tick.tsx +1 -1
  253. package/src/components/detail.tsx +56 -151
  254. package/src/components/dropdown.tsx +70 -36
  255. package/src/components/footer.tsx +58 -33
  256. package/src/components/form/checkbox.tsx +30 -32
  257. package/src/components/form/date-picker.tsx +27 -47
  258. package/src/components/form/description.tsx +19 -18
  259. package/src/components/form/dropdown.tsx +95 -103
  260. package/src/components/form/file-autocomplete.tsx +9 -8
  261. package/src/components/form/file-picker.tsx +46 -46
  262. package/src/components/form/form-end.tsx +6 -4
  263. package/src/components/form/index.tsx +38 -48
  264. package/src/components/form/password-field.tsx +25 -27
  265. package/src/components/form/separator.tsx +3 -2
  266. package/src/components/form/tagpicker.tsx +2 -1
  267. package/src/components/form/text-area.tsx +25 -30
  268. package/src/components/form/text-field.tsx +25 -27
  269. package/src/components/form/use-form-navigation.tsx +4 -5
  270. package/src/components/form/with-left-border.tsx +48 -10
  271. package/src/components/icon.tsx +69 -0
  272. package/src/components/image.tsx +60 -7
  273. package/src/components/list.tsx +270 -202
  274. package/src/components/loading-bar.tsx +4 -3
  275. package/src/components/metadata.tsx +217 -0
  276. package/src/components/theme-picker.tsx +3 -2
  277. package/src/examples/actions-context.tsx +63 -0
  278. package/src/examples/actions-context.vitest.tsx +110 -0
  279. package/src/examples/actions-dialog-layout.vitest.tsx +2 -1
  280. package/src/examples/file-autocomplete.vitest.tsx +15 -15
  281. package/src/examples/form-basic.tsx +12 -0
  282. package/src/examples/form-basic.vitest.tsx +74 -74
  283. package/src/examples/form-dropdown.tsx +8 -0
  284. package/src/examples/form-dropdown.vitest.tsx +364 -421
  285. package/src/examples/form-tagpicker.vitest.tsx +56 -54
  286. package/src/examples/github.vitest.tsx +252 -0
  287. package/src/examples/internal/rhf-custom-ref.tsx +16 -15
  288. package/src/examples/internal/scrollbox-with-descendants.tsx +4 -2
  289. package/src/examples/internal/simple-dialog.tsx +1 -1
  290. package/src/examples/internal/simple-scrollbox.vitest.tsx +14 -9
  291. package/src/examples/list-controlled-search.tsx +28 -0
  292. package/src/examples/list-controlled-search.vitest.tsx +49 -0
  293. package/src/examples/list-detail-metadata.tsx +8 -5
  294. package/src/examples/list-detail-metadata.vitest.tsx +22 -22
  295. package/src/examples/list-dropdown-default.vitest.tsx +12 -12
  296. package/src/examples/list-scrollbox.vitest.tsx +52 -38
  297. package/src/examples/list-with-detail.vitest.tsx +45 -41
  298. package/src/examples/list-with-dropdown.vitest.tsx +5 -5
  299. package/src/examples/list-with-sections.vitest.tsx +65 -12
  300. package/src/examples/list-with-toast.vitest.tsx +4 -4
  301. package/src/examples/simple-file-picker.vitest.tsx +12 -12
  302. package/src/examples/simple-grid.vitest.tsx +53 -53
  303. package/src/examples/simple-image-mask.tsx +58 -0
  304. package/src/examples/simple-navigation.vitest.tsx +19 -19
  305. package/src/examples/store.vitest.tsx +1 -1
  306. package/src/examples/swift-extension.vitest.tsx +4 -2
  307. package/src/examples/synonyms.vitest.tsx +31 -9
  308. package/src/examples/toast-action.vitest.tsx +8 -8
  309. package/src/examples/toast-variations.tsx +1 -1
  310. package/src/examples/toast-variations.vitest.tsx +69 -134
  311. package/src/extensions/dev.tsx +3 -2
  312. package/src/extensions/dev.vitest.tsx +65 -28
  313. package/src/extensions/react-refresh-init.tsx +4 -3
  314. package/src/index.tsx +3 -1
  315. package/src/internal/date-picker-widget.tsx +2 -1
  316. package/src/internal/dialog.tsx +100 -28
  317. package/src/internal/navigation.tsx +8 -1
  318. package/src/internal/offscreen.tsx +10 -0
  319. package/src/internal/providers.tsx +34 -8
  320. package/src/internal/scrollbox.tsx +4 -2
  321. package/src/logger.tsx +4 -0
  322. package/src/preload.tsx +5 -17
  323. package/src/state.tsx +12 -0
  324. package/src/theme.tsx +6 -9
  325. package/src/utils/run-command.tsx +32 -8
  326. package/src/utils.tsx +58 -23
  327. package/src/watcher.tsx +26 -6
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Custom Dropdown Component
3
+ *
4
+ * Reusable dropdown with search, scroll, keyboard navigation.
5
+ * Uses same pattern as custom-renderable-list-v2.tsx:
6
+ * - Custom renderables for Dropdown/DropdownItem
7
+ * - onLifecyclePass for item registration
8
+ * - Zustand store for state sync with React
9
+ */
10
+ import { Renderable, BoxRenderable, type RenderContext, type BoxOptions } from '@opentui/core';
11
+ import React from 'react';
12
+ interface DropdownStoreState {
13
+ selectedIndex: number;
14
+ visibleCount: number;
15
+ totalCount: number;
16
+ searchQuery: string;
17
+ renderTick: number;
18
+ }
19
+ declare const useDropdownStore: import("zustand").UseBoundStore<import("zustand").StoreApi<DropdownStoreState>>;
20
+ interface DropdownItemOptions extends BoxOptions {
21
+ itemTitle?: string;
22
+ itemId?: string;
23
+ keywords?: string[];
24
+ onSelect?: () => void;
25
+ }
26
+ declare class DropdownItemRenderable extends BoxRenderable {
27
+ itemTitle: string;
28
+ itemId?: string;
29
+ keywords?: string[];
30
+ onSelect?: () => void;
31
+ visibleIndex: number;
32
+ private parentDropdown?;
33
+ constructor(ctx: RenderContext, options: DropdownItemOptions);
34
+ matchesSearch(query: string): boolean;
35
+ }
36
+ interface DropdownOptions extends BoxOptions {
37
+ placeholder?: string;
38
+ onSelect?: (itemId: string) => void;
39
+ onSelectionChange?: (itemId: string) => void;
40
+ }
41
+ declare class DropdownRenderable extends BoxRenderable {
42
+ private registeredItems;
43
+ private searchInput;
44
+ private scrollBox;
45
+ private statusText;
46
+ searchQuery: string;
47
+ onSelect?: (itemId: string) => void;
48
+ onSelectionChange?: (itemId: string) => void;
49
+ constructor(ctx: RenderContext, options: DropdownOptions);
50
+ add(child: Renderable, index?: number): number;
51
+ registerItem(item: DropdownItemRenderable): void;
52
+ private getAllItems;
53
+ setSearchQuery(query: string): void;
54
+ private refilter;
55
+ private updateStatusText;
56
+ moveSelection(delta: number): void;
57
+ private scrollToIndex;
58
+ private notifySelectionChange;
59
+ triggerSelect(): void;
60
+ getFirstItemTitle(): string;
61
+ getSelectedItemTitle(): string;
62
+ }
63
+ declare global {
64
+ namespace JSX {
65
+ interface IntrinsicElements {
66
+ 'custom-dropdown': DropdownOptions & {
67
+ ref?: React.Ref<DropdownRenderable>;
68
+ };
69
+ 'custom-dropdown-item': DropdownItemOptions & {
70
+ ref?: React.Ref<DropdownItemRenderable>;
71
+ };
72
+ }
73
+ }
74
+ }
75
+ interface DropdownProps {
76
+ children?: React.ReactNode;
77
+ placeholder?: string;
78
+ onSelect?: (itemId: string) => void;
79
+ onSelectionChange?: (itemId: string) => void;
80
+ }
81
+ declare function Dropdown({ children, placeholder, onSelect, onSelectionChange }: DropdownProps): any;
82
+ interface DropdownItemProps {
83
+ id?: string;
84
+ title: string;
85
+ keywords?: string[];
86
+ onSelect?: () => void;
87
+ }
88
+ declare function DropdownItem({ id, title, keywords, onSelect }: DropdownItemProps): any;
89
+ interface DropdownType {
90
+ (props: DropdownProps): any;
91
+ Item: typeof DropdownItem;
92
+ }
93
+ declare const CustomDropdown: DropdownType;
94
+ export { CustomDropdown, Dropdown, DropdownItem, useDropdownStore, DropdownRenderable, DropdownItemRenderable };
95
+ declare function Example({ useMany }: {
96
+ useMany?: boolean;
97
+ }): any;
98
+ export { Example };
99
+ //# sourceMappingURL=custom-dropdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-dropdown.d.ts","sourceRoot":"","sources":["../../../src/examples/internal/custom-dropdown.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,270 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
2
+ /**
3
+ * Custom Dropdown Component
4
+ *
5
+ * Reusable dropdown with search, scroll, keyboard navigation.
6
+ * Uses same pattern as custom-renderable-list-v2.tsx:
7
+ * - Custom renderables for Dropdown/DropdownItem
8
+ * - onLifecyclePass for item registration
9
+ * - Zustand store for state sync with React
10
+ */
11
+ import { BoxRenderable, TextRenderable, ScrollBoxRenderable, } from '@opentui/core';
12
+ import { extend, useKeyboard } from '@opentui/react';
13
+ import { useRef, useState } from 'react';
14
+ import { renderWithProviders } from '../../utils';
15
+ import { create } from 'zustand';
16
+ import { Theme } from 'termcast/src/theme';
17
+ const useDropdownStore = create(() => ({
18
+ selectedIndex: 0,
19
+ visibleCount: 0,
20
+ totalCount: 0,
21
+ searchQuery: '',
22
+ renderTick: 0,
23
+ }));
24
+ // ─────────────────────────────────────────────────────────────────────────────
25
+ // Helper: Find parent of specific type
26
+ // ─────────────────────────────────────────────────────────────────────────────
27
+ function findParent(node, type) {
28
+ let current = node.parent;
29
+ while (current) {
30
+ if (current instanceof type) {
31
+ return current;
32
+ }
33
+ current = current.parent;
34
+ }
35
+ return undefined;
36
+ }
37
+ class DropdownItemRenderable extends BoxRenderable {
38
+ itemTitle = '';
39
+ itemId;
40
+ keywords;
41
+ onSelect;
42
+ visibleIndex = -1;
43
+ parentDropdown;
44
+ constructor(ctx, options) {
45
+ super(ctx, { ...options, flexDirection: 'row', width: '100%' });
46
+ this.onLifecyclePass = () => {
47
+ if (!this.parentDropdown) {
48
+ this.parentDropdown = findParent(this, DropdownRenderable);
49
+ this.parentDropdown?.registerItem(this);
50
+ }
51
+ };
52
+ }
53
+ matchesSearch(query) {
54
+ if (!query)
55
+ return true;
56
+ const lowerQuery = query.toLowerCase();
57
+ if (this.itemTitle.toLowerCase().includes(lowerQuery))
58
+ return true;
59
+ if (this.keywords?.some((k) => k.toLowerCase().includes(lowerQuery)))
60
+ return true;
61
+ return false;
62
+ }
63
+ }
64
+ class DropdownRenderable extends BoxRenderable {
65
+ registeredItems = new Set();
66
+ searchInput;
67
+ scrollBox;
68
+ statusText;
69
+ searchQuery = '';
70
+ onSelect;
71
+ onSelectionChange;
72
+ constructor(ctx, options) {
73
+ super(ctx, { ...options, flexDirection: 'column' });
74
+ // Search input display
75
+ this.searchInput = new TextRenderable(ctx, {
76
+ content: options.placeholder || 'Search...',
77
+ fg: Theme.textMuted,
78
+ });
79
+ super.add(this.searchInput);
80
+ // Scrollable content area
81
+ this.scrollBox = new ScrollBoxRenderable(ctx, {
82
+ flexDirection: 'column',
83
+ flexGrow: 1,
84
+ });
85
+ super.add(this.scrollBox);
86
+ // Status text
87
+ this.statusText = new TextRenderable(ctx, {
88
+ content: '0 items',
89
+ fg: Theme.textMuted,
90
+ });
91
+ super.add(this.statusText);
92
+ }
93
+ add(child, index) {
94
+ return this.scrollBox.add(child, index);
95
+ }
96
+ registerItem(item) {
97
+ this.registeredItems.add(item);
98
+ this.refilter();
99
+ }
100
+ getAllItems() {
101
+ return Array.from(this.registeredItems);
102
+ }
103
+ setSearchQuery(query) {
104
+ this.searchQuery = query;
105
+ this.searchInput.content = query || 'Search...';
106
+ this.searchInput.fg = query ? Theme.text : Theme.textMuted;
107
+ useDropdownStore.setState({ searchQuery: query });
108
+ this.refilter();
109
+ }
110
+ refilter() {
111
+ const allItems = this.getAllItems();
112
+ let visibleIndex = 0;
113
+ for (const item of allItems) {
114
+ const matches = item.matchesSearch(this.searchQuery);
115
+ if (matches) {
116
+ item.visibleIndex = visibleIndex++;
117
+ item.visible = true;
118
+ }
119
+ else {
120
+ item.visibleIndex = -1;
121
+ item.visible = false;
122
+ }
123
+ }
124
+ const { selectedIndex } = useDropdownStore.getState();
125
+ const clampedIndex = Math.min(Math.max(0, selectedIndex), visibleIndex - 1);
126
+ useDropdownStore.setState({
127
+ visibleCount: visibleIndex,
128
+ totalCount: allItems.length,
129
+ selectedIndex: clampedIndex >= 0 ? clampedIndex : 0,
130
+ renderTick: useDropdownStore.getState().renderTick + 1,
131
+ });
132
+ this.updateStatusText(visibleIndex, allItems.length);
133
+ this.notifySelectionChange(clampedIndex >= 0 ? clampedIndex : 0);
134
+ }
135
+ updateStatusText(visibleCount, totalCount) {
136
+ const searchText = this.searchQuery ? ` • "${this.searchQuery}"` : '';
137
+ this.statusText.content = `${visibleCount} of ${totalCount} items${searchText}`;
138
+ }
139
+ moveSelection(delta) {
140
+ const { selectedIndex, visibleCount } = useDropdownStore.getState();
141
+ if (visibleCount === 0)
142
+ return;
143
+ const newIndex = (selectedIndex + delta + visibleCount) % visibleCount;
144
+ useDropdownStore.setState({ selectedIndex: newIndex });
145
+ this.scrollToIndex(newIndex);
146
+ this.notifySelectionChange(newIndex);
147
+ }
148
+ scrollToIndex(index) {
149
+ const item = this.getAllItems().find((i) => i.visibleIndex === index);
150
+ if (item && this.scrollBox) {
151
+ // Use scrollTo method from ScrollBoxRenderable
152
+ const itemHeight = 1; // Each item is 1 row
153
+ const targetY = index * itemHeight;
154
+ this.scrollBox.scrollTo(targetY);
155
+ }
156
+ }
157
+ notifySelectionChange(index) {
158
+ const item = this.getAllItems().find((i) => i.visibleIndex === index);
159
+ if (item && this.onSelectionChange) {
160
+ this.onSelectionChange(item.itemId || item.itemTitle);
161
+ }
162
+ }
163
+ triggerSelect() {
164
+ const { selectedIndex } = useDropdownStore.getState();
165
+ const item = this.getAllItems().find((i) => i.visibleIndex === selectedIndex);
166
+ if (item) {
167
+ item.onSelect?.();
168
+ this.onSelect?.(item.itemId || item.itemTitle);
169
+ }
170
+ }
171
+ getFirstItemTitle() {
172
+ const items = this.getAllItems().filter((i) => i.visibleIndex !== -1);
173
+ items.sort((a, b) => a.visibleIndex - b.visibleIndex);
174
+ return items[0]?.itemTitle ?? '';
175
+ }
176
+ getSelectedItemTitle() {
177
+ const { selectedIndex } = useDropdownStore.getState();
178
+ const item = this.getAllItems().find((i) => i.visibleIndex === selectedIndex);
179
+ return item?.itemTitle ?? '';
180
+ }
181
+ }
182
+ // ─────────────────────────────────────────────────────────────────────────────
183
+ // Register custom elements
184
+ // ─────────────────────────────────────────────────────────────────────────────
185
+ extend({
186
+ 'custom-dropdown': DropdownRenderable,
187
+ 'custom-dropdown-item': DropdownItemRenderable,
188
+ });
189
+ function Dropdown({ children, placeholder, onSelect, onSelectionChange }) {
190
+ const dropdownRef = useRef(null);
191
+ useKeyboard((evt) => {
192
+ const dropdown = dropdownRef.current;
193
+ if (!dropdown)
194
+ return;
195
+ if (evt.name === 'up') {
196
+ dropdown.moveSelection(-1);
197
+ return;
198
+ }
199
+ if (evt.name === 'down') {
200
+ dropdown.moveSelection(1);
201
+ return;
202
+ }
203
+ if (evt.name === 'return') {
204
+ const selectedTitle = dropdown.getSelectedItemTitle();
205
+ if (selectedTitle && onSelect) {
206
+ onSelect(selectedTitle);
207
+ }
208
+ dropdown.triggerSelect(); // Also trigger item's onSelect
209
+ return;
210
+ }
211
+ if (evt.name === 'backspace') {
212
+ const current = dropdown.searchQuery;
213
+ dropdown.setSearchQuery(current.slice(0, -1));
214
+ return;
215
+ }
216
+ // Typing for search
217
+ if (evt.name.length === 1 && /^[a-zA-Z0-9]$/.test(evt.name) && !evt.ctrl && !evt.meta) {
218
+ dropdown.setSearchQuery(dropdown.searchQuery + evt.name);
219
+ }
220
+ });
221
+ return (_jsx("custom-dropdown", { ref: dropdownRef, placeholder: placeholder, onSelect: onSelect, onSelectionChange: onSelectionChange, flexGrow: 1, children: children }));
222
+ }
223
+ function DropdownItem({ id, title, keywords, onSelect }) {
224
+ const itemRef = useRef(null);
225
+ const selectedIndex = useDropdownStore((s) => s.selectedIndex);
226
+ useDropdownStore((s) => s.renderTick);
227
+ const isSelected = itemRef.current?.visibleIndex === selectedIndex;
228
+ return (_jsxs("custom-dropdown-item", { ref: itemRef, itemTitle: title, itemId: id, keywords: keywords, onSelect: onSelect, backgroundColor: isSelected ? Theme.accent : undefined, flexShrink: 0, children: [_jsx("text", { flexShrink: 0, children: isSelected ? '› ' : ' ' }), _jsx("text", { flexShrink: 0, children: title })] }));
229
+ }
230
+ const CustomDropdown = Dropdown;
231
+ CustomDropdown.Item = DropdownItem;
232
+ export { CustomDropdown, Dropdown, DropdownItem, useDropdownStore, DropdownRenderable, DropdownItemRenderable };
233
+ // ─────────────────────────────────────────────────────────────────────────────
234
+ // Example
235
+ // ─────────────────────────────────────────────────────────────────────────────
236
+ function Example({ useMany = false }) {
237
+ const [selectedItem, setSelectedItem] = useState(null);
238
+ const [hoverItem, setHoverItem] = useState(null);
239
+ const defaultItems = [
240
+ { id: 'apple', title: 'Apple', keywords: ['fruit', 'red'] },
241
+ { id: 'banana', title: 'Banana', keywords: ['fruit', 'yellow'] },
242
+ { id: 'carrot', title: 'Carrot', keywords: ['vegetable', 'orange'] },
243
+ { id: 'date', title: 'Date', keywords: ['fruit', 'sweet'] },
244
+ ];
245
+ // Generate many items for scroll testing
246
+ const manyItems = Array.from({ length: 20 }, (_, i) => ({
247
+ id: `item-${i + 1}`,
248
+ title: `Item ${i + 1}`,
249
+ }));
250
+ const items = useMany ? manyItems : defaultItems;
251
+ return (_jsxs("box", { flexDirection: "column", padding: 1, height: "100%", children: [_jsx("text", { marginBottom: 1, children: "Custom Dropdown Example" }), selectedItem && _jsxs("text", { flexShrink: 0, fg: Theme.accent, children: ["Selected: ", selectedItem] }), hoverItem && _jsxs("text", { flexShrink: 0, fg: Theme.textMuted, children: ["Hover: ", hoverItem] }), _jsx("box", { marginTop: 1, height: 10, border: ['top', 'bottom', 'left', 'right'], borderStyle: "single", children: _jsx(CustomDropdown, { placeholder: "Search items...", onSelect: (id) => {
252
+ setSelectedItem(items.find((i) => i.id === id)?.title || id);
253
+ }, onSelectionChange: (id) => {
254
+ setHoverItem(items.find((i) => i.id === id)?.title || id);
255
+ }, children: items.map((item) => (_jsx(CustomDropdown.Item, { id: item.id, title: item.title, keywords: 'keywords' in item ? item.keywords : undefined }, item.id))) }) })] }));
256
+ }
257
+ export { Example };
258
+ if (import.meta.main) {
259
+ useDropdownStore.setState({
260
+ selectedIndex: 0,
261
+ visibleCount: 0,
262
+ totalCount: 0,
263
+ searchQuery: '',
264
+ renderTick: 0,
265
+ });
266
+ // Check for --many flag to test scrolling with many items
267
+ const useMany = process.argv.includes('--many');
268
+ renderWithProviders(_jsx(Example, { useMany: useMany }));
269
+ }
270
+ //# sourceMappingURL=custom-dropdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-dropdown.js","sourceRoot":"","sources":["../../../src/examples/internal/custom-dropdown.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Custom Renderable Form Example
3
+ *
4
+ * Demonstrates hybrid pattern for building forms:
5
+ * - Form container = custom renderable (owns focus, navigation, scroll, RHF methods)
6
+ * - Form fields = React components wrapped in self-registering renderables
7
+ * - Tests dynamic field registration via timeout
8
+ *
9
+ * ## Architecture
10
+ *
11
+ * CustomFormRenderable (custom renderable)
12
+ * ├── owns: react-hook-form methods, focusedFieldId, field registry, scrollbox
13
+ * ├── methods: registerField(), focusField(), focusNext(), focusPrev()
14
+ * │
15
+ * └── CustomFormFieldWrapperRenderable (thin wrapper)
16
+ * ├── self-registers via onLifecyclePass (SYNC - no timing issues)
17
+ * └── React children (label, textarea) rendered inside
18
+ *
19
+ * ## Key Patterns
20
+ *
21
+ * 1. Wrapper renderable self-registers synchronously when added to tree
22
+ * 2. No useEffect needed for registration - onLifecyclePass handles it
23
+ * 3. Focus state in parent, checked in children each render
24
+ * 4. react-hook-form: useForm() in React, passed as prop to renderable, exposed via context
25
+ * 5. Tab navigation via parent methods (focusNext/focusPrev)
26
+ */
27
+ import React from 'react';
28
+ interface CustomFormProps {
29
+ children: React.ReactNode;
30
+ }
31
+ declare function CustomForm({ children }: CustomFormProps): any;
32
+ declare namespace CustomForm {
33
+ var TextField: typeof CustomFormTextField;
34
+ }
35
+ interface TextFieldProps {
36
+ id: string;
37
+ title: string;
38
+ placeholder?: string;
39
+ }
40
+ declare function CustomFormTextField({ id, title, placeholder }: TextFieldProps): any;
41
+ declare function Example(): any;
42
+ export { CustomForm, CustomFormTextField, Example };
43
+ //# sourceMappingURL=custom-renderable-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-renderable-form.d.ts","sourceRoot":"","sources":["../../../src/examples/internal/custom-renderable-form.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAcH,OAAO,KAAiE,MAAM,OAAO,CAAA;AA2QrF,UAAU,eAAe;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED,iBAAS,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE,eAAe,GAAG,GAAG,CAyBtD;kBAzBQ,UAAU;;;AA+BnB,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,iBAAS,mBAAmB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,cAAc,GAAG,GAAG,CAqC5E;AASD,iBAAS,OAAO,IAAI,GAAG,CAoCtB;AAMD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,OAAO,EAAE,CAAA"}