GrFormSection

  • core
  • forms
  • API · 4 props

Groups related form fields into a clear, meaningful section.

import { GrFormSection } from '@feugene/granularity/components/GrFormSection'

Overview

When to take it

  • the form is long — “Contacts”, “Delivery”, “Payment”: the sections give structure and points of navigation;
  • the section is needed by a blind user — the heading renders as an h2…h6 tag, and the form is walked by headings;
  • the section has actions — “Add”, “Reset” in the right part of the header;
  • the section needs an explanation — a description under the heading rather than a hint at every field.

When to take something else

NeedTake
Rules and submissionGrForm
The wrapper of a single fieldGrFormField
The sections are switched rather than following one anotherGrTabs
The section collapsesGrCollapse
Just a card is neededGrCard

Playground controls come from the API, not from hand

Stage

Loading…

0 changed· state is in the URL

Examples 3 each with a live demo and its code

  • A checkout read by its headings

    A long form gets structure from its sections: each title is a real h3 under the page’s h2, so a screen reader walks the form by headings, and the description speaks for the group — «we send the receipt here» — rather than hanging on the first field.

    Checkout

    Contact

    We send the receipt and delivery updates here.

    Delivery address

    Couriers deliver on weekdays, 9:00–18:00.

    Payment

  • An action that belongs to the section

    The title slot carries a counter next to the heading, and the actions slot holds what applies to the whole section — «Reset to defaults». Inside the list such a button would compete with the switches it resets.

    Notifications 3 of 5 on

    Email notifications for [email protected]
    An invoice is paidRight away
    An invoice becomes overdueThe morning after the due date
    Weekly revenue summaryMondays at 9:00
    Someone mentions youIn comments and notes
    Product newsAbout once a month
  • Security as a landmark, and a danger zone

    landmark turns a large section into a region named by its heading, worth it where people jump straight to «Security». The danger zone puts its one action in the head through actions and a link in the description slot.

    Security

    Applies to every member of the workspace.

    Danger zone

    Deleting removes projects, invoices and members. What is kept for tax purposes

API generated from the package · cannot drift

Props

PropTypedefaultDescription
titlestring | undefinedundefinedThe heading of the section — a real `h2`…`h6` by which the form is navigated. The `#title` slot is stronger.
descriptionstring | undefinedundefinedAn explanation under the heading, linked to the section through `aria-describedby`. The `#description` slot is stronger.
headingLevel2 | 3 | 4 | 5 | 6 | undefinedundefinedThe level of the heading to fit the structure of the page. Unset — it comes from `GrConfigProvider`, otherwise `3`.
landmarkboolean | undefinedfalseDeclare the section a `region` landmark. Off by default: five sections of a form would give five landmarks and clutter the overview, while the structure is carried by the heading anyway. It is worth switching on where the section really is large and it is worth jumping to it as to a region.

Slots

SlotTypeDescription
defaultanyThe content of the section.
titleanyThe heading as a whole — instead of the `title` string.
descriptionanyThe description as a whole — instead of the `description` string.
actionsanyThe actions in the right part of the header: "Add", "Reset".

Types

Every exported type of the subpath, grouped by the file it lives in. Names, generics and bodies come from the package’s declaration files and cannot drift.

Import
import type { GrFormSectionProps, GrFormSectionConfigurableProps, GrFormSectionHeadingLevel } from '@feugene/granularity/components/GrFormSection'

Filedist/types/components/GrFormSection/GrFormSection.vue.d.ts

GrFormSectionPropsinterface
interface GrFormSectionProps {
    title?: string;
    description?: string;
    headingLevel?: GrFormSectionHeadingLevel;
    landmark?: boolean;
}

Filedist/types/components/GrFormSection/config.d.ts

grFormSectionConfigconst
const grFormSectionConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrFormSection">;

Filedist/types/components/GrFormSection/defaults.d.ts

GrFormSectionConfigurablePropsinterface
interface GrFormSectionConfigurableProps {
    headingLevel: GrFormSectionHeadingLevel;
}

Filedist/types/components/GrFormSection/grFormSectionStyles.d.ts

GrFormSectionHeadingLeveltype
type GrFormSectionHeadingLevel = typeof GR_FORM_SECTION_HEADING_LEVELS[number];

Filedist/types/components/GrFormSection/safelist.d.ts

grFormSectionSafelistconst
const grFormSectionSafelist: string[];

Usage from the library prose

The heading is real

A blind user walks a long form by headings, so the heading of a section renders as an h2…h6 tag rather than as bold text:

vue
<GrFormSection title="Profile" :heading-level="2" description="Public data">
  <GrFormField label="Name"><GrInput v-model="name" /></GrFormField>
</GrFormSection>

headingLevel is 3 by default and is read from GrConfigProvider (componentDefaults.GrFormSection.headingLevel) — the level is set once for the whole application, if the form has a page structure of its own.

A landmark on request

The root is a <section>, but without a name: a named section becomes a region landmark, and five sections of a form would give five regions in the overview of a screen reader. The structure is carried by the heading.

Where a section really is large and it is worth jumping to it as to a region, switch landmark on — the name will come from the heading:

vue
<GrFormSection landmark title="Security" />

The description is linked to the section through aria-describedby in both modes.

The slots
SlotWhat it replaces
titlethe heading as a whole — a link, a badge, a counter
descriptionthe description as a whole
actionsthe right part of the header: “Add”, “Reset”
defaultthe content of the section

The header is a single row: the heading with the description on the left, the actions on the right; on a narrow screen the actions wrap under the heading. Without a heading, a description and actions the header is not rendered at all.

The border and collapsing

There are deliberately no bordered/collapsible props — that is composition, not a setting:

vue
<GrCard class="p-4">
  <GrFormSection title="Profile" />
</GrCard>

Collapsing is given by GrCollapse — it has the same headingLevel, so the structure of the headings does not break.