Examples

Interactive Form

A fillable PDF form combining every form component — text inputs (including formatted, multiline, and read-only variants), checkboxes, a dropdown, and a multi-select list, grouped into sections with <FieldSet>.

RegistrationForm.vue
<script setup lang="ts">
import { StyleSheet } from '@vuepdf/renderer'

const styles = StyleSheet.create({
  page: {
    backgroundColor: '#fafafa',
    padding: 40,
    fontSize: 10,
  },
  title: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#1a1a1a',
  },
  subtitle: {
    fontSize: 9,
    color: '#888',
    marginBottom: 20,
  },
  card: {
    backgroundColor: '#ffffff',
    borderRadius: 5,
    padding: 16,
    borderWidth: 1,
    borderColor: '#e8e8e8',
    marginBottom: 8,
  },
  sectionLabel: {
    fontSize: 8,
    color: '#999',
    textTransform: 'uppercase',
    letterSpacing: 0.5,
    marginBottom: 12,
  },
  fieldGroup: {
    marginBottom: 12,
  },
  label: {
    fontSize: 10,
    color: '#333',
    marginBottom: 4,
  },
  input: {
    height: 24,
    borderWidth: 1,
    borderColor: '#cbd5e1',
  },
  textarea: {
    height: 70,
    fontSize: 9,
    borderWidth: 1,
    borderColor: '#cbd5e1',
  },
  checkboxRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 6,
    marginBottom: 8,
  },
  checkbox: {
    width: 12,
    height: 12,
  },
  select: {
    height: 20,
    borderWidth: 1,
    borderColor: '#cbd5e1',
  },
  list: {
    height: 56,
    borderWidth: 1,
    borderColor: '#cbd5e1',
  },
})
</script>

<template>
  <Document title="Registration Form">
    <Page size="A4" :style="styles.page">
      <Text :style="styles.title">Registration</Text>
      <Text :style="styles.subtitle">
        Fill this form in your PDF reader and save a copy.
      </Text>

      <FieldSet name="applicant" :style="styles.card">
        <Text :style="styles.sectionLabel">Applicant</Text>

        <View :style="styles.fieldGroup">
          <Text :style="styles.label">Full name</Text>
          <TextInput name="fullName" required :style="styles.input" />
        </View>

        <View :style="styles.fieldGroup">
          <Text :style="styles.label">Email</Text>
          <TextInput name="email" no-spell :style="styles.input" />
        </View>

        <View :style="styles.fieldGroup">
          <Text :style="styles.label">Date of birth</Text>
          <TextInput
            name="dob"
            :format="{ type: 'date', param: 'dd/mm/yyyy' }"
            :style="styles.input"
          />
        </View>

        <View :style="styles.fieldGroup">
          <Text :style="styles.label">Phone</Text>
          <TextInput
            name="phone"
            :format="{ type: 'phone' }"
            :style="styles.input"
          />
        </View>
      </FieldSet>

      <FieldSet name="address" :style="styles.card">
        <Text :style="styles.sectionLabel">Address</Text>

        <View :style="styles.fieldGroup">
          <Text :style="styles.label">Street</Text>
          <TextInput name="street" :style="styles.input" />
        </View>

        <View :style="styles.fieldGroup">
          <Text :style="styles.label">City</Text>
          <TextInput name="city" :style="styles.input" />
        </View>
      </FieldSet>

      <View :style="styles.card">
        <Text :style="styles.sectionLabel">Preferences</Text>

        <View :style="styles.fieldGroup">
          <Text :style="styles.label">Country</Text>
          <Select
            name="country"
            :select="['', 'Nigeria', 'Ghana', 'Kenya', 'South Africa']"
            value=""
            default-value=""
            :style="styles.select"
          />
        </View>

        <View :style="styles.fieldGroup">
          <Text :style="styles.label">Languages</Text>
          <List
            name="languages"
            multi-select
            sort
            :select="['English', 'French', 'Hausa', 'Igbo', 'Yoruba']"
            :style="styles.list"
          />
        </View>

        <View :style="styles.checkboxRow">
          <Checkbox name="newsletter" checked :style="styles.checkbox" />
          <Text>Send me the monthly newsletter</Text>
        </View>

        <View :style="styles.checkboxRow">
          <Checkbox name="terms" x-mark :style="styles.checkbox" />
          <Text>I accept the terms and conditions</Text>
        </View>
      </View>

      <View :style="styles.card">
        <Text :style="styles.sectionLabel">Anything else?</Text>
        <TextInput name="notes" multiline :max-length="500" :style="styles.textarea" />
      </View>

      <View :style="styles.card">
        <Text :style="styles.sectionLabel">Office use only</Text>
        <TextInput
          name="reference"
          value="REF-0001"
          read-only
          :style="styles.input"
        />
      </View>
    </Page>
  </Document>
</template>

Exported Data

When the reader fills this form in and the data is read back, the fields inside a <FieldSet> are namespaced under it:

  • applicant.fullName, applicant.email, applicant.dob, applicant.phone
  • address.street, address.city
  • country, languages, newsletter, terms, notes, reference
<Select> and <List> are never namespaced by a <FieldSet>, which is why country and languages stay at the top level here even though the other preference fields sit alongside them.
Try this document in the Playground — the form components are available there, and you can see the fields become interactive in the embedded viewer.