Icons
The app's icons: small drawings in two tones of ink, by name. They are also in @buerli.io/react-cad/icons, with
nothing but React.
Components
Icon
const Icon: React.FC<IconProps>;
Draws one of the app's icons: a sign on a 20 × 20 sheet, in two tones of the theme's ink.
It is an inline <svg> that the stylesheet (AppStyle) inks: its lines are the theme's ink, what a sign
is done to is grey, and an axis is in its own colour. It is given the drawing's name, or a url that is a
reference (iconRef) or an image's url, which it shows as an <img>. A name that has no drawing shows a
dashed square. The drawings are icons. Its props: IconProps.
Example
// on a page that only needs the icons: nothing but React
import { Icon, iconDataUrl, iconRef } from '@buerli.io/react-cad/icons'
const ToolButton = ({ onClick }: { onClick: () => void }) => (
<button className="rcad-tool" onClick={onClick} title="Extrude">
<Icon name="extrusion" size={20} />
</button>
)
// a reference goes where an image's url went before; an image's url still shows as an <img>
const Fillet = () => <Icon url={iconRef('fillet')} size={16} title="Fillet" />
const Logo = () => <Icon url="/logo.svg" size={24} title="Our app" />
// where no stylesheet reaches: the same drawing in colours of its own
const Favicon = () => <link rel="icon" href={iconDataUrl('part', { ink: '#e7000b' }, 32)} />
Objects
icons
const icons: {
angle: IconLayer[];
angleOX: (["sub", string] | ["", string])[];
anglePattern: IconLayer[];
angleZ: IconLayer[];
appearance: (["tone", string] | ["", string])[];
arc: (["fill", string] | ["sub", string])[];
arc3Points: (["fill", string] | ["", string])[];
arcCenter: (["fill", string] | ["sub", string] | ["", string])[];
arcTangent: (["fill", string] | ["sub", string] | ["", string])[];
arrowRight: string;
assembly: (["sub", string] | ["tone", string] | ["", string])[];
axisX: IconLayer[];
axisY: IconLayer[];
axisZ: IconLayer[];
back: string;
barycenter: (["fill", string] | ["sub", string])[];
bbox: (["tone", string] | ["", string] | ["sub-dash", string])[];
box: (["tone", string] | ["", string])[];
boxHeight: IconLayer[];
boxLength: IconLayer[];
boxWidth: IconLayer[];
capSheet: IconLayer[];
capSolid: (["tone", string] | ["", string])[];
caret: string;
chamfer: (["sub", string] | ["", string])[];
chamferAngle: IconLayer[];
chamferOffset1: (["sub", string] | ["", string])[];
chamferOffset2: (["sub", string] | ["", string])[];
check: string;
chevronDown: string;
chevronLeft: string;
chevronRight: string;
chevronUp: string;
circleCenter: (
| ["fill", string]
| ["sub", string]
| ["tone", string]
| ["", string])[];
circularPattern: IconLayer[];
circularPatternConstraint: IconLayer[];
close: string;
coincident: (["fill", string] | ["sub", string] | ["", string])[];
colinear: (["", string] | ["sub-dash", string])[];
compositeCurve: (["fill", string] | ["", string])[];
concentric: (["fill", string] | ["", string])[];
cone: (["tone", string] | ["", string])[];
coneBase: IconLayer[];
coneHeight: (["sub", string] | ["", string])[];
coneTop: IconLayer[];
constructionLine: (["fill", string] | ["dash", string])[];
copy: (["sub", string] | ["tone", string] | ["", string])[];
countAngular: IconLayer[];
countX: IconLayer[];
countY: IconLayer[];
csysFrom: (["sub", string] | ["", string])[];
csysTo: (["sub", string] | ["", string])[];
cylinder: (["tone", string] | ["", string])[];
cylinderHeight: (["sub", string] | ["", string])[];
cylindrical: (["sub", string] | ["", string])[];
diameter: (["sub", string] | ["", string])[];
dimHorizontal: IconLayer[];
dimLinear: (["sub-fill", string] | ["sub", string] | ["", string])[];
dims: (["sub", string] | ["", string])[];
dimVertical: IconLayer[];
direction: (["sub", string] | ["", string])[];
direction3d: (["sub", string] | ["", string])[];
directionCurve: (["sub", string] | ["", string])[];
directionPlanes: (["sub", string] | ["", string])[];
directionPoints: (["sub-fill", string] | ["", string])[];
directionX: IconLayer[];
directionY: IconLayer[];
distanceX: IconLayer[];
distanceY: IconLayer[];
distanceZ: (["sub", string] | ["z", string])[];
download: string;
edges: (["fill", string] | ["sub", string] | ["", string])[];
edit: string;
enter: (["sub", string] | ["", string])[];
entityDeletion: (["sub", string] | ["", string])[];
equal: (["sub", string] | ["", string])[];
error: string;
export: string;
expressions: string;
extrusion: (["tone", string] | ["", string])[];
eye: (["fill", string] | ["tone", string] | ["", string])[];
eyeOff: (["sub-fill", string] | ["sub", string] | ["", string])[];
face: IconLayer[];
fastened: (["fill", string] | ["sub", string])[];
fastenedOrigin: (["sub", string] | ["", string])[];
file: string;
fillet: (["sub", string] | ["", string])[];
filletRadius: (["fill", string] | ["sub", string] | ["", string])[];
fixed: (["fill", string] | ["", string])[];
flipX: IconLayer[];
flipXInv: IconLayer[];
flipY: IconLayer[];
flipYInv: IconLayer[];
flipZ: IconLayer[];
flipZInv: IconLayer[];
gear: (["sub-fill", string] | ["sub", string] | ["", string])[];
gearFirst: IconLayer[];
gearRatio: IconLayer[];
gearSecond: IconLayer[];
grip: ["fill", string][];
group: (["sub-fill", string] | ["dash", string])[];
horizontal: (["sub-fill", string] | ["sub", string] | ["", string])[];
import: string;
info: string;
innerCircle: (["fill", string] | ["sub", string])[];
instance: (["tone", string] | ["", string])[];
instances: (["tone", string] | ["", string])[];
instancesOpen: string;
intersection: (["fill", string] | ["sub", string] | ["", string])[];
intersectionPoint: (["fill", string] | ["sub", string])[];
limitDown: (["sub", string] | ["", string])[];
limitUp: (["sub", string] | ["", string])[];
line: (["fill", string] | ["", string])[];
linearPattern: IconLayer[];
linearPatternConstraint: IconLayer[];
lineOnPlane: (["sub", string] | ["", string])[];
link: string;
look: (["sub", string] | ["tone", string] | ["", string])[];
loop: (["fill", string] | ["sub", string] | ["", string])[];
mate1: IconLayer[];
mate2: IconLayer[];
measure: (["tone", string] | ["", string])[];
menu: string;
merged: IconLayer[];
message: string;
midpoint: (["sub-fill", string] | ["fill", string] | ["sub", string])[];
midpointLine: (["fill", string] | ["sub", string])[];
midpointPoints: (["sub-fill", string] | ["fill", string])[];
minus: string;
mirror: (
| ["sub", string]
| ["tone", string]
| ["", string]
| ["axis", string])[];
mirrorLine: (["sub-fill", string] | ["", string])[];
missing: ["sub-dash", string][];
more: ["fill", string][];
normal: (["sub", string] | ["", string])[];
notMerged: (["tone", string] | ["", string])[];
offsetX: IconLayer[];
offsetXMax: IconLayer[];
offsetXMin: IconLayer[];
offsetY: IconLayer[];
offsetYMax: IconLayer[];
offsetYMin: IconLayer[];
offsetZ: IconLayer[];
offsetZMax: IconLayer[];
offsetZMin: IconLayer[];
open: string;
origin: (["fill", string] | ["sub", string])[];
parallel: (["sub", string] | ["", string])[];
parallelLines: ["", string][];
part: (["tone", string] | ["", string])[];
pattern2dCircular: IconLayer[];
pattern2dLinear: IconLayer[];
pattern2dMirror: (["sub-fill", string] | ["fill", string] | ["axis", string])[];
perpendicular: (["sub", string] | ["", string])[];
pin: string;
planar: (["sub", string] | ["", string])[];
planeFront: IconLayer[];
planeOffset: IconLayer[];
planeRight: IconLayer[];
planeTop: IconLayer[];
plus: string;
point: (["fill", string] | ["sub", string])[];
pointOnPlane: (["fill", string] | ["sub", string])[];
pointsOnPlane: (["fill", string] | ["sub", string])[];
position: (["fill", string] | ["sub", string])[];
products: string;
question: string;
radius: (["fill", string] | ["sub", string] | ["", string])[];
rect2Points: (["fill", string] | ["tone", string] | ["", string])[];
rectCenter: (["fill", string] | ["tone", string] | ["", string])[];
redo: string;
region: (["sub", string] | ["tone", string] | ["", string])[];
rename: (["sub", string] | ["", string])[];
reorient0: IconLayer[];
reorient180: IconLayer[];
reorient270: IconLayer[];
reorient90: IconLayer[];
revolute: (["sub", string] | ["", string])[];
revolve: (["sub-fill", string] | ["tone", string] | ["", string])[];
revolveAxis: (["sub", string] | ["", string])[];
revolveEnd: IconLayer[];
revolveStart: IconLayer[];
rigidSet: (["sub-fill", string] | ["dash", string])[];
rotation: IconLayer[];
rotation3d: (["sub", string] | ["", string])[];
rotationAngle: (["sub", string] | ["", string])[];
rotationX: IconLayer[];
rotationY: IconLayer[];
rotationZ: IconLayer[];
rotationZMax: IconLayer[];
rotationZMin: IconLayer[];
search: string;
select: (["tone", string] | ["", string])[];
session: (["sub", string] | ["", string])[];
sheet: IconLayer[];
sheetBody: IconLayer[];
sidebar: (["fill", string] | ["", string])[];
sidebarOff: (["sub", string] | ["", string])[];
sketch: (["fill", string] | ["tone", string] | ["", string])[];
sketchAngle: (["fill", string] | ["sub", string] | ["", string])[];
sketchCountAngular: IconLayer[];
sketchCountX: IconLayer[];
sketchCountY: IconLayer[];
sketchDirectionX: IconLayer[];
sketchDirectionY: IconLayer[];
sketchDistanceX: IconLayer[];
sketchDistanceY: IconLayer[];
sketchFillet: (["sub", string] | ["", string])[];
slice: (["sub", string] | ["tone", string] | ["", string])[];
sliceBySheet: (["sub", string] | ["tone", string] | ["", string])[];
slider: (["sub", string] | ["", string])[];
solid: (["tone", string] | ["", string])[];
solidLine: (["fill", string] | ["", string])[];
sphere: (["tone", string] | ["", string])[];
spherical: (["sub", string] | ["tone", string] | ["", string])[];
sphericalMax: (["sub", string] | ["", string])[];
split: (["fill", string] | ["", string])[];
subtraction: (["tone", string] | ["", string] | ["sub-dash", string])[];
success: string;
switchDirection1: string;
switchDirection2: string;
switchNormal1: (["sub", string] | ["", string])[];
switchNormal2: (["sub", string] | ["", string])[];
switchX1: IconLayer[];
switchX2: IconLayer[];
switchY1: IconLayer[];
switchY2: IconLayer[];
symmetric: (["fill", string] | ["", string] | ["axis", string])[];
tangent: (["fill", string] | ["sub", string] | ["", string])[];
theme: (["fill", string] | ["", string])[];
toSubassembly: (["sub", string] | ["", string])[];
transformByCsys: IconLayer[];
translation: IconLayer[];
translationDistance: (["sub", string] | ["", string])[];
trash: string;
trim: (["sub", string] | ["", string] | ["sub-dash", string])[];
twist: (["tone", string] | ["", string])[];
twistAngle: (["sub", string] | ["", string])[];
undo: string;
union: (["tone", string] | ["", string])[];
useGeometry: IconLayer[];
useReference: IconLayer[];
vertical: (["sub-fill", string] | ["sub", string] | ["", string])[];
viewEdges: (["", string] | ["sub-dash", string])[];
viewFaces: (["tone", string] | ["", string])[];
viewNormal: (["sub", string] | ["tone", string] | ["", string])[];
viewPoints: (["fill", string] | ["sub", string])[];
viewWire: (["sub", string] | ["", string])[];
warning: string;
workAxis: (["fill", string] | ["", string])[];
workCSys: (["fill", string] | ["", string])[];
workPlane: IconLayer[];
workPoint: (["fill", string] | ["", string])[];
zoomFit: (["tone", string] | ["", string])[];
};
Every drawing the app has, by name: what Icon draws.
The sheets are the app's own signs (its bars, rows and menus), the features, the sketch's tools and constraints,
what a field sets (a length, a count, an angle, along an axis), what a field picks, the mates of an assembly, and a
few glyphs. missing is the dashed square that stands in for a name that has no drawing.
Type Declaration
Example
import { Icon, icons } from '@buerli.io/react-cad'
import type { IconName } from '@buerli.io/react-cad'
// a sheet of every icon there is, each with its name
const Sheet = () => (
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(8, 1fr)', gap: 12 }}>
{(Object.keys(icons) as IconName[]).map((name) => (
<figure key={name}>
<Icon name={name} size={32} title={name} />
<figcaption>{name}</figcaption>
</figure>
))}
</div>
)
Functions
iconDataUrl()
function iconDataUrl(
name,
inks,
size?,
seenAt?
): string;
An icon as a data: url of its svg (iconSvg): for an <img>, a CSS background or a texture's loader.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
name | string | undefined | The drawing's name, or its reference (iconRef). |
inks | { ink: string; x?: string; y?: string; z?: string; } | undefined | Its colours, such as { ink: '#0f1320' }. |
inks.ink | string | undefined | The ink: what the sign is about. What it is done to is the same, at 46 %. |
inks.x? | string | undefined | The X axis' colour. Default: the ink. |
inks.y? | string | undefined | The Y axis' colour. Default: the ink. |
inks.z? | string | undefined | The Z axis' colour. Default: the ink. |
size? | number | 20 | The svg's width and height in px. Default 20. |
seenAt? | number | size | The size in px it is seen at, which its lines are weighed for. Default: size. |
Returns
string
Example
import { iconDataUrl, useRCadTheme } from '@buerli.io/react-cad'
// an icon as an <img>, in the theme's colours: the axes in their own
function AxisBadge() {
const colors = useRCadTheme()
const src = iconDataUrl('rotation3d', { ink: colors.ink, x: colors.axisX, y: colors.axisY, z: colors.axisZ }, 24)
return <img src={src} width={24} height={24} alt="Rotation" />
}
iconRef()
function iconRef(name): string;
An icon's reference: a string ('rcad:extrusion') that goes wherever an image's url went before.
It goes into a plugin description's iconUrl or a menu item's icon, say: Icon draws it from its url, and
shows anything else it is handed there as the image it is. iconSvg and iconDataUrl take it too.
Parameters
| Parameter | Type | Description |
|---|---|---|
name | | "pointOnPlane" | "normal" | "origin" | "radius" | "position" | "slice" | "edges" | "box" | "message" | "copy" | "products" | "error" | "success" | "info" | "warning" | "theme" | "search" | "split" | "trim" | "fixed" | "link" | "angle" | "enter" | "loop" | "menu" | "select" | "line" | "cylindrical" | "sphere" | "spherical" | "group" | "part" | "rotation" | "direction" | "close" | "flipY" | "arc" | "cone" | "union" | "instance" | "mirror" | "appearance" | "caret" | "solid" | "region" | "horizontal" | "vertical" | "open" | "sheet" | "edit" | "mate1" | "mate2" | "instances" | "undo" | "redo" | "face" | "cylinder" | "point" | "twist" | "offsetX" | "offsetY" | "intersection" | "slider" | "download" | "file" | "more" | "translationDistance" | "equal" | "sketch" | "back" | "chevronLeft" | "chevronRight" | "chevronDown" | "chevronUp" | "arrowRight" | "check" | "plus" | "minus" | "grip" | "sidebar" | "sidebarOff" | "eye" | "eyeOff" | "trash" | "rename" | "pin" | "export" | "import" | "question" | "toSubassembly" | "session" | "viewFaces" | "viewWire" | "viewEdges" | "viewPoints" | "look" | "dims" | "measure" | "bbox" | "zoomFit" | "viewNormal" | "expressions" | "extrusion" | "revolve" | "subtraction" | "fillet" | "chamfer" | "sliceBySheet" | "linearPattern" | "circularPattern" | "translation" | "transformByCsys" | "workPlane" | "workAxis" | "workPoint" | "workCSys" | "axisX" | "axisY" | "axisZ" | "planeTop" | "planeFront" | "planeRight" | "assembly" | "entityDeletion" | "compositeCurve" | "boxLength" | "boxWidth" | "boxHeight" | "limitUp" | "limitDown" | "capSolid" | "capSheet" | "twistAngle" | "revolveAxis" | "revolveStart" | "revolveEnd" | "cylinderHeight" | "diameter" | "coneHeight" | "coneBase" | "coneTop" | "filletRadius" | "chamferOffset1" | "chamferOffset2" | "chamferAngle" | "distanceX" | "distanceY" | "distanceZ" | "countX" | "countY" | "countAngular" | "anglePattern" | "angleZ" | "rotationAngle" | "merged" | "notMerged" | "gearFirst" | "gearSecond" | "gearRatio" | "sphericalMax" | "offsetXMin" | "offsetXMax" | "offsetYMin" | "offsetYMax" | "offsetZ" | "offsetZMin" | "offsetZMax" | "directionX" | "directionY" | "rotationX" | "rotationY" | "rotationZ" | "rotationZMin" | "rotationZMax" | "rotation3d" | "switchDirection1" | "switchDirection2" | "switchNormal1" | "switchNormal2" | "switchX1" | "switchX2" | "switchY1" | "switchY2" | "flipX" | "flipXInv" | "flipYInv" | "flipZ" | "flipZInv" | "reorient0" | "reorient90" | "reorient180" | "reorient270" | "rect2Points" | "rectCenter" | "circleCenter" | "arcTangent" | "arcCenter" | "arc3Points" | "sketchFillet" | "useGeometry" | "useReference" | "solidLine" | "constructionLine" | "mirrorLine" | "coincident" | "tangent" | "parallelLines" | "perpendicular" | "colinear" | "concentric" | "midpoint" | "symmetric" | "rigidSet" | "dimHorizontal" | "dimVertical" | "dimLinear" | "angleOX" | "pattern2dLinear" | "pattern2dCircular" | "pattern2dMirror" | "sketchDistanceX" | "sketchDistanceY" | "sketchDirectionX" | "sketchDirectionY" | "sketchCountX" | "sketchCountY" | "sketchCountAngular" | "sketchAngle" | "instancesOpen" | "sheetBody" | "csysFrom" | "csysTo" | "direction3d" | "directionPoints" | "directionPlanes" | "directionCurve" | "planeOffset" | "pointsOnPlane" | "lineOnPlane" | "barycenter" | "midpointPoints" | "midpointLine" | "innerCircle" | "intersectionPoint" | "fastenedOrigin" | "fastened" | "revolute" | "planar" | "parallel" | "linearPatternConstraint" | "circularPatternConstraint" | "gear" | "missing" | The drawing's name. |
Returns
string
Example
import { Icon, iconRef } from '@buerli.io/react-cad'
// what took an image's url takes the reference: it is drawn as the sign, in the theme's ink
const tools = [
{ name: 'Extrude', iconUrl: iconRef('extrusion') },
{ name: 'Logo', iconUrl: '/logo.svg' },
]
const Tools = () => (
<>{tools.map((tool) => <Icon key={tool.name} url={tool.iconUrl} size={20} title={tool.name} />)}</>
)
Types
IconName
type IconName = keyof typeof icons;
The name of one of the app's drawings: a key of icons, such as 'extrusion'.
IconProps
type IconProps = {
className?: string;
name?: IconName;
size?: number;
style?: React.CSSProperties;
title?: string;
url?: string;
};
Props of Icon.
Properties
| Property | Type | Description |
|---|---|---|
className? | string | A class for the <svg>, besides rcad-icon. |
name? | IconName | A drawing's name. |
size? | number | Its width and height in px. Its lines keep their weight on the screen at any size. Default 20. |
style? | React.CSSProperties | Its style. |
title? | string | What it says to a screen reader (and an image's alt). Without it, the icon is hidden from one. |
url? | string | Or its reference (see iconRef), or the url of an image, which is shown as an <img>. |
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.
IconDrawing
type IconDrawing = string | readonly IconLayer[];
An icon's drawing: its layers, back to front, each a pen and an SVG path on the 20 × 20 sheet ([pen, d]); or, for
a sign that is one path in ink, just that path.
The pens are '' (ink: what the sign is about), 'sub' (grey: what it is done to), 'dash' and 'sub-dash',
'axis' (grey, chain-dashed), 'fill' and 'sub-fill' (filled), 'tone' (a wash of ink: the face of what the
sign is about), and 'x', 'y', 'z' (a line in an axis' own colour). In a path, a part in square brackets is
filled as well as drawn: an arrow's head, M3 10H13[M17 10L13 8V12Z].
Example
import type { IconDrawing } from '@buerli.io/react-cad'
// a sign that is one path in ink, and one in layers: what is done to in grey, what it is about in ink
const plus: IconDrawing = 'M10 4v12M4 10h12'
const eyeOff: IconDrawing = [
['sub', 'M2 10C4 6.7 6.8 5 10 5s6 1.7 8 5c-2 3.3-4.8 5-8 5s-6-1.7-8-5Z'],
['', 'M4 16 16 4'],
]
iconSvg()
function iconSvg(
name,
inks,
size?,
seenAt?
): string;
An icon as a standalone svg, its colours written into it: for where no stylesheet reaches.
That is a texture on the canvas, say, or an image's url (iconDataUrl). Its lines are weighed for the size it is seen at, which a texture drawn large, to stay sharp, and shown small says apart from its size.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
name | string | undefined | The drawing's name, or its reference (iconRef). |
inks | { ink: string; x?: string; y?: string; z?: string; } | undefined | Its colours, such as { ink: '#0f1320' }. |
inks.ink | string | undefined | The ink: what the sign is about. What it is done to is the same, at 46 %. |
inks.x? | string | undefined | The X axis' colour. Default: the ink. |
inks.y? | string | undefined | The Y axis' colour. Default: the ink. |
inks.z? | string | undefined | The Z axis' colour. Default: the ink. |
size? | number | 20 | The svg's width and height in px. Default 20. |
seenAt? | number | size | The size in px it is seen at, which its lines are weighed for. Default: size. |
Returns
string
The svg's markup.
Example
import * as THREE from 'three'
import { getStage, iconSvg } from '@buerli.io/react-cad'
// a sign as a texture on the stage: drawn at 96 px to stay sharp, its lines weighed for 16 px on screen
const stage = getStage()
const svg = iconSvg('workPlane', { ink: stage.datum }, 96, 16)
const texture = new THREE.TextureLoader().load('data:image/svg+xml;utf8,' + encodeURIComponent(svg))
const material = new THREE.SpriteMaterial({ map: texture, transparent: true })