Input
A single-line field where users can input and edit text.
Props
text.
off.
goa.
false.
false.
false.
false.
false.
30ch.
1.
0.
left.
default.
Events
Slots
const [open, setOpen] = useState(false);<GoabButton leadingIcon="add" onClick={() => setOpen(true)}>
Add Record
</GoabButton>
<GoabDrawer
maxSize="492px"
open={open}
heading="Add Record"
position="right"
onClose={() => setOpen(false)}
actions={
<GoabButtonGroup alignment="start">
<GoabButton type="primary" size="compact" onClick={() => setOpen(false)}>
Add record
</GoabButton>
<GoabButton type="tertiary" size="compact" onClick={() => setOpen(false)}>
Cancel
</GoabButton>
</GoabButtonGroup>
}
>
<GoabFormItem label="Level of education">
<GoabDropdown onChange={() => {}} name="education" value="university">
<GoabDropdownItem value="high-school" label="High School Diploma" />
<GoabDropdownItem value="college" label="College Diploma" />
<GoabDropdownItem value="university" label="University Degree" />
<GoabDropdownItem value="masters" label="Master's Degree" />
<GoabDropdownItem value="doctorate" label="Doctorate" />
</GoabDropdown>
</GoabFormItem>
<GoabFormItem label="Educational institution" mt="l">
<GoabInput name="education" type="text" onChange={() => {}} />
</GoabFormItem>
<GoabFormItem label="Field of study" requirement="optional" mt="l">
<GoabInput name="fieldOfStudy" type="text" onChange={() => {}} />
</GoabFormItem>
<GoabFormItem label="Is the person currently attending?" mt="l">
<GoabRadioGroup
name="attendTraining"
orientation="horizontal"
onChange={() => {}}
>
<GoabRadioItem value="yes" label="Yes" />
<GoabRadioItem value="no" label="No" />
</GoabRadioGroup>
</GoabFormItem>
<GoabFormItem label="Start date" mt="l">
<GoabDatePicker onChange={() => {}} value={new Date("2022-09-01")} />
<GoabCheckbox
name="startDateApproximate"
text="Approximate date"
value="y"
mt="s"
/>
</GoabFormItem>
<GoabFormItem label="Credential received?" mt="l">
<GoabRadioGroup
name="credentialReceived"
orientation="horizontal"
onChange={() => {}}
>
<GoabRadioItem value="yes" label="Yes" />
<GoabRadioItem value="no" label="No" />
</GoabRadioGroup>
</GoabFormItem>
</GoabDrawer>open = false;
onClick() {
this.open = true;
}
onClose() {
this.open = false;
}
dropdownOnChange(event: any) {
console.log(event);
}
inputOnChange(event: any) {
console.log(event);
}
radioOnChange(event: any) {
console.log(event);
}
dateOnChange(event: any) {
console.log(event);
}
closeDrawer() {
this.open = false;
}<goab-button leadingIcon="add" (onClick)="onClick()">Add Record</goab-button>
<goab-drawer
maxSize="492px"
[open]="open"
heading="Add Record"
position="right"
(onClose)="onClose()"
[actions]="actions"
>
<goab-form-item label="Level of education">
<goab-dropdown
(onChange)="dropdownOnChange($event)"
name="education"
value="university"
>
<goab-dropdown-item
value="high-school"
label="High School Diploma"
></goab-dropdown-item>
<goab-dropdown-item value="college" label="College Diploma"></goab-dropdown-item>
<goab-dropdown-item
value="university"
label="University Degree"
></goab-dropdown-item>
<goab-dropdown-item value="masters" label="Master's Degree"></goab-dropdown-item>
<goab-dropdown-item value="doctorate" label="Doctorate"></goab-dropdown-item>
</goab-dropdown>
</goab-form-item>
<goab-form-item label="Educational institution" mt="l">
<goab-input
name="education"
type="text"
(onChange)="inputOnChange($event)"
></goab-input>
</goab-form-item>
<goab-form-item label="Field of study" requirement="optional" mt="l">
<goab-input
name="fieldOfStudy"
type="text"
(onChange)="inputOnChange($event)"
></goab-input>
</goab-form-item>
<goab-form-item label="Is the person currently attending?" mt="l">
<goab-radio-group
name="attendTraining"
orientation="horizontal"
(onChange)="radioOnChange($event)"
>
<goab-radio-item value="yes" label="Yes"></goab-radio-item>
<goab-radio-item value="no" label="No"></goab-radio-item>
</goab-radio-group>
</goab-form-item>
<goab-form-item label="Start date" mt="l">
<goab-date-picker (onChange)="dateOnChange($event)"></goab-date-picker>
<goab-checkbox
name="startDateApproximate"
text="Approximate date"
value="y"
mt="s"
></goab-checkbox>
</goab-form-item>
<goab-form-item label="Credential received?" mt="l">
<goab-radio-group
name="credentialReceived"
orientation="horizontal"
(onChange)="radioOnChange($event)"
>
<goab-radio-item value="yes" label="Yes"></goab-radio-item>
<goab-radio-item value="no" label="No"></goab-radio-item>
</goab-radio-group>
</goab-form-item>
<ng-template #actions>
<goab-button-group alignment="start">
<goab-button type="primary" size="compact" (onClick)="closeDrawer()"
>Add record</goab-button
>
<goab-button type="tertiary" size="compact" (onClick)="closeDrawer()"
>Cancel</goab-button
>
</goab-button-group>
</ng-template>
</goab-drawer>const drawer = document.getElementById("record-drawer");
const openBtn = document.getElementById("open-drawer-btn");
const addBtn = document.getElementById("add-record-btn");
const cancelBtn = document.getElementById("cancel-btn");
openBtn.addEventListener("_click", () => {
drawer.setAttribute("open", "true");
});
drawer.addEventListener("_close", () => {
drawer.removeAttribute("open");
});
addBtn.addEventListener("_click", () => {
drawer.removeAttribute("open");
});
cancelBtn.addEventListener("_click", () => {
drawer.removeAttribute("open");
});<goa-button version="2" id="open-drawer-btn" leadingicon="add">Add Record</goa-button>
<goa-drawer
version="2"
id="record-drawer"
max-size="492px"
heading="Add Record"
position="right"
>
<goa-form-item version="2" label="Level of education">
<goa-dropdown version="2" name="education" value="university">
<goa-dropdown-item
value="high-school"
label="High School Diploma"
></goa-dropdown-item>
<goa-dropdown-item value="college" label="College Diploma"></goa-dropdown-item>
<goa-dropdown-item value="university" label="University Degree"></goa-dropdown-item>
<goa-dropdown-item value="masters" label="Master's Degree"></goa-dropdown-item>
<goa-dropdown-item value="doctorate" label="Doctorate"></goa-dropdown-item>
</goa-dropdown>
</goa-form-item>
<goa-form-item version="2" label="Educational institution" mt="l">
<goa-input version="2" name="education" type="text"></goa-input>
</goa-form-item>
<goa-form-item version="2" label="Field of study" requirement="optional" mt="l">
<goa-input version="2" name="fieldOfStudy" type="text"></goa-input>
</goa-form-item>
<goa-form-item version="2" label="Is the person currently attending?" mt="l">
<goa-radio-group version="2" name="attendTraining" orientation="horizontal">
<goa-radio-item value="yes" label="Yes"></goa-radio-item>
<goa-radio-item value="no" label="No"></goa-radio-item>
</goa-radio-group>
</goa-form-item>
<goa-form-item version="2" label="Start date" mt="l">
<goa-date-picker version="2"></goa-date-picker>
<goa-checkbox
version="2"
name="startDateApproximate"
text="Approximate date"
value="y"
mt="s"
></goa-checkbox>
</goa-form-item>
<goa-form-item version="2" label="Credential received?" mt="l">
<goa-radio-group version="2" name="credentialReceived" orientation="horizontal">
<goa-radio-item value="yes" label="Yes"></goa-radio-item>
<goa-radio-item value="no" label="No"></goa-radio-item>
</goa-radio-group>
</goa-form-item>
<div slot="actions">
<goa-button-group alignment="start">
<goa-button version="2" id="add-record-btn" type="primary" size="compact"
>Add record</goa-button
>
<goa-button version="2" id="cancel-btn" type="tertiary" size="compact"
>Cancel</goa-button
>
</goa-button-group>
</div>
</goa-drawer>const [open, setOpen] = useState(false);
const [type, setType] = useState<string>();
const [name, setName] = useState<string>();
const [description, setDescription] = useState<string>();<GoabButton type="tertiary" leadingIcon="add" onClick={() => setOpen(true)}>
Add another item
</GoabButton>
<GoabModal
heading="Add a new item"
open={open}
actions={
<GoabButtonGroup alignment="end">
<GoabButton type="tertiary" size="compact" onClick={() => setOpen(false)}>
Cancel
</GoabButton>
<GoabButton type="primary" size="compact" onClick={() => setOpen(false)}>
Save new item
</GoabButton>
</GoabButtonGroup>
}
>
<p>Fill in the information to create a new item</p>
<GoabFormItem label="Type" mt="l">
<GoabDropdown onChange={(e) => setType(e.value)} value={type}>
<GoabDropdownItem value="1" label="Option 1" />
<GoabDropdownItem value="2" label="Option 2" />
</GoabDropdown>
</GoabFormItem>
<GoabFormItem label="Name" mt="l">
<GoabInput
onChange={(e) => setName(e.value)}
value={name}
name="name"
width="100%"
/>
</GoabFormItem>
<GoabFormItem label="Description" mt="l">
<GoabTextArea
name="description"
rows={3}
width="100%"
onChange={(e) => setDescription(e.value)}
value={description}
/>
</GoabFormItem>
</GoabModal>open = false;
type: string | undefined = "";
name = "";
description = "";
toggleModal() {
this.open = !this.open;
}
updateType(event: any) {
this.type = event.value;
}
updateName(event: any) {
this.name = event.value;
}
updateDescription(event: any) {
this.description = event.value;
}<goab-button type="tertiary" leadingIcon="add" (onClick)="toggleModal()"
>Add another item</goab-button
>
<goab-modal
[open]="open"
(onClose)="toggleModal()"
heading="Add a new item"
[actions]="actions"
>
<p>Fill in the information to create a new item</p>
<goab-form-item label="Type" mt="l">
<goab-dropdown (onChange)="updateType($event)" [value]="type">
<goab-dropdown-item value="1" label="Option 1"></goab-dropdown-item>
<goab-dropdown-item value="2" label="Option 2"></goab-dropdown-item>
</goab-dropdown>
</goab-form-item>
<goab-form-item label="Name" mt="l">
<goab-input
name="name"
width="100%"
(onChange)="updateName($event)"
[value]="name"
></goab-input>
</goab-form-item>
<goab-form-item label="Description" mt="l">
<goab-textarea
name="description"
width="100%"
[rows]="3"
(onChange)="updateDescription($event)"
[value]="description"
></goab-textarea>
</goab-form-item>
<ng-template #actions>
<goab-button-group alignment="end">
<goab-button type="tertiary" size="compact" (onClick)="toggleModal()"
>Cancel</goab-button
>
<goab-button type="primary" size="compact" (onClick)="toggleModal()"
>Save new item</goab-button
>
</goab-button-group>
</ng-template>
</goab-modal>const modal = document.getElementById("add-item-modal");
const openBtn = document.getElementById("open-modal-btn");
const cancelBtn = document.getElementById("cancel-btn");
const saveBtn = document.getElementById("save-btn");
openBtn.addEventListener("_click", () => {
modal.setAttribute("open", "true");
});
modal.addEventListener("_close", () => {
modal.removeAttribute("open");
});
cancelBtn.addEventListener("_click", () => {
modal.removeAttribute("open");
});
saveBtn.addEventListener("_click", () => {
modal.removeAttribute("open");
});<goa-button version="2" id="open-modal-btn" type="tertiary" leadingicon="add"
>Add another item</goa-button
>
<goa-modal version="2" id="add-item-modal" heading="Add a new item">
<p>Fill in the information to create a new item</p>
<goa-form-item version="2" label="Type" mt="l">
<goa-dropdown version="2" id="type-dropdown">
<goa-dropdown-item value="1" label="Option 1"></goa-dropdown-item>
<goa-dropdown-item value="2" label="Option 2"></goa-dropdown-item>
</goa-dropdown>
</goa-form-item>
<goa-form-item version="2" label="Name" mt="l">
<goa-input version="2" name="name" width="100%" id="name-input"></goa-input>
</goa-form-item>
<goa-form-item version="2" label="Description" mt="l">
<goa-textarea
version="2"
name="description"
width="100%"
rows="3"
id="description-textarea"
></goa-textarea>
</goa-form-item>
<div slot="actions">
<goa-button-group alignment="end">
<goa-button version="2" id="cancel-btn" type="tertiary" size="compact"
>Cancel</goa-button
>
<goa-button version="2" id="save-btn" type="primary" size="compact"
>Save new item</goa-button
>
</goa-button-group>
</div>
</goa-modal>const [address, setAddress] = useState("");
const [suite, setSuite] = useState("");
const [city, setCity] = useState("");
const [province, setProvince] = useState("");
const [postalCode, setPostalCode] = useState("");<GoabText size="heading-l" mt="none" mb="xl">
What is your address?
</GoabText>
<GoabFormItem label="Street Address">
<GoabInput
name="address"
type="text"
value={address}
onChange={(e) => setAddress(e.value)}
width="100%"
/>
</GoabFormItem>
<GoabFormItem label="Suite or unit #" mt="l">
<GoabInput
name="suite"
type="text"
value={suite}
onChange={(e) => setSuite(e.value)}
width="100%"
/>
</GoabFormItem>
<GoabFormItem label="City or town" mt="l">
<GoabInput
name="city"
type="text"
value={city}
onChange={(e) => setCity(e.value)}
width="100%"
/>
</GoabFormItem>
<GoabBlock direction="row" gap="l" mt="l">
<GoabFormItem label="Province or territory">
<GoabDropdown
onChange={(e) => setProvince(e.value ?? "")}
name="province"
value={province}
width="100%"
>
<GoabDropdownItem label="Alberta" value="AB" />
<GoabDropdownItem label="British Columbia" value="BC" />
<GoabDropdownItem label="Manitoba" value="MB" />
<GoabDropdownItem label="New Brunswick" value="NB" />
<GoabDropdownItem label="Newfoundland and Labrador" value="NL" />
<GoabDropdownItem label="Northwest Territories" value="NT" />
<GoabDropdownItem label="Nova Scotia" value="NS" />
<GoabDropdownItem label="Nunavut" value="NU" />
<GoabDropdownItem label="Ontario" value="ON" />
<GoabDropdownItem label="Prince Edward Island" value="PE" />
<GoabDropdownItem label="Quebec" value="QC" />
<GoabDropdownItem label="Saskatchewan" value="SK" />
<GoabDropdownItem label="Yukon" value="YT" />
</GoabDropdown>
</GoabFormItem>
<GoabFormItem label="Postal Code">
<GoabInput
name="postalCode"
type="text"
value={postalCode}
onChange={(e) => setPostalCode(e.value)}
width="7ch"
/>
</GoabFormItem>
</GoabBlock>
<GoabButtonGroup alignment="start" mt="2xl">
<GoabButton type="primary" onClick={() => {}}>
Save and continue
</GoabButton>
<GoabButton type="secondary" onClick={() => {}}>
Cancel
</GoabButton>
</GoabButtonGroup>form!: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
address: [""],
suite: [""],
city: [""],
province: [""],
postalCode: [""],
});
}
onClick() {
// Handle form submission
}<goab-text size="heading-l" mt="none" mb="xl">What is your address?</goab-text>
<goab-form-item label="Street Address">
<goab-input
name="address"
type="text"
[formControl]="form.controls.address"
width="100%"
></goab-input>
</goab-form-item>
<goab-form-item label="Suite or unit #" mt="l">
<goab-input
name="suite"
type="text"
[formControl]="form.controls.suite"
width="100%"
></goab-input>
</goab-form-item>
<goab-form-item label="City or town" mt="l">
<goab-input
name="city"
type="text"
[formControl]="form.controls.city"
width="100%"
></goab-input>
</goab-form-item>
<goab-block direction="row" gap="l" mt="l">
<goab-form-item label="Province or territory">
<goab-dropdown name="province" [formControl]="form.controls.province" width="100%">
<goab-dropdown-item label="Alberta" value="AB"></goab-dropdown-item>
<goab-dropdown-item label="British Columbia" value="BC"></goab-dropdown-item>
<goab-dropdown-item label="Manitoba" value="MB"></goab-dropdown-item>
<goab-dropdown-item label="New Brunswick" value="NB"></goab-dropdown-item>
<goab-dropdown-item
label="Newfoundland and Labrador"
value="NL"
></goab-dropdown-item>
<goab-dropdown-item label="Northwest Territories" value="NT"></goab-dropdown-item>
<goab-dropdown-item label="Nova Scotia" value="NS"></goab-dropdown-item>
<goab-dropdown-item label="Nunavut" value="NU"></goab-dropdown-item>
<goab-dropdown-item label="Ontario" value="ON"></goab-dropdown-item>
<goab-dropdown-item label="Prince Edward Island" value="PE"></goab-dropdown-item>
<goab-dropdown-item label="Quebec" value="QC"></goab-dropdown-item>
<goab-dropdown-item label="Saskatchewan" value="SK"></goab-dropdown-item>
<goab-dropdown-item label="Yukon" value="YT"></goab-dropdown-item>
</goab-dropdown>
</goab-form-item>
<goab-form-item label="Postal Code">
<goab-input
name="postalCode"
type="text"
[formControl]="form.controls.postalCode"
width="7ch"
></goab-input>
</goab-form-item>
</goab-block>
<goab-button-group alignment="start" mt="2xl">
<goab-button type="primary" (onClick)="onClick()">Save and continue</goab-button>
<goab-button type="secondary" (onClick)="onClick()">Cancel</goab-button>
</goab-button-group>document.getElementById("save-btn")?.addEventListener("_click", () => {
console.log("Form submitted");
});<goa-text size="heading-l" mt="none" mb="xl">What is your address?</goa-text>
<goa-form-item version="2" label="Street Address">
<goa-input
version="2"
name="address"
type="text"
width="100%"
id="address-input"
></goa-input>
</goa-form-item>
<goa-form-item version="2" label="Suite or unit #" mt="l">
<goa-input
version="2"
name="suite"
type="text"
width="100%"
id="suite-input"
></goa-input>
</goa-form-item>
<goa-form-item version="2" label="City or town" mt="l">
<goa-input version="2" name="city" type="text" width="100%" id="city-input"></goa-input>
</goa-form-item>
<goa-block direction="row" gap="l" mt="l">
<goa-form-item version="2" label="Province or territory">
<goa-dropdown version="2" name="province" id="province-dropdown" width="100%">
<goa-dropdown-item label="Alberta" value="AB"></goa-dropdown-item>
<goa-dropdown-item label="British Columbia" value="BC"></goa-dropdown-item>
<goa-dropdown-item label="Manitoba" value="MB"></goa-dropdown-item>
<goa-dropdown-item label="New Brunswick" value="NB"></goa-dropdown-item>
<goa-dropdown-item label="Newfoundland and Labrador" value="NL"></goa-dropdown-item>
<goa-dropdown-item label="Northwest Territories" value="NT"></goa-dropdown-item>
<goa-dropdown-item label="Nova Scotia" value="NS"></goa-dropdown-item>
<goa-dropdown-item label="Nunavut" value="NU"></goa-dropdown-item>
<goa-dropdown-item label="Ontario" value="ON"></goa-dropdown-item>
<goa-dropdown-item label="Prince Edward Island" value="PE"></goa-dropdown-item>
<goa-dropdown-item label="Quebec" value="QC"></goa-dropdown-item>
<goa-dropdown-item label="Saskatchewan" value="SK"></goa-dropdown-item>
<goa-dropdown-item label="Yukon" value="YT"></goa-dropdown-item>
</goa-dropdown>
</goa-form-item>
<goa-form-item version="2" label="Postal Code">
<goa-input
version="2"
name="postalCode"
type="text"
width="7ch"
id="postal-input"
></goa-input>
</goa-form-item>
</goa-block>
<goa-button-group alignment="start" mt="2xl">
<goa-button version="2" type="primary" id="save-btn">Save and continue</goa-button>
<goa-button version="2" type="secondary" id="cancel-btn">Cancel</goa-button>
</goa-button-group>const [bankNumber, setBankNumber] = useState("");
const [transitNumber, setTransitNumber] = useState("");
const [accountNumber, setAccountNumber] = useState("");<GoabText tag="h1" size="heading-l" mt="none" mb="m">
Direct deposit information
</GoabText>
<GoabText tag="p" mb="xl">
Find this information on your bank's website or on your personal cheques. Contact
your bank if you can't find this information.
</GoabText>
<form>
<GoabFormItem label="Bank or Institution number" helpText="3-4 digits in length">
<GoabInput
maxLength={4}
name="bankNumber"
onChange={(e) => setBankNumber(e.value)}
value={bankNumber}
ariaLabel="bankNumber"
width="88px"
/>
</GoabFormItem>
<GoabFormItem
label="Branch or Transit number"
helpText="5 digits in length"
mt="l"
>
<GoabInput
maxLength={5}
name="transitNumber"
onChange={(e) => setTransitNumber(e.value)}
value={transitNumber}
ariaLabel="transitNumber"
width="143px"
/>
</GoabFormItem>
<GoabFormItem label="Account number" helpText="3-12 digits in length" mt="l">
<GoabInput
maxLength={12}
name="accountNumber"
value={accountNumber}
onChange={(e) => setAccountNumber(e.value)}
ariaLabel="accountNumber"
/>
</GoabFormItem>
</form>
<GoabDetails
heading="Where can I find this information on a personal cheque?"
mt="l"
>
<GoabText tag="p" mb="m">
Below is an example of where you can find the required bank information on a
personal cheque.
</GoabText>
<img
src="https://design.alberta.ca/images/details-demo.jpg"
alt="Cheque example showing bank information locations"
/>
</GoabDetails>
<GoabButton type="submit" mt="2xl">
Save and continue
</GoabButton>form!: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
bankNumber: [""],
transitNumber: [""],
accountNumber: [""],
});
}<goab-text tag="h1" size="heading-l" mt="none" mb="m"
>Direct deposit information</goab-text
>
<goab-text tag="p" mb="xl">
Find this information on your bank's website or on your personal cheques. Contact your
bank if you can't find this information.
</goab-text>
<form [formGroup]="form">
<goab-form-item label="Bank or Institution number" helpText="3-4 digits in length">
<goab-input
[maxLength]="4"
name="bankNumber"
formControlName="bankNumber"
ariaLabel="bankNumber"
width="88px"
>
</goab-input>
</goab-form-item>
<goab-form-item label="Branch or Transit number" helpText="5 digits in length" mt="l">
<goab-input
[maxLength]="5"
name="transitNumber"
formControlName="transitNumber"
ariaLabel="transitNumber"
width="143px"
>
</goab-input>
</goab-form-item>
<goab-form-item label="Account number" helpText="3-12 digits in length" mt="l">
<goab-input
[maxLength]="12"
name="accountNumber"
formControlName="accountNumber"
ariaLabel="accountNumber"
>
</goab-input>
</goab-form-item>
</form>
<goab-details heading="Where can I find this information on a personal cheque?" mt="l">
<goab-text tag="p" mb="m"
>Below is an example of where you can find the required bank information on a personal
cheque.</goab-text
>
<img src="https://design.alberta.ca/images/details-demo.jpg" alt="Cheque example" />
</goab-details>
<goab-button type="submit" mt="2xl" (onClick)="onSubmit()">
Save and continue
</goab-button>["bank-number-input", "transit-number-input", "account-number-input"].forEach((id) => {
document.getElementById(id)?.addEventListener("_change", (e) => {
console.log(`${id}:`, e.detail.value);
});
});<goa-text as="h1" size="heading-l" mt="none" mb="m">Direct deposit information</goa-text>
<goa-text as="p" mb="xl">
Find this information on your bank's website or on your personal cheques. Contact your
bank if you can't find this information.
</goa-text>
<form>
<goa-form-item
version="2"
label="Bank or Institution number"
helptext="3-4 digits in length"
>
<goa-input
version="2"
maxlength="4"
name="bankNumber"
id="bank-number-input"
aria-label="bankNumber"
width="88px"
>
</goa-input>
</goa-form-item>
<goa-form-item
version="2"
label="Branch or Transit number"
helptext="5 digits in length"
mt="l"
>
<goa-input
version="2"
maxlength="5"
name="transitNumber"
id="transit-number-input"
aria-label="transitNumber"
width="143px"
>
</goa-input>
</goa-form-item>
<goa-form-item
version="2"
label="Account number"
helptext="3-12 digits in length"
mt="l"
>
<goa-input
version="2"
maxlength="12"
name="accountNumber"
id="account-number-input"
aria-label="accountNumber"
>
</goa-input>
</goa-form-item>
</form>
<goa-details heading="Where can I find this information on a personal cheque?" mt="l">
<goa-text as="p" mb="m"
>Below is an example of where you can find the required bank information on a personal
cheque.</goa-text
>
<img src="https://design.alberta.ca/images/details-demo.jpg" alt="Cheque example" />
</goa-details>
<goa-button version="2" id="submit-btn" type="submit" mt="2xl">
Save and continue
</goa-button>const [bandNo, setBandNo] = useState("");
const [family, setFamily] = useState("");
const [position, setPosition] = useState("");<GoabFormItem label="Indian registration number" labelSize="large">
<GoabBlock gap="m" direction="row">
<GoabFormItem label="Band #" helpText="3 digits">
<GoabInput
onChange={(e) => setBandNo(e.value)}
value={bandNo}
name="bandNo"
width="88px"
maxLength={3}
/>
</GoabFormItem>
<GoabFormItem label="Family" helpText="Up to 5 digits">
<GoabInput
onChange={(e) => setFamily(e.value)}
value={family}
name="family"
width="105px"
maxLength={5}
/>
</GoabFormItem>
<GoabFormItem label="Position" helpText="2 digits">
<GoabInput
onChange={(e) => setPosition(e.value)}
value={position}
name="position"
width="71px"
maxLength={2}
/>
</GoabFormItem>
</GoabBlock>
</GoabFormItem>form!: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
bandNo: [""],
family: [""],
position: [""],
});
}<form [formGroup]="form">
<goab-form-item label="Indian registration number" labelSize="large">
<goab-block gap="m" direction="row">
<goab-form-item label="Band #" helpText="3 digits">
<goab-input formControlName="bandNo" name="bandNo" width="88px" [maxLength]="3">
</goab-input>
</goab-form-item>
<goab-form-item label="Family" helpText="Up to 5 digits">
<goab-input formControlName="family" name="family" width="105px" [maxLength]="5">
</goab-input>
</goab-form-item>
<goab-form-item label="Position" helpText="2 digits">
<goab-input
formControlName="position"
name="position"
width="71px"
[maxLength]="2"
>
</goab-input>
</goab-form-item>
</goab-block>
</goab-form-item>
</form>["band-input", "family-input", "position-input"].forEach((id) => {
document.getElementById(id)?.addEventListener("_change", (e) => {
console.log(`${id}:`, e.detail.value);
});
});<goa-form-item version="2" label="Indian registration number" labelsize="large">
<goa-block gap="m" direction="row">
<goa-form-item version="2" label="Band #" helptext="3 digits">
<goa-input version="2" name="bandNo" id="band-input" width="88px" maxlength="3">
</goa-input>
</goa-form-item>
<goa-form-item version="2" label="Family" helptext="Up to 5 digits">
<goa-input version="2" name="family" id="family-input" width="105px" maxlength="5">
</goa-input>
</goa-form-item>
<goa-form-item version="2" label="Position" helptext="2 digits">
<goa-input
version="2"
name="position"
id="position-input"
width="71px"
maxlength="2"
>
</goa-input>
</goa-form-item>
</goa-block>
</goa-form-item>Ask a user for dollar amounts
const [tuitionAmount, setTuitionAmount] = useState("");
const [suppliesAmount, setSuppliesAmount] = useState("");
const [othersAmount, setOthersAmount] = useState("");<GoabFormItem label="Tuition">
<GoabInput
onChange={(e) => setTuitionAmount(e.value)}
value={tuitionAmount}
name="tuitionAmount"
leadingContent="$"
/>
</GoabFormItem>
<GoabFormItem label="Books/Supplies/Instruments" mt="l">
<GoabInput
onChange={(e) => setSuppliesAmount(e.value)}
value={suppliesAmount}
name="suppliesAmount"
leadingContent="$"
/>
</GoabFormItem>
<GoabFormItem label="Other costs" mt="l">
<GoabInput
onChange={(e) => setOthersAmount(e.value)}
value={othersAmount}
name="othersAmount"
leadingContent="$"
/>
</GoabFormItem>costFormGroup = new FormGroup({
tuitionFeeAmount: new FormControl(""),
suppliesAmount: new FormControl(""),
othersAmount: new FormControl(""),
});<form [formGroup]="costFormGroup">
<goab-form-item label="Tuition">
<goab-input
name="tuition"
formControlName="tuitionFeeAmount"
leadingContent="$"
></goab-input>
</goab-form-item>
<goab-form-item label="Books/Supplies/Instruments" mt="l">
<goab-input
name="book"
formControlName="suppliesAmount"
leadingContent="$"
></goab-input>
</goab-form-item>
<goab-form-item label="Other costs" mt="l">
<goab-input
name="others"
formControlName="othersAmount"
leadingContent="$"
></goab-input>
</goab-form-item>
</form>["tuition-input", "supplies-input", "others-input"].forEach((id) => {
document.getElementById(id)?.addEventListener("_change", (e) => {
console.log(`${id}:`, e.detail.value);
});
});<form>
<goa-form-item version="2" label="Tuition">
<goa-input version="2" name="tuition" id="tuition-input">
<div slot="leadingContent">$</div>
</goa-input>
</goa-form-item>
<goa-form-item version="2" label="Books/Supplies/Instruments" mt="l">
<goa-input version="2" name="book" id="supplies-input">
<div slot="leadingContent">$</div>
</goa-input>
</goa-form-item>
<goa-form-item version="2" label="Other costs" mt="l">
<goa-input version="2" name="others" id="others-input">
<div slot="leadingContent">$</div>
</goa-input>
</goa-form-item>
</form>Dynamically add an item to a dropdown list
type Task = {
value: string;
label: string;
mount: GoabDropdownItemMountType;
};
const DEFAULT_TASKS: Task[] = [
{ label: "Finish Report", value: "finish-report", mount: "append" },
{ label: "Attend Meeting", value: "attend-meeting", mount: "append" },
{ label: "Reply Emails", value: "reply-emails", mount: "append" },
];
const [tasks, setTasks] = useState<Task[]>(DEFAULT_TASKS);
const [newTask, setNewTask] = useState<string>("");
const [mountType, setMountType] = useState<string>("append");
const [selectedTask, setSelectedTask] = useState<string>("");
const [taskError, setTaskError] = useState<boolean>(false);
const [isReset, setIsReset] = useState<boolean>(false);
function onMountTypeChange(value: string | undefined) {
setMountType(value as string);
}
function addTask() {
if (newTask === "") {
setTaskError(true);
return;
}
setTaskError(false);
const task: Task = {
label: newTask,
value: newTask.toLowerCase().replace(" ", "-"),
mount: mountType as GoabDropdownItemMountType,
};
setTasks([...tasks, task]);
setNewTask("");
setIsReset(false);
}
function reset() {
setTasks(DEFAULT_TASKS);
setMountType("append");
setNewTask("");
setSelectedTask("");
setTaskError(false);
setIsReset(true);
}<GoabFormItem
requirement="required"
label="Name of item"
error={taskError ? "Please enter item name" : undefined}
helpText="Add an item to the dropdown list below"
>
<GoabInput
onChange={(event: GoabInputOnChangeDetail) => setNewTask(event.value)}
name="item"
value={newTask}
/>
</GoabFormItem>
<GoabFormItem mt="l" label="Add to">
<GoabRadioGroup
name="mountType"
onChange={(event: GoabRadioGroupOnChangeDetail) =>
onMountTypeChange(event.value)
}
value={mountType}
orientation="horizontal"
>
<GoabRadioItem value="prepend" label="Start" />
<GoabRadioItem value="append" label="End" />
</GoabRadioGroup>
</GoabFormItem>
<GoabButtonGroup alignment="start" gap="relaxed" mt="l">
<GoabButton type="primary" onClick={addTask}>
Add new item
</GoabButton>
<GoabButton type="tertiary" onClick={reset}>
Reset list
</GoabButton>
</GoabButtonGroup>
<GoabDivider mt="l" />
<GoabFormItem mt="l" label="All items">
<div style={{ width: isReset ? "320px" : "auto" }}>
<GoabDropdown
key={tasks.length}
onChange={(event: GoabDropdownOnChangeDetail) =>
setSelectedTask(event.value as string)
}
value={selectedTask}
name="selectedTask"
>
{tasks.map((task) => (
<GoabDropdownItem
key={task.value}
value={task.value}
mountType={task.mount}
label={task.label}
/>
))}
</GoabDropdown>
</div>
</GoabFormItem>defaultTasks: Task[] = [
{ label: "Finish Report", value: "finish-report", mount: "append" },
{ label: "Attend Meeting", value: "attend-meeting", mount: "append" },
{ label: "Reply Emails", value: "reply-emails", mount: "append" },
];
tasks: Task[] = [...this.defaultTasks];
newTask = "";
mountType: GoabDropdownItemMountType = "append";
selectedTask = "";
taskError = false;
renderTrigger = true;
onMountTypeChange(event: GoabRadioGroupOnChangeDetail): void {
this.mountType = event.value as GoabDropdownItemMountType;
}
onNewTaskChange(event: GoabInputOnChangeDetail): void {
this.newTask = event.value;
this.taskError = false;
}
onSelectedTaskChange(event: GoabDropdownOnChangeDetail): void {
this.selectedTask = event.value as string;
}
addTask(): void {
if (this.newTask === "") {
this.taskError = true;
return;
}
this.taskError = false;
const task: Task = {
label: this.newTask,
value: this.newTask.toLowerCase().replace(" ", "-"),
mount: this.mountType,
};
this.tasks =
this.mountType === "prepend" ? [task, ...this.tasks] : [...this.tasks, task];
this.newTask = "";
}
reset(): void {
this.newTask = "";
this.selectedTask = "";
this.taskError = false;
this.tasks = [...this.defaultTasks];
this.forceRerender();
}
forceRerender(): void {
this.renderTrigger = false;
setTimeout(() => {
this.renderTrigger = true;
}, 0);
}
trackByFn(index: number, item: Task): string {
return item.value;
}<goab-form-item
requirement="required"
label="Name of item"
[error]="taskError ? 'Please enter item name' : undefined"
helpText="Add an item to the dropdown list below"
>
<goab-input name="item" [value]="newTask" (onChange)="onNewTaskChange($event)">
</goab-input>
</goab-form-item>
<goab-form-item mt="l" label="Add to">
<goab-radio-group
name="mountType"
[value]="mountType"
orientation="horizontal"
(onChange)="onMountTypeChange($event)"
>
<goab-radio-item value="prepend" label="Start"></goab-radio-item>
<goab-radio-item value="append" label="End"></goab-radio-item>
</goab-radio-group>
</goab-form-item>
<goab-button-group alignment="start" gap="relaxed" mt="l">
<goab-button type="primary" (onClick)="addTask()"> Add new item </goab-button>
<goab-button type="tertiary" (onClick)="reset()"> Reset list </goab-button>
</goab-button-group>
<goab-divider mt="l"></goab-divider>
<goab-form-item mt="l" label="All items">
<ng-container *ngIf="renderTrigger">
<goab-dropdown
[value]="selectedTask"
name="selectedTask"
(onChange)="onSelectedTaskChange($event)"
>
@for (task of tasks; track task.value) {
<goab-dropdown-item
[value]="task.value"
[mountType]="task.mount"
[label]="task.label"
>
</goab-dropdown-item>
}
</goab-dropdown>
</ng-container>
</goab-form-item>const itemInput = document.getElementById("item-input");
const itemFormItem = document.getElementById("item-form-item");
const mountTypeGroup = document.getElementById("mount-type");
const addBtn = document.getElementById("add-btn");
const resetBtn = document.getElementById("reset-btn");
const dropdown = document.getElementById("task-dropdown");
let mountType = "append";
let newTask = "";
const defaultItems = [
{ value: "finish-report", label: "Finish Report" },
{ value: "attend-meeting", label: "Attend Meeting" },
{ value: "reply-emails", label: "Reply Emails" },
];
mountTypeGroup.addEventListener("_change", (e) => {
mountType = e.detail.value;
});
itemInput.addEventListener("_change", (e) => {
newTask = e.detail.value;
itemFormItem.removeAttribute("error");
});
addBtn.addEventListener("_click", () => {
if (newTask === "") {
itemFormItem.setAttribute("error", "Please enter item name");
return;
}
const newItem = document.createElement("goa-dropdown-item");
newItem.setAttribute("value", newTask.toLowerCase().replace(" ", "-"));
newItem.setAttribute("label", newTask);
newItem.setAttribute("mount", mountType);
dropdown.appendChild(newItem);
itemInput.value = "";
newTask = "";
});
resetBtn.addEventListener("_click", () => {
dropdown.innerHTML = "";
defaultItems.forEach((item) => {
const dropdownItem = document.createElement("goa-dropdown-item");
dropdownItem.setAttribute("value", item.value);
dropdownItem.setAttribute("label", item.label);
dropdown.appendChild(dropdownItem);
});
itemInput.value = "";
newTask = "";
itemFormItem.removeAttribute("error");
});<goa-form-item
version="2"
id="item-form-item"
requirement="required"
label="Name of item"
helptext="Add an item to the dropdown list below"
>
<goa-input version="2" id="item-input" name="item"></goa-input>
</goa-form-item>
<goa-form-item version="2" mt="l" label="Add to">
<goa-radio-group
version="2"
id="mount-type"
name="mountType"
value="append"
orientation="horizontal"
>
<goa-radio-item value="prepend" label="Start"></goa-radio-item>
<goa-radio-item value="append" label="End"></goa-radio-item>
</goa-radio-group>
</goa-form-item>
<goa-button-group alignment="start" gap="relaxed" mt="l">
<goa-button version="2" id="add-btn" type="primary">Add new item</goa-button>
<goa-button version="2" id="reset-btn" type="tertiary">Reset list</goa-button>
</goa-button-group>
<goa-divider mt="l"></goa-divider>
<goa-form-item version="2" mt="l" label="All items">
<goa-dropdown version="2" id="task-dropdown" name="selectedTask">
<goa-dropdown-item value="finish-report" label="Finish Report"></goa-dropdown-item>
<goa-dropdown-item value="attend-meeting" label="Attend Meeting"></goa-dropdown-item>
<goa-dropdown-item value="reply-emails" label="Reply Emails"></goa-dropdown-item>
</goa-dropdown>
</goa-form-item>Disabled button with a required field
const [inputValue, setInputValue] = useState("");
const handleInputChange = (detail: GoabInputOnChangeDetail) => {
setInputValue(detail.value);
};
const handleConfirm = () => {
// Handle form submission
console.log("Form submitted with:", inputValue);
};
const handleCancel = () => {
// Handle cancellation
setInputValue("");
};<form>
<GoabFormItem label="Name" requirement="required">
<GoabInput
name="input"
type="text"
onChange={handleInputChange}
value={inputValue}
width="100%"
/>
</GoabFormItem>
<GoabButtonGroup alignment="start" mt="xl">
<GoabButton disabled={inputValue.trim() === ""} onClick={handleConfirm}>
Confirm
</GoabButton>
<GoabButton type="secondary" onClick={handleCancel}>
Cancel
</GoabButton>
</GoabButtonGroup>
</form>inputValue = "";
onInputChange(detail: GoabInputOnChangeDetail): void {
this.inputValue = detail.value;
}
onConfirm(): void {
// Handle form submission
console.log("Form submitted with:", this.inputValue);
}
onCancel(): void {
// Handle cancellation
this.inputValue = "";
}
get isDisabled(): boolean {
return this.inputValue.trim() === "";
}<form>
<goab-form-item label="Name" requirement="required">
<goab-input
name="input"
type="text"
(onChange)="onInputChange($event)"
[value]="inputValue"
width="100%"
>
</goab-input>
</goab-form-item>
<goab-button-group alignment="start" mt="xl">
<goab-button [disabled]="isDisabled" (onClick)="onConfirm()"> Confirm </goab-button>
<goab-button type="secondary" (onClick)="onCancel()"> Cancel </goab-button>
</goab-button-group>
</form>const nameInput = document.getElementById("name-input");
const confirmBtn = document.getElementById("confirm-btn");
const cancelBtn = document.getElementById("cancel-btn");
nameInput.addEventListener("_change", (e) => {
const value = e.detail.value.trim();
if (value === "") {
confirmBtn.setAttribute("disabled", "true");
} else {
confirmBtn.removeAttribute("disabled");
}
});
confirmBtn.addEventListener("_click", () => {
console.log("Form submitted with:", nameInput.value);
});
cancelBtn.addEventListener("_click", () => {
nameInput.value = "";
confirmBtn.setAttribute("disabled", "true");
});<form id="required-field-form">
<goa-form-item version="2" label="Name" requirement="required">
<goa-input
version="2"
id="name-input"
name="input"
type="text"
width="100%"
></goa-input>
</goa-form-item>
<goa-button-group alignment="start" mt="xl">
<goa-button version="2" id="confirm-btn" disabled="true">Confirm</goa-button>
<goa-button version="2" id="cancel-btn" type="secondary">Cancel</goa-button>
</goa-button-group>
</form>Filter data in a table
const [typedChips, setTypedChips] = useState<string[]>([]);
const [inputValue, setInputValue] = useState("");
const [inputError, setInputError] = useState("");
const errorEmpty = "Empty filter";
const errorDuplicate = "Enter a unique filter";
const data = useMemo(
() => [
{
status: { type: "information" as GoabBadgeType, text: "In progress" },
name: "Ivan Schmidt",
id: "7838576954",
},
{
status: { type: "success" as GoabBadgeType, text: "Completed" },
name: "Luz Lakin",
id: "8576953364",
},
{
status: { type: "information" as GoabBadgeType, text: "In progress" },
name: "Keith McGlynn",
id: "9846041345",
},
{
status: { type: "success" as GoabBadgeType, text: "Completed" },
name: "Melody Frami",
id: "7385256175",
},
{
status: { type: "important" as GoabBadgeType, text: "Updated" },
name: "Frederick Skiles",
id: "5807570418",
},
{
status: { type: "success" as GoabBadgeType, text: "Completed" },
name: "Dana Pfannerstill",
id: "5736306857",
},
],
[],
);
const [dataFiltered, setDataFiltered] = useState(data);
const handleInputChange = (detail: GoabInputOnChangeDetail) => {
const newValue = detail.value.trim();
setInputValue(newValue);
};
const handleInputKeyPress = (detail: GoabInputOnKeyPressDetail) => {
if (detail.key === "Enter") {
applyFilter();
}
};
const applyFilter = () => {
if (inputValue === "") {
setInputError(errorEmpty);
return;
}
if (typedChips.length > 0 && typedChips.includes(inputValue)) {
setInputError(errorDuplicate);
return;
}
setTypedChips([...typedChips, inputValue]);
setTimeout(() => {
setInputValue("");
}, 0);
setInputError("");
};
const removeTypedChip = (chip: string) => {
setTypedChips(typedChips.filter((c) => c !== chip));
setInputError("");
};
const checkNested = useCallback((obj: object, chip: string): boolean => {
return Object.values(obj).some((value) =>
typeof value === "object" && value !== null
? checkNested(value, chip)
: typeof value === "string" && value.toLowerCase().includes(chip.toLowerCase()),
);
}, []);
const getFilteredData = useCallback(
(typedChips: string[]) => {
if (typedChips.length === 0) {
return data;
}
return data.filter((item: object) =>
typedChips.every((chip) => checkNested(item, chip)),
);
},
[checkNested, data],
);
useEffect(() => {
setDataFiltered(getFilteredData(typedChips));
}, [getFilteredData, typedChips]);<GoabFormItem id="filterChipInput" error={inputError} mb="m">
<GoabBlock gap="xs" direction="row" alignment="start" width="100%">
<div style={{ flex: 1 }}>
<GoabInput
name="filterChipInput"
aria-labelledby="filterChipInput"
value={inputValue}
leadingIcon="search"
width="100%"
onChange={handleInputChange}
onKeyPress={handleInputKeyPress}
/>
</div>
<GoabButton type="secondary" onClick={applyFilter} leadingIcon="filter">
Filter
</GoabButton>
</GoabBlock>
</GoabFormItem>
{typedChips.length > 0 && (
<div>
<GoabText tag="span" color="secondary" mb="xs" mr="xs">
Filter:
</GoabText>
{typedChips.map((typedChip, index) => (
<GoabFilterChip
key={index}
content={typedChip}
mb="xs"
mr="xs"
onClick={() => removeTypedChip(typedChip)}
/>
))}
<GoabButton
type="tertiary"
size="compact"
mb="xs"
onClick={() => setTypedChips([])}
>
Clear all
</GoabButton>
</div>
)}
<GoabTable width="100%">
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th className="goa-table-number-header">ID Number</th>
</tr>
</thead>
<tbody>
{dataFiltered.map((item) => (
<tr key={item.id}>
<td>
<GoabBadge
type={item.status.type}
content={item.status.text}
icon={false}
/>
</td>
<td>{item.name}</td>
<td className="goa-table-number-column">{item.id}</td>
</tr>
))}
</tbody>
</GoabTable>
{dataFiltered.length === 0 && data.length > 0 && (
<GoabBlock mt="l" mb="l">
No results found
</GoabBlock>
)}typedChips: string[] = [];
inputValue = "";
inputError = "";
readonly errorEmpty = "Empty filter";
readonly errorDuplicate = "Enter a unique filter";
readonly data: DataItem[] = [
{
status: { type: "information", text: "In progress" },
name: "Ivan Schmidt",
id: "7838576954",
},
{
status: { type: "success", text: "Completed" },
name: "Luz Lakin",
id: "8576953364",
},
{
status: { type: "information", text: "In progress" },
name: "Keith McGlynn",
id: "9846041345",
},
{
status: { type: "success", text: "Completed" },
name: "Melody Frami",
id: "7385256175",
},
{
status: { type: "important", text: "Updated" },
name: "Frederick Skiles",
id: "5807570418",
},
{
status: { type: "success", text: "Completed" },
name: "Dana Pfannerstill",
id: "5736306857",
},
];
dataFiltered = this.getFilteredData(this.typedChips);
handleInputChange(detail: GoabInputOnChangeDetail): void {
const newValue = detail.value.trim();
this.inputValue = newValue;
}
handleInputKeyPress(detail: GoabInputOnKeyPressDetail): void {
if (detail.key === "Enter") {
this.applyFilter();
}
}
applyFilter(): void {
if (this.inputValue === "") {
this.inputError = this.errorEmpty;
return;
}
if (this.typedChips.includes(this.inputValue)) {
this.inputError = this.errorDuplicate;
return;
}
this.typedChips = [...this.typedChips, this.inputValue];
this.inputValue = "";
this.inputError = "";
this.dataFiltered = this.getFilteredData(this.typedChips);
}
removeTypedChip(chip: string): void {
this.typedChips = this.typedChips.filter((c) => c !== chip);
this.dataFiltered = this.getFilteredData(this.typedChips);
this.inputError = "";
}
removeAllTypedChips(): void {
this.typedChips = [];
this.dataFiltered = this.getFilteredData(this.typedChips);
this.inputError = "";
}
getFilteredData(typedChips: string[]): DataItem[] {
if (typedChips.length === 0) {
return this.data;
}
return this.data.filter((item) =>
typedChips.every((chip) => this.checkNested(item, chip)),
);
}
checkNested(obj: object, chip: string): boolean {
return Object.values(obj).some((value) =>
typeof value === "object" && value !== null
? this.checkNested(value, chip)
: typeof value === "string" && value.toLowerCase().includes(chip.toLowerCase()),
);
}<goab-form-item id="filterChipInput" [error]="inputError" mb="m">
<goab-block gap="xs" direction="row" alignment="start" width="100%">
<div style="flex: 1">
<goab-input
name="filterChipInput"
aria-labelledby="filterChipInput"
[value]="inputValue"
leadingIcon="search"
width="100%"
(onChange)="handleInputChange($event)"
(onKeyPress)="handleInputKeyPress($event)"
>
</goab-input>
</div>
<goab-button type="secondary" (onClick)="applyFilter()" leadingIcon="filter">
Filter
</goab-button>
</goab-block>
</goab-form-item>
@if (typedChips.length > 0) {
<ng-container>
<goab-text tag="span" color="secondary" mb="xs" mr="xs"> Filter: </goab-text>
@for (typedChip of typedChips; track typedChip; let index = $index) {
<goab-filter-chip
[content]="typedChip"
mb="xs"
mr="xs"
(onClick)="removeTypedChip(typedChip)"
>
</goab-filter-chip>
}
<goab-button type="tertiary" size="compact" mb="xs" (onClick)="removeAllTypedChips()">
Clear all
</goab-button>
</ng-container>
}
<goab-table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th class="goa-table-number-header">ID Number</th>
</tr>
</thead>
<tbody>
@for (item of dataFiltered; track $index) {
<tr>
<td>
<goab-badge
[type]="item.status.type"
[content]="item.status.text"
[icon]="false"
></goab-badge>
</td>
<td>{{ item.name }}</td>
<td class="goa-table-number-column">{{ item.id }}</td>
</tr>
}
</tbody>
</goab-table>
@if (dataFiltered.length === 0 && data.length > 0) {
<goab-block mt="l" mb="l"> No results found </goab-block>
}const filterInput = document.getElementById("filter-input");
const filterBtn = document.getElementById("filter-btn");
const filterFormItem = document.getElementById("filter-form-item");
const chipsContainer = document.getElementById("chips-container");
const chipsList = document.getElementById("chips-list");
const clearAllBtn = document.getElementById("clear-all-btn");
const tableRows = document.querySelectorAll("tbody tr");
let typedChips = [];
function filterTable() {
tableRows.forEach((row) => {
const badge = row.querySelector("goa-badge");
const badgeText = badge ? badge.getAttribute("content") || "" : "";
const text = (row.textContent + " " + badgeText).toLowerCase();
const matches =
typedChips.length === 0 ||
typedChips.every((chip) => text.includes(chip.toLowerCase()));
row.style.display = matches ? "" : "none";
});
}
function renderChips() {
chipsList.innerHTML = "";
typedChips.forEach((chip) => {
const filterChip = document.createElement("goa-filter-chip");
filterChip.setAttribute("version", "2");
filterChip.setAttribute("content", chip);
filterChip.setAttribute("mb", "xs");
filterChip.setAttribute("mr", "xs");
filterChip.addEventListener("_click", () => removeChip(chip));
chipsList.appendChild(filterChip);
});
chipsContainer.style.display = typedChips.length > 0 ? "block" : "none";
filterTable();
}
function applyFilter() {
const value = filterInput.value.trim();
if (value === "") {
filterFormItem.setAttribute("error", "Empty filter");
return;
}
if (typedChips.includes(value)) {
filterFormItem.setAttribute("error", "Enter a unique filter");
return;
}
typedChips.push(value);
filterInput.value = "";
filterFormItem.removeAttribute("error");
renderChips();
}
function removeChip(chip) {
typedChips = typedChips.filter((c) => c !== chip);
renderChips();
}
filterBtn.addEventListener("_click", applyFilter);
clearAllBtn.addEventListener("_click", () => {
typedChips = [];
renderChips();
});<goa-form-item version="2" id="filter-form-item" mb="m">
<goa-block gap="xs" direction="row" alignment="center" width="100%">
<div style="flex: 1">
<goa-input
version="2"
id="filter-input"
name="filterChipInput"
leadingicon="search"
width="100%"
>
</goa-input>
</div>
<goa-button version="2" id="filter-btn" type="secondary" leadingicon="filter">
Filter
</goa-button>
</goa-block>
</goa-form-item>
<div id="chips-container" style="display: none">
<goa-text as="span" color="secondary" mb="xs" mr="xs">Filter:</goa-text>
<span id="chips-list"></span>
<goa-button version="2" id="clear-all-btn" type="tertiary" size="compact" mb="xs">
Clear all
</goa-button>
</div>
<goa-table version="2" width="100%" mt="s">
<table style="width: 100%">
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th class="goa-table-number-header">ID Number</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<goa-badge
version="2"
type="information"
content="In progress"
icon="false"
></goa-badge>
</td>
<td>Ivan Schmidt</td>
<td class="goa-table-number-column">7838576954</td>
</tr>
<tr>
<td>
<goa-badge
version="2"
type="success"
content="Completed"
icon="false"
></goa-badge>
</td>
<td>Luz Lakin</td>
<td class="goa-table-number-column">8576953364</td>
</tr>
<tr>
<td>
<goa-badge
version="2"
type="information"
content="In progress"
icon="false"
></goa-badge>
</td>
<td>Keith McGlynn</td>
<td class="goa-table-number-column">9846041345</td>
</tr>
<tr>
<td>
<goa-badge
version="2"
type="success"
content="Completed"
icon="false"
></goa-badge>
</td>
<td>Melody Frami</td>
<td class="goa-table-number-column">7385256175</td>
</tr>
<tr>
<td>
<goa-badge
version="2"
type="important"
content="Updated"
icon="false"
></goa-badge>
</td>
<td>Frederick Skiles</td>
<td class="goa-table-number-column">5807570418</td>
</tr>
<tr>
<td>
<goa-badge
version="2"
type="success"
content="Completed"
icon="false"
></goa-badge>
</td>
<td>Dana Pfannerstill</td>
<td class="goa-table-number-column">5736306857</td>
</tr>
</tbody>
</table>
</goa-table>Group related questions together on a question page
const [addressLine1, setAddressLine1] = useState("");
const [addressLine2, setAddressLine2] = useState("");
const [townCity, setTownCity] = useState("");
const [province, setProvince] = useState("");
const [postalCode, setPostalCode] = useState("");<GoabLink leadingIcon="arrow-back" size="small" mb="none">
Back
</GoabLink>
<GoabText tag="h2" mt="xl" mb="m">
Your address
</GoabText>
<GoabText mt="none" mb="xl">
This is the home address of the person applying
</GoabText>
<GoabFormItem label="Address line 1">
<GoabInput
onChange={(event) => setAddressLine1(event.value)}
value={addressLine1}
name="address-line-1"
ariaLabel="Address line 1"
width="100%"
/>
</GoabFormItem>
<GoabFormItem label="Address line 2" mt="l">
<GoabInput
onChange={(event) => setAddressLine2(event.value)}
value={addressLine2}
name="address-line-2"
ariaLabel="Address line 2"
width="100%"
/>
</GoabFormItem>
<GoabFormItem label="Town or city" mt="l">
<GoabInput
onChange={(event) => setTownCity(event.value)}
value={townCity}
name="town-city"
ariaLabel="Town or city name"
width="460px"
/>
</GoabFormItem>
<GoabFormItem label="Province or territory" mt="l" id="provinceLabel">
<GoabDropdown
onChange={(event) => setProvince(event.value ?? "")}
value={province}
name="province-territory"
ariaLabelledBy="provinceLabel"
>
<GoabDropdownItem value="AB" label="Alberta" />
<GoabDropdownItem value="BC" label="British Columbia" />
<GoabDropdownItem value="MB" label="Manitoba" />
<GoabDropdownItem value="NB" label="New Brunswick" />
<GoabDropdownItem value="NL" label="Newfoundland and Labrador" />
<GoabDropdownItem value="NS" label="Nova Scotia" />
<GoabDropdownItem value="ON" label="Ontario" />
<GoabDropdownItem value="PE" label="Prince Edward Island" />
<GoabDropdownItem value="QC" label="Quebec" />
<GoabDropdownItem value="SK" label="Saskatchewan" />
<GoabDropdownItem value="NT" label="Northwest Territories" />
<GoabDropdownItem value="NU" label="Nunavut" />
<GoabDropdownItem value="YT" label="Yukon" />
</GoabDropdown>
</GoabFormItem>
<GoabFormItem label="Postal code" mt="l">
<GoabInput
onChange={(event) => setPostalCode(event.value)}
value={postalCode}
name="postal-code"
width="105px"
/>
</GoabFormItem>
<GoabButton type="submit" mt="2xl">
Save and continue
</GoabButton>addressLine1 = "";
addressLine2 = "";
townCity = "";
province = "";
postalCode = "";
onAddressLine1Change(value: string): void {
this.addressLine1 = value;
}
onAddressLine2Change(value: string): void {
this.addressLine2 = value;
}
onTownCityChange(value: string): void {
this.townCity = value;
}
onProvinceChange(value: string): void {
this.province = value;
}
onPostalCodeChange(value: string): void {
this.postalCode = value;
}
onSubmit(): void {
console.log("Form submitted");
}<goab-link leadingIcon="arrow-back" size="small" mb="none"> Back </goab-link>
<goab-text tag="h2" mt="xl" mb="m">Your address</goab-text>
<goab-text mt="none" mb="xl">This is the home address of the person applying</goab-text>
<goab-form-item label="Address line 1">
<goab-input
(onChange)="onAddressLine1Change($event)"
[value]="addressLine1"
name="address-line-1"
ariaLabel="Address line 1"
width="100%"
>
</goab-input>
</goab-form-item>
<goab-form-item label="Address line 2" mt="l">
<goab-input
(onChange)="onAddressLine2Change($event)"
[value]="addressLine2"
name="address-line-2"
ariaLabel="Address line 2"
width="100%"
>
</goab-input>
</goab-form-item>
<goab-form-item label="Town or city" mt="l">
<goab-input
(onChange)="onTownCityChange($event)"
[value]="townCity"
name="town-city"
ariaLabel="Town or city name"
width="460px"
>
</goab-input>
</goab-form-item>
<goab-form-item label="Province or territory" mt="l" id="provinceLabel">
<goab-dropdown
(onChange)="onProvinceChange($event)"
[value]="province"
name="province-territory"
ariaLabelledBy="provinceLabel"
>
<goab-dropdown-item value="AB" label="Alberta"></goab-dropdown-item>
<goab-dropdown-item value="BC" label="British Columbia"></goab-dropdown-item>
<goab-dropdown-item value="MB" label="Manitoba"></goab-dropdown-item>
<goab-dropdown-item value="NB" label="New Brunswick"></goab-dropdown-item>
<goab-dropdown-item value="NL" label="Newfoundland and Labrador"></goab-dropdown-item>
<goab-dropdown-item value="NS" label="Nova Scotia"></goab-dropdown-item>
<goab-dropdown-item value="ON" label="Ontario"></goab-dropdown-item>
<goab-dropdown-item value="PE" label="Prince Edward Island"></goab-dropdown-item>
<goab-dropdown-item value="QC" label="Quebec"></goab-dropdown-item>
<goab-dropdown-item value="SK" label="Saskatchewan"></goab-dropdown-item>
<goab-dropdown-item value="NT" label="Northwest Territories"></goab-dropdown-item>
<goab-dropdown-item value="NU" label="Nunavut"></goab-dropdown-item>
<goab-dropdown-item value="YT" label="Yukon"></goab-dropdown-item>
</goab-dropdown>
</goab-form-item>
<goab-form-item label="Postal code" mt="l">
<goab-input
(onChange)="onPostalCodeChange($event)"
[value]="postalCode"
name="postal-code"
width="105px"
>
</goab-input>
</goab-form-item>
<goab-button type="submit" mt="2xl" (onClick)="onSubmit()">
Save and continue
</goab-button>document.getElementById("address-line-1").addEventListener("_change", (e) => {
console.log("Address line 1:", e.detail.value);
});
document.getElementById("province-territory").addEventListener("_change", (e) => {
console.log("Province:", e.detail.value);
});
document.getElementById("submit-btn").addEventListener("_click", () => {
console.log("Form submitted");
});<goa-link leadingicon="arrow-back" size="small" mb="none"> Back </goa-link>
<goa-text as="h2" mt="xl" mb="m">Your address</goa-text>
<goa-text mt="none" mb="xl">This is the home address of the person applying</goa-text>
<goa-form-item version="2" label="Address line 1">
<goa-input
version="2"
id="address-line-1"
name="address-line-1"
aria-label="Address line 1"
width="100%"
>
</goa-input>
</goa-form-item>
<goa-form-item version="2" label="Address line 2" mt="l">
<goa-input
version="2"
id="address-line-2"
name="address-line-2"
aria-label="Address line 2"
width="100%"
>
</goa-input>
</goa-form-item>
<goa-form-item version="2" label="Town or city" mt="l">
<goa-input
version="2"
id="town-city"
name="town-city"
aria-label="Town or city name"
width="460px"
>
</goa-input>
</goa-form-item>
<goa-form-item version="2" label="Province or territory" mt="l" id="provinceLabel">
<goa-dropdown
version="2"
id="province-territory"
name="province-territory"
aria-labelledby="provinceLabel"
>
<goa-dropdown-item value="AB" label="Alberta"></goa-dropdown-item>
<goa-dropdown-item value="BC" label="British Columbia"></goa-dropdown-item>
<goa-dropdown-item value="MB" label="Manitoba"></goa-dropdown-item>
<goa-dropdown-item value="NB" label="New Brunswick"></goa-dropdown-item>
<goa-dropdown-item value="NL" label="Newfoundland and Labrador"></goa-dropdown-item>
<goa-dropdown-item value="NS" label="Nova Scotia"></goa-dropdown-item>
<goa-dropdown-item value="ON" label="Ontario"></goa-dropdown-item>
<goa-dropdown-item value="PE" label="Prince Edward Island"></goa-dropdown-item>
<goa-dropdown-item value="QC" label="Quebec"></goa-dropdown-item>
<goa-dropdown-item value="SK" label="Saskatchewan"></goa-dropdown-item>
<goa-dropdown-item value="NT" label="Northwest Territories"></goa-dropdown-item>
<goa-dropdown-item value="NU" label="Nunavut"></goa-dropdown-item>
<goa-dropdown-item value="YT" label="Yukon"></goa-dropdown-item>
</goa-dropdown>
</goa-form-item>
<goa-form-item version="2" label="Postal code" mt="l">
<goa-input version="2" id="postal-code" name="postal-code" width="105px"> </goa-input>
</goa-form-item>
<goa-button version="2" type="submit" mt="2xl" id="submit-btn">
Save and continue
</goa-button>Question page
const [answer, setAnswer] = useState("");
const handleContinue = () => {
console.log("Answer submitted:", answer);
}; <GoabLink leadingIcon="arrow-back" size="small" mb="none">
Back
</GoabLink>
<GoabText tag="h1" mt="xl" mb="m">
What is your email address?
</GoabText>
<GoabText mt="none" mb="xl">
We'll use this to send you confirmation of your application.
</GoabText>
<GoabFormItem label="Email address">
<GoabInput
name="email"
type="email"
value={answer}
onChange={(e) => setAnswer(e.value)}
width="100%"
/>
</GoabFormItem>
<GoabButtonGroup alignment="start" mt="2xl">
<GoabButton type="primary" onClick={handleContinue}>
Continue
</GoabButton>
</GoabButtonGroup>
);
}answer = "";
onAnswerChange(event: { value: string }): void {
this.answer = event.value;
}
handleContinue(): void {
console.log("Answer submitted:", this.answer);
}<goab-link leadingIcon="arrow-back" size="small" mb="none"> Back </goab-link>
<goab-text tag="h1" mt="xl" mb="m">What is your email address?</goab-text>
<goab-text mt="none" mb="xl"
>We'll use this to send you confirmation of your application.</goab-text
>
<goab-form-item label="Email address">
<goab-input
name="email"
type="email"
[value]="answer"
(onChange)="onAnswerChange($event)"
width="100%"
>
</goab-input>
</goab-form-item>
<goab-button-group alignment="start" mt="2xl">
<goab-button type="primary" (onClick)="handleContinue()"> Continue </goab-button>
</goab-button-group>const emailInput = document.getElementById("email-input");
const continueBtn = document.getElementById("continue-btn");
let answer = "";
emailInput.addEventListener("_change", (e) => {
answer = e.detail.value;
});
continueBtn.addEventListener("_click", () => {
console.log("Answer submitted:", answer);
});<goa-link leadingicon="arrow-back" size="small" mb="none"> Back </goa-link>
<goa-text as="h1" mt="xl" mb="m">What is your email address?</goa-text>
<goa-text mt="none" mb="xl"
>We'll use this to send you confirmation of your application.</goa-text
>
<goa-form-item version="2" label="Email address">
<goa-input version="2" id="email-input" name="email" type="email" width="100%">
</goa-input>
</goa-form-item>
<goa-button-group alignment="start" mt="2xl">
<goa-button version="2" id="continue-btn" type="primary"> Continue </goa-button>
</goa-button-group>Reveal input based on a selection
const [contactMethod, setContactMethod] = useState("");
const [checkboxSelection, setCheckboxSelection] = useState<string[]>([]);<GoabFormItem
label="How would you like to be contacted?"
helpText="Select one option"
>
<GoabRadioGroup
name="contactMethod"
value={contactMethod}
onChange={(e) => setContactMethod(e.value)}
>
<GoabRadioItem
value="email"
label="Email"
reveal={
<GoabFormItem label="Email address">
<GoabInput name="email" onChange={() => {}} value="" />
</GoabFormItem>
}
/>
<GoabRadioItem
value="phone"
label="Phone"
reveal={
<GoabFormItem label="Phone number">
<GoabInput name="phoneNumber" onChange={() => {}} value="" />
</GoabFormItem>
}
/>
<GoabRadioItem
value="text"
label="Text message"
reveal={
<GoabFormItem label="Mobile phone number">
<GoabInput name="mobilePhoneNumber" onChange={() => {}} value="" />
</GoabFormItem>
}
/>
</GoabRadioGroup>
</GoabFormItem>
<GoabFormItem label="How would you like to be contacted?" mt="xl">
<GoabCheckboxList
name="contactMethods"
value={checkboxSelection}
onChange={(e) => setCheckboxSelection(e.value || [])}
>
<GoabCheckbox
name="email"
text="Email"
value="email"
reveal={
<GoabFormItem label="Email address">
<GoabInput name="email" onChange={() => {}} value="" />
</GoabFormItem>
}
/>
<GoabCheckbox
name="phone"
text="Phone"
value="phone"
reveal={
<GoabFormItem label="Phone number">
<GoabInput name="phoneNumber" onChange={() => {}} value="" />
</GoabFormItem>
}
/>
<GoabCheckbox
name="text"
text="Text message"
value="text"
reveal={
<GoabFormItem label="Mobile phone number">
<GoabInput name="mobilePhoneNumber" onChange={() => {}} value="" />
</GoabFormItem>
}
/>
</GoabCheckboxList>
</GoabFormItem>form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
contactMethod: [""],
phoneNumber: [""],
emailAddress: [""],
emailContactMethod: [false],
phoneContactMethod: [false],
textContactMethod: [false],
});
}<goab-form-item
[formGroup]="form"
label="How would you like to be contacted?"
helpText="Select one option"
>
<goab-radio-group name="contactMethod" formControlName="contactMethod">
<goab-radio-item label="Email" value="email" [reveal]="emailReveal">
<ng-template #emailReveal>
<goab-form-item label="Email address">
<goab-input name="email" formControlName="emailAddress"></goab-input>
</goab-form-item>
</ng-template>
</goab-radio-item>
<goab-radio-item value="phone" label="Phone" [reveal]="phoneReveal">
<ng-template #phoneReveal>
<goab-form-item label="Phone number">
<goab-input name="phone" formControlName="phoneNumber"></goab-input>
</goab-form-item>
</ng-template>
</goab-radio-item>
<goab-radio-item value="text" label="Text message" [reveal]="textReveal">
<ng-template #textReveal>
<goab-form-item label="Mobile phone number">
<goab-input name="mobile" formControlName="phoneNumber"></goab-input>
</goab-form-item>
</ng-template>
</goab-radio-item>
</goab-radio-group>
</goab-form-item>
<goab-form-item [formGroup]="form" label="How would you like to be contacted?" mt="xl">
<goab-checkbox-list name="contactMethods" formControlName="contactMethods">
<goab-checkbox name="email" text="Email" value="email" [reveal]="checkEmailReveal">
<ng-template #checkEmailReveal>
<goab-form-item label="Email address">
<goab-input name="email" formControlName="emailAddress"></goab-input>
</goab-form-item>
</ng-template>
</goab-checkbox>
<goab-checkbox name="phone" text="Phone" value="phone" [reveal]="checkPhoneReveal">
<ng-template #checkPhoneReveal>
<goab-form-item label="Phone number">
<goab-input name="phone" formControlName="phoneNumber"></goab-input>
</goab-form-item>
</ng-template>
</goab-checkbox>
<goab-checkbox
name="text"
text="Text message"
value="text"
[reveal]="checkTextReveal"
>
<ng-template #checkTextReveal>
<goab-form-item label="Mobile phone number">
<goab-input name="mobile" formControlName="phoneNumber"></goab-input>
</goab-form-item>
</ng-template>
</goab-checkbox>
</goab-checkbox-list>
</goab-form-item><goa-form-item
version="2"
label="How would you like to be contacted?"
helptext="Select one option"
>
<goa-radio-group version="2" name="contactMethod" id="radio-contact">
<goa-radio-item value="email" label="Email">
<div slot="reveal">
<goa-form-item version="2" label="Email address">
<goa-input version="2" name="email"></goa-input>
</goa-form-item>
</div>
</goa-radio-item>
<goa-radio-item value="phone" label="Phone">
<div slot="reveal">
<goa-form-item version="2" label="Phone number">
<goa-input version="2" name="phone"></goa-input>
</goa-form-item>
</div>
</goa-radio-item>
<goa-radio-item value="text" label="Text message">
<div slot="reveal">
<goa-form-item version="2" label="Mobile phone number">
<goa-input version="2" name="mobile"></goa-input>
</goa-form-item>
</div>
</goa-radio-item>
</goa-radio-group>
</goa-form-item>
<goa-form-item version="2" label="How would you like to be contacted?" mt="xl">
<goa-checkbox-list name="contactMethods">
<goa-checkbox version="2" name="emailContact" text="Email">
<div slot="reveal">
<goa-form-item version="2" label="Email address">
<goa-input version="2" name="emailInput"></goa-input>
</goa-form-item>
</div>
</goa-checkbox>
<goa-checkbox version="2" name="phoneContact" text="Phone">
<div slot="reveal">
<goa-form-item version="2" label="Phone number">
<goa-input version="2" name="phoneInput"></goa-input>
</goa-form-item>
</div>
</goa-checkbox>
<goa-checkbox version="2" name="textContact" text="Text message">
<div slot="reveal">
<goa-form-item version="2" label="Mobile phone number">
<goa-input version="2" name="mobileInput"></goa-input>
</goa-form-item>
</div>
</goa-checkbox>
</goa-checkbox-list>
</goa-form-item>const [search, setSearch] = useState("");
const onClick = () => {
console.log("search:", search);
};<form>
<GoabFormItem>
<GoabBlock gap="xs" direction="row">
<GoabInput
type="search"
name="search"
value={search}
onChange={(e) => setSearch(e.value)}
leadingIcon="search"
/>
<GoabButton type="primary" onClick={onClick}>
Search
</GoabButton>
</GoabBlock>
</GoabFormItem>
</form>form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
search: [""],
});
}
onClick(): void {
console.log("search:", this.form.controls["search"].value);
}<form [formGroup]="form">
<goab-form-item>
<goab-block gap="xs" direction="row">
<goab-input
type="search"
name="search"
formControlName="search"
leadingIcon="search"
>
</goab-input>
<goab-button type="primary" (onClick)="onClick()">Search</goab-button>
</goab-block>
</goab-form-item>
</form>const searchInput = document.getElementById("search-input");
const searchBtn = document.getElementById("search-btn");
let searchValue = "";
searchInput.addEventListener("_change", (e) => {
searchValue = e.detail.value;
});
searchBtn.addEventListener("_click", () => {
console.log("search:", searchValue);
});<form>
<goa-form-item version="2">
<goa-block gap="xs" direction="row">
<goa-input
version="2"
id="search-input"
type="search"
name="search"
leadingicon="search"
>
</goa-input>
<goa-button version="2" id="search-btn" type="primary">Search</goa-button>
</goa-block>
</goa-form-item>
</form>Show a simple progress indicator on a question page with multiple questions
<GoabLink leadingIcon="arrow-back" size="small" mb="none">
Back
</GoabLink>
<GoabText tag="h3" size="body-m" mt="xl" mb="none" color="secondary">
Step 1 of 5
</GoabText>
<GoabText tag="h2" mt="xs" mb="xl">
Personal information
</GoabText>
<GoabFormItem label="What is your name?">
<GoabInput
onChange={() => {}}
name="name"
ariaLabel="what is your name?"
width="50ch"
/>
</GoabFormItem>
<GoabFormItem label="What is your phone number?" mt="l">
<GoabInput
onChange={() => {}}
name="phone-number"
ariaLabel="what is your phone number?"
leadingContent="+1"
/>
</GoabFormItem>
<GoabFormItem label="What is your home postal code?" mt="l">
<GoabInput
onChange={() => {}}
name="postal-code"
width="14ch"
ariaLabel="what is your home postal code"
/>
</GoabFormItem>
<GoabButton type="submit" mt="2xl">
Save and continue
</GoabButton>onChange(event: GoabInputOnChangeDetail): void {
console.log("Value:", event.value);
}<goab-link leadingIcon="arrow-back" size="small" mb="none"> Back </goab-link>
<goab-text tag="h3" size="body-m" mt="xl" mb="none" color="secondary"
>Step 1 of 5</goab-text
>
<goab-text tag="h2" mt="xs" mb="xl">Personal information</goab-text>
<goab-form-item label="What is your name?">
<goab-input
(onChange)="onChange($event)"
name="name"
ariaLabel="what is your name?"
width="50ch"
></goab-input>
</goab-form-item>
<goab-form-item label="What is your phone number?" mt="l">
<goab-input
(onChange)="onChange($event)"
name="phone-number"
ariaLabel="what is your phone number?"
leadingContent="+1"
></goab-input>
</goab-form-item>
<goab-form-item label="What is your home postal code?" mt="l">
<goab-input
(onChange)="onChange($event)"
name="postal-code"
width="14ch"
ariaLabel="what is your home postal code"
></goab-input>
</goab-form-item>
<goab-button type="submit" mt="2xl"> Save and continue </goab-button>document.querySelectorAll("goa-input").forEach((input) => {
input.addEventListener("_change", (e) => {
console.log(`${e.target.name}:`, e.detail.value);
});
});<goa-link leadingicon="arrow-back" size="small" mb="none"> Back </goa-link>
<goa-text as="h3" size="body-m" mt="xl" mb="none" color="secondary">Step 1 of 5</goa-text>
<goa-text as="h2" mt="xs" mb="xl">Personal information</goa-text>
<goa-form-item version="2" label="What is your name?">
<goa-input
version="2"
name="name"
aria-label="what is your name?"
width="50ch"
></goa-input>
</goa-form-item>
<goa-form-item version="2" label="What is your phone number?" mt="l">
<goa-input version="2" name="phone-number" aria-label="what is your phone number?">
<div slot="leadingContent">+1</div>
</goa-input>
</goa-form-item>
<goa-form-item version="2" label="What is your home postal code?" mt="l">
<goa-input
version="2"
name="postal-code"
width="14ch"
aria-label="what is your home postal code"
></goa-input>
</goa-form-item>
<goa-button version="2" type="submit" mt="2xl"> Save and continue </goa-button>Slotted error text in a form item
const [value, setValue] = useState("");
const onChange = (detail: GoabInputOnChangeDetail) => {
setValue(detail.value);
};
const errorMessage = (
<>
<i>This is </i> slotted <b>error text</b>.
</>
);<GoabFormItem label="First name" error={errorMessage}>
<GoabInput onChange={onChange} value={value} name="item" error={true} />
</GoabFormItem>form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
item: [""],
});
}<goab-form-item label="First name" [formGroup]="form" [error]="errorTemplate">
<goab-input name="item" formControlName="item" [error]="true"></goab-input>
<ng-template #errorTemplate>
<span>This is </span>
<i>slotted </i>
<b>error text.</b>
</ng-template>
</goab-form-item>const input = document.querySelector('goa-input[name="item"]');
input.addEventListener("_change", (e) => {
console.log("Value changed:", e.detail.value);
});<goa-form-item version="2" label="First name">
<goa-input version="2" name="item" error="true"></goa-input>
<div slot="error">
<span>This is </span>
<i>slotted </i>
<b>error text.</b>
</div>
</goa-form-item>Slotted helper text in a form item
const [value, setValue] = useState("");
const onChange = (detail: GoabInputOnChangeDetail) => {
setValue(detail.value);
};
const helpText = (
<>
<i>This is </i> slotted <b>help text</b>.
</>
);<GoabFormItem label="First name" helpText={helpText}>
<GoabInput onChange={onChange} value={value} name="item" />
</GoabFormItem>form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
item: [""],
});
}<goab-form-item label="First name" [formGroup]="form" [helpText]="helpTextTemplate">
<goab-input name="item" formControlName="item"></goab-input>
<ng-template #helpTextTemplate>
<span>This is </span>
<i>slotted </i>
<b>help text</b>.
</ng-template>
</goab-form-item>const input = document.querySelector('goa-input[name="item"]');
input.addEventListener("_change", (e) => {
console.log("Value changed:", e.detail.value);
});<goa-form-item version="2" label="First name">
<goa-input version="2" name="item"></goa-input>
<div slot="helptext">
<span>This is </span>
<i>slotted </i>
<b>help text</b>.
</div>
</goa-form-item>const [typedChips, setTypedChips] = useState<string[]>([]);
const [inputValue, setInputValue] = useState("");
const addChip = () => {
if (inputValue.trim()) {
setTypedChips([...typedChips, inputValue.trim()]);
setInputValue("");
}
};<GoabFormItem label="Type to create a chip" mb="m">
<GoabBlock gap="xs" direction="row">
<div style={{ flex: 1 }}>
<GoabInput
name="chipInput"
value={inputValue}
onChange={(e) => setInputValue(e.value)}
onKeyPress={(e) => {
if (e.key === "Enter" && e.value.trim()) {
setTypedChips([...typedChips, e.value.trim()]);
setTimeout(() => setInputValue(""), 0);
} else if (
e.key === "Backspace" &&
!e.value.trim() &&
typedChips.length > 0
) {
setTypedChips(typedChips.slice(0, -1));
}
}}
width="100%"
/>
</div>
<GoabButton type="secondary" onClick={addChip}>
Add
</GoabButton>
</GoabBlock>
</GoabFormItem>
<div>
{typedChips.map((chip, index) => (
<GoabFilterChip
key={index}
content={chip}
mb="xs"
mr="xs"
onClick={() => setTypedChips(typedChips.filter((c) => c !== chip))}
/>
))}
</div>typedChips: string[] = [];
inputValue = "";
handleInputChange(detail: GoabInputOnChangeDetail): void {
const newValue = detail.value.trim();
this.inputValue = newValue;
}
handleInputKeyPress(detail: GoabInputOnKeyPressDetail): void {
const newValue = detail.value.trim();
if (detail.key === "Enter" && newValue !== "") {
this.addChip();
} else if (
!this.inputValue &&
this.typedChips.length > 0 &&
detail.key === "Backspace"
) {
this.typedChips.pop();
}
}
addChip(): void {
if (this.inputValue.trim()) {
this.typedChips.push(this.inputValue.trim());
this.inputValue = "";
}
}
removeTypedChip(chip: string): void {
this.typedChips = this.typedChips.filter((c) => c !== chip);
}<goab-form-item label="Type to create a chip" mb="m">
<goab-block gap="xs" direction="row">
<div style="flex: 1">
<goab-input
[value]="inputValue"
(onChange)="handleInputChange($event)"
(onKeyPress)="handleInputKeyPress($event)"
width="100%"
>
</goab-input>
</div>
<goab-button type="secondary" (onClick)="addChip()">Add</goab-button>
</goab-block>
</goab-form-item>
@if (typedChips.length > 0) {
<div>
@for (typedChip of typedChips; track typedChip) {
<goab-filter-chip
[content]="typedChip"
mb="xs"
mr="xs"
(onClick)="removeTypedChip(typedChip)"
>
</goab-filter-chip>
}
</div>
}const typedChips = [];
const input = document.getElementById("chip-input");
const addBtn = document.getElementById("add-btn");
const container = document.getElementById("chips-container");
let currentValue = "";
function renderChips() {
container.innerHTML = "";
typedChips.forEach((chip) => {
const chipEl = document.createElement("goa-filter-chip");
chipEl.setAttribute("version", "2");
chipEl.setAttribute("content", chip);
chipEl.setAttribute("mb", "xs");
chipEl.setAttribute("mr", "xs");
chipEl.addEventListener("_click", () => removeChip(chip));
container.appendChild(chipEl);
});
}
function addChip() {
if (currentValue.trim()) {
typedChips.push(currentValue.trim());
currentValue = "";
input.setAttribute("value", "");
renderChips();
}
}
function removeChip(chip) {
const index = typedChips.indexOf(chip);
if (index > -1) {
typedChips.splice(index, 1);
renderChips();
}
}
input.addEventListener("_change", (e) => {
currentValue = e.detail.value || "";
});
addBtn.addEventListener("_click", () => {
addChip();
});<goa-form-item version="2" label="Type to create a chip" mb="m">
<goa-block gap="xs" direction="row">
<div style="flex: 1">
<goa-input version="2" id="chip-input" width="100%"></goa-input>
</div>
<goa-button version="2" id="add-btn" type="secondary">Add</goa-button>
</goa-block>
</goa-form-item>
<div id="chips-container"></div>States
When you must disable a button or input:
- Provide nearby text explaining what needs to happen first
- Consider showing the element enabled with validation on submit instead
- Use aria-describedby to link the disabled element to explanatory text
Other
The form item automatically associates the label with the input for screen readers, ensuring your form is accessible.
Types
Content
Placeholder text disappears when users start typing, leaving them without context for what the field is asking for.
Always use a visible label above or beside the input field. Placeholder text can provide an example of the expected format, but should never be the only indication of what information is needed.
Sizing
Known input length: Use fixed-width inputs for content with a specific length, such as postal code (7 characters) or year (4 characters).
Unknown input length: If you don’t know how many characters the user will need (like their name), make your text input 100% of the container.
Forms
Capture text input from users in forms.
When to use
Use Input when you need users to enter:
- Short text answers (names, email addresses)
- Numbers (phone numbers, quantities)
- Dates and times
- Search queries
When not to use
Don’t use Input when:
- Users need to enter multiple lines of text (use Textarea)
- Users need to select from predefined options (use Dropdown or Radio)
- The input requires complex formatting (consider specialized components)
Types
Input supports multiple HTML input types:
- text - General text entry (default)
- email - Email addresses with validation
- password - Masked password entry
- number - Numeric values with stepper
- date - Date picker
- tel - Phone numbers
- search - Search with clear button
States
- Default - Normal interactive state
- Focused - When the input has keyboard focus
- Error - When validation fails
- Disabled - When input is not available
- Read-only - When showing value without editing