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.
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".
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
| Group | Components |
|---|---|
| Action | VButton, VIconButton, VTooltipButton |
| Structure | VCard, VDivider, VEmptyState |
| Form | VLabel, VField, VInput, VTextarea, VSelect, VCheckbox, VRadio, VSwitch, VRating |
| Signalling | VBadge, VTag, VAlert, VAvatar |
| Waiting | VSpinner, VSkeleton, VProgress |
| Data | VStat, VTable, VPagination |
| Navigation and step by step | VBreadcrumb, VSteps, VTimeline |
| Code | VCodeBlock |
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>
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.