@cascadetui/solid 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 cascade
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,188 @@
1
+ # @cascadetui/solid
2
+
3
+ Solid.js support for [Cascade](https://github.com/kirosnn/cascade).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun install solid-js @cascadetui/solid
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ 1. Add jsx config to tsconfig.json:
14
+
15
+ ```json
16
+ {
17
+ "compilerOptions": {
18
+ "jsx": "preserve",
19
+ "jsxImportSource": "@cascadetui/solid"
20
+ }
21
+ }
22
+ ```
23
+
24
+ 2. Add preload script to bunfig.toml:
25
+
26
+ ```toml
27
+ preload = ["@cascadetui/solid/preload"]
28
+ ```
29
+
30
+ 3. Add render function to index.tsx:
31
+
32
+ ```tsx
33
+ import { render } from "@cascadetui/solid"
34
+
35
+ render(() => <text>Hello, World!</text>)
36
+ ```
37
+
38
+ 4. Run with `bun index.tsx`.
39
+
40
+ 5. To build use [Bun.build](https://bun.com/docs/bundler) ([source](https://github.com/kirosnn/cascade/issues/122)):
41
+
42
+ ```ts
43
+ import solidPlugin from "@cascadetui/solid/bun-plugin"
44
+
45
+ await Bun.build({
46
+ entrypoints: ["./index.tsx"],
47
+ target: "bun",
48
+ outdir: "./build",
49
+ plugins: [solidPlugin],
50
+ compile: {
51
+ target: "bun-darwin-arm64",
52
+ outfile: "app-macos",
53
+ },
54
+ })
55
+ ```
56
+
57
+ ## Table of Contents
58
+
59
+ - [Core Concepts](#core-concepts)
60
+ - [Components](#components)
61
+ - [API Reference](#api-reference)
62
+ - [render(node, rendererOrConfig?)](#rendernode-rendererorconfig)
63
+ - [testRender(node, options?)](#testrendernode-options)
64
+ - [extend(components)](#extendcomponents)
65
+ - [getComponentCatalogue()](#getcomponentcatalogue)
66
+ - [Hooks](#hooks)
67
+ - [Portal](#portal)
68
+ - [Dynamic](#dynamic)
69
+ - [Components](#components-1)
70
+ - [Layout & Display](#layout--display)
71
+ - [Input](#input)
72
+ - [Code & Diff](#code--diff)
73
+ - [Text Modifiers](#text-modifiers)
74
+
75
+ ## Core Concepts
76
+
77
+ ### Components
78
+
79
+ Cascade Solid exposes intrinsic JSX elements that map to Cascade renderables:
80
+
81
+ - **Layout & Display:** `text`, `box`, `scrollbox`, `ascii_font`
82
+ - **Input:** `input`, `textarea`, `select`, `tab_select`
83
+ - **Code & Diff:** `code`, `line_number`, `diff`
84
+ - **Text Modifiers:** `span`, `strong`, `b`, `em`, `i`, `u`, `br`, `a`
85
+
86
+ ## API Reference
87
+
88
+ ### `render(node, rendererOrConfig?)`
89
+
90
+ Render a Solid component tree into a CLI renderer. If `rendererOrConfig` is omitted, a renderer is created with default options.
91
+
92
+ ```tsx
93
+ import { render } from "@cascadetui/solid"
94
+
95
+ render(() => <App />)
96
+ ```
97
+
98
+ **Parameters:**
99
+
100
+ - `node`: Function returning a JSX element.
101
+ - `rendererOrConfig?`: `CliRenderer` instance or `CliRendererConfig`.
102
+
103
+ ### `testRender(node, options?)`
104
+
105
+ Create a test renderer for snapshots and interaction tests.
106
+
107
+ ```tsx
108
+ import { testRender } from "@cascadetui/solid"
109
+
110
+ const testSetup = await testRender(() => <App />, { width: 40, height: 10 })
111
+ ```
112
+
113
+ ### `extend(components)`
114
+
115
+ Register custom renderables as JSX intrinsic elements.
116
+
117
+ ```tsx
118
+ import { extend } from "@cascadetui/solid"
119
+
120
+ extend({ customBox: CustomBoxRenderable })
121
+ ```
122
+
123
+ ### `getComponentCatalogue()`
124
+
125
+ Returns the current component catalogue that powers JSX tag lookup.
126
+
127
+ ### Hooks
128
+
129
+ - `useRenderer()`
130
+ - `onResize(callback)`
131
+ - `useTerminalDimensions()`
132
+ - `useKeyboard(handler, options?)`
133
+ - `usePaste(handler)`
134
+ - `useSelectionHandler(handler)`
135
+ - `useTimeline(options?)`
136
+
137
+ ### `Portal`
138
+
139
+ Render children into a different mount node, useful for overlays and tooltips.
140
+
141
+ ```tsx
142
+ import { Portal } from "@cascadetui/solid"
143
+ ;<Portal mount={renderer.root}>
144
+ <box border>Overlay</box>
145
+ </Portal>
146
+ ```
147
+
148
+ ### `Dynamic`
149
+
150
+ Render arbitrary intrinsic elements or components dynamically.
151
+
152
+ ```tsx
153
+ import { Dynamic } from "@cascadetui/solid"
154
+ ;<Dynamic component={isMultiline() ? "textarea" : "input"} />
155
+ ```
156
+
157
+ ## Components
158
+
159
+ ### Layout & Display
160
+
161
+ - `text`: styled text container
162
+ - `box`: layout container with borders, padding, and flex settings
163
+ - `scrollbox`: scrollable container
164
+ - `ascii_font`: ASCII art text renderer
165
+
166
+ ### Input
167
+
168
+ - `input`: single-line text input
169
+ - `textarea`: multi-line text input
170
+ - `select`: list selection
171
+ - `tab_select`: tab-based selection
172
+
173
+ ### Code & Diff
174
+
175
+ - `code`: syntax-highlighted code blocks
176
+ - `line_number`: line-numbered code display with diff/diagnostic helpers
177
+ - `diff`: unified or split diff viewer
178
+
179
+ ### Text Modifiers
180
+
181
+ These must appear inside a `text` component:
182
+
183
+ - `span`: inline styled text
184
+ - `strong`/`b`: bold text
185
+ - `em`/`i`: italic text
186
+ - `u`: underline text
187
+ - `br`: line break
188
+ - `a`: link text with `href`
@@ -0,0 +1,154 @@
1
+ export function useTimeline(options?: {}): Timeline;
2
+ export function useTerminalDimensions(): import("solid-js").Accessor<{
3
+ width: any;
4
+ height: any;
5
+ }>;
6
+ export function useSelectionHandler(callback: any): void;
7
+ export function useRenderer(): any;
8
+ export function usePaste(callback: any): void;
9
+ export function useKeyboard(callback: any, options: any): void;
10
+ export function useKeyHandler(callback: any, options: any): void;
11
+ export function use(fn: any, element: any, arg: any): any;
12
+ export var textNodeKeys: string[];
13
+ export function testRender(node: any, renderConfig?: {}): Promise<{
14
+ renderer: import("@cascadetui/core/testing").TestRenderer;
15
+ mockInput: import("@cascadetui/core/testing").MockInput;
16
+ mockMouse: import("@cascadetui/core/testing").MockMouse;
17
+ renderOnce: () => Promise<void>;
18
+ captureCharFrame: () => string;
19
+ captureSpans: () => import("@cascadetui/core").CapturedFrame;
20
+ resize: (width: number, height: number) => void;
21
+ }>;
22
+ export function spread(node: any, accessor: any, skipChildren: any): void;
23
+ export function setProp(node: any, name: any, value: any, prev: any): any;
24
+ export function render(node: any, rendererOrConfig?: {}): Promise<void>;
25
+ export function onResize(callback: any): void;
26
+ declare var mergeProps3: typeof mergeProps;
27
+ declare function memo2(fn: any): import("solid-js").Accessor<any>;
28
+ export var insertNode: any;
29
+ export function insert(parent: any, accessor: any, marker: any, initial: any): any;
30
+ export function getComponentCatalogue(): {
31
+ box: typeof BoxRenderable;
32
+ text: typeof TextRenderable3;
33
+ input: typeof InputRenderable2;
34
+ select: typeof SelectRenderable2;
35
+ textarea: typeof TextareaRenderable;
36
+ ascii_font: typeof ASCIIFontRenderable;
37
+ tab_select: typeof TabSelectRenderable2;
38
+ scrollbox: typeof ScrollBoxRenderable2;
39
+ code: typeof CodeRenderable;
40
+ diff: typeof DiffRenderable;
41
+ line_number: typeof LineNumberRenderable;
42
+ markdown: typeof MarkdownRenderable;
43
+ span: typeof SpanRenderable;
44
+ strong: typeof BoldSpanRenderable;
45
+ b: typeof BoldSpanRenderable;
46
+ em: typeof ItalicSpanRenderable;
47
+ i: typeof ItalicSpanRenderable;
48
+ u: typeof UnderlineSpanRenderable;
49
+ br: typeof LineBreakRenderable;
50
+ a: typeof LinkRenderable;
51
+ };
52
+ export function extend(objects: any): void;
53
+ export var effect: typeof createRenderEffect;
54
+ export var createTextNode: any;
55
+ export function createSlotNode(): SlotRenderable;
56
+ export var createElement: any;
57
+ export function createDynamic(component: any, props: any): import("solid-js").Accessor<any>;
58
+ declare var createComponent2: typeof createComponent;
59
+ export namespace componentCatalogue {
60
+ export { BoxRenderable as box };
61
+ export { TextRenderable3 as text };
62
+ export { InputRenderable2 as input };
63
+ export { SelectRenderable2 as select };
64
+ export { TextareaRenderable as textarea };
65
+ export { ASCIIFontRenderable as ascii_font };
66
+ export { TabSelectRenderable2 as tab_select };
67
+ export { ScrollBoxRenderable2 as scrollbox };
68
+ export { CodeRenderable as code };
69
+ export { DiffRenderable as diff };
70
+ export { LineNumberRenderable as line_number };
71
+ export { MarkdownRenderable as markdown };
72
+ export { SpanRenderable as span };
73
+ export { BoldSpanRenderable as strong };
74
+ export { BoldSpanRenderable as b };
75
+ export { ItalicSpanRenderable as em };
76
+ export { ItalicSpanRenderable as i };
77
+ export { UnderlineSpanRenderable as u };
78
+ export { LineBreakRenderable as br };
79
+ export { LinkRenderable as a };
80
+ }
81
+ export namespace baseComponents { }
82
+ export function _render(code: any, element: any): undefined;
83
+ export class UnderlineSpanRenderable extends TextModifierRenderable {
84
+ constructor(options: any);
85
+ }
86
+ export class TextSlotRenderable extends TextNodeRenderable3 {
87
+ constructor(id: any, parent: any);
88
+ slotParent: any;
89
+ destroyed: boolean;
90
+ }
91
+ export class SlotRenderable extends SlotBaseRenderable {
92
+ layoutNode: any;
93
+ textNode: any;
94
+ destroyed: boolean;
95
+ getSlotChild(parent: any): any;
96
+ }
97
+ export var RendererContext: import("solid-js").Context<any>;
98
+ export function Portal(props: any): SlotRenderable;
99
+ export class LinkRenderable extends SpanRenderable {
100
+ }
101
+ export class LineBreakRenderable extends SpanRenderable {
102
+ add(): number;
103
+ }
104
+ export class LayoutSlotRenderable extends SlotBaseRenderable {
105
+ constructor(id: any, parent: any);
106
+ yogaNode: Yoga.Node;
107
+ slotParent: any;
108
+ destroyed: boolean;
109
+ getLayoutNode(): Yoga.Node;
110
+ updateFromLayout(): void;
111
+ updateLayout(): void;
112
+ onRemove(): void;
113
+ }
114
+ export class ItalicSpanRenderable extends TextModifierRenderable {
115
+ constructor(options: any);
116
+ }
117
+ export function Dynamic(props: any): import("solid-js").Accessor<any>;
118
+ export class BoldSpanRenderable extends TextModifierRenderable {
119
+ constructor(options: any);
120
+ }
121
+ import { Timeline } from "@cascadetui/core";
122
+ import { mergeProps } from "solid-js";
123
+ import { BoxRenderable } from "@cascadetui/core";
124
+ import { TextRenderable as TextRenderable3 } from "@cascadetui/core";
125
+ import { InputRenderable as InputRenderable2 } from "@cascadetui/core";
126
+ import { SelectRenderable as SelectRenderable2 } from "@cascadetui/core";
127
+ import { TextareaRenderable } from "@cascadetui/core";
128
+ import { ASCIIFontRenderable } from "@cascadetui/core";
129
+ import { TabSelectRenderable as TabSelectRenderable2 } from "@cascadetui/core";
130
+ import { ScrollBoxRenderable as ScrollBoxRenderable2 } from "@cascadetui/core";
131
+ import { CodeRenderable } from "@cascadetui/core";
132
+ import { DiffRenderable } from "@cascadetui/core";
133
+ import { LineNumberRenderable } from "@cascadetui/core";
134
+ import { MarkdownRenderable } from "@cascadetui/core";
135
+ declare class SpanRenderable extends TextNodeRenderable3 {
136
+ constructor(_ctx: any, options: any);
137
+ _ctx: any;
138
+ }
139
+ import { createRenderEffect } from "solid-js";
140
+ import { createComponent } from "solid-js";
141
+ declare class TextModifierRenderable extends SpanRenderable {
142
+ }
143
+ import { TextNodeRenderable as TextNodeRenderable3 } from "@cascadetui/core";
144
+ declare class SlotBaseRenderable extends BaseRenderable {
145
+ constructor(id: any);
146
+ add(obj: any, index: any): void;
147
+ remove(id: any): void;
148
+ insertBefore(obj: any, anchor: any): void;
149
+ getRenderable(id: any): void;
150
+ findDescendantById(id: any): void;
151
+ }
152
+ import { Yoga } from "@cascadetui/core";
153
+ import { BaseRenderable } from "@cascadetui/core";
154
+ export { mergeProps3 as mergeProps, memo2 as memo, createComponent2 as createComponent };
package/index.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { CliRenderer, type CliRendererConfig } from "@cascadetui/core";
2
+ import { type TestRendererOptions } from "@cascadetui/core/testing";
3
+ import type { JSX } from "./jsx-runtime";
4
+ export declare const render: (node: () => JSX.Element, rendererOrConfig?: CliRenderer | CliRendererConfig) => Promise<void>;
5
+ export declare const testRender: (node: () => JSX.Element, renderConfig?: TestRendererOptions) => Promise<{
6
+ renderer: import("@cascadetui/core/testing").TestRenderer;
7
+ mockInput: import("@cascadetui/core/testing").MockInput;
8
+ mockMouse: import("@cascadetui/core/testing").MockMouse;
9
+ renderOnce: () => Promise<void>;
10
+ captureCharFrame: () => string;
11
+ captureSpans: () => import("@cascadetui/core").CapturedFrame;
12
+ resize: (width: number, height: number) => void;
13
+ }>;
14
+ export * from "./src/reconciler";
15
+ export * from "./src/elements";
16
+ export * from "./src/types/elements";
17
+ export { type JSX };