<arc-page-indicator> Overview
Guidelines
When to use
- Use PageIndicator alongside a Carousel or swipe container for visual context
- Enable clickable mode when users should be able to jump to any page directly
- Keep the count reasonable — five to seven dots maximum for quick scanning
- Position the indicator below or overlaid on the paged content
- Synchronise the value prop with the parent component's active page state
When not to use
- Use PageIndicator for progress — use Progress or Stepper instead
- Display more than ten dots — the pattern breaks down at high counts
- Use PageIndicator without a corresponding paged content area
- Rely on PageIndicator as the only navigation mechanism — pair with swipe or buttons
- Place multiple PageIndicators for the same content sequence
Features
- Horizontal dot row for position indication
- Active dot fills with accent-primary and scales up
- Passive (read-only) and interactive (clickable) modes
- arc-change event when a dot is clicked in interactive mode
- Controlled count and value props for external synchronisation
- Compact footprint suitable for overlay positioning
- Keyboard accessible in clickable mode with arrow keys
- Token-driven theming via CSS custom properties
Preview
Usage
This component requires JavaScript. No pure HTML/CSS version is available — use the Web Component directly or a framework wrapper.
<script type="module" src="@arclux/arc-ui"></script>
<arc-page-indicator count="5" value="2" clickable id="dots"></arc-page-indicator>
<script>
document.querySelector('#dots').addEventListener('arc-change', (e) => {
console.log('page:', e.detail.value);
});
</script> import { useState } from 'react';
import { PageIndicator } from '@arclux/arc-ui-react';
export function Gallery() {
const [page, setPage] = useState(0);
return (
<PageIndicator
count={5}
value={page}
clickable
onArcChange={(e) => setPage(e.detail.value)}
/>
);
} <script setup>
import { ref } from 'vue';
import { PageIndicator } from '@arclux/arc-ui-vue';
const page = ref(0);
function onChange(e) {
page.value = e.detail.value;
}
</script>
<template>
<PageIndicator :count="5" :value="page" clickable @arc-change="onChange" />
</template> <script>
import { PageIndicator } from '@arclux/arc-ui-svelte';
let page = 0;
</script>
<PageIndicator
count={5}
value={page}
clickable
on:arc-change={(e) => (page = e.detail.value)}
/> import { Component } from '@angular/core';
import { PageIndicator } from '@arclux/arc-ui-angular';
@Component({
imports: [PageIndicator],
template: `
<PageIndicator
[count]="5"
[value]="page"
clickable
(arc-change)="onChange($event)"
/>
`,
})
export class GalleryComponent {
page = 0;
onChange(e: CustomEvent) {
this.page = e.detail.value;
}
} import { createSignal } from 'solid-js';
import { PageIndicator } from '@arclux/arc-ui-solid';
export function Gallery() {
const [page, setPage] = createSignal(0);
return (
<PageIndicator
count={5}
value={page()}
clickable
onArcChange={(e) => setPage(e.detail.value)}
/>
);
} import { useState } from 'preact/hooks';
import { PageIndicator } from '@arclux/arc-ui-preact';
export function Gallery() {
const [page, setPage] = useState(0);
return (
<PageIndicator
count={5}
value={page}
clickable
onArcChange={(e) => setPage(e.detail.value)}
/>
);
} API
| Prop | Type | Default | Description |
|---|---|---|---|
count | number | 3 | Total number of dots to display. |
value | number | 0 | Zero-based index of the active dot. |
clickable | boolean | false | When true, dots become interactive tap targets that dispatch arc-change on click. |
Events
| Event | Description |
|---|---|
arc-change | Fired when a dot is clicked (clickable mode only) with detail: { value }. |