Skip to content

theNewDynamic/astro-forms

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HUGE can build forms from a few config lines

TL;DR:

Setup

// astro.config.mjs
import tndForms from "./src/packages/forms"
export default defineConfig({
  site: 'https://something.com',
  intergrations: [
    tndForms({
      submitCopy: 'Get in touch',
    })
  ]
})

Usage

---
import type { FormType } from '@forms/types'
import Form from "@forms/components/Form.astro";
const contactForm: FormType = {
  netlify: {
    id: 'contact'
  },
  captcha: true,
  redirect: "/thank-you/",
  fields: [
    {
      name: 'name',
      required: true,
      label: 'Name',
    },
    {
      // Group Field won't display a "<legend>" unless the 'label' key is explicitly set.
      name: 'contacts',
      type: 'group',
      columns: 2,
      fields: [
        {
          name: 'email',
          label: 'Email Address',
          type: 'email',
          required: true,
        },
        {
          name: 'phone',
          label: 'Phone Number',
          type: 'phone'
        },
      ]
    },
    {
      name: "company_size",
      label: "Company Size",
      type: "select",
      options: ["1 - 5", "6-20", "more"]
    },
    {
      name: 'message',
      label: 'Message',
      type: 'textarea'
    }
  ]
}
---
<h1>Contact Us!</h1>
<Form form={contactForm} />

Form Settings

Everying up to the

  • id*: This will be used to invoke the form.
  • action: A string. This value will fill the action attribute of the form. For built-in solutions, this is usually not required.
  • redirect (N,F,C): A string. A URL to which the form will redirect upon succes. Available on some solution.
  • submit_copy: A string. The copy of the submit button. Ex: Get in touch!
  • attributes: A map. A set of custom attributes to add to the form tag. Keys without values will be added as boolean attributes. Note that some attributes are added automatically (action, netlify-honeypot etc...) They will be overwritten by any honomymous attribute added here.
  • fields: An array. The list of fields to be printed among the forms.

Form Settings Example

  • title: Title of the form. (string)
  • action: Overwrite action value generated by the service logic. (string)
  • netlify: Netlify service configuration. (Service)
  • formspree: Formspree service configuration. (Service)
  • attributes: A map. A set of custom attributes to add to the input tag. Keys without values will be added as boolean attributes. Note that some attributes are added automatically (method, action etc...) They will be overwritten by any honomymous attribute added here.
  • method: Method used by the form. (string, default: 'POST', example: 'POST')
  • captcha: Use the service's captcha solution. (boolean, default: false)
  • cc: Send a copy of the submission to provided email(s). Only available on Formspree. (string)
  • redirect: Where to send the user after form submission. (string)
  • submitCopy: Customize the submit button's copy. (string, default: 'Submit', example: 'Sign up')
  • fields: Array of Field objects representing the form fields.
  • components: Override built-in label/wrapper/input components for this form or declare your own for custom input types. (object)

Fields Settings

A field is a group of HTML tags that consists of inputs, label. Some field can hold several inputs and label.

  • name: The name of the field (should be slug-like). (string)
  • type: The type of the field. (string, default: 'text', example: 'textarea')
  • value: Value for hidden fields. (string or number)
  • placeholder: Placeholder attribute for the field. (string)
  • hint: Smaller text below the field. (string)
  • attributes: A map. A set of custom attributes to add to the input tag. Keys without values will be added as boolean attributes. Note that some attributes are added automatically (name, id etc...) They will be overwritten by any honomymous attribute added here.
  • label: If set, used as a label. (string, default: name, example: 'Telephone')
  • required: Make the field 'required'. Label will be appended with '*'. (boolean)
  • options: Array of strings or objects for field options.
  • rows: Number of rows for textarea. (number)
  • columns: Reserved for group fields. (number)
  • fields: Array of nested fields for group fields.
  • components: Override built-in label/wrapper/input components for this field or declare your own for custom input types. (FormComponents)

Built in Field types

