Skip to main content

React

The React API provides bindings for classcad. It makes it easier to use the API in a reactive context and with components specifically. For the most part it helps you to manage and access drawing across the component tree.

npm install @buerli.io/react

Types

It consists of only one hook useBuerliCadFacade.

type BuerliCadReturn = {
/** The facade object that mediates between ClassCAD and buerli */
facade: BuerliCadFacade
/** The ClassCAD API */
api: ClassCADApi
/** The buerli drawing id */
drawingId: DrawingID
/** Renderable component that ties a @buerli.io/react BuerliGeometry to the buerli drawing */
Geometry: (props: BuerliGeometryProps) => JSX.Element
}

useBuerliCadFacade(name: string): BuerliCadReturn

Usage

You must call init before you can use the classcad API. You should do this in the root of your application.

import { useEffect } from 'react'
import { Canvas } from '@react-three/fiber'
import { useBuerliCadFacade } from '@buerli.io/react'
import { init, WASMClient } from '@buerli.io/classcad'

// Get your key from the user area on classcad.ch
const classcadKey = '...'
init((drawingId) => new WASMClient(drawingId, { classcadKey }))

Then you can use the ClassCAD API and other functionality in your components.

function App() {
const { drawing, drawingId, api, Geometry } = useBuerliCadFacade()
///...
}

Managing ClassCAD/buerli sessions

useBuerliCadFacade automatically connects to and manages a ClassCAD drawing instance. Each session is identified by a string, which is "default" if you do not provide one, as in useBuerliCadFacade("default"). You use this identifier to access the same session across different components.

If all components using the same identifier unmount, the session will automatically be disconnected and freed.

function Foo() {
const { api } = useBuerliCadFacade('main')
...

function Bar() {
// This will access the same session as Foo
const { api } = useBuerliCadFacade('main')
...

function Render() {
const { Geometry } = useBuerliCadFacade('main')
// This will render the outcome of the "main" session
return <Geometry />

You can also create multiple sessions:

function SessionA() {
const { api } = useBuerliCadFacade('A')
...

function SessionB() {
// This is a different session than SessionA
const { api } = useBuerliCadFacade('B')
...

API

.facade

The facade object that mediates between ClassCAD and buerli. See BuerliCadFacade for more details.

.drawingId

The buerli drawing id. This is a unique identifier of a session.

.api

The ClassCAD API

api contains all the ClassCAD commands. You can call it in events, effects, or anywhere you like. It contains apis for parts, assemblies, geometries, and more. You can find the full API documentation here.

All commands are async and return a promise with the same structure, which contains a result, which usually is an ID, and messages which are used for error-handling. Commands will throw an error if the messages array contains any messages with a level greater than 0. The maxLevel is the maximum level of the messages, which can be used to determine if there are any errors.

Promise<{
result: number | null
messages?: {
message: string
level: number
code: number
api: string
}[]
maxLevel?: number
}>

A simple example.

function Box({ width = 100, length = 100, height = 100 }) {
const { api } = useBuerliCadFacade("box")
useEffect(() => {
// This will create a box
async function run() {
const { result: part } = await api.v1.part.create({ name: 'Part' })
await api.v1.part.box({ id: part, width, length, height })
}
run()
}, [])
...
}

.Geometry

You have created geometry in Buerli, but you want to show it in your THREEJS app. Geometry is a renderable @react-three/fiber component that is primed to a drawings state. It will automatically update when the drawing changes, and it will also handle the loading state via suspense. You need to render this component in a react-three-fiber Canvas.

function Scene() {
const { Geometry } = useBuerliCadFacade('box')
return <Geometry />
}

function App() {
return (
<Canvas>
<Scene />
</Canvas>
)
}