Angular
In Angular, Orbit's markup goes into component templates. Two details matter: allow custom elements with CUSTOM_ELEMENTS_SCHEMA, and bind value as an attribute.
Install
npm install @zumer/orbit
Add the stylesheet to the global styles in angular.json:
"styles": [
"node_modules/@zumer/orbit/dist/orbit.css",
"src/styles.css"
]
Import the runtime once, in src/main.ts:
import '@zumer/orbit';
A gauge
A progress ring with its value in the middle, bound to a signal. value works as an attribute and as a property, so [value] and [attr.value] both redraw the ring. [attr.value] also writes it into the server-rendered HTML.
import { Component, CUSTOM_ELEMENTS_SCHEMA, signal } from '@angular/core';
@Component({
selector: 'app-gauge',
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
templateUrl: './gauge.component.html',
styleUrl: './gauge.component.css',
})
export class GaugeComponent {
value = signal(72);
}
<!-- gauge.component.html -->
<div class="gauge">
<div class="bigbang">
<div class="gravity-spot">
<div class="orbit-10">
<o-progress [attr.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" [value]="value()"
(input)="value.set(+$any($event.target).value)">
</div>
/* gauge.component.css */
.gauge { width: 220px; }
.orbit-10 { --o-size-ratio: 2; }
.orbit-0 { --o-size-ratio: 12; }
o-progress {
--o-fill: var(--o-cyan);
--o-back-fill: var(--o-cyan-lighter);
--o-stroke: none;
}
.capsule { font-size: 28px; font-weight: 600; }
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 bound values and @for blocks need no extra call. Importing Orbit during server rendering is safe. To wait until arcs are drawn, use the runtime API.