@opentui/solid 0.1.87 → 0.1.89
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/README.md +2 -0
- package/dist/index.d.ts +5 -0
- package/index.d.ts +5 -4
- package/index.js +165 -0
- package/jsx-runtime.d.ts +1 -1
- package/package.json +9 -4
- package/scripts/preload.ts +2 -3
- package/scripts/runtime-plugin-support.d.ts +1 -0
- package/scripts/runtime-plugin-support.ts +59 -0
- package/scripts/solid-plugin.d.ts +8 -0
- package/scripts/solid-plugin.ts +139 -41
- package/src/elements/extras.d.ts +1 -1
- package/src/elements/hooks.d.ts +2 -0
- package/src/elements/index.d.ts +5 -5
- package/src/plugins/slot.d.ts +25 -0
- package/src/reconciler.d.ts +1 -1
package/README.md
CHANGED
|
@@ -128,6 +128,8 @@ Returns the current component catalogue that powers JSX tag lookup.
|
|
|
128
128
|
|
|
129
129
|
- `useRenderer()`
|
|
130
130
|
- `onResize(callback)`
|
|
131
|
+
- `onFocus(callback)`
|
|
132
|
+
- `onBlur(callback)`
|
|
131
133
|
- `useTerminalDimensions()`
|
|
132
134
|
- `useKeyboard(handler, options?)`
|
|
133
135
|
- `usePaste(handler)`
|
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ export function spread(node: any, accessor: any, skipChildren: any): void;
|
|
|
23
23
|
export function setProp(node: any, name: any, value: any, prev: any): any;
|
|
24
24
|
export function render(node: any, rendererOrConfig?: {}): Promise<void>;
|
|
25
25
|
export function onResize(callback: any): void;
|
|
26
|
+
export function onFocus(callback: any): void;
|
|
27
|
+
export function onBlur(callback: any): void;
|
|
26
28
|
declare var mergeProps3: typeof mergeProps;
|
|
27
29
|
declare function memo2(fn: any): import("solid-js").Accessor<any>;
|
|
28
30
|
export var insertNode: any;
|
|
@@ -52,7 +54,9 @@ export function getComponentCatalogue(): {
|
|
|
52
54
|
export function extend(objects: any): void;
|
|
53
55
|
export var effect: typeof createRenderEffect;
|
|
54
56
|
export var createTextNode: any;
|
|
57
|
+
export function createSolidSlotRegistry(renderer: any, context: any, options?: {}): import("@opentui/core").SlotRegistry<any, object, any>;
|
|
55
58
|
export function createSlotNode(): SlotRenderable;
|
|
59
|
+
export function createSlot(registry: any, options?: {}): (props: any) => any;
|
|
56
60
|
export var createElement: any;
|
|
57
61
|
export function createDynamic(component: any, props: any): import("solid-js").Accessor<any>;
|
|
58
62
|
declare var createComponent2: typeof createComponent;
|
|
@@ -95,6 +99,7 @@ export class SlotRenderable extends SlotBaseRenderable {
|
|
|
95
99
|
destroyed: boolean;
|
|
96
100
|
getSlotChild(parent: any): any;
|
|
97
101
|
}
|
|
102
|
+
export function Slot(props: any): import("solid-js").Accessor<any>;
|
|
98
103
|
export var RendererContext: import("solid-js").Context<any>;
|
|
99
104
|
export function Portal(props: any): SlotRenderable;
|
|
100
105
|
export class LinkRenderable extends SpanRenderable {
|
package/index.d.ts
CHANGED
|
@@ -11,8 +11,9 @@ export declare const testRender: (node: () => JSX.Element, renderConfig?: TestRe
|
|
|
11
11
|
captureSpans: () => import("@opentui/core").CapturedFrame;
|
|
12
12
|
resize: (width: number, height: number) => void;
|
|
13
13
|
}>;
|
|
14
|
-
export * from "./src/reconciler";
|
|
15
|
-
export * from "./src/elements";
|
|
16
|
-
export * from "./src/time-to-first-draw";
|
|
17
|
-
export * from "./src/
|
|
14
|
+
export * from "./src/reconciler.js";
|
|
15
|
+
export * from "./src/elements/index.js";
|
|
16
|
+
export * from "./src/time-to-first-draw.js";
|
|
17
|
+
export * from "./src/plugins/slot.js";
|
|
18
|
+
export * from "./src/types/elements.js";
|
|
18
19
|
export { type JSX };
|
package/index.js
CHANGED
|
@@ -80,6 +80,24 @@ var usePaste = (callback) => {
|
|
|
80
80
|
});
|
|
81
81
|
};
|
|
82
82
|
var useKeyHandler = useKeyboard;
|
|
83
|
+
var onFocus = (callback) => {
|
|
84
|
+
const renderer = useRenderer();
|
|
85
|
+
onMount(() => {
|
|
86
|
+
renderer.on("focus", callback);
|
|
87
|
+
});
|
|
88
|
+
onCleanup(() => {
|
|
89
|
+
renderer.off("focus", callback);
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
var onBlur = (callback) => {
|
|
93
|
+
const renderer = useRenderer();
|
|
94
|
+
onMount(() => {
|
|
95
|
+
renderer.on("blur", callback);
|
|
96
|
+
});
|
|
97
|
+
onCleanup(() => {
|
|
98
|
+
renderer.off("blur", callback);
|
|
99
|
+
});
|
|
100
|
+
};
|
|
83
101
|
var useSelectionHandler = (callback) => {
|
|
84
102
|
const renderer = useRenderer();
|
|
85
103
|
onMount(() => {
|
|
@@ -945,6 +963,148 @@ var TimeToFirstDraw = (props) => {
|
|
|
945
963
|
return _el$;
|
|
946
964
|
})();
|
|
947
965
|
};
|
|
966
|
+
// src/plugins/slot.tsx
|
|
967
|
+
import { createSlotRegistry } from "@opentui/core";
|
|
968
|
+
import { children, createMemo as createMemo3, createSignal as createSignal2, ErrorBoundary, For, onCleanup as onCleanup3, splitProps as splitProps2 } from "solid-js";
|
|
969
|
+
function createSolidSlotRegistry(renderer, context, options = {}) {
|
|
970
|
+
return createSlotRegistry(renderer, "solid:slot-registry", context, options);
|
|
971
|
+
}
|
|
972
|
+
function createSlot(registry, options = {}) {
|
|
973
|
+
return function BoundSlot(props) {
|
|
974
|
+
return createComponent2(Slot, mergeProps3(props, {
|
|
975
|
+
registry,
|
|
976
|
+
get pluginFailurePlaceholder() {
|
|
977
|
+
return options.pluginFailurePlaceholder;
|
|
978
|
+
}
|
|
979
|
+
}));
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
function Slot(props) {
|
|
983
|
+
const [local, slotProps] = splitProps2(props, ["registry", "name", "mode", "children", "pluginFailurePlaceholder"]);
|
|
984
|
+
const registry = () => local.registry;
|
|
985
|
+
const pluginFailurePlaceholder = () => local.pluginFailurePlaceholder;
|
|
986
|
+
const [version, setVersion] = createSignal2(0);
|
|
987
|
+
const unsubscribe = registry().subscribe(() => {
|
|
988
|
+
setVersion((current) => current + 1);
|
|
989
|
+
});
|
|
990
|
+
onCleanup3(unsubscribe);
|
|
991
|
+
const entries = createMemo3((previousEntries = []) => {
|
|
992
|
+
version();
|
|
993
|
+
const resolvedEntries = registry().resolveEntries(local.name);
|
|
994
|
+
const previousById = new Map(previousEntries.map((entry) => [entry.id, entry]));
|
|
995
|
+
return resolvedEntries.map((entry) => {
|
|
996
|
+
const previousEntry = previousById.get(entry.id);
|
|
997
|
+
if (previousEntry && previousEntry.renderer === entry.renderer) {
|
|
998
|
+
return previousEntry;
|
|
999
|
+
}
|
|
1000
|
+
return entry;
|
|
1001
|
+
});
|
|
1002
|
+
});
|
|
1003
|
+
const entryIds = createMemo3(() => entries().map((entry) => entry.id));
|
|
1004
|
+
const entriesById = createMemo3(() => new Map(entries().map((entry) => [entry.id, entry])));
|
|
1005
|
+
const slotName = () => String(local.name);
|
|
1006
|
+
const FallbackView = () => {
|
|
1007
|
+
const resolvedFallbackChildren = children(() => local.children);
|
|
1008
|
+
return memo2(resolvedFallbackChildren);
|
|
1009
|
+
};
|
|
1010
|
+
const renderFallback = () => {
|
|
1011
|
+
return createComponent2(FallbackView, {});
|
|
1012
|
+
};
|
|
1013
|
+
const resolveFallback = (fallbackValue) => fallbackValue?.() ?? null;
|
|
1014
|
+
const renderPluginFailurePlaceholder = (failure, fallbackValue) => {
|
|
1015
|
+
if (!pluginFailurePlaceholder()) {
|
|
1016
|
+
return resolveFallback(fallbackValue);
|
|
1017
|
+
}
|
|
1018
|
+
try {
|
|
1019
|
+
return pluginFailurePlaceholder()(failure);
|
|
1020
|
+
} catch (error) {
|
|
1021
|
+
registry().reportPluginError({
|
|
1022
|
+
pluginId: failure.pluginId,
|
|
1023
|
+
slot: failure.slot ?? slotName(),
|
|
1024
|
+
phase: "error_placeholder",
|
|
1025
|
+
source: "solid",
|
|
1026
|
+
error
|
|
1027
|
+
});
|
|
1028
|
+
return resolveFallback(fallbackValue);
|
|
1029
|
+
}
|
|
1030
|
+
};
|
|
1031
|
+
const renderEntry = (entry, fallbackOnError) => {
|
|
1032
|
+
let initialRender;
|
|
1033
|
+
try {
|
|
1034
|
+
initialRender = entry.renderer(registry().context, slotProps);
|
|
1035
|
+
} catch (error) {
|
|
1036
|
+
const failure = registry().reportPluginError({
|
|
1037
|
+
pluginId: entry.id,
|
|
1038
|
+
slot: slotName(),
|
|
1039
|
+
phase: "render",
|
|
1040
|
+
source: "solid",
|
|
1041
|
+
error
|
|
1042
|
+
});
|
|
1043
|
+
return renderPluginFailurePlaceholder(failure, fallbackOnError);
|
|
1044
|
+
}
|
|
1045
|
+
const resolvedInitialRender = children(() => initialRender);
|
|
1046
|
+
const hasInitialOutput = resolvedInitialRender.toArray().some((node) => node !== null && node !== undefined && node !== false);
|
|
1047
|
+
if (!hasInitialOutput) {
|
|
1048
|
+
return resolveFallback(fallbackOnError);
|
|
1049
|
+
}
|
|
1050
|
+
return createComponent2(ErrorBoundary, {
|
|
1051
|
+
fallback: (error) => {
|
|
1052
|
+
const failure = registry().reportPluginError({
|
|
1053
|
+
pluginId: entry.id,
|
|
1054
|
+
slot: slotName(),
|
|
1055
|
+
phase: "render",
|
|
1056
|
+
source: "solid",
|
|
1057
|
+
error
|
|
1058
|
+
});
|
|
1059
|
+
return renderPluginFailurePlaceholder(failure, fallbackOnError);
|
|
1060
|
+
},
|
|
1061
|
+
get children() {
|
|
1062
|
+
return resolvedInitialRender();
|
|
1063
|
+
}
|
|
1064
|
+
});
|
|
1065
|
+
};
|
|
1066
|
+
const AppendEntry = (appendProps) => {
|
|
1067
|
+
const entry = createMemo3(() => entriesById().get(appendProps.entryId));
|
|
1068
|
+
return memo2(() => {
|
|
1069
|
+
const resolvedEntry = entry();
|
|
1070
|
+
if (!resolvedEntry) {
|
|
1071
|
+
return null;
|
|
1072
|
+
}
|
|
1073
|
+
return renderEntry(resolvedEntry);
|
|
1074
|
+
});
|
|
1075
|
+
};
|
|
1076
|
+
const appendView = [renderFallback, createComponent2(For, {
|
|
1077
|
+
get each() {
|
|
1078
|
+
return entryIds();
|
|
1079
|
+
},
|
|
1080
|
+
children: (entryId) => createComponent2(AppendEntry, {
|
|
1081
|
+
entryId
|
|
1082
|
+
})
|
|
1083
|
+
})];
|
|
1084
|
+
return memo2(() => {
|
|
1085
|
+
const resolvedEntries = entries();
|
|
1086
|
+
const mode = local.mode ?? "append";
|
|
1087
|
+
if (resolvedEntries.length === 0) {
|
|
1088
|
+
return renderFallback();
|
|
1089
|
+
}
|
|
1090
|
+
if (mode === "single_winner") {
|
|
1091
|
+
const winner = resolvedEntries[0];
|
|
1092
|
+
if (!winner) {
|
|
1093
|
+
return renderFallback();
|
|
1094
|
+
}
|
|
1095
|
+
return renderEntry(winner, renderFallback);
|
|
1096
|
+
}
|
|
1097
|
+
if (mode === "replace") {
|
|
1098
|
+
const renderedEntries = resolvedEntries.map((entry) => renderEntry(entry));
|
|
1099
|
+
const hasPluginOutput = renderedEntries.some((entry) => entry !== null && entry !== undefined && entry !== false);
|
|
1100
|
+
if (!hasPluginOutput) {
|
|
1101
|
+
return renderFallback();
|
|
1102
|
+
}
|
|
1103
|
+
return renderedEntries;
|
|
1104
|
+
}
|
|
1105
|
+
return appendView;
|
|
1106
|
+
});
|
|
1107
|
+
}
|
|
948
1108
|
|
|
949
1109
|
// index.ts
|
|
950
1110
|
var mountSolidRoot = (renderer, node) => {
|
|
@@ -1029,6 +1189,8 @@ export {
|
|
|
1029
1189
|
setProp,
|
|
1030
1190
|
render,
|
|
1031
1191
|
onResize,
|
|
1192
|
+
onFocus,
|
|
1193
|
+
onBlur,
|
|
1032
1194
|
mergeProps3 as mergeProps,
|
|
1033
1195
|
memo2 as memo,
|
|
1034
1196
|
insertNode,
|
|
@@ -1037,7 +1199,9 @@ export {
|
|
|
1037
1199
|
extend,
|
|
1038
1200
|
effect,
|
|
1039
1201
|
createTextNode,
|
|
1202
|
+
createSolidSlotRegistry,
|
|
1040
1203
|
createSlotNode,
|
|
1204
|
+
createSlot,
|
|
1041
1205
|
createElement,
|
|
1042
1206
|
createDynamic,
|
|
1043
1207
|
createComponent2 as createComponent,
|
|
@@ -1048,6 +1212,7 @@ export {
|
|
|
1048
1212
|
TimeToFirstDraw,
|
|
1049
1213
|
TextSlotRenderable,
|
|
1050
1214
|
SlotRenderable,
|
|
1215
|
+
Slot,
|
|
1051
1216
|
RendererContext,
|
|
1052
1217
|
Portal,
|
|
1053
1218
|
LinkRenderable,
|
package/jsx-runtime.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"version": "0.1.
|
|
7
|
+
"version": "0.1.89",
|
|
8
8
|
"description": "SolidJS renderer for OpenTUI",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"repository": {
|
|
@@ -25,15 +25,19 @@
|
|
|
25
25
|
"types": "./scripts/solid-plugin.d.ts",
|
|
26
26
|
"import": "./scripts/solid-plugin.ts"
|
|
27
27
|
},
|
|
28
|
+
"./runtime-plugin-support": {
|
|
29
|
+
"types": "./scripts/runtime-plugin-support.d.ts",
|
|
30
|
+
"import": "./scripts/runtime-plugin-support.ts"
|
|
31
|
+
},
|
|
28
32
|
"./jsx-runtime": "./jsx-runtime.d.ts",
|
|
29
33
|
"./jsx-dev-runtime": "./jsx-runtime.d.ts"
|
|
30
34
|
},
|
|
31
35
|
"dependencies": {
|
|
32
36
|
"@babel/core": "7.28.0",
|
|
33
37
|
"@babel/preset-typescript": "7.27.1",
|
|
34
|
-
"@opentui/core": "0.1.
|
|
38
|
+
"@opentui/core": "0.1.89",
|
|
35
39
|
"babel-plugin-module-resolver": "5.0.2",
|
|
36
|
-
"babel-preset-solid": "1.9.
|
|
40
|
+
"babel-preset-solid": "1.9.10",
|
|
37
41
|
"entities": "7.0.1",
|
|
38
42
|
"s-js": "^0.4.9"
|
|
39
43
|
},
|
|
@@ -41,9 +45,10 @@
|
|
|
41
45
|
"@types/babel__core": "7.20.5",
|
|
42
46
|
"@types/bun": "latest",
|
|
43
47
|
"@types/node": "^24.0.0",
|
|
48
|
+
"solid-js": "1.9.11",
|
|
44
49
|
"typescript": "^5"
|
|
45
50
|
},
|
|
46
51
|
"peerDependencies": {
|
|
47
|
-
"solid-js": "1.9.
|
|
52
|
+
"solid-js": "1.9.11"
|
|
48
53
|
}
|
|
49
54
|
}
|
package/scripts/preload.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function ensureRuntimePluginSupport(): boolean;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { plugin as registerBunPlugin } from "bun"
|
|
2
|
+
import * as coreRuntime from "@opentui/core"
|
|
3
|
+
import {
|
|
4
|
+
createRuntimePlugin,
|
|
5
|
+
isCoreRuntimeModuleSpecifier,
|
|
6
|
+
runtimeModuleIdForSpecifier,
|
|
7
|
+
type RuntimeModuleEntry,
|
|
8
|
+
} from "@opentui/core/runtime-plugin"
|
|
9
|
+
import * as solidJsRuntime from "solid-js"
|
|
10
|
+
import * as solidJsStoreRuntime from "solid-js/store"
|
|
11
|
+
import * as solidRuntime from "../index"
|
|
12
|
+
import { ensureSolidTransformPlugin } from "./solid-plugin"
|
|
13
|
+
|
|
14
|
+
const runtimePluginSupportInstalledKey = Symbol.for("opentui.solid.runtime-plugin-support")
|
|
15
|
+
|
|
16
|
+
type RuntimePluginSupportState = typeof globalThis & {
|
|
17
|
+
[runtimePluginSupportInstalledKey]?: boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const additionalRuntimeModules: Record<string, RuntimeModuleEntry> = {
|
|
21
|
+
"@opentui/solid": solidRuntime as Record<string, unknown>,
|
|
22
|
+
"solid-js": solidJsRuntime as Record<string, unknown>,
|
|
23
|
+
"solid-js/store": solidJsStoreRuntime as Record<string, unknown>,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const resolveRuntimeSpecifier = (specifier: string): string | null => {
|
|
27
|
+
if (!isCoreRuntimeModuleSpecifier(specifier) && !additionalRuntimeModules[specifier]) {
|
|
28
|
+
return null
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return runtimeModuleIdForSpecifier(specifier)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function ensureRuntimePluginSupport(): boolean {
|
|
35
|
+
const state = globalThis as RuntimePluginSupportState
|
|
36
|
+
|
|
37
|
+
if (state[runtimePluginSupportInstalledKey]) {
|
|
38
|
+
return false
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
ensureSolidTransformPlugin({
|
|
42
|
+
moduleName: runtimeModuleIdForSpecifier("@opentui/solid"),
|
|
43
|
+
resolvePath(specifier) {
|
|
44
|
+
return resolveRuntimeSpecifier(specifier)
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
registerBunPlugin(
|
|
49
|
+
createRuntimePlugin({
|
|
50
|
+
core: coreRuntime as Record<string, unknown>,
|
|
51
|
+
additional: additionalRuntimeModules,
|
|
52
|
+
}),
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
state[runtimePluginSupportInstalledKey] = true
|
|
56
|
+
return true
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ensureRuntimePluginSupport()
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
import { type BunPlugin } from "bun";
|
|
2
|
+
export type ResolveImportPath = (specifier: string) => string | null;
|
|
3
|
+
export interface CreateSolidTransformPluginOptions {
|
|
4
|
+
moduleName?: string;
|
|
5
|
+
resolvePath?: ResolveImportPath;
|
|
6
|
+
}
|
|
7
|
+
export declare function ensureSolidTransformPlugin(input?: CreateSolidTransformPluginOptions): boolean;
|
|
8
|
+
export declare function resetSolidTransformPluginState(): void;
|
|
9
|
+
export declare function createSolidTransformPlugin(input?: CreateSolidTransformPluginOptions): BunPlugin;
|
|
2
10
|
declare const solidTransformPlugin: BunPlugin;
|
|
3
11
|
export default solidTransformPlugin;
|
package/scripts/solid-plugin.ts
CHANGED
|
@@ -1,51 +1,149 @@
|
|
|
1
1
|
import { transformAsync } from "@babel/core"
|
|
2
|
-
import { readFile } from "node:fs/promises"
|
|
3
2
|
// @ts-expect-error - Types not important.
|
|
4
3
|
import ts from "@babel/preset-typescript"
|
|
5
4
|
// @ts-expect-error - Types not important.
|
|
5
|
+
import moduleResolver from "babel-plugin-module-resolver"
|
|
6
|
+
// @ts-expect-error - Types not important.
|
|
6
7
|
import solid from "babel-preset-solid"
|
|
7
|
-
import { type BunPlugin } from "bun"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
8
|
+
import { plugin as registerBunPlugin, type BunPlugin } from "bun"
|
|
9
|
+
|
|
10
|
+
export type ResolveImportPath = (specifier: string) => string | null
|
|
11
|
+
|
|
12
|
+
const solidTransformStateKey = Symbol.for("opentui.solid.transform")
|
|
13
|
+
|
|
14
|
+
type SolidTransformRuntime = {
|
|
15
|
+
moduleName?: string
|
|
16
|
+
resolvePath?: ResolveImportPath
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type SolidTransformState = {
|
|
20
|
+
installed: boolean
|
|
21
|
+
runtime?: SolidTransformRuntime
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type GlobalSolidTransformState = typeof globalThis & {
|
|
25
|
+
[solidTransformStateKey]?: SolidTransformState
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface CreateSolidTransformPluginOptions {
|
|
29
|
+
moduleName?: string
|
|
30
|
+
resolvePath?: ResolveImportPath
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const getSolidTransformState = (): SolidTransformState => {
|
|
34
|
+
const state = globalThis as GlobalSolidTransformState
|
|
35
|
+
state[solidTransformStateKey] ??= { installed: false }
|
|
36
|
+
return state[solidTransformStateKey]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const getSolidTransformRuntime = (): SolidTransformRuntime => {
|
|
40
|
+
return getSolidTransformState().runtime ?? {}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const sourcePath = (path: string): string => {
|
|
44
|
+
const searchIndex = path.indexOf("?")
|
|
45
|
+
const hashIndex = path.indexOf("#")
|
|
46
|
+
const end = [searchIndex, hashIndex].filter((index) => index >= 0).sort((a, b) => a - b)[0]
|
|
47
|
+
return end === undefined ? path : path.slice(0, end)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const hasSolidTransformRuntime = (input: CreateSolidTransformPluginOptions): boolean => {
|
|
51
|
+
return input.moduleName !== undefined || input.resolvePath !== undefined
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function ensureSolidTransformPlugin(input: CreateSolidTransformPluginOptions = {}): boolean {
|
|
55
|
+
const state = getSolidTransformState()
|
|
56
|
+
|
|
57
|
+
if (hasSolidTransformRuntime(input)) {
|
|
58
|
+
state.runtime = {
|
|
59
|
+
moduleName: input.moduleName,
|
|
60
|
+
resolvePath: input.resolvePath,
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (state.installed) {
|
|
65
|
+
return false
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
registerBunPlugin(createSolidTransformPlugin())
|
|
69
|
+
state.installed = true
|
|
70
|
+
return true
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function resetSolidTransformPluginState(): void {
|
|
74
|
+
const state = getSolidTransformState()
|
|
75
|
+
state.installed = false
|
|
76
|
+
delete state.runtime
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function createSolidTransformPlugin(input: CreateSolidTransformPluginOptions = {}): BunPlugin {
|
|
80
|
+
return {
|
|
81
|
+
name: "bun-plugin-solid",
|
|
82
|
+
setup: (build) => {
|
|
83
|
+
build.onLoad(
|
|
84
|
+
{ filter: /[\/\\]node_modules[\/\\]solid-js[\/\\]dist[\/\\]server\.js(?:[?#].*)?$/ },
|
|
85
|
+
async (args) => {
|
|
86
|
+
const path = sourcePath(args.path).replace("server.js", "solid.js")
|
|
87
|
+
const file = Bun.file(path)
|
|
88
|
+
const code = await file.text()
|
|
89
|
+
return { contents: code, loader: "js" }
|
|
90
|
+
},
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
build.onLoad(
|
|
94
|
+
{ filter: /[\/\\]node_modules[\/\\]solid-js[\/\\]store[\/\\]dist[\/\\]server\.js(?:[?#].*)?$/ },
|
|
95
|
+
async (args) => {
|
|
96
|
+
const path = sourcePath(args.path).replace("server.js", "store.js")
|
|
97
|
+
const file = Bun.file(path)
|
|
98
|
+
const code = await file.text()
|
|
99
|
+
return { contents: code, loader: "js" }
|
|
100
|
+
},
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
build.onLoad({ filter: /\.(js|ts)x(?:[?#].*)?$/ }, async (args) => {
|
|
104
|
+
const path = sourcePath(args.path)
|
|
105
|
+
const file = Bun.file(path)
|
|
106
|
+
const code = await file.text()
|
|
107
|
+
const runtime = getSolidTransformRuntime()
|
|
108
|
+
const moduleName = input.moduleName ?? runtime.moduleName ?? "@opentui/solid"
|
|
109
|
+
const resolvePath = input.resolvePath ?? runtime.resolvePath
|
|
110
|
+
const plugins = resolvePath
|
|
111
|
+
? [
|
|
112
|
+
[
|
|
113
|
+
moduleResolver,
|
|
114
|
+
{
|
|
115
|
+
resolvePath(specifier: string) {
|
|
116
|
+
return resolvePath(specifier) ?? specifier
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
]
|
|
121
|
+
: []
|
|
122
|
+
|
|
123
|
+
const transforms = await transformAsync(code, {
|
|
124
|
+
filename: path,
|
|
125
|
+
plugins,
|
|
126
|
+
presets: [
|
|
127
|
+
[
|
|
128
|
+
solid,
|
|
129
|
+
{
|
|
130
|
+
moduleName,
|
|
131
|
+
generate: "universal",
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
[ts],
|
|
39
135
|
],
|
|
40
|
-
|
|
41
|
-
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
contents: transforms?.code ?? "",
|
|
140
|
+
loader: "js",
|
|
141
|
+
}
|
|
42
142
|
})
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
loader: "js",
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
},
|
|
143
|
+
},
|
|
144
|
+
}
|
|
49
145
|
}
|
|
50
146
|
|
|
147
|
+
const solidTransformPlugin = createSolidTransformPlugin()
|
|
148
|
+
|
|
51
149
|
export default solidTransformPlugin
|
package/src/elements/extras.d.ts
CHANGED
package/src/elements/hooks.d.ts
CHANGED
|
@@ -32,5 +32,7 @@ export declare const usePaste: (callback: (event: PasteEvent) => void) => void;
|
|
|
32
32
|
* @deprecated renamed to useKeyboard
|
|
33
33
|
*/
|
|
34
34
|
export declare const useKeyHandler: (callback: (key: KeyEvent) => void, options?: UseKeyboardOptions) => void;
|
|
35
|
+
export declare const onFocus: (callback: () => void) => void;
|
|
36
|
+
export declare const onBlur: (callback: () => void) => void;
|
|
35
37
|
export declare const useSelectionHandler: (callback: (selection: Selection) => void) => void;
|
|
36
38
|
export declare const useTimeline: (options?: TimelineOptions) => Timeline;
|
package/src/elements/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ASCIIFontRenderable, BoxRenderable, CodeRenderable, DiffRenderable, InputRenderable, LineNumberRenderable, MarkdownRenderable, ScrollBoxRenderable, SelectRenderable, TabSelectRenderable, TextareaRenderable, TextNodeRenderable, TextRenderable, type RenderContext, type TextNodeOptions } from "@opentui/core";
|
|
2
|
-
import type { RenderableConstructor } from "../types/elements";
|
|
3
|
-
export * from "./hooks";
|
|
4
|
-
export * from "./extras";
|
|
5
|
-
export * from "./slot";
|
|
2
|
+
import type { RenderableConstructor } from "../types/elements.js";
|
|
3
|
+
export * from "./hooks.js";
|
|
4
|
+
export * from "./extras.js";
|
|
5
|
+
export * from "./slot.js";
|
|
6
6
|
declare class SpanRenderable extends TextNodeRenderable {
|
|
7
7
|
private readonly _ctx;
|
|
8
8
|
constructor(_ctx: RenderContext | null, options: TextNodeOptions);
|
|
@@ -69,4 +69,4 @@ export declare const componentCatalogue: ComponentCatalogue;
|
|
|
69
69
|
*/
|
|
70
70
|
export declare function extend<T extends ComponentCatalogue>(objects: T): void;
|
|
71
71
|
export declare function getComponentCatalogue(): ComponentCatalogue;
|
|
72
|
-
export type { ExtendedComponentProps, ExtendedIntrinsicElements, RenderableConstructor } from "../types/elements";
|
|
72
|
+
export type { ExtendedComponentProps, ExtendedIntrinsicElements, RenderableConstructor } from "../types/elements.js";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SlotRegistry, type CliRenderer, type Plugin, type PluginContext, type PluginErrorEvent, type SlotMode, type SlotRegistryOptions } from "@opentui/core";
|
|
2
|
+
import { type JSX } from "solid-js";
|
|
3
|
+
export type { SlotMode };
|
|
4
|
+
type SlotMap = Record<string, object>;
|
|
5
|
+
export type SolidPlugin<TSlots extends SlotMap, TContext extends PluginContext = PluginContext> = Plugin<JSX.Element, TSlots, TContext>;
|
|
6
|
+
export type SolidSlotProps<TSlots extends SlotMap, K extends keyof TSlots, TContext extends PluginContext = PluginContext> = {
|
|
7
|
+
registry: SlotRegistry<JSX.Element, TSlots, TContext>;
|
|
8
|
+
name: K;
|
|
9
|
+
mode?: SlotMode;
|
|
10
|
+
children?: JSX.Element;
|
|
11
|
+
pluginFailurePlaceholder?: (failure: PluginErrorEvent) => JSX.Element;
|
|
12
|
+
} & TSlots[K];
|
|
13
|
+
export type SolidBoundSlotProps<TSlots extends SlotMap, K extends keyof TSlots> = {
|
|
14
|
+
name: K;
|
|
15
|
+
mode?: SlotMode;
|
|
16
|
+
children?: JSX.Element;
|
|
17
|
+
} & TSlots[K];
|
|
18
|
+
export type SolidRegistrySlotComponent<TSlots extends SlotMap, TContext extends PluginContext = PluginContext> = <K extends keyof TSlots>(props: SolidSlotProps<TSlots, K, TContext>) => JSX.Element;
|
|
19
|
+
export type SolidSlotComponent<TSlots extends SlotMap> = <K extends keyof TSlots>(props: SolidBoundSlotProps<TSlots, K>) => JSX.Element;
|
|
20
|
+
export interface SolidSlotOptions {
|
|
21
|
+
pluginFailurePlaceholder?: (failure: PluginErrorEvent) => JSX.Element;
|
|
22
|
+
}
|
|
23
|
+
export declare function createSolidSlotRegistry<TSlots extends SlotMap, TContext extends PluginContext = PluginContext>(renderer: CliRenderer, context: TContext, options?: SlotRegistryOptions): SlotRegistry<JSX.Element, TSlots, TContext>;
|
|
24
|
+
export declare function createSlot<TSlots extends SlotMap, TContext extends PluginContext = PluginContext>(registry: SlotRegistry<JSX.Element, TSlots, TContext>, options?: SolidSlotOptions): SolidSlotComponent<TSlots>;
|
|
25
|
+
export declare function Slot<TSlots extends SlotMap, TContext extends PluginContext = PluginContext, K extends keyof TSlots = keyof TSlots>(props: SolidSlotProps<TSlots, K, TContext>): JSX.Element;
|
package/src/reconciler.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseRenderable } from "@opentui/core";
|
|
2
|
-
import { SlotRenderable } from "./elements";
|
|
2
|
+
import { SlotRenderable } from "./elements/index.js";
|
|
3
3
|
export type DomNode = BaseRenderable;
|
|
4
4
|
export declare function createSlotNode(): SlotRenderable;
|
|
5
5
|
export declare const _render: (code: () => BaseRenderable, node: BaseRenderable) => () => void, effect: <T>(fn: (prev?: T) => T, init?: T) => void, memo: <T>(fn: () => T, equal: boolean) => () => T, createComponent: <T>(Comp: (props: T) => BaseRenderable, props: T) => BaseRenderable, createElement: (tag: string) => BaseRenderable, createTextNode: (value: string) => BaseRenderable, insertNode: (parent: BaseRenderable, node: BaseRenderable, anchor?: BaseRenderable | undefined) => void, insert: <T>(parent: any, accessor: T | (() => T), marker?: any | null, initial?: any) => BaseRenderable, spread: <T>(node: any, accessor: (() => T) | T, skipChildren?: boolean) => void, setProp: <T>(node: BaseRenderable, name: string, value: T, prev?: T | undefined) => T, mergeProps: (...sources: unknown[]) => unknown, use: <A, T>(fn: (element: BaseRenderable, arg: A) => T, element: BaseRenderable, arg: A) => T;
|