Skip to main content

Panels

The app's frame and its panels: Drawing in one piece, or the model tree, the toolbar, the sidebar, the messages and the windows of the dialogs, laid out by the app. Start with Drawing.

Components​

Drawing​

const Drawing: React.FC<DrawingProps>;

The app's frame around a drawing: a bar with its tools, a sidebar with the model's tree and its bodies, the stage, and a footer that says where things stand.

It is what Buerligons is made of, in one piece: the ToolBar in the bar, the SideBar, and on the stage the ViewOptionButtons, the ViewPlugButtons, the Messages, and the windows of the active feature (FeaturePlugin) and of the global plugins (GlobalPlugins). It mounts the stylesheet (AppStyle) itself. The sidebar's edge is dragged to set its width, and a button in the bar puts it away; both are kept for the next visit (in localStorage).

Drawing contains no canvas: the app's canvas is its child, and fills the stage. The plugins need buerli's PluginManager mounted once in the app, and BuerliPluginsGeometry in the canvas for what they draw (both from @buerli.io/react).

Where the app's init left buerli's stock form controls in, Drawing hands buerli react-cad's elements instead; an app that brought controls of its own keeps them. It also sets the colour of the model's edges and points in buerli's geometry config to the theme's ink, whenever the theme changes.

Its props: DrawingProps.

Example​

import { Canvas } from '@react-three/fiber'
import { BuerliCadFacade } from '@buerli.io/classcad'
import { useBuerliCadFacade } from '@buerli.io/react'
import { Drawing, Menu, sessionClient, StageLook } from '@buerli.io/react-cad'

function Editor() {
const { drawingId, Geometry } = useBuerliCadFacade('bracket')
const file = {
undo: { caption: 'Undo', callback: () => BuerliCadFacade.utils.undo(drawingId) },
redo: { caption: 'Redo', callback: () => BuerliCadFacade.utils.redo(drawingId) },
}
return (
<Drawing
drawingId={drawingId}
Menu={<Menu items={file} trigger={['click']} />}
Status="ClassCAD · in this tab"
Trail={<a href="/help">Help</a>}
readOnly={sessionClient.useSessionRole() === 'view'}>
<Canvas orthographic>
<StageLook />
<Geometry />
</Canvas>
</Drawing>
)
}

ModelTree​

const ModelTree: React.FC<ModelTreeProps>;

Shows the structure of the model: a part's features, or an assembly's nodes.

Which of the two it shows is the useEditMode of the drawing. For a part it is the list of its features in the order they are built, with the rollback bar: a feature is dragged to reorder it, double-clicked to open its dialog, and has a context menu (rename, edit, delete). For an assembly it is the tree of its instances; one is double-clicked to work on it. The header names the current product and has its actions: back out of it, export it, convert to a subassembly, open the products. With neither a part nor an assembly, it shows a placeholder. Read-only (DrawingProps.readOnly), the tree is browsed but not edited.

Its props: ModelTreeProps.

Example​

import { Canvas } from '@react-three/fiber'
import { BuerliPluginsGeometry, useBuerliCadFacade } from '@buerli.io/react'
import { AppStyle, FeaturePlugin, FtVisibilityController, GlobalPlugins, Messages, ModelTree, StageLook, ToolBar } from '@buerli.io/react-cad'

// The pieces laid out by the app instead of Drawing: then `init` is given react-cad's `elements` by the app.
function Workbench() {
const { drawingId, Geometry } = useBuerliCadFacade('bracket')
return (
<div className="rcad" style={{ display: 'grid', gridTemplate: '48px 1fr / 280px 1fr', height: '100vh' }}>
<AppStyle />
<header style={{ gridColumn: 'span 2' }}><ToolBar drawingId={drawingId} /></header>
<aside><ModelTree drawingId={drawingId} /></aside>
<main style={{ position: 'relative' }}>
<Canvas orthographic>
<StageLook />
<Geometry />
<BuerliPluginsGeometry drawingId={drawingId} />
</Canvas>
<Messages drawingId={drawingId} />
</main>
<FeaturePlugin drawingId={drawingId} />
<GlobalPlugins drawingId={drawingId} />
<FtVisibilityController drawingId={drawingId} />
</div>
)
}

