Usage Guide
Refine components are native Web Components. Once imported, they behave like regular HTML elements — set attributes, listen to DOM events, use slots for content projection.
Installation
Import the global styles first, then register only the components you need:
import '@vielzeug/refine/tokens.css';
import '@vielzeug/refine/button';
import '@vielzeug/refine/input';
import '@vielzeug/refine/dialog';The token stylesheet supplies Refine's design tokens and cascade layers without changing browser defaults. Add the reset only when your application explicitly wants it:
import '@vielzeug/refine/styles/preflight.css';Attributes and Events
Set attributes directly on the element. Attributes map to component props:
<ore-button variant="outline" color="secondary" size="lg" disabled>
Large Outline Button
</ore-button>Components emit standard DOM events. Common event names: click, input, change, and open-change. Custom events carry a detail object:
const input = document.querySelector('ore-input');
input.addEventListener('input', () => {
console.log(input.value);
});Native browser events (click, focus, blur) work as normal. Custom events with event.detail require addEventListener in React 18 and earlier — see the Framework Integration guide.
Slots
Slots let you pass HTML into named regions of a component without JavaScript.
Content placed directly inside the element fills the default slot:
<ore-button>Save Changes</ore-button>
<ore-card>Any HTML content here</ore-card>Components with distinct regions expose named slots:
<ore-card>
<span slot="header">Card Heading</span>
<p>Main body content fills the default slot.</p>
<div slot="footer">
<ore-button size="sm" variant="outline">Cancel</ore-button>
<ore-button size="sm">Confirm</ore-button>
</div>
</ore-card>Many input components expose prefix and suffix slots for icons or actions:
<ore-button>
<ore-icon slot="prefix" name="arrow-left" size="18"></ore-icon>
Back
</ore-button>
<ore-input label="Search">
<ore-icon slot="suffix" name="search" size="18" aria-hidden="true"></ore-icon>
</ore-input>Each component's available slots are listed in its API Reference table.
Composing with Ore and Ripple
Refine components are plain HTML elements — they compose naturally with Ore custom elements and Ripple signals.
Build a custom component that wraps Refine elements:
import '@vielzeug/refine/button';
import '@vielzeug/refine/input';
import { define, html } from '@vielzeug/ore';
import { signal } from '@vielzeug/ripple';
define('my-search-bar', () => {
const query = signal('');
return html`
<ore-input
.value=${query}
@input=${(e) => (query.value = e.currentTarget.value)}
label="Search"
/>
<ore-button @click=${() => search(query.value)} variant="solid" color="primary">
Search
</ore-button>
`;
});Drive component state from reactive signals:
import { signal, effect } from '@vielzeug/ripple';
const isLoading = signal(false);
const btn = document.querySelector('ore-button');
effect(() => {
btn.loading = isLoading.value;
});Framework Integration
For React, Vue, Svelte, and Angular wiring — including event handling, TypeScript declarations, Vite setup, and SSR guards — see the Framework Integration guide.
Accessibility
All Refine components target WCAG 2.1 AA. ARIA roles and states are managed automatically. For the full compliance contract, per-component coverage, and testing strategy, see the Accessibility page.
The two things you always control:
- Icon-only buttons require a
labelattribute — it becomesaria-label. - Decorative icons should have
aria-hidden="true"so screen readers skip them.