Components and state

Ready-made components

The full build registers 29 components with a look of their own, accessible and in step with the theme. None of them uses the browser's default appearance, and no colour is hardcoded in the CSS: everything comes from the palette, which you change in one line.

voodoo.full.min.js only

The V* components exist only in the full build. In the other two files the tags are simply not recognized and stay in the HTML as they are.

Using them

<div v-data="{ email: '' }">
  <VButton variant="primary" size="lg" icon="check">Save</VButton>
  <VButton variant="ghost">Cancel</VButton>
  <VBadge tone="success">Active</VBadge>
  <VTag>draft</VTag>

  <VInput label="Email" type="email" icon="mail"
          hint="We never share it" v-model="email"></VInput>

  <VAlert tone="warning" title="Heads up" closable>
    The invoice is due in three days.
  </VAlert>

  <VStat label="Revenue" value="$128,400" delta="12.4" icon="chart"></VStat>
</div>

Each one takes both spellings, <VButton> and <v-button>. The boolean props accept the empty attribute, the text true and the reactive binding :loading="saving".

Always close the tag

These components are custom tags, and HTML does not accept self-closing outside the known tags: <VInput ... /> closes nothing, and the browser puts the whole rest of the block inside the component. Always write <VInput ...></VInput>. The symptom, when this slips through, is a stretch of the page vanishing with no error in the console at all.

The whole list

GroupComponents
ActionVButton, VIconButton, VTooltipButton
StructureVCard, VDivider, VEmptyState
FormVLabel, VField, VInput, VTextarea, VSelect, VCheckbox, VRadio, VSwitch, VRating
SignallingVBadge, VTag, VAlert, VAvatar
WaitingVSpinner, VSkeleton, VProgress
DataVStat, VTable, VPagination
Navigation and step by stepVBreadcrumb, VSteps, VTimeline
CodeVCodeBlock

The props of each one, one by one, are in the ready-made components reference.

Table and pagination

<div v-data="{ orders: [
  { name: 'Ann',   total: '$1,200' },
  { name: 'Bob',   total: '$890' },
  { name: 'Chris', total: '$2,310' }
] }">
  <VTable columns="name:Customer, total:Total:right" :rows="orders" striped></VTable>
</div>

The spelling of columns is key:Title:alignment, separated by commas. The rows come from any reactive array — a v-resource included, which gives you a table bound to the API with no assembly code at all.

Inside a form

They work with v-submit and v-validate with no adaptation: what reaches the server is what ordinary fields would send, because underneath they are ordinary fields.

<form v-submit="/api/signups" v-validate v-toast-success="Sign-up sent!">
  <VInput label="Name" name="name" required></VInput>
  <VInput label="Email" name="email" type="email" required></VInput>
  <VSelect label="Plan" name="plan" options="Monthly, Yearly" required></VSelect>
  <VCheckbox name="terms" label="I accept the terms" required></VCheckbox>
  <VButton type="submit" :loading="$form.loading">Send</VButton>
</form>

The palette

The scale of shades is generated from your colours, so changing the brand colour changes the whole interface — buttons, fields, alerts, charts and the UI components of the essential build along with it.

V.palette({ primary: '#0F766E', accent: '#F59E0B', radius: '10px' });
<div>
  <script>
    V.config.globals.applyPalette = (colour) => V.palette({ primary: colour });
  </script>

  <div v-data="{ colour: '#0f766e' }">
    <div class="linha">
      <input type="color" v-model="colour">
      <button @click="applyPalette(colour)">Apply to the palette</button>
    </div>
    <VButton variant="primary">A primary button</VButton>
    <VBadge tone="primary">A badge</VBadge>
  </div>
</div>
Why the example goes through a function

The V object does not exist inside expressions: they only see the scopes, the magic variables and a closed list of globals. To call the library from inside the HTML, publish the function on V.config.globals, as above. The expression reference explains why and lists what is allowed.

The theme and palette page shows the generated tokens, the light and dark themes, and how to use the same variables in your own CSS.