Skip to main content
VelinStyle v1.3.0
⌂ Home
  1. Docs
  2. Installation & Build
  3. Vite & React

Vite starter & React 1.2.2

The Vite + static HTML starter in the VelinStyle repo plus the official @velinstyle/react package — one workflow for plain sites and React apps. Deutsch: Vite-Starter & React

Maturity: Documented as stable in VelinStyle 1.2.0. Design Intelligence (plan / review / agent meta) is separate and beta / foundation where noted.

When to use

When not

Vite Starter Template

Path: templates/vite-velinstyle. It pins VelinStyle with "velinstyle": "file:../.." so you can edit the framework and see changes immediately.

git clone https://github.com/SkyliteDesign/velinstyle
cd velinstyle/templates/vite-velinstyle
npm install
npm run dev

Use npm run build when you want a production bundle.

Use this template as the reference for loading core CSS, optional theme stylesheets, and the components bundle.

React integration

Package: @velinstyle/react (packages/react). The React package is a thin wrapper around native Web Components — no re-implementation, no duplicated logic; you get typed props and JSX ergonomics on top of the same elements as in HTML.

Wrappers exist for every canonical velin-* element. The export list is generated from the framework's component registry and CI fails when it drifts, so a new component cannot ship without a wrapper. Deprecated *-wc aliases are intentionally left out.

Build locally (from the repository root, after git clone; peer react):

npm run build:react

Usage — import VelinStyle CSS and the components bundle once; use wrappers like any native element. Props map to attributes on the custom element; handlers and refs attach to the underlying DOM node.

import { useRef } from 'react';
import { VelinDialog, VelinThemeToggle } from '@velinstyle/react';
import '@birdapi/velinstyle/css';
import '@birdapi/velinstyle/bundle';

export function App() {
  const dialogRef = useRef(null);
  return (
    <>
      <VelinThemeToggle target="html" />
      <VelinDialog ref={dialogRef} />
      <button type="button" onClick={() => dialogRef.current?.confirm('Continue?', { title: 'Settings' })}>
        Open dialog
      </button>
    </>
  );
}

Runtime boot in React

You can still tree-shake: call bootFromDOM(document, { attributes: true }) once at app start, or register([...]) for known tags. The React wrappers assume the custom element is defined (via bundle import or runtime).

How props are mapped

React 18 turns every unknown prop into a string attribute, so open={false} would render open="false" — still truthy for hasAttribute — and objects would be stringified. The wrappers route each prop to the form the custom element expects:

Prop valueApplied as
string, numberattribute
booleanpresence attribute (set or removed)
object, array, functionelement property
onVelin* functionaddEventListener for the matching custom event
null / undefinedomitted
onClick and other React eventspassed to React unchanged

Custom event names follow the prop name: onVelinSearchSelect binds velin-search-select.

<VelinSearch
  entries={entries}                    // element property, not stringified
  open={isOpen}                        // presence attribute
  onVelinSearchSelect={handleSelect}   // custom event listener
  onClick={handleClick}                // regular React handler
/>

For custom elements of your own, createVelinComponent('my-widget') builds a wrapper with the same behaviour.

React notes:

See also