@aspicio/elements
Framework-neutral web components for the
Aspicio DXF viewer.
One implementation of the embed UI, consumable from plain HTML, Vue,
Svelte — with React, Vue, and Svelte veneers (@aspicio/react,
@aspicio/vue, @aspicio/svelte) layered on top.
npm install @aspicio/elements three
<aspicio-embed> — batteries included: layer list + interactive preview
in one tag.
<aspicio-preview> — the embeddable canvas alone: pan/zoom/rotate
(mouse and multi-touch), animated fit, batched WebGL rendering. No
chrome. Set the hover-pick attribute to hit-test the layer under the
cursor.
<aspicio-layer-panel> — the ready-made layer list, identical to the
demo app: header with layer count, visibility checkboxes,
effective-color swatches, entity counts, hover-to-highlight,
double-click-to-solo (with a banner), and a gesture-hints footer.
theme="none" renders a minimal list.
One tag
<script type="module">
import "@aspicio/elements";
</script>
<aspicio-embed src-url="/drawing.dxf" style="height: 480px"></aspicio-embed>
Attributes: src-url, panel (left | right | none), theme
(aspicio | none), no-download, shortcuts. Rich data goes through
properties: src (DXF text | File | Blob | ArrayBuffer), options
(viewer options), panelStyle (style object applied to the inner
panel). The readonly viewer property exposes the full DxfViewer.
Events (all CustomEvents dispatched on the element):
loaded | { layers, stats } | after each successful load |
load-error | { error } | when a load fails |
viewer-change | { viewer } | when the viewer is created (null on disconnect) |
hover-layer | { layer } | layer under the cursor, or null (hover-pick) |
Vue
For idiomatic props and typed emits, use
@aspicio/vue — thin Vue 3 components over these elements.
Consuming the elements natively works too: tell the compiler about the
aspicio- tags (Vue docs)
and use them directly:
export default {
plugins: [
vue({
template: {
compilerOptions: { isCustomElement: (tag) => tag.startsWith("aspicio-") },
},
}),
],
};
<script setup>
import "@aspicio/elements";
const onLoaded = (e) => console.log(e.detail.stats);
</script>
<template>
<aspicio-embed src-url="/drawing.dxf" style="height: 480px" @loaded="onLoaded" />
</template>
Vue binds attributes for primitives and DOM properties for rich values
automatically — :src="file" and :options="{ background: 0x16181d }"
just work.
Svelte
For typed callback props, use @aspicio/svelte — the same
three components as raw Svelte 5 source. Consuming the elements natively
works too:
<script>
import "@aspicio/elements";
</script>
<aspicio-embed
src-url="/drawing.dxf"
style="height: 480px"
onloaded={(e) => console.log(e.detail.stats)}
></aspicio-embed>
Theming
The elements render in shadow DOM, so host-page CSS can't accidentally
restyle their internals — and every integration looks pixel-identical.
Deliberate theming has two hooks:
-
Design tokens as CSS custom properties (they inherit, so set them
on the element or any ancestor):
aspicio-embed {
--aspicio-crease: #ff5c8a;
--aspicio-panel: #101216;
}
The full token list ships as the aspicioTokens export.
-
Parts for structural styling: ::part(panel), ::part(header),
::part(row), ::part(checkbox), ::part(swatch), ::part(name),
::part(count), ::part(hints), ::part(solo-banner),
::part(canvas-host), ::part(download).
The theme uses IBM Plex font stacks but never loads webfonts itself
(no surprise network requests from a library). Load IBM Plex Sans/Mono
in your page for the exact demo typography; otherwise system faces are
used.
Notes
- The
viewer property (also delivered by viewer-change) is the full
@aspicio/core API — fitView, zoomBy, resetRotation,
setLayerVisible, setLayerHighlight, pickLayer, view, stats,
toSVG, toPNG.
- Changing
src / src-url loads the new document; the most recently
set source wins (if both are set at creation, src-url does), and
stale in-flight loads are ignored.
shortcuts keys are scoped to the focused embed (click it first):
F fit, +/- zoom, R reset rotation, A show all layers —
multiple embeds on a page don't collide.
- Removing an element disposes its WebGL viewer; re-inserting it starts
a fresh one and reloads the current source.
- Importing the package registers the elements as a side effect; the
module is safe to import in SSR (Node) environments — the viewer is
only created in the browser. See
apps/elements-example for a full
setup.