ToolBar​

const ToolBar: React.FC<ToolBarProps>;

The tools a part or an assembly is built with: one button a tool, its drawing on it.

Tools that are kin share a button; its caret opens the set. In a part the tools are the features (a sketch, work geometry, extrusion, boolean, fillet, patterns, primitives …), in an assembly the constraints. A tool makes the new feature (uncommitted, in the current product) and opens its dialog; while a feature's dialog is open, it makes none. Until the drawing has a current product, the buttons are placeholders.

Its props: ToolBarProps. The example of ModelTree lays it out with the other panels.


const SideBar: React.FC<SideBarProps>;

The sidebar's two panes: the model's tree above, and what the model is made of below it.

The upper pane is the ModelTree (a part's features, an assembly's nodes); the lower one is the part's bodies (Solids) or the assembly's constraints (Constraints), as the current product is a part or an assembly. While the drawing has pending commands, the panes take no clicks. Drawing renders it in its sidebar; an app that composes the pieces itself gives it a container of the height it is to fill.

Its props: SideBarProps.

Example​

import type { DrawingID } from '@buerli.io/core'
import { AppStyle, SideBar } from '@buerli.io/react-cad'

// the tree and the bodies (or constraints) of a drawing, in a column of the app's own
function ModelColumn({ drawingId }: { drawingId: DrawingID }) {
return (
<aside className="rcad" style={{ width: 300, height: '100%', display: 'flex', flexDirection: 'column' }}>
<AppStyle />
<SideBar drawingId={drawingId} />
</aside>
)
}

Messages​

const Messages: React.FC<MessagesProps>;

The app's messages: what buerli's showMessage (@buerli.io/core) says, as toasts and in a log.

A new message comes up as a toast and leaves again after a few seconds; an error stays until the log has been opened. The button under the toasts opens the log of all of them, and a dot on it says that there are new ones; the log has a button that clears it. Drawing shows them in the stage's lower right corner.

Its props: MessagesProps.

Example​

import { showMessage } from '@buerli.io/core'
import type { DrawingID } from '@buerli.io/core'
import { Messages } from '@buerli.io/react-cad'

// where the app shows them: over the stage's lower right corner
const Toasts = () => (
<div style={{ position: 'absolute', right: 12, bottom: 12, zIndex: 6 }}>
<Messages drawingId={drawingId} />
</div>
)

// anywhere in the app: a toast, and a line in the log
showMessage({ type: 'warning', text: 'The sketch is not closed: nothing was extruded.', drawingId })

FeaturePlugin​

const FeaturePlugin: React.FC<FeaturePluginProps>;

The window of the active feature: the dialog of the feature's plugin, in a window that can be dragged.

The active feature is the drawing's plugin.active.feature (set by the ToolBar for a new feature, and by a double click in the ModelTree). The window's head is the feature's drawing, its name and the call that makes it; closing it sets the active feature to none. It renders nothing while no feature is active. Drawing renders it over the stage.

Its props: FeaturePluginProps.

Example​

import { getDrawing } from '@buerli.io/core'
import type { DrawingID, ObjectID } from '@buerli.io/core'
import { FeaturePlugin } from '@buerli.io/react-cad'

// the window, once, over the app's stage
const Dialog = () => <FeaturePlugin drawingId={drawingId} modalProps={{ width: 312, minPosition: { x: 300, y: 60 } }} />

// a feature's dialog opened from the app: the window shows it
getDrawing(drawingId).api.plugin.setActiveFeature(extrusionId)

GlobalPlugins​

const GlobalPlugins: React.FC<GlobalPluginsProps>;

The windows of the drawing's global plugins (Measure, Expressions, Products, …): one for each plugin that is on.

The global plugins are the ones init's globalPlugins gives every drawing. A plugin is switched on and off with the drawing's api.plugin.setActiveGlobal (as the ViewPlugButtons and the model tree's header do), and closing its window switches it off. Drawing renders them over the stage; an app that composes the pieces itself renders them once, anywhere.

Its props: GlobalPluginsProps.

Example​

import { getDrawing } from '@buerli.io/core'
import type { DrawingID } from '@buerli.io/core'
import { GlobalPlugins } from '@buerli.io/react-cad'

// the windows, once, anywhere in the app
const Windows = () => <GlobalPlugins drawingId={drawingId} modalProps={{ width: 380, minPosition: { x: 300, y: 60 } }} />

// a button of the app's own that opens the Measure panel
const openMeasure = () => {
const { plugin, api } = getDrawing(drawingId)
const measure = plugin.global.find((id) => plugin.refs[id].name === 'Measure')
if (measure) api.plugin.setActiveGlobal(measure, true)
}

Constraints​

const Constraints: React.FC<ConstraintsProps>;

Lists the constraints of the current assembly, and says whether the assembly's solver has solved them.

A row has a context menu (rename, delete), and the pointer on it shows the mates the constraint joins (HoveredConstraintDisplay). Its props: ConstraintsProps. The example of useEditMode shows it for an assembly.


Readfile​

const Readfile: ForwardRefExoticComponent<ReadfileProps & RefAttributes<any>>;

A hidden file input that loads a model the user picks: an .ofb, .stp/.step or .iwp file.

Its ref is the <input>: a button of the app's calls ref.current.click() to open the browser's file dialog. The file is loaded into a new drawing named after it (BuerliCadFacade.utils.connect), which becomes the active one. A guest of a shared session loads it into the session's drawing instead, in place of its model, for everyone in it. What goes wrong is said with showMessage. Its props: ReadfileProps.

Example​

import { useRef } from 'react'
import { Readfile } from '@buerli.io/react-cad'

// an Open button: the browser's file dialog, and the model the user picks in a drawing of its own
function OpenButton() {
const input = useRef<HTMLInputElement>(null)
return (
<>
<button onClick={() => input.current?.click()}>Open…</button>
<Readfile ref={input} singleDrawingApp />
</>
)
}

Solids​

const Solids: React.FC<SolidsProps>;

Lists the bodies of the current product: its solids and sheets (useVisibleSolids).

A row is hovered and selected with the body on the stage, renamed, shown or hidden with its eye, and has a context menu. Several rows are selected with Shift and Ctrl.

Its props: SolidsProps. The example of useEditMode shows it for a part, and Constraints for an assembly.


ViewOptionButtons​

const ViewOptionButtons: React.FC;

Switches for what of the model is shown: its faces, its wires, its edges, its points.

Each is a switch over buerli's geometry config, the one setViewOptions sets; the wireframe is only there while the faces are shown. They take no props: they are the same for every drawing. Drawing docks them on the stage's right-hand side.

Example​

import { ThemeToggle, ViewOptionButtons, ViewPlugButtons } from '@buerli.io/react-cad'
import type { DrawingID } from '@buerli.io/core'

// the stage's docks of an app that lays the pieces out itself
const StageDocks = ({ drawingId }: { drawingId: DrawingID }) => (
<>
<div className="rcad-dock rcad-dock-col" style={{ position: 'absolute', top: 12, right: 12 }}>
<ViewOptionButtons />
<ThemeToggle />
</div>
<div className="rcad-dock" style={{ position: 'absolute', bottom: 12, left: 12 }}>
<ViewPlugButtons drawingId={drawingId} />
</div>
</>
)

ViewPlugButtons​

const ViewPlugButtons: React.FC<ViewPlugButtonsProps>;

Buttons that open and close the global plugins laid over the stage: Dimensions, Measure, Bounding box, Session Management.

A button is there only where the drawing has the plugin (init's globalPlugins); it switches the plugin on and off, and its window is one of the GlobalPlugins. The Session Management button is not shown to a guest of a shared session. Drawing docks them in the stage's lower left corner.

Its props: ViewPlugButtonsProps.

Example​

import { init, WASMClient } from '@buerli.io/classcad'
import type { DrawingID } from '@buerli.io/core'
import { BoundingBoxInfo, Dimensions, elements, Measure, ViewPlugButtons } from '@buerli.io/react-cad'

// a button for each of these global plugins that the drawings have
init((drawingId) => new WASMClient(drawingId, { token: 'ccpk_…' }), {
elements,
globalPlugins: [Dimensions, Measure, BoundingBoxInfo],
})

const Tools = ({ drawingId }: { drawingId: DrawingID }) => (
<div className="rcad-dock" style={{ position: 'absolute', left: 12, bottom: 12 }}>
<ViewPlugButtons drawingId={drawingId} />
</div>
)

Functions​

getViewOptions()​

function getViewOptions(): ViewOptions;

What of the model is drawn now, as buerli's geometry config says (which the stage draws from).

The example of setViewOptions switches one of them with it.

Returns​

ViewOptions

The ViewOptions in force, for every drawing.


setViewOptions()​

function setViewOptions(options): void;

Shows or hides what of the model is drawn, for every drawing.

It merges the options into buerli's geometry config (init's config.geometry); what it leaves out stays as it is. The ViewOptionButtons show what is set here, whoever sets it: the user, or the app (Buerligons switches the edges off in its realistic look).

Parameters​

ParameterTypeDescription
optionsPartial<ViewOptions>What to change, such as { edges: false }.

Returns​

void

Example​

import { getViewOptions, setViewOptions } from '@buerli.io/react-cad'

// a key that switches the edges on and off, as the edges' button on the stage does
window.addEventListener('keydown', (e) => {
if (e.key !== 'e') return
const { edges } = getViewOptions()
setViewOptions({ edges: !edges })
})

// a look of the app's own: the faces alone, without edges or points
setViewOptions({ faces: true, wireframe: false, edges: false, vertices: false })

Types​

ConstraintsProps​

type ConstraintsProps = {
drawingId: DrawingID;
};

Props of Constraints.

Properties​

PropertyTypeDescription
drawingIdDrawingIDThe drawing whose current assembly's constraints are listed.

DrawingProps​

type DrawingProps = {
children?: React.ReactNode;
drawingId: DrawingID;
Menu?: React.JSX.Element;
readOnly?: boolean;
Status?: React.ReactNode;
themeSwitch?: boolean;
Trail?: React.ReactNode;
ViewOptions?: React.ReactNode;
};

Props of Drawing.

Properties​

PropertyTypeDescription
children?React.ReactNodeWhat fills the stage: the app's canvas, with the drawing's geometry in it.
drawingIdDrawingIDThe drawing to show, such as the active one (useBuerli(s => s.drawing.active)).
Menu?React.JSX.ElementWhat leads the bar, before the button that puts the sidebar away: a file menu, undo and redo.
readOnly?booleanWhen true, hides the feature toolbar and disables model-tree editing (browsing stays). Default false.
Status?React.ReactNodeWhat the footer's first cell names before the engine's state (ready, working, not connected): where the engine runs, say. Default: ClassCAD.
themeSwitch?booleanShows the theme switch (ThemeToggle) at the end of the bar. false where the page has a switch of its own and sets the app's theme from it with setRCadThemeMode. Default true.
Trail?React.ReactNodeWhat the bar ends with, before the theme switch.
ViewOptions?React.ReactNodeButtons of the app's own for the stage's right-hand dock, after the ViewOptionButtons.

FeaturePluginProps​

type FeaturePluginProps = {
drawingId: DrawingID;
modalProps?: {
bodyStyle?: React.CSSProperties;
minPosition?: {
x?: number;
y?: number;
};
width?: string | number;
};
};

Props of FeaturePlugin.

Properties​

PropertyTypeDescription
drawingIdDrawingIDThe drawing whose active feature's dialog is shown.
modalProps?{ bodyStyle?: React.CSSProperties; minPosition?: { x?: number; y?: number; }; width?: string | number; }Where and how wide the window is.
modalProps.bodyStyle?React.CSSPropertiesThe style of the window's body, such as its maxHeight.
modalProps.minPosition?{ x?: number; y?: number; }The leftmost and topmost the window's corner goes, in the browser window (px): it opens there at the least.
modalProps.minPosition.x?numberThe leftmost.
modalProps.minPosition.y?numberThe topmost.
modalProps.width?string | numberThe window's width (px, or a CSS length).

GlobalPluginsProps​

type GlobalPluginsProps = {
drawingId: DrawingID;
modalProps?: {
bodyStyle?: React.CSSProperties;
minPosition?: {
x?: number;
y?: number;
};
width?: string | number;
};
};

Props of GlobalPlugins.

Properties​

PropertyTypeDescription
drawingIdDrawingIDThe drawing whose global plugins are shown.
modalProps?{ bodyStyle?: React.CSSProperties; minPosition?: { x?: number; y?: number; }; width?: string | number; }Where and how wide their windows are.
modalProps.bodyStyle?React.CSSPropertiesThe style of the window's body, such as its maxHeight.
modalProps.minPosition?{ x?: number; y?: number; }The leftmost and topmost the window's corner goes, in the browser window (px): it opens there at the least.
modalProps.minPosition.x?numberThe leftmost.
modalProps.minPosition.y?numberThe topmost.
modalProps.width?string | numberThe window's width (px, or a CSS length).

MessagesProps​

type MessagesProps = {
drawingId: DrawingID;
};

Props of Messages.

Properties​

PropertyTypeDescription
drawingIdDrawingIDThe drawing the messages are of: when it changes, the log is cleared.

ModelTreeProps​

type ModelTreeProps = {
drawingId: DrawingID;
};

Props of ModelTree.

Properties​

PropertyTypeDescription
drawingIdDrawingIDThe drawing whose model is shown.

ReadfileProps​

type ReadfileProps = {
singleDrawingApp?: boolean;
};

Props of Readfile.

Properties​

PropertyTypeDescription
singleDrawingApp?booleanRemoves the drawing that was active before, once the file is loaded into a new one: the app has one drawing.

SideBarProps​

type SideBarProps = {
drawingId: DrawingID;
};

Props of SideBar.

Properties​

PropertyTypeDescription
drawingIdDrawingIDThe drawing whose model is shown.

SolidsProps​

type SolidsProps = {
drawingId: DrawingID;
};

Props of Solids.

Properties​

PropertyTypeDescription
drawingIdDrawingIDThe drawing whose bodies are listed.

ToolBarProps​

type ToolBarProps = {
drawingId: DrawingID;
};

Props of ToolBar.

Properties​

PropertyTypeDescription
drawingIdDrawingIDThe drawing whose current product the tools build.

ViewOptions​

type ViewOptions = {
edges: boolean;
faces: boolean;
vertices: boolean;
wireframe: boolean;
};

What of the model is drawn: its faces (or their wires), its edges, its points.

Properties​

PropertyTypeDescription
edgesbooleanThe edges are drawn.
facesbooleanThe faces are drawn.
verticesbooleanThe points are drawn.
wireframebooleanThe faces are drawn as their wires (only while they are drawn).

ViewPlugButtonsProps​

type ViewPlugButtonsProps = {
drawingId: DrawingID;
};

Props of ViewPlugButtons.

Properties​

PropertyTypeDescription
drawingIdDrawingIDThe drawing whose global plugins the buttons open.

Advanced​

Most apps do not need these directly: types they meet through the exports above, and what is there for special cases or for building on buerli itself.

FtVisibilityController​

const FtVisibilityController: React.FC<FtVisibilityControllerProps>;

Shows and hides the views of the current part's features as the rollback bar and the fields ask.

A feature below the rollback bar is not in force: its view (a work plane, a sketch) is hidden while it is there, and shown again when the bar moves past it. While a field picks, the features picked into it by their tree object (a sketch, a work plane) are shown, and hidden again afterwards if they were hidden before. It renders nothing. Drawing renders it; an app that composes the pieces itself renders it once beside its ModelTree, as the example there does. Its props: FtVisibilityControllerProps.


FtVisibilityControllerProps​

type FtVisibilityControllerProps = {
drawingId: DrawingID;
};

Props of FtVisibilityController.

Properties​

PropertyTypeDescription
drawingIdDrawingIDThe drawing whose features' views it shows and hides.