diff --git a/examples/Hello.fixture.tsx b/examples/Hello.fixture.tsx deleted file mode 100644 index c8c2db3..0000000 --- a/examples/Hello.fixture.tsx +++ /dev/null @@ -1 +0,0 @@ -export default

hello world

diff --git a/examples/cube.fixture.tsx b/examples/cube.fixture.tsx new file mode 100644 index 0000000..f4fd457 --- /dev/null +++ b/examples/cube.fixture.tsx @@ -0,0 +1,8 @@ +import { Cube } from "../lib" +import { JsCadFixture } from "../lib/components/jscad-fixture" + +export default () => ( + + + +) diff --git a/examples/sphere.fixture.tsx b/examples/sphere.fixture.tsx new file mode 100644 index 0000000..38a0148 --- /dev/null +++ b/examples/sphere.fixture.tsx @@ -0,0 +1,8 @@ +import { Sphere } from "../lib" +import { JsCadFixture } from "../lib/components/jscad-fixture" + +export default () => ( + + + +) diff --git a/examples/JSCadShape.fixture.tsx b/lib/components/jscad-fixture.tsx similarity index 86% rename from examples/JSCadShape.fixture.tsx rename to lib/components/jscad-fixture.tsx index 9817bbe..c0d6dd8 100644 --- a/examples/JSCadShape.fixture.tsx +++ b/lib/components/jscad-fixture.tsx @@ -1,30 +1,27 @@ import React from "react" -import { createJSCADRenderer, Cube, Sphere } from "../lib" +import { createJSCADRenderer, Cube, Sphere } from "../../lib" import * as jscad from "@jscad/modeling" import * as THREE from "three" // @ts-ignore import { OrbitControls } from "three/examples/jsm/controls/OrbitControls" -import convertCSGToThreeGeom from "../lib/convert-csg-to-three-geom" +import convertCSGToThreeGeom from "../../lib/convert-csg-to-three-geom" -const { createJSCADRoot } = createJSCADRenderer(jscad) +const { createJSCADRoot } = createJSCADRenderer(jscad as any) -function Scene() { - return ( - <> - - - - ) -} - -export default function JSCadShapeFixture() { +export function JsCadFixture({ + children, + wireframe, +}: { + children: any + wireframe?: boolean +}) { const containerRef = React.useRef(null) React.useEffect(() => { if (containerRef.current) { const jscadGeoms: any[] = [] const root = createJSCADRoot(jscadGeoms) - root.render() + root.render(children) // Here, you would typically use the container to render the 3D shape // For this example, we'll just log the result @@ -60,7 +57,7 @@ export default function JSCadShapeFixture() { console.log(geometry) const material = new THREE.MeshStandardMaterial({ color: 0xffffff, - wireframe: true, + wireframe, }) const cube = new THREE.Mesh(geometry, material) scene.add(cube) diff --git a/lib/create-host-config.ts b/lib/create-host-config.ts new file mode 100644 index 0000000..114b310 --- /dev/null +++ b/lib/create-host-config.ts @@ -0,0 +1,118 @@ +export function createHostConfig(jscad: JSCADModule) { + const hostConfig: ReactReconciler.HostConfig< + string, // Type + Props, // Props + JSCADPrimitive, // Container + JSCADPrimitive, // Instance + never, // TextInstance + never, // SuspenseInstance + never, // HydratableInstance + JSCADPrimitive, // PublicInstance + {}, // HostContext + boolean, // UpdatePayload + never, // ChildSet + number, // TimeoutHandle + number // NoTimeout + > = { + now: Date.now, + supportsMutation: true, + supportsPersistence: false, + supportsHydration: false, + + createInstance( + type: string, + props: Props, + rootContainerInstance: any, + hostContext: any, + internalInstanceHandle: any + ) { + switch (type) { + case "cube": + return jscad.primitives.cube({ size: (props as CubeProps).size }) + case "sphere": + return jscad.primitives.sphere({ + radius: (props as SphereProps).radius, + }) + default: + throw new Error(`Unknown element type: ${type}`) + } + }, + + createTextInstance() { + throw new Error("Text elements are not supported in JSCAD") + }, + + appendInitialChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) { + return jscad.booleans.union(parentInstance, child) as JSCADPrimitive + }, + + appendChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) { + return jscad.booleans.union(parentInstance, child) as JSCADPrimitive + }, + + removeChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) { + return jscad.booleans.subtract(parentInstance, child) as JSCADPrimitive + }, + + appendChildToContainer(container: JSCADPrimitive[], child: JSCADPrimitive) { + container.push(child) + }, + + removeChildFromContainer( + container: JSCADPrimitive[], + child: JSCADPrimitive + ) { + const index = container.indexOf(child) + if (index !== -1) container.splice(index, 1) + }, + + prepareUpdate() { + return true + }, + + commitUpdate( + instance: JSCADPrimitive, + updatePayload: any, + type: string, + oldProps: Props, + newProps: Props + ) { + // Re-create the instance with new props + return this.createInstance(type, newProps, instance, {}, null) + }, + + finalizeInitialChildren() { + return false + }, + + prepareForCommit() { + return null + }, + resetAfterCommit() {}, + getPublicInstance(instance: JSCADPrimitive) { + return instance + }, + getRootHostContext() { + return {} + }, + getChildHostContext() { + return {} + }, + shouldSetTextContent() { + return false + }, + clearContainer() {}, + scheduleTimeout: setTimeout, + cancelTimeout: clearTimeout, + noTimeout: -1, + isPrimaryRenderer: true, + getCurrentEventPriority: () => 99, + getInstanceFromNode: () => null, + beforeActiveInstanceBlur: () => {}, + afterActiveInstanceBlur: () => {}, + prepareScopeUpdate: () => {}, + getInstanceFromScope: () => null, + detachDeletedInstance: () => {}, + } + return hostConfig +} diff --git a/lib/index.tsx b/lib/index.tsx index 0e4cfc7..244f359 100644 --- a/lib/index.tsx +++ b/lib/index.tsx @@ -1,157 +1,11 @@ import ReactReconciler from "react-reconciler" import React from "react" - -// Define a type for the JSCAD module structure we expect -interface JSCADModule { - primitives: { - cube: (options: { size: number | [number, number, number] }) => any - sphere: (options: { radius: number }) => any - } - booleans: { - union: (a: any, b: any) => any - subtract: (a: any, b: any) => any - } -} - -// Define types for JSCAD objects and operations -type JSCADPrimitive = - | ReturnType - | ReturnType -type JSCADOperation = - | JSCADModule["booleans"]["union"] - | JSCADModule["booleans"]["subtract"] - -// Define prop types for our components -interface CubeProps { - size: number | [number, number, number] -} - -interface SphereProps { - radius: number -} +import type { JSCADModule, JSCADPrimitive } from "./jscad-primitives" +import { createHostConfig } from "./create-host-config" +import { Cube, Sphere, type CubeProps, type SphereProps } from "./jscad-fns" type Props = CubeProps | SphereProps -// Create a function that returns the host config -function createHostConfig(jscad: JSCADModule) { - const hostConfig: ReactReconciler.HostConfig< - string, // Type - Props, // Props - JSCADPrimitive, // Container - JSCADPrimitive, // Instance - never, // TextInstance - never, // SuspenseInstance - never, // HydratableInstance - JSCADPrimitive, // PublicInstance - {}, // HostContext - boolean, // UpdatePayload - never, // ChildSet - number, // TimeoutHandle - number // NoTimeout - > = { - now: Date.now, - supportsMutation: true, - supportsPersistence: false, - supportsHydration: false, - - createInstance( - type: string, - props: Props, - rootContainerInstance: any, - hostContext: any, - internalInstanceHandle: any - ) { - switch (type) { - case "cube": - return jscad.primitives.cube({ size: (props as CubeProps).size }) - case "sphere": - return jscad.primitives.sphere({ - radius: (props as SphereProps).radius, - }) - default: - throw new Error(`Unknown element type: ${type}`) - } - }, - - createTextInstance() { - throw new Error("Text elements are not supported in JSCAD") - }, - - appendInitialChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) { - return jscad.booleans.union(parentInstance, child) as JSCADPrimitive - }, - - appendChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) { - return jscad.booleans.union(parentInstance, child) as JSCADPrimitive - }, - - removeChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) { - return jscad.booleans.subtract(parentInstance, child) as JSCADPrimitive - }, - - appendChildToContainer(container: JSCADPrimitive[], child: JSCADPrimitive) { - container.push(child) - }, - - removeChildFromContainer( - container: JSCADPrimitive[], - child: JSCADPrimitive - ) { - const index = container.indexOf(child) - if (index !== -1) container.splice(index, 1) - }, - - prepareUpdate() { - return true - }, - - commitUpdate( - instance: JSCADPrimitive, - updatePayload: any, - type: string, - oldProps: Props, - newProps: Props - ) { - // Re-create the instance with new props - return this.createInstance(type, newProps, instance, {}, null) - }, - - finalizeInitialChildren() { - return false - }, - - prepareForCommit() { - return null - }, - resetAfterCommit() {}, - getPublicInstance(instance: JSCADPrimitive) { - return instance - }, - getRootHostContext() { - return {} - }, - getChildHostContext() { - return {} - }, - shouldSetTextContent() { - return false - }, - clearContainer() {}, - scheduleTimeout: setTimeout, - cancelTimeout: clearTimeout, - noTimeout: -1, - isPrimaryRenderer: true, - getCurrentEventPriority: () => 99, - getInstanceFromNode: () => null, - beforeActiveInstanceBlur: () => {}, - afterActiveInstanceBlur: () => {}, - prepareScopeUpdate: () => {}, - getInstanceFromScope: () => null, - detachDeletedInstance: () => {}, - } - return hostConfig -} - // Create a function that returns the reconciler and root creation function function createJSCADRenderer(jscad: JSCADModule) { const hostConfig = createHostConfig(jscad) @@ -178,15 +32,6 @@ function createJSCADRenderer(jscad: JSCADModule) { return { createJSCADRoot } } -// Example usage -function Cube({ size }: CubeProps) { - return -} - -function Sphere({ radius }: SphereProps) { - return -} - function Scene() { return ( <> @@ -198,16 +43,3 @@ function Scene() { // Export the creation function and components export { createJSCADRenderer, Cube, Sphere, Scene } - -// Usage example (commented out as it depends on the actual JSCAD module) -/* -import * as jscad from '@jscad/modeling'; - -const { createJSCADRoot } = createJSCADRenderer(jscad); - -const container: JSCADPrimitive[] = []; -const root = createJSCADRoot(container); -root.render(); - -console.log(container); -*/ diff --git a/lib/jscad-fns/cube.tsx b/lib/jscad-fns/cube.tsx new file mode 100644 index 0000000..804da18 --- /dev/null +++ b/lib/jscad-fns/cube.tsx @@ -0,0 +1,9 @@ +// Define prop types for our components +export interface CubeProps { + size: number | [number, number, number] +} + +// Example usage +export function Cube({ size }: CubeProps) { + return +} diff --git a/lib/jscad-fns/index.ts b/lib/jscad-fns/index.ts new file mode 100644 index 0000000..90806be --- /dev/null +++ b/lib/jscad-fns/index.ts @@ -0,0 +1,2 @@ +export * from "./cube" +export * from "./sphere" diff --git a/lib/jscad-fns/sphere.tsx b/lib/jscad-fns/sphere.tsx new file mode 100644 index 0000000..b360004 --- /dev/null +++ b/lib/jscad-fns/sphere.tsx @@ -0,0 +1,7 @@ +export interface SphereProps { + radius: number +} + +export function Sphere({ radius }: SphereProps) { + return +} diff --git a/lib/jscad-primitives.ts b/lib/jscad-primitives.ts new file mode 100644 index 0000000..390a4db --- /dev/null +++ b/lib/jscad-primitives.ts @@ -0,0 +1,19 @@ +// Define a type for the JSCAD module structure we expect +export interface JSCADModule { + primitives: { + cube: (options: { size: number | [number, number, number] }) => any + sphere: (options: { radius: number }) => any + } + booleans: { + union: (a: any, b: any) => any + subtract: (a: any, b: any) => any + } +} + +// Define types for JSCAD objects and operations +export type JSCADPrimitive = + | ReturnType + | ReturnType +export type JSCADOperation = + | JSCADModule["booleans"]["union"] + | JSCADModule["booleans"]["subtract"] diff --git a/lib/types.ts b/lib/types.ts new file mode 100644 index 0000000..e69de29