page.mdx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. import { pageMetadata } from "@/lib/page-metadata"
  2. export const metadata = pageMetadata("docs/api/ink")
  3. # @json-render/ink
  4. Terminal renderer for [Ink](https://github.com/vadimdemedes/ink) with multiple standard components, providers, hooks, and streaming support.
  5. ## Installation
  6. <PackageInstall packages="@json-render/core @json-render/ink" />
  7. Peer dependencies: `react ^18.0.0 || ^19.0.0`, `ink ^6.0.0`, and `zod ^4.0.0`.
  8. <PackageInstall packages="react ink zod" />
  9. ## Standard Components
  10. ### Layout
  11. <table>
  12. <thead>
  13. <tr><th>Component</th><th>Props</th><th>Description</th></tr>
  14. </thead>
  15. <tbody>
  16. <tr><td><code>Box</code></td><td><code>flexDirection</code>, <code>alignItems</code>, <code>justifyContent</code>, <code>gap</code>, <code>padding</code>, <code>margin</code>, <code>borderStyle</code>, <code>borderColor</code>, <code>width</code>, <code>height</code>, <code>display</code>, <code>overflow</code></td><td>Flexbox layout container (like a terminal div)</td></tr>
  17. <tr><td><code>Spacer</code></td><td>(none)</td><td>Flexible empty space that expands to fill available room</td></tr>
  18. <tr><td><code>Newline</code></td><td><code>count</code></td><td>Insert blank lines</td></tr>
  19. </tbody>
  20. </table>
  21. ### Content
  22. <table>
  23. <thead>
  24. <tr><th>Component</th><th>Props</th><th>Description</th></tr>
  25. </thead>
  26. <tbody>
  27. <tr><td><code>Text</code></td><td><code>text</code>, <code>color</code>, <code>bold</code>, <code>italic</code>, <code>underline</code>, <code>strikethrough</code>, <code>dimColor</code>, <code>inverse</code>, <code>wrap</code></td><td>Text output with styling</td></tr>
  28. <tr><td><code>Heading</code></td><td><code>text</code>, <code>level</code> (h1-h4), <code>color</code></td><td>Section heading</td></tr>
  29. <tr><td><code>Divider</code></td><td><code>character</code>, <code>color</code>, <code>dimColor</code>, <code>title</code>, <code>width</code></td><td>Horizontal separator line with optional title</td></tr>
  30. <tr><td><code>Badge</code></td><td><code>label</code>, <code>variant</code></td><td>Colored inline label (default, info, success, warning, error)</td></tr>
  31. <tr><td><code>Spinner</code></td><td><code>label</code>, <code>color</code></td><td>Animated loading spinner</td></tr>
  32. <tr><td><code>ProgressBar</code></td><td><code>progress</code> (0-1), <code>width</code>, <code>color</code>, <code>label</code></td><td>Horizontal progress bar</td></tr>
  33. <tr><td><code>StatusLine</code></td><td><code>text</code>, <code>status</code>, <code>icon</code></td><td>Status message with colored icon</td></tr>
  34. <tr><td><code>KeyValue</code></td><td><code>label</code>, <code>value</code>, <code>labelColor</code>, <code>separator</code></td><td>Key-value pair display</td></tr>
  35. <tr><td><code>Link</code></td><td><code>url</code>, <code>label</code>, <code>color</code></td><td>Renders a URL as underlined text. Shows "label (url)" when label is provided.</td></tr>
  36. <tr><td><code>Markdown</code></td><td><code>text</code></td><td>Renders markdown with terminal styling (headings, bold, italic, code, lists, blockquotes, horizontal rules)</td></tr>
  37. </tbody>
  38. </table>
  39. ### Data
  40. <table>
  41. <thead>
  42. <tr><th>Component</th><th>Props</th><th>Description</th></tr>
  43. </thead>
  44. <tbody>
  45. <tr><td><code>Table</code></td><td><code>columns</code>, <code>rows</code>, <code>borderStyle</code>, <code>headerColor</code></td><td>Tabular data with headers</td></tr>
  46. <tr><td><code>List</code></td><td><code>items</code>, <code>ordered</code>, <code>bulletChar</code>, <code>spacing</code></td><td>Bulleted or numbered list</td></tr>
  47. <tr><td><code>ListItem</code></td><td><code>title</code>, <code>subtitle</code>, <code>leading</code>, <code>trailing</code></td><td>Structured list row</td></tr>
  48. <tr><td><code>Card</code></td><td><code>title</code>, <code>borderStyle</code>, <code>borderColor</code>, <code>padding</code></td><td>Bordered container with optional title</td></tr>
  49. <tr><td><code>Sparkline</code></td><td><code>data</code>, <code>width</code>, <code>color</code>, <code>label</code>, <code>min</code>, <code>max</code></td><td>Inline sparkline chart using Unicode blocks (▁▂▃▄▅▆▇█)</td></tr>
  50. <tr><td><code>BarChart</code></td><td><code>data</code> (label/value/color), <code>width</code>, <code>showValues</code>, <code>showPercentage</code></td><td>Horizontal bar chart for comparing values</td></tr>
  51. </tbody>
  52. </table>
  53. ### Interactive
  54. <table>
  55. <thead>
  56. <tr><th>Component</th><th>Props</th><th>Description</th></tr>
  57. </thead>
  58. <tbody>
  59. <tr><td><code>TextInput</code></td><td><code>placeholder</code>, <code>value</code> (use <code>$bindState</code>), <code>label</code>, <code>mask</code></td><td>Text input field. Press Enter to submit.</td></tr>
  60. <tr><td><code>Select</code></td><td><code>options</code>, <code>value</code> (use <code>$bindState</code>), <code>label</code></td><td>Arrow-key selection menu</td></tr>
  61. <tr><td><code>MultiSelect</code></td><td><code>options</code>, <code>value</code> (use <code>$bindState</code>), <code>label</code>, <code>min</code>, <code>max</code></td><td>Multi-selection menu. Space to toggle, Enter to confirm.</td></tr>
  62. <tr><td><code>ConfirmInput</code></td><td><code>message</code>, <code>defaultValue</code>, <code>yesLabel</code>, <code>noLabel</code></td><td>Yes/No confirmation prompt. Press Y or N.</td></tr>
  63. <tr><td><code>Tabs</code></td><td><code>tabs</code>, <code>value</code> (use <code>$bindState</code>), <code>color</code></td><td>Tab bar navigation with left/right arrow keys. Place child content inside with visible conditions.</td></tr>
  64. </tbody>
  65. </table>
  66. ## Providers
  67. ### JSONUIProvider
  68. Convenience wrapper around all providers: `StateProvider` → `VisibilityProvider` → `ValidationProvider` → `ActionProvider` → `FocusProvider`.
  69. ```tsx
  70. import { JSONUIProvider, Renderer } from "@json-render/ink";
  71. <JSONUIProvider initialState={{}} handlers={handlers}>
  72. <Renderer spec={spec} registry={registry} />
  73. </JSONUIProvider>
  74. ```
  75. ### StateProvider
  76. ```tsx
  77. <StateProvider initialState={object} onStateChange={fn}>
  78. {children}
  79. </StateProvider>
  80. ```
  81. <table>
  82. <thead>
  83. <tr><th>Prop</th><th>Type</th><th>Description</th></tr>
  84. </thead>
  85. <tbody>
  86. <tr><td><code>store</code></td><td><code>StateStore</code></td><td>External store (controlled mode). When provided, <code>initialState</code> and <code>onStateChange</code> are ignored.</td></tr>
  87. <tr><td><code>initialState</code></td><td><code>Record&lt;string, unknown&gt;</code></td><td>Initial state model (uncontrolled mode).</td></tr>
  88. <tr><td><code>onStateChange</code></td><td><code>{'(changes: Array<{ path: string; value: unknown }>) => void'}</code></td><td>Callback when state changes (uncontrolled mode).</td></tr>
  89. </tbody>
  90. </table>
  91. #### External Store (Controlled Mode)
  92. Pass a `StateStore` to bypass internal state and wire json-render to any state management:
  93. ```tsx
  94. import { createStateStore } from "@json-render/ink";
  95. const store = createStateStore({ count: 0 });
  96. <StateProvider store={store}>
  97. {children}
  98. </StateProvider>
  99. // Mutate from anywhere — components re-render automatically:
  100. store.set("/count", 1);
  101. ```
  102. The `store` prop is also available on `JSONUIProvider` and `createRenderer`.
  103. ### ActionProvider
  104. ```tsx
  105. <ActionProvider handlers={Record<string, ActionHandler>} navigate={fn}>
  106. {children}
  107. </ActionProvider>
  108. ```
  109. Built-in actions: `setState`, `pushState`, `removeState`, `log`, `exit`. Custom handlers override built-ins. Includes a terminal confirmation dialog (press Y/N) for actions with `confirm`.
  110. ### VisibilityProvider
  111. ```tsx
  112. <VisibilityProvider>
  113. {children}
  114. </VisibilityProvider>
  115. ```
  116. ### ValidationProvider
  117. ```tsx
  118. <ValidationProvider>
  119. {children}
  120. </ValidationProvider>
  121. ```
  122. ### FocusProvider
  123. ```tsx
  124. <FocusProvider>
  125. {children}
  126. </FocusProvider>
  127. ```
  128. Manages Tab-cycling focus between interactive components (TextInput, Select). Supports `useFocusDisable` to suppress cycling during modal dialogs.
  129. ## defineRegistry
  130. Create a type-safe component registry. Standard components are built-in; only register custom components.
  131. ```tsx
  132. import { defineRegistry, type Components } from "@json-render/ink";
  133. const { registry, handlers, executeAction } = defineRegistry(catalog, {
  134. components: {
  135. MyWidget: ({ props }) => <Text>{props.label}</Text>,
  136. } as Components<typeof catalog>,
  137. actions: {
  138. submit: async (params, setState, state) => {
  139. // custom action logic
  140. },
  141. },
  142. });
  143. ```
  144. `handlers` is designed for `JSONUIProvider`/`ActionProvider`. `executeAction` is an imperative helper.
  145. ## createRenderer
  146. Higher-level helper that wraps `Renderer` + all providers into a single component.
  147. ```tsx
  148. import { createRenderer } from "@json-render/ink";
  149. const UIRenderer = createRenderer(catalog, components);
  150. <UIRenderer spec={spec} state={initialState} />;
  151. ```
  152. ## Hooks
  153. ### useUIStream
  154. ```typescript
  155. const {
  156. spec, // Spec | null - current UI state
  157. isStreaming, // boolean - true while streaming
  158. error, // Error | null
  159. send, // (prompt: string, context?: Record<string, unknown>) => Promise<void>
  160. stop, // () => void - abort the current stream
  161. clear, // () => void - reset spec and error
  162. } = useUIStream({
  163. api: string,
  164. onComplete?: (spec: Spec) => void,
  165. onError?: (error: Error) => void,
  166. fetch?: (url: string, init?: RequestInit) => Promise<Response>,
  167. validate?: boolean,
  168. maxRetries?: number,
  169. });
  170. ```
  171. ### useStateStore
  172. ```typescript
  173. const { state, get, set, update } = useStateStore();
  174. ```
  175. ### useStateValue
  176. ```typescript
  177. const value = useStateValue(path: string);
  178. ```
  179. ### useBoundProp
  180. ```typescript
  181. const [value, setValue] = useBoundProp(resolvedValue, bindingPath);
  182. ```
  183. ### useActions
  184. ```typescript
  185. const { execute } = useActions();
  186. ```
  187. ### useIsVisible
  188. ```typescript
  189. const isVisible = useIsVisible(condition?: VisibilityCondition);
  190. ```
  191. ### useFocus
  192. ```typescript
  193. const { isActive, id } = useFocus();
  194. ```
  195. ### useFocusDisable
  196. ```typescript
  197. useFocusDisable(disabled: boolean);
  198. ```
  199. Suppresses Tab-cycling while `disabled` is true (e.g., during a modal dialog).
  200. ## Catalog Exports
  201. ```typescript
  202. import { standardComponentDefinitions, standardActionDefinitions } from "@json-render/ink/catalog";
  203. import { schema } from "@json-render/ink/schema";
  204. ```
  205. <table>
  206. <thead>
  207. <tr><th>Export</th><th>Purpose</th></tr>
  208. </thead>
  209. <tbody>
  210. <tr><td><code>standardComponentDefinitions</code></td><td>Catalog definitions for all 19 standard components</td></tr>
  211. <tr><td><code>standardActionDefinitions</code></td><td>Catalog definitions for standard actions (setState, pushState, removeState, log, exit)</td></tr>
  212. <tr><td><code>schema</code></td><td>Ink element tree schema</td></tr>
  213. </tbody>
  214. </table>
  215. ## Server Export
  216. ```typescript
  217. import { schema, standardComponentDefinitions, standardActionDefinitions } from "@json-render/ink/server";
  218. ```
  219. Re-exports the schema and catalog definitions for server-side usage (e.g., building system prompts).