Components

How a Vuesax component is built, what props it accepts, and the conventions every one of them follows.

A component is one native Web Component in a single file:

vs-button.js    ← the custom element — copy this

It defines a standard custom element (customElements.define('vs-button', …)) with zero dependencies, so it runs unchanged in React, Svelte, Vue, Angular, Solid or a plain HTML page.

Some components reuse another tag: vs-notification pulls in a toast child, vs-file-tree pulls in its node element. Those come as sibling vs-*.js files imported by a relative path — the code panel lists everything, and the copy bundles them together. Nothing is hidden.

The shared prop language

Almost every component speaks the same four props, so switching between them never means relearning an API.

PropValuesNotes
sizesm · md · lgReads the control scale — see Theming
variantprimary · secondary · ghostVisual weight
tonedefault · danger · warn · successSemantic color
radiusnone · subtle · rounded · pill · squircleCorner shape

Plus two that show up wherever they make sense:

  • disabled — non-interactive, effects off.
  • glow — the proximity light on the border. true by default; set false in dense UI.
<vs-button label="Delete" variant="secondary" tone="danger" size="sm" radius="pill"></vs-button>

Defaults come from the control bar

The controls you see on a component’s page are its real props, and their starting values are its real defaults. What you tune in the browser is exactly what the prop does in your app — there is no separate “demo config”.

Effects that are already wired

Two behaviors are baked into most interactive components:

Proximity glow — the border lights up as the cursor approaches, before any hover. It is driven by a single shared pointer engine that writes CSS variables directly and skips offscreen elements — no re-render, no per-element listeners.

Press ripple + tilt — a droplet ripple from the exact press point, with a slight 3D tilt toward the cursor. Both are disabled automatically under reduced motion.

Both ship inlined inside the component’s own file — there is no effects.css to add. They just work the moment the element is on the page.

Slots

Where a component renders content you might want to replace, it exposes a slot with a sensible fallback:

<vs-button>
  <span class="icon"><svg><!-- your icon --></svg></span>
  Save
</vs-button>

Slots are the native <slot> mechanism, so they work in any framework. The label attribute is the shortcut; the default slot is the escape hatch.

Values: properties and events

Anything with a value exposes a value property and fires input / change events — the standard form-control contract. Because it is a native element, your framework’s two-way binding maps straight onto it with no adapter:

<!-- vanilla -->
<vs-input type="email" label="Email"></vs-input>

<!-- Vue      -->  <vs-input v-model="email" label="Email" />
<!-- Svelte   -->  <vs-input bind:value={email} label="Email" />
<!-- React    -->  <vs-input value={email} onInput={e => setEmail(e.target.value)} label="Email" />

Pass object or array inputs (a select’s options, a tree’s nodes) as DOM properties rather than attributes: el.options = [...].

Accessibility

Components ship with roles, aria-* state and keyboard handling — arrow keys in menus and tabs, Esc to dismiss overlays, focus returned to the trigger on close, visible focus rings that survive theming. Keep those attributes when you edit the copy; they are not decoration.

Variants and families

Many components have siblings: VsDropdown, VsDropdownBlur, VsDropdownFold, VsDropdownGlow… Same skeleton and same props, one different motion or surface treatment. In the catalog they are grouped under the base name in the left rail. Pick the one whose feel you want; they are interchangeable in markup.

Editing your copy

It is your file now. Rename it, strip the props you don’t use, delete the ripple, change the markup — nothing phones home and nothing will overwrite it. The two things worth keeping:

  1. The token fallbacks (var(--x, 12px)) — that pattern is what lets the component survive in a project without tokens.
  2. The reduced-motion guards — see Effects & motion.