Vue

In Vue you write Orbit's markup straight into templates. The only setup is telling the compiler that <o-arc> and <o-progress> are custom elements, not Vue components.

Install

npm install @zumer/orbit

Import the stylesheet and the runtime in your entry file:

// main.js
import '@zumer/orbit/style';
import '@zumer/orbit';

import { createApp } from 'vue';
import App from './App.vue';

createApp(App).mount('#app');

Then, in the Vite config:

// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: (tag) => tag.startsWith('o-'),
        },
      },
    }),
  ],
});

A gauge

A progress ring with its value in the middle, bound to a ref:

<script setup>
import { ref } from 'vue';
import './gauge.css';

const value = ref(72);
</script>

<template>
  <div class="gauge">
    <div class="bigbang">
      <div class="gravity-spot">
        <div class="orbit-10">
          <o-progress :value="value" shape="rounded"></o-progress>
        </div>
        <div class="orbit-0">
          <div class="satellite at-center">
            <div class="capsule">{{ value }}%</div>
          </div>
        </div>
      </div>
    </div>
    <input type="range" min="0" max="100" v-model.number="value">
  </div>
</template>
/* gauge.css */
.gauge { width: 220px; }
.gauge .orbit-10 { --o-size-ratio: 2; }
.gauge .orbit-0 { --o-size-ratio: 12; }
.gauge o-progress {
  --o-fill: var(--o-cyan);
  --o-back-fill: var(--o-cyan-lighter);
  --o-stroke: none;
}
.gauge .capsule { font-size: 28px; font-weight: 600; }

Satellites rendered with v-for are spread around their ring however many there are.

The same markup in plain HTML. Move the slider: changing value is all it takes.

Orbit watches the page for added, removed and reordered elements, attribute and style changes, and containers that change size, so a re-render needs no extra call. To wait until arcs are drawn, or to update after a change Orbit cannot see, use the runtime API.

Nuxt

Importing Orbit on the server is safe. Put the stylesheet in css, the custom element rule in vue.compilerOptions, and the runtime in a client plugin:

// nuxt.config.ts
export default defineNuxtConfig({
  css: ['@zumer/orbit/style'],
  vue: {
    compilerOptions: { isCustomElement: (tag) => tag.startsWith('o-') },
  },
});

// app/plugins/orbit.client.ts
import '@zumer/orbit';
export default defineNuxtPlugin(() => {});

In Nuxt 3 the plugin is plugins/orbit.client.ts, at the root. Nuxt 4 ignores that folder, so there the elements would never be defined.

Without a build step

With Vue from a CDN, load Orbit's two files with <link> and <script> (see Install) and set the same rule on the app:

const app = Vue.createApp({ data: () => ({ value: 72 }) });
app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('o-');
app.mount('#app');