text|phone|email|file|textarea: Will use the same template with the defined type attribute

{
  name: 'name',
  label: 'Full Name',
  type: 'text'
}

select: A select field. Takes one extra key (options)

{
  name: 'state',
  label: 'State',
  type: 'select',
  options: [
    'Alabama',
    'Alaska',
    // ...
  ]
}

You can use an array of objects if sent values are different than the title.

{
  ...seeAbove,
  options: [
    { title: 'Alabama', value: 'AL' },
    { title: 'Alaska', value: 'AK' },
  ]
}

checkboxes|radios: A multiple choice field using either checkboxes or radios. Use radios type for radios and checkboxes for multiple checkboxes.

{
  name: 'source',
  label: 'How did you hear from us?',
  type: 'radios',
  options: [
    'A friend',
    'Internet',
    'Ad'
  ]
}

checkbox

A single checkbox field

{
  type: 'checkbox',
  name: 'agree',
  label: 'Do you agree with everything we will ever say?'
}

hidden

A hidden field

{
  type: 'hidden',
  name: 'lang_code',
  value: 'en'
}

In absence of the value setting, the module will use a hidden field's label setting for the value attribute.

Overriding Components

Every structural component can be replaced with your own Astro component via the components key, either at the form level (applies to all fields in the form) or at the field level (applies to that field only).

Submit button

Pass a custom submit component at the form level:

---
import MySubmit from './MySubmit.astro'

const form = {
  fields: [...],
  components: {
    submit: MySubmit
  }
}
---
<Form {form} />

Your component receives copy (the button label string) plus any extra props passed to <Form>:

---
// MySubmit.astro
const { copy } = Astro.props
---
<button type="submit" class="btn btn-primary">{copy}</button>

Field wrapper, label, and input

Override wrapper, label, and input components for all fields in a form:

---
import MyWrapper from './MyWrapper.astro'
import MyLabel from './MyLabel.astro'

const form = {
  fields: [...],
  components: {
    wrapper: MyWrapper,
    label: MyLabel,
  }
}
---

Override input for a specific field type across the whole form (e.g. replace all textareas):

components: {
  textarea: MyTextArea,
}

Override at the field level to target a single field only:

---
import MyInput from './MyInput.astro'

const form = {
  fields: [
    {
      name: 'email',
      type: 'email',
      components: {
        input: MyInput,
      }
    }
  ]
}
---

Custom wrapper components receive type, classes (array), and named slots label, input, and hint. Custom label and input components receive the full field object and classes (array).

Applying overrides to all forms

If you want the same component overrides across every form, wrap your form data with a helper:

import MySubmit from './MySubmit.astro'

const withOverrides = (form) => ({
  ...form,
  components: {
    submit: MySubmit,
    ...form.components,
  }
})
<Form form={withOverrides(contactForm)} />

Styling

The package ships with minimal default styles. The easiest way to customize them is via CSS custom properties, which should be declared on the form element or any ancestor (e.g. :root).

Variable Default Controls
--tnd-forms-input-bg white Background color of all inputs and selects
--tnd-forms-input-border 1px solid currentColor Border of all inputs, selects, and textareas
--tnd-forms-input-padding .5rem Padding inside all inputs, selects, and textareas
--tnd-forms-field-gap 1rem Vertical spacing between fields
--tnd-forms-rounded 3px Border radius of inputs and the submit button

Declare overrides in any global stylesheet:

:root {
  --tnd-forms-input-bg: #f9f9f9;
  --tnd-forms-input-border: 2px solid #ccc;
  --tnd-forms-input-padding: .75rem;
  --tnd-forms-field-gap: 1.5rem;
  --tnd-forms-rounded: 6px;
}

Or scope them to a specific form using the class passed via the classes prop:

.my-contact-form {
  --tnd-forms-input-bg: #fff8f0;
}
<Form form={contactForm} classes="my-contact-form" />

About

Astro integration for building forms from structured data

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors