Skip to content

feat(viewer): add a toolbar extension API to the embeddable viewer - #19

Open
ericgozzi wants to merge 7 commits into
mainfrom
feature/viewer-extension-api
Open

feat(viewer): add a toolbar extension API to the embeddable viewer#19
ericgozzi wants to merge 7 commits into
mainfrom
feature/viewer-extension-api

Conversation

@ericgozzi

Copy link
Copy Markdown
Collaborator

Lets consumers add their own toolbar tools via createViewer({ toolbarTools }) instead of forking the app shell: a ToolDefinition list of Vue components rendered after the built-in tool groups, a narrow useViewerMessaging() composable for talking to a backend, and a new /ui subpath exporting the stable subset of the internal component kit (Button, Kbd, KbdGroup, Tooltip*) to build them with. Documented in docs/extending-the-viewer.md and demonstrated in examples/embedded_custom_tool.html.

Also fixes prepare so a git-dependency install (e.g. github:compas-dev/compas_threejs_ts#) actually builds dist-lib before use, via a small cross-platform script - the previous inline cmd1 || true && cmd2 no-ops the build under cmd.exe on Windows, since its &&/|| chaining doesn't group the way POSIX shells do.

The title must be a conventional commit:
fix:, feat:, feat!: for a breaking change, or one of build: chore:
ci: docs: perf: refactor: style: test:. Release Please builds
CHANGELOG.md and the next version number from it. Apply the no changelog
label to skip. Running npm install enables a commit-msg hook that checks
your commits as you make them.

Checklist

  • npm run check is green (formatting, lint, types, unit tests, both builds).
  • npm run test:browser and npm run test:package pass.

ericgozzi and others added 4 commits August 17, 2026 10:44
… edit

Mirrors frontend edits back to the backend's live COMPAS objects instead of
only receiving updates from it:

- Transform gizmo drag/rotate on a picked object now sends the world-space
  delta to the backend on release (dispatch: object_transform), computed
  against the object's matrix as of drag-start so it's correct regardless of
  whether the frontend's placement convention for that object is identity or
  absolute. Also guards against a continuously self-animating object (e.g. a
  spinning torus) rebuilding the mesh out from under an active drag.
- New "Add object" toolbar control (AddObjectButton.vue) sends
  create_geometry for Box/Sphere/Point, spawned at the camera's current orbit
  target.
- New "Material" toolbar control (MaterialButton.vue) streams color/
  metalness/roughness edits (material_edit) for the picked object, with
  local instant preview.
- New reactive store field pickedObjectGuid, since nothing previously exposed
  the current pick selection to Vue components.

Requires the paired compas_threejs backend changes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Explains the transform-gizmo delta math, the two bugs found and fixed while
building it (wrong matrix convention, a spinning object fighting its own
drag), the new create_geometry/material_edit UI, and the new pickedObjectGuid
store field, for a future agent to pick up without re-deriving it. Pairs with
the equivalent doc in the compas_threejs backend repo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ericgozzi
ericgozzi marked this pull request as ready for review August 19, 2026 13:15
Lets consumers add their own toolbar tools via createViewer({ toolbarTools })
instead of forking the app shell: a ToolDefinition list of Vue components
rendered after the built-in tool groups, a narrow useViewerMessaging()
composable for talking to a backend, and a new /ui subpath exporting the
stable subset of the internal component kit (Button, Kbd, KbdGroup,
Tooltip*) to build them with. Documented in docs/extending-the-viewer.md and
demonstrated in examples/embedded_custom_tool.html.

Also fixes `prepare` so a git-dependency install (e.g.
github:compas-dev/compas_threejs_ts#<branch>) actually builds dist-lib
before use, via a small cross-platform script - the previous inline
`cmd1 || true && cmd2` no-ops the build under cmd.exe on Windows, since its
&&/|| chaining doesn't group the way POSIX shells do.
Extends the toolbar extension API from the previous commit with per-panel
placement and styling, so a consumer can fully restyle/relayout without
forking the app shell:

- toolbarPlacement / openbarPlacement / objectActionsPlacement options
  ("corner" | "docked-top" / "docked-left"), each defaulting to today's
  floating-corner behavior. Docked-top toolbar and object-actions bars share
  a height via --docked-bar-height, derived from the new --docked-bar-padding
  so consumers only need to tune one value.
- --toolbar-background/--toolbar-border-color and their object-actions
  equivalents, so those two panels' look is independently overridable
  instead of only through the shared .theme class (which still covers
  Openbar and box-shadow/backdrop-filter for all three).
- --section-title-background/-shadow/-blur, replacing the FUNCTIONS/METADATA
  headers' hardcoded glass bezel.
- Toolbar's root selector picked up a `div.` prefix, matching its sibling
  components: without it, its specificity exactly ties a consumer's
  `:root .theme { border: ... }`-style override and loses on source order.

Verified end-to-end against timber_model_viewer's frontend-src, including a
real minified-build bug in Vite's CSS minifier (silently drops an unprefixed
backdrop-filter declared alongside its -webkit- pair).
scripts/prepare.mjs inherited the vite build's stdout, which broke CI's
test:package step: some npm versions still run `prepare` during
`npm pack --ignore-scripts --json` (the flag reliably skips it in newer npm,
but not consistently across versions - CI's Node 22 setup installs an older
bundled npm than this repo's pinned packageManager). When that happens, the
build's stdout interleaves with npm pack's own --json output and JSON.parse
fails downstream in scripts/test-package.mjs.

prepare.mjs now captures the build's output instead of inheriting it, only
surfacing it (on stderr, never stdout) if the build actually fails - verified
both paths directly. Also fixes a real, separate bug in test-package.mjs
while I was in there: its spawnSync calls for npm.cmd needed shell: true on
Windows (Node can't exec a .cmd shim without going through a shell), so the
script has never actually run to completion locally on Windows until now.
@ericgozzi
ericgozzi force-pushed the feature/viewer-extension-api branch from f3e5c3c to c516317 Compare August 19, 2026 13:15
@ericgozzi
ericgozzi requested a review from gonzalocasas August 19, 2026 13:15
Base automatically changed from feature/bidirectional-sync to main September 7, 2026 08:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant