Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solid #2

Merged
merged 4 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion flex/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@r-tui/flex",
"version": "0.1.6",
"version": "0.1.7",
"description": "",
"main": "dist/index.js",
"types": "dist/index.d.js",
Expand Down
32 changes: 19 additions & 13 deletions flex/src/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,29 +172,27 @@ export function appendChildNode<D extends BaseDom>(
}

export function insertBeforeNode<D extends BaseDom>(
parent: D,
node: D,
newChildNode: D,
beforeChildNode: D,
): void {
if (newChildNode.parentNode) {
removeChildNode(newChildNode.parentNode, newChildNode)
anchor: D,
) {
if (node.parentNode) {
removeChildNode(node.parentNode, node)
}

newChildNode.parentNode = node
node.parentNode = parent

const index = node.childNodes.indexOf(beforeChildNode)
const index = parent.childNodes.indexOf(anchor)
if (index >= 0) {
node.childNodes.splice(index, 0, newChildNode)
parent.childNodes.splice(index, 0, node)
return
}

node.childNodes.push(newChildNode)
parent.childNodes.push(node)
return parent.childNodes
}

export function removeChildNode<D extends BaseDom>(
node: D,
removeNode: D,
): void {
export function removeChildNode<D extends BaseDom>(node: D, removeNode: D) {
removeNode.parentNode = undefined

const index = node.childNodes.indexOf(removeNode)
Expand All @@ -211,3 +209,11 @@ export function setAttribute<D extends BaseDom>(
// @ts-ignore
node.attributes[key] = value
}

export function getNextSibling<D extends BaseDom>(node: D) {
if (!node || !node.parentNode) return
const childNodes = node.parentNode.childNodes
const i = childNodes.indexOf(node)
if (i < 0 || i >= childNodes.length) return
return childNodes[i + 1]
}
21 changes: 6 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@
"name": "r-tui",
"version": "0.0.0",
"private": true,
"files": [
"dist",
"readme.md",
"package.json"
],
"files": ["dist", "readme.md", "package.json"],
"description": "react terminal UI",
"scripts": {
"case-police": "case-police \"**/*.ts\" fix",
Expand All @@ -23,12 +19,7 @@
"release": "pnpm publish -r --access public",
"release-alpha": "pnpm publish -r --access public --tag alpha"
},
"keywords": [
"TS",
"React",
"r-tui",
"terminal"
],
"keywords": ["TS", "React", "r-tui", "terminal"],
"author": "ahaoboy",
"license": "MIT",
"devDependencies": {
Expand All @@ -46,10 +37,10 @@
"case-police": "^0.6.1",
"core-js": "^3.37.1",
"dotenv": "^16.4.5",
"esbuild": "^0.19.12",
"tsx": "^4.16.0",
"typescript": "^5.5.2",
"vitest": "^1.6.0"
},
"packageManager": "[email protected]+sha256.691fe176eea9a8a80df20e4976f3dfb44a04841ceb885638fe2a26174f81e65e"
"vitest": "^1.6.0",
"esbuild": "^0.23.0",
"esbuild-plugin-solid": "^0.6.0"
}
}
3 changes: 2 additions & 1 deletion pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ packages:
- 'canvas'
- 'share'
- 'terminal'
- 'flex'
- 'flex'
- 'solid'
2 changes: 1 addition & 1 deletion react/src/examples/cmd.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useMemo, useState } from "react"
import { Box } from "../"
import { useReadLine } from "../hook/input"
import { useReadLine } from "../hook"
import { spawn } from "node:child_process"

export default function App() {
Expand Down
2 changes: 1 addition & 1 deletion react/src/examples/echo.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react"
import { Box } from "../"
import { useReadLine } from "../hook/input"
import { useReadLine } from "../hook"

export default function App() {
const data = useReadLine()
Expand Down
2 changes: 1 addition & 1 deletion react/src/examples/input.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react"
import { Box } from "../"
import { useInput } from "../hook/input"
import { useInput } from "../hook"

export default function App() {
const key = useInput()
Expand Down
6 changes: 2 additions & 4 deletions react/src/examples/ls.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useRef, useState } from "react"
import { Box, render } from "../"
import { Box } from "../"
import child_process from "node:child_process"
import { Down, Enter, Tab, Up, offInput, onInput } from "../hook/input"
import { Down, Enter, Tab, Up, offInput, onInput } from "../hook"

type Info = {
name: string
Expand Down Expand Up @@ -96,5 +96,3 @@ export default function App() {
</Box>
)
}

render(<App />)
2 changes: 1 addition & 1 deletion react/src/examples/move-box.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react"
import { Box } from "../"
import { Down, Left, Right, Up, onInput } from "../hook/input"
import { Down, Left, Right, Up, onInput } from "../hook"

export default function App() {
const [x, setX] = useState(0)
Expand Down
2 changes: 1 addition & 1 deletion react/src/examples/readline.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react"
import { Box } from "../"
import { useReadLine } from "../hook/input"
import { useReadLine } from "../hook"

export default function App() {
const data = useReadLine()
Expand Down
2 changes: 1 addition & 1 deletion react/src/examples/snake.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { choice, Color } from "@r-tui/share"
import React, { useEffect, useRef, useState } from "react"
import { Box } from "../ui"
import { onInput } from "../hook/input"
import { onInput } from "../hook"
import { getTerminalShape } from "@r-tui/terminal"

const initSnakeLen = 10
Expand Down
3 changes: 1 addition & 2 deletions react/src/ui/box.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from "react"
import { forwardRef } from "react"
import type { TDom, TDomProps } from "../render/flex"
import type { BaseDomProps } from "@r-tui/flex"
import type { TDom } from "../render/flex"

export const Box = forwardRef<
TDom,
Expand Down
19 changes: 19 additions & 0 deletions solid/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { build } from "esbuild"
import { solidPlugin } from "./esbuild-plugin-solid"

build({
entryPoints: ["./src/examples/index.tsx"],
bundle: true,
outdir: "bundle",
// TODO: solid not support node platform?
// platform:"node",
external: ["fs", "node:child_process"],
plugins: [
solidPlugin({
solid: {
moduleName: "@r-tui/solid",
generate: "universal",
},
}),
],
}).catch(() => process.exit(1))
121 changes: 121 additions & 0 deletions solid/esbuild-plugin-solid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { Plugin } from "esbuild"
import { parse } from "node:path"
import { readFile } from "node:fs/promises"
// @ts-ignore
import { transformAsync, TransformOptions } from "@babel/core"
// @ts-ignore
import solid from "babel-preset-solid"
// @ts-ignore
import ts from "@babel/preset-typescript"

// These options are partly taken from vite-plugin-solid:

/** Configuration options for esbuild-plugin-solid */
export interface Options {
/** The options to use for @babel/preset-typescript @default {} */
typescript?: object
/**
* Pass any additional babel transform options. They will be merged with
* the transformations required by Solid.
*
* @default {}
*/
babel?:
| TransformOptions
| ((source: string, id: string, ssr: boolean) => TransformOptions)
| ((source: string, id: string, ssr: boolean) => Promise<TransformOptions>)
/**
* Pass any additional [babel-plugin-jsx-dom-expressions](https://github.com/ryansolid/dom-expressions/tree/main/packages/babel-plugin-jsx-dom-expressions#plugin-options).
* They will be merged with the defaults sets by [babel-preset-solid](https://github.com/solidjs/solid/blob/main/packages/babel-preset-solid/index.js#L8-L25).
*
* @default {}
*/
solid?: {
/**
* The name of the runtime module to import the methods from.
*
* @default "solid-js/web"
*/
moduleName?: string

/**
* The output mode of the compiler.
* Can be:
* - "dom" is standard output
* - "ssr" is for server side rendering of strings.
* - "universal" is for using custom renderers from solid-js/universal
*
* @default "dom"
*/
generate?: "ssr" | "dom" | "universal"

/**
* Indicate whether the output should contain hydratable markers.
*
* @default false
*/
hydratable?: boolean

/**
* Boolean to indicate whether to enable automatic event delegation on camelCase.
*
* @default true
*/
delegateEvents?: boolean

/**
* Boolean indicates whether smart conditional detection should be used.
* This optimizes simple boolean expressions and ternaries in JSX.
*
* @default true
*/
wrapConditionals?: boolean

/**
* Boolean indicates whether to set current render context on Custom Elements and slots.
* Useful for seemless Context API with Web Components.
*
* @default true
*/
contextToCustomElements?: boolean

/**
* Array of Component exports from module, that aren't included by default with the library.
* This plugin will automatically import them if it comes across them in the JSX.
*
* @default ["For","Show","Switch","Match","Suspense","SuspenseList","Portal","Index","Dynamic","ErrorBoundary"]
*/
builtIns?: string[]
}
}

export function solidPlugin(options?: Options): Plugin {
return {
name: "esbuild:solid",

setup(build) {
build.onLoad({ filter: /\.(t|j)sx$/ }, async (args) => {
const source = await readFile(args.path, { encoding: "utf-8" })

const { name, ext } = parse(args.path)
const filename = name + ext

const result = await transformAsync(source, {
presets: [
[solid, options?.solid ?? {}],
[ts, options?.typescript ?? {}],
],
filename,
sourceMaps: "inline",
...(options?.babel ?? {}),
})

if (result?.code === undefined || result.code === null) {
throw new Error("No result was provided from Babel")
}

return { contents: result.code, loader: "js" }
})
},
}
}
45 changes: 45 additions & 0 deletions solid/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "@r-tui/solid",
"version": "0.1.2",
"description": "@r-tui/solid",
"main": "dist/index.js",
"types": "dist/index.d.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"module": "./dist/index.js"
},
"./examples": {
"types": "./dist/examples/index.d.ts",
"import": "./dist/examples/index.js",
"module": "./dist/examples/index.js"
}
},
"scripts": {
"bundle": "tsx ./build.ts",
"build": "tsc -p ./tsconfig.build.json",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@r-tui/canvas": "workspace:*",
"@r-tui/flex": "workspace:*",
"@r-tui/share": "workspace:*",
"@r-tui/terminal": "workspace:*",
"e-color": "^0.1.3",
"lodash-es": "^4.17.21",
"@r-tui/solid": "workspace:*"
},
"devDependencies": {
"solid-js": "^1.8.19",
"babel-preset-solid": "^1.8.19",
"@babel/core": "^7.24.7",
"@babel/preset-typescript": "^7.24.7"
},
"peerDependencies": {
"solid-js": "^1.8.19"
}
}
5 changes: 5 additions & 0 deletions solid/src/examples/base.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Box } from "@r-tui/solid"

export default function App() {
return <Box color="green" text="hello" />
}
Loading