Block
Group components into a block with consistent space between.
Props
gap
Spacing
Spacing between items. Uses design system spacing tokens.
Defaults to
m.
direction
row | column
Stacking direction of child components.
Defaults to
row.
alignment
center | start | end | normal
Primary axis alignment of child components.
Defaults to
normal.
testId
string
Sets a data-testid attribute for automated testing.
minWidth
string
Sets the minimum width of the block container.
maxWidth
string
Sets the maximum width of the block container.
width
string
Sets the width of the block container. Defaults to max-content.
mt, mr, mb, ml
none | 3xs | 2xs | xs | s | m | l | xl | 2xl | 3xl | 4xl
Apply margin to the top, right, bottom, and/or left of the component.
Restricted access (401)
.error-page-content {
text-align: center;
}
.error-page-icon {
display: flex;
align-items: center;
justify-content: center;
width: 7.5rem;
height: 7.5rem;
border-radius: 50%;
background-color: var(--goa-color-greyscale-100);
}
/* Icon scaled beyond xlarge (2.5rem cap) to match the page-scale visual weight. */
/* Tracked in icon-sizes-above-xlarge gap ticket. */
.error-page-icon goa-icon,
.error-page-icon goab-icon {
transform: scale(1.35);
}
.error-page-underline {
width: 6.875rem;
height: var(--goa-space-xs);
background-color: var(--goa-color-info-default);
}<GoabPageBlock>
<div className="error-page-content">
<GoabBlock
direction="column"
alignment="center"
gap="xl"
width="100%"
mt="3xl"
mb="3xl"
>
<GoabBlock direction="column" alignment="center" gap="m" width="100%">
<div className="error-page-icon">
<GoabIcon role="presentation" type="warning" size="xlarge" />
</div>
<GoabText size="body-m" color="secondary" mt="none" mb="none">
Error 401
</GoabText>
<div className="error-page-underline" aria-hidden="true" />
</GoabBlock>
<GoabBlock direction="column" alignment="center" gap="l" width="100%">
<GoabText tag="h1" size="heading-l" mt="none" mb="none">
Restricted access
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
We cannot provide access to this page without valid credentials. Please sign in or
contact support at{" "}
<GoabLink>
<a href="mailto:cs.licensingsupport@gov.ab.ca">cs.licensingsupport@gov.ab.ca</a>
</GoabLink>{" "}
to request access.
</GoabText>
</GoabBlock>
<GoabButton type="primary" size="compact" onClick={() => (window.location.href = "/")}>
Go to home page
</GoabButton>
</GoabBlock>
</div>
</GoabPageBlock>goHome() {
window.location.href = "/";
}<goab-page-block>
<div class="error-page-content">
<goab-block direction="column" alignment="center" gap="xl" width="100%" mt="3xl" mb="3xl">
<goab-block direction="column" alignment="center" gap="m" width="100%">
<div class="error-page-icon">
<goab-icon role="presentation" type="warning" size="xlarge"></goab-icon>
</div>
<goab-text size="body-m" color="secondary" mt="none" mb="none">Error 401</goab-text>
<div class="error-page-underline" aria-hidden="true"></div>
</goab-block>
<goab-block direction="column" alignment="center" gap="l" width="100%">
<goab-text tag="h1" size="heading-l" mt="none" mb="none">Restricted access</goab-text>
<goab-text size="body-m" mt="none" mb="none">
We cannot provide access to this page without valid credentials. Please sign in or
contact support at
<goab-link>
<a href="mailto:cs.licensingsupport@gov.ab.ca">cs.licensingsupport@gov.ab.ca</a>
</goab-link>
to request access.
</goab-text>
</goab-block>
<goab-button type="primary" size="compact" (onClick)="goHome()">Go to home page</goab-button>
</goab-block>
</div>
</goab-page-block><goa-page-block>
<div style="text-align: center;">
<goa-block direction="column" alignment="center" gap="xl" width="100%" mt="3xl" mb="3xl">
<goa-block direction="column" alignment="center" gap="m" width="100%">
<div
style="display: flex; align-items: center; justify-content: center; width: 7.5rem; height: 7.5rem; border-radius: 50%; background-color: var(--goa-color-greyscale-100);"
>
<goa-icon role="presentation" type="warning" size="xlarge" style="transform: scale(1.35);"></goa-icon>
</div>
<goa-text size="body-m" color="secondary" mt="none" mb="none">Error 401</goa-text>
<div
aria-hidden="true"
style="width: 6.875rem; height: 0.5rem; background-color: var(--goa-color-info-default);"
></div>
</goa-block>
<goa-block direction="column" alignment="center" gap="l" width="100%">
<goa-text as="h1" size="heading-l" mt="none" mb="none">Restricted access</goa-text>
<goa-text size="body-m" mt="none" mb="none">
We cannot provide access to this page without valid credentials. Please sign in or
contact support at
<goa-link>
<a href="mailto:cs.licensingsupport@gov.ab.ca">cs.licensingsupport@gov.ab.ca</a>
</goa-link>
to request access.
</goa-text>
</goa-block>
<goa-button version="2" type="primary" size="compact" onclick="window.location.href='/'">Go to home page</goa-button>
</goa-block>
</div>
</goa-page-block>Server problem (500)
.error-page-content {
text-align: center;
}
.error-page-icon {
display: flex;
align-items: center;
justify-content: center;
width: 7.5rem;
height: 7.5rem;
border-radius: 50%;
background-color: var(--goa-color-greyscale-100);
}
/* Icon scaled beyond xlarge (2.5rem cap) to match the page-scale visual weight. */
/* Tracked in icon-sizes-above-xlarge gap ticket. */
.error-page-icon goa-icon,
.error-page-icon goab-icon {
transform: scale(1.35);
}
.error-page-underline {
width: 6.875rem;
height: var(--goa-space-xs);
background-color: var(--goa-color-info-default);
}<GoabPageBlock>
<div className="error-page-content">
<GoabBlock
direction="column"
alignment="center"
gap="xl"
width="100%"
mt="3xl"
mb="3xl"
>
<GoabBlock direction="column" alignment="center" gap="m" width="100%">
<div className="error-page-icon">
<GoabIcon role="presentation" type="warning" size="xlarge" />
</div>
<GoabText size="body-m" color="secondary" mt="none" mb="none">
Error 500
</GoabText>
<div className="error-page-underline" aria-hidden="true" />
</GoabBlock>
<GoabBlock direction="column" alignment="center" gap="l" width="100%">
<GoabText tag="h1" size="heading-l" mt="none" mb="none">
We are experiencing a problem
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
We cannot load this page right now. Please try again in a few minutes. We apologize
for the inconvenience.
</GoabText>
</GoabBlock>
<GoabButton type="primary" size="compact" onClick={() => (window.location.href = "/")}>
Go to home page
</GoabButton>
</GoabBlock>
</div>
</GoabPageBlock>goHome() {
window.location.href = "/";
}<goab-page-block>
<div class="error-page-content">
<goab-block direction="column" alignment="center" gap="xl" width="100%" mt="3xl" mb="3xl">
<goab-block direction="column" alignment="center" gap="m" width="100%">
<div class="error-page-icon">
<goab-icon role="presentation" type="warning" size="xlarge"></goab-icon>
</div>
<goab-text size="body-m" color="secondary" mt="none" mb="none">Error 500</goab-text>
<div class="error-page-underline" aria-hidden="true"></div>
</goab-block>
<goab-block direction="column" alignment="center" gap="l" width="100%">
<goab-text tag="h1" size="heading-l" mt="none" mb="none">We are experiencing a problem</goab-text>
<goab-text size="body-m" mt="none" mb="none">
We cannot load this page right now. Please try again in a few minutes. We apologize for the inconvenience.
</goab-text>
</goab-block>
<goab-button type="primary" size="compact" (onClick)="goHome()">Go to home page</goab-button>
</goab-block>
</div>
</goab-page-block><goa-page-block>
<div style="text-align: center;">
<goa-block direction="column" alignment="center" gap="xl" width="100%" mt="3xl" mb="3xl">
<goa-block direction="column" alignment="center" gap="m" width="100%">
<div
style="display: flex; align-items: center; justify-content: center; width: 7.5rem; height: 7.5rem; border-radius: 50%; background-color: var(--goa-color-greyscale-100);"
>
<goa-icon role="presentation" type="warning" size="xlarge" style="transform: scale(1.35);"></goa-icon>
</div>
<goa-text size="body-m" color="secondary" mt="none" mb="none">Error 500</goa-text>
<div
aria-hidden="true"
style="width: 6.875rem; height: 0.5rem; background-color: var(--goa-color-info-default);"
></div>
</goa-block>
<goa-block direction="column" alignment="center" gap="l" width="100%">
<goa-text as="h1" size="heading-l" mt="none" mb="none">We are experiencing a problem</goa-text>
<goa-text size="body-m" mt="none" mb="none">
We cannot load this page right now. Please try again in a few minutes. We apologize for the inconvenience.
</goa-text>
</goa-block>
<goa-button version="2" type="primary" size="compact" onclick="window.location.href='/'">Go to home page</goa-button>
</goa-block>
</div>
</goa-page-block>Page not found (404)
.error-page-content {
text-align: center;
}
.error-page-icon {
display: flex;
align-items: center;
justify-content: center;
width: 7.5rem;
height: 7.5rem;
border-radius: 50%;
background-color: var(--goa-color-greyscale-100);
}
/* Icon scaled beyond xlarge (2.5rem cap) to match the page-scale visual weight. */
/* Tracked in icon-sizes-above-xlarge gap ticket. */
.error-page-icon goa-icon,
.error-page-icon goab-icon {
transform: scale(1.35);
}
.error-page-underline {
width: 6.875rem;
height: var(--goa-space-xs);
background-color: var(--goa-color-info-default);
}<GoabPageBlock>
<div className="error-page-content">
<GoabBlock
direction="column"
alignment="center"
gap="xl"
width="100%"
mt="3xl"
mb="3xl"
>
<GoabBlock direction="column" alignment="center" gap="m" width="100%">
<div className="error-page-icon">
<GoabIcon role="presentation" type="warning" size="xlarge" />
</div>
<GoabText size="body-m" color="secondary" mt="none" mb="none">
Error 404
</GoabText>
<div className="error-page-underline" aria-hidden="true" />
</GoabBlock>
<GoabBlock direction="column" alignment="center" gap="l" width="100%">
<GoabText tag="h1" size="heading-l" mt="none" mb="none">
Page not found
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
The page you're looking for doesn't exist or has been moved.
</GoabText>
</GoabBlock>
<GoabButton type="primary" size="compact" onClick={() => (window.location.href = "/")}>
Go to home page
</GoabButton>
</GoabBlock>
</div>
</GoabPageBlock>goHome() {
window.location.href = "/";
}<goab-page-block>
<div class="error-page-content">
<goab-block direction="column" alignment="center" gap="xl" width="100%" mt="3xl" mb="3xl">
<goab-block direction="column" alignment="center" gap="m" width="100%">
<div class="error-page-icon">
<goab-icon role="presentation" type="warning" size="xlarge"></goab-icon>
</div>
<goab-text size="body-m" color="secondary" mt="none" mb="none">Error 404</goab-text>
<div class="error-page-underline" aria-hidden="true"></div>
</goab-block>
<goab-block direction="column" alignment="center" gap="l" width="100%">
<goab-text tag="h1" size="heading-l" mt="none" mb="none">Page not found</goab-text>
<goab-text size="body-m" mt="none" mb="none">The page you're looking for doesn't exist or has been moved.</goab-text>
</goab-block>
<goab-button type="primary" size="compact" (onClick)="goHome()">Go to home page</goab-button>
</goab-block>
</div>
</goab-page-block><goa-page-block>
<div style="text-align: center;">
<goa-block direction="column" alignment="center" gap="xl" width="100%" mt="3xl" mb="3xl">
<goa-block direction="column" alignment="center" gap="m" width="100%">
<div
style="display: flex; align-items: center; justify-content: center; width: 7.5rem; height: 7.5rem; border-radius: 50%; background-color: var(--goa-color-greyscale-100);"
>
<goa-icon role="presentation" type="warning" size="xlarge" style="transform: scale(1.35);"></goa-icon>
</div>
<goa-text size="body-m" color="secondary" mt="none" mb="none">Error 404</goa-text>
<div
aria-hidden="true"
style="width: 6.875rem; height: 0.5rem; background-color: var(--goa-color-info-default);"
></div>
</goa-block>
<goa-block direction="column" alignment="center" gap="l" width="100%">
<goa-text as="h1" size="heading-l" mt="none" mb="none">Page not found</goa-text>
<goa-text size="body-m" mt="none" mb="none">The page you're looking for doesn't exist or has been moved.</goa-text>
</goa-block>
<goa-button version="2" type="primary" size="compact" onclick="window.location.href='/'">Go to home page</goa-button>
</goa-block>
</div>
</goa-page-block>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 [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 [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>Card view of case files
.case-file-row {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
gap: var(--goa-space-m);
}<GoabContainer mt="l">
<div className="case-file-row">
<GoabBlock direction="column" gap="2xs">
<GoabText size="heading-xs" mt="none" mb="2xs">
Fiscal year: 2021/2022
</GoabText>
<GoabText size="body-s" mt="none" mb="none">
Submitted: April 23, 2023
</GoabText>
</GoabBlock>
<GoabBlock direction="row" gap="l" alignment="center">
<GoabBadge type="default" content="Not started" />
<GoabButton type="tertiary" size="compact">
Start
</GoabButton>
</GoabBlock>
</div>
</GoabContainer>
<GoabContainer>
<div className="case-file-row">
<GoabBlock direction="column" gap="2xs">
<GoabText size="heading-xs" mt="none" mb="2xs">
Fiscal year: 2020/2021
</GoabText>
<GoabText size="body-s" mt="none" mb="none">
Submitted: April 9, 2022
</GoabText>
</GoabBlock>
<GoabBlock direction="row" gap="l" alignment="center">
<GoabBadge type="important" content="Information needed" />
<GoabButton type="tertiary" size="compact">
Edit
</GoabButton>
</GoabBlock>
</div>
</GoabContainer>
<GoabContainer>
<div className="case-file-row">
<GoabBlock direction="column" gap="2xs">
<GoabText size="heading-xs" mt="none" mb="2xs">
Fiscal year: 2019/2020
</GoabText>
<GoabText size="body-s" mt="none" mb="none">
Submitted: April 14, 2021
</GoabText>
</GoabBlock>
<GoabBlock direction="row" gap="l" alignment="center">
<GoabBadge type="success" content="Approved" />
<GoabButton type="tertiary" size="compact">
View
</GoabButton>
</GoabBlock>
</div>
</GoabContainer><goab-container mt="l">
<div class="case-file-row">
<goab-block direction="column" gap="2xs">
<goab-text size="heading-xs" mt="none" mb="2xs">Fiscal year: 2021/2022</goab-text>
<goab-text size="body-s" mt="none" mb="none">Submitted: April 23, 2023</goab-text>
</goab-block>
<goab-block direction="row" gap="l" alignment="center">
<goab-badge type="default" content="Not started"></goab-badge>
<goab-button type="tertiary" size="compact">Start</goab-button>
</goab-block>
</div>
</goab-container>
<goab-container>
<div class="case-file-row">
<goab-block direction="column" gap="2xs">
<goab-text size="heading-xs" mt="none" mb="2xs">Fiscal year: 2020/2021</goab-text>
<goab-text size="body-s" mt="none" mb="none">Submitted: April 9, 2022</goab-text>
</goab-block>
<goab-block direction="row" gap="l" alignment="center">
<goab-badge type="important" content="Information needed"></goab-badge>
<goab-button type="tertiary" size="compact">Edit</goab-button>
</goab-block>
</div>
</goab-container>
<goab-container>
<div class="case-file-row">
<goab-block direction="column" gap="2xs">
<goab-text size="heading-xs" mt="none" mb="2xs">Fiscal year: 2019/2020</goab-text>
<goab-text size="body-s" mt="none" mb="none">Submitted: April 14, 2021</goab-text>
</goab-block>
<goab-block direction="row" gap="l" alignment="center">
<goab-badge type="success" content="Approved"></goab-badge>
<goab-button type="tertiary" size="compact">View</goab-button>
</goab-block>
</div>
</goab-container>.case-file-row {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
gap: var(--goa-space-m);
}<goa-container mt="l">
<div class="case-file-row">
<goa-block direction="column" gap="2xs">
<goa-text size="heading-xs" mt="none" mb="2xs">Fiscal year: 2021/2022</goa-text>
<goa-text size="body-s" mt="none" mb="none">Submitted: April 23, 2023</goa-text>
</goa-block>
<goa-block direction="row" gap="l" alignment="center">
<goa-badge version="2" type="default" content="Not started"></goa-badge>
<goa-button version="2" type="tertiary" size="compact">Start</goa-button>
</goa-block>
</div>
</goa-container>
<goa-container>
<div class="case-file-row">
<goa-block direction="column" gap="2xs">
<goa-text size="heading-xs" mt="none" mb="2xs">Fiscal year: 2020/2021</goa-text>
<goa-text size="body-s" mt="none" mb="none">Submitted: April 9, 2022</goa-text>
</goa-block>
<goa-block direction="row" gap="l" alignment="center">
<goa-badge version="2" type="important" content="Information needed"></goa-badge>
<goa-button version="2" type="tertiary" size="compact">Edit</goa-button>
</goa-block>
</div>
</goa-container>
<goa-container>
<div class="case-file-row">
<goa-block direction="column" gap="2xs">
<goa-text size="heading-xs" mt="none" mb="2xs">Fiscal year: 2019/2020</goa-text>
<goa-text size="body-s" mt="none" mb="none">Submitted: April 14, 2021</goa-text>
</goa-block>
<goa-block direction="row" gap="l" alignment="center">
<goa-badge version="2" type="success" content="Approved"></goa-badge>
<goa-button version="2" type="tertiary" size="compact">View</goa-button>
</goa-block>
</div>
</goa-container>Copy to clipboard
.token-block {
background-color: var(--goa-color-interactive-default);
height: 22px;
width: 24px;
border-radius: var(--goa-border-radius-s);
}const [isCopied, setIsCopied] = useState(false);
function copyCode() {
const codeToCopy = "$goa-color-interactive-default";
navigator.clipboard.writeText(codeToCopy).then(() => {
setIsCopied(true);
setTimeout(() => setIsCopied(false), 1000);
});
}<GoabBlock alignment="center">
<div className="token-block" />
<span>$goa-color-interactive-default</span>
<GoabTooltip content={isCopied ? "Copied" : "Copy?"} position="top">
<GoabIconButton icon="copy" onClick={copyCode} mt="2xs" />
</GoabTooltip>
</GoabBlock>isCopied = false;
copyCode(): void {
const codeToCopy = "$goa-color-interactive-default";
navigator.clipboard.writeText(codeToCopy).then(() => {
this.isCopied = true;
setTimeout(() => (this.isCopied = false), 1000);
});
}<goab-block alignment="center" gap="s">
<div class="token-block"></div>
<span>$goa-color-interactive-default</span>
<goab-tooltip [content]="isCopied ? 'Copied' : 'Copy?'" position="top">
<goab-icon-button icon="copy" (onClick)="copyCode()" mt="2xs"></goab-icon-button>
</goab-tooltip>
</goab-block>.token-block {
background-color: var(--goa-color-interactive-default);
height: 22px;
width: 24px;
border-radius: var(--goa-border-radius-s);
}const copyBtn = document.getElementById("copy-btn");
const tooltip = document.getElementById("copy-tooltip");
function copyCode() {
const codeToCopy = "$goa-color-interactive-default";
navigator.clipboard.writeText(codeToCopy).then(() => {
tooltip.setAttribute("content", "Copied");
setTimeout(() => {
tooltip.setAttribute("content", "Copy?");
}, 1000);
});
}
copyBtn.addEventListener("_click", copyCode);<goa-block alignment="center">
<div class="token-block"></div>
<span>$goa-color-interactive-default</span>
<goa-tooltip id="copy-tooltip" content="Copy?" position="top">
<goa-icon-button id="copy-btn" icon="copy" mt="2xs"></goa-icon-button>
</goa-tooltip>
</goa-block>Display user information
const handleAddToCalendar = () => {
console.log("Add to calendar clicked");
};<GoabContainer>
<GoabText tag="span" size="body-m" color="secondary" mt="none" mb="none">
Housing Advisor
</GoabText>
<GoabText size="heading-m" mt="none" mb="s">
Tracy Hero
</GoabText>
<GoabBlock direction="row" gap="s">
<GoabBlock direction="column" gap="m">
<GoabText tag="span" size="heading-xs" mt="none" mb="none">
Email
</GoabText>
<GoabText tag="span" size="heading-xs" mt="none" mb="none">
Phone
</GoabText>
</GoabBlock>
<GoabBlock direction="column" gap="m">
<GoabText tag="span" size="body-m" mt="none" mb="none">
tracyhero@email.com
</GoabText>
<GoabText tag="span" size="body-m" mt="none" mb="none">
283-203-4921
</GoabText>
</GoabBlock>
</GoabBlock>
</GoabContainer>
<GoabContainer
type="non-interactive"
accent="thick"
heading="Upcoming important due dates"
actions={
<GoabButton
type="tertiary"
size="compact"
leadingIcon="calendar"
onClick={handleAddToCalendar}
>
Add to calendar
</GoabButton>
}
>
<GoabTable width="100%" striped>
<tbody>
<tr>
<td>Business plan submission</td>
<td style={{ textAlign: "right" }}>June 30, 2024</td>
</tr>
<tr>
<td>Annual review</td>
<td style={{ textAlign: "right" }}>October 3, 2024</td>
</tr>
<tr>
<td>Application submission</td>
<td style={{ textAlign: "right" }}>December 20, 2024</td>
</tr>
<tr>
<td>Application review</td>
<td style={{ textAlign: "right" }}>January 3, 2025</td>
</tr>
</tbody>
</GoabTable>
</GoabContainer>onAddToCalendar(): void {
console.log("Add to calendar clicked");
}<goab-container>
<goab-text tag="span" size="body-m" color="secondary" mt="none" mb="none"
>Housing Advisor</goab-text
>
<goab-text size="heading-m" mt="none" mb="s">Tracy Hero</goab-text>
<goab-block direction="row" gap="s">
<goab-block direction="column" gap="m">
<goab-text tag="span" size="heading-xs" mt="none" mb="none">Email</goab-text>
<goab-text tag="span" size="heading-xs" mt="none" mb="none">Phone</goab-text>
</goab-block>
<goab-block direction="column" gap="m">
<goab-text tag="span" size="body-m" mt="none" mb="none"
>tracyhero@email.com</goab-text
>
<goab-text tag="span" size="body-m" mt="none" mb="none">283-203-4921</goab-text>
</goab-block>
</goab-block>
</goab-container>
<goab-container type="non-interactive" accent="thick">
<div slot="title">Upcoming important due dates</div>
<div slot="actions">
<goab-button
type="tertiary"
size="compact"
leadingIcon="calendar"
(onClick)="onAddToCalendar()"
>
Add to calendar
</goab-button>
</div>
<goab-table width="100%" [striped]="true">
<tbody>
<tr>
<td>Business plan submission</td>
<td style="text-align: right">June 30, 2024</td>
</tr>
<tr>
<td>Annual review</td>
<td style="text-align: right">October 3, 2024</td>
</tr>
<tr>
<td>Application submission</td>
<td style="text-align: right">December 20, 2024</td>
</tr>
<tr>
<td>Application review</td>
<td style="text-align: right">January 3, 2025</td>
</tr>
</tbody>
</goab-table>
</goab-container>const calendarBtn = document.getElementById("calendar-btn");
calendarBtn.addEventListener("_click", () => {
console.log("Add to calendar clicked");
});<goa-container>
<goa-text as="span" size="body-m" color="secondary" mt="none" mb="none"
>Housing Advisor</goa-text
>
<goa-text size="heading-m" mt="none" mb="s">Tracy Hero</goa-text>
<goa-block direction="row" gap="s">
<goa-block direction="column" gap="m">
<goa-text as="span" size="heading-xs" mt="none" mb="none">Email</goa-text>
<goa-text as="span" size="heading-xs" mt="none" mb="none">Phone</goa-text>
</goa-block>
<goa-block direction="column" gap="m">
<goa-text as="span" size="body-m" mt="none" mb="none">tracyhero@email.com</goa-text>
<goa-text as="span" size="body-m" mt="none" mb="none">283-203-4921</goa-text>
</goa-block>
</goa-block>
</goa-container>
<goa-container type="non-interactive" accent="thick">
<div slot="title">Upcoming important due dates</div>
<div slot="actions">
<goa-button
version="2"
id="calendar-btn"
type="tertiary"
size="compact"
leadingicon="calendar"
>
Add to calendar
</goa-button>
</div>
<goa-table version="2" width="100%" striped="true">
<table style="width: 100%">
<tbody>
<tr>
<td>Business plan submission</td>
<td style="text-align: right">June 30, 2024</td>
</tr>
<tr>
<td>Annual review</td>
<td style="text-align: right">October 3, 2024</td>
</tr>
<tr>
<td>Application submission</td>
<td style="text-align: right">December 20, 2024</td>
</tr>
<tr>
<td>Application review</td>
<td style="text-align: right">January 3, 2025</td>
</tr>
</tbody>
</table>
</goa-table>
</goa-container>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>Result page
<GoabText tag="h1" mt="none">
You have completed the application
</GoabText>
<GoabCallout type="success" heading="Application submitted">
<GoabText size="body-m" mt="none" mb="s">
You will receive a copy of the confirmation to the email name@email.com
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
Your reference number is: <strong>1234ABC</strong>
</GoabText>
</GoabCallout>
<GoabText tag="h2" mt="xl" mb="m">
What happens next
</GoabText>
<GoabText size="body-m" mt="none" mb="s">
We've sent your application to service name. They will contact you to confirm your
registration.
</GoabText>
<GoabText size="body-m" mt="none" mb="s">
You can now close this window.
</GoabText>
<GoabText size="body-m" mt="none" mb="s">
What did you think of this service? <a href="#">Give feedback</a>
</GoabText>
<GoabText tag="h2" mt="xl" mb="m">
If you have questions about your application
</GoabText>
<GoabText size="body-m" mt="none" mb="s">
Contact the [ministry area].
</GoabText>
<GoabText size="body-m" mt="none" mb="s">
Email: <a href="mailto:information@gov.ab.ca">information@gov.ab.ca</a>
</GoabText>
<GoabText size="body-m" mt="none" mb="s">
Phone: <a href="tel:7801234567">780 123 4567</a>
</GoabText>
);
}<goab-text tag="h1" mt="none">You have completed the application</goab-text>
<goab-callout type="success" heading="Application submitted">
<goab-text size="body-m" mt="none" mb="s"
>You will receive a copy of the confirmation to the email
name@email.com</goab-text
>
<goab-text size="body-m" mt="none" mb="none"
>Your reference number is: <strong>1234ABC</strong></goab-text
>
</goab-callout>
<goab-text tag="h2" mt="xl" mb="m">What happens next</goab-text>
<goab-text size="body-m" mt="none" mb="s"
>We've sent your application to service name. They will contact you to confirm your
registration.</goab-text
>
<goab-text size="body-m" mt="none" mb="s">You can now close this window.</goab-text>
<goab-text size="body-m" mt="none" mb="s"
>What did you think of this service? <a href="#">Give feedback</a></goab-text
>
<goab-text tag="h2" mt="xl" mb="m"
>If you have questions about your application</goab-text
>
<goab-text size="body-m" mt="none" mb="s">Contact the [ministry area].</goab-text>
<goab-text size="body-m" mt="none" mb="s"
>Email:
<a href="mailto:information@gov.ab.ca">information@gov.ab.ca</a></goab-text
>
<goab-text size="body-m" mt="none" mb="s"
>Phone: <a href="tel:7801234567">780 123 4567</a></goab-text
><goa-text as="h1" mt="none">You have completed the application</goa-text>
<goa-callout version="2" type="success" heading="Application submitted">
<goa-text size="body-m" mt="none" mb="s"
>You will receive a copy of the confirmation to the email name@email.com</goa-text
>
<goa-text size="body-m" mt="none" mb="none"
>Your reference number is: <strong>1234ABC</strong></goa-text
>
</goa-callout>
<goa-text as="h2" mt="xl" mb="m">What happens next</goa-text>
<goa-text size="body-m" mt="none" mb="s"
>We've sent your application to service name. They will contact you to confirm your
registration.</goa-text
>
<goa-text size="body-m" mt="none" mb="s">You can now close this window.</goa-text>
<goa-text size="body-m" mt="none" mb="s"
>What did you think of this service? <a href="#">Give feedback</a></goa-text
>
<goa-text as="h2" mt="xl" mb="m">If you have questions about your application</goa-text>
<goa-text size="body-m" mt="none" mb="s">Contact the [ministry area].</goa-text>
<goa-text size="body-m" mt="none" mb="s"
>Email: <a href="mailto:information@gov.ab.ca">information@gov.ab.ca</a></goa-text
>
<goa-text size="body-m" mt="none" mb="s"
>Phone: <a href="tel:7801234567">780 123 4567</a></goa-text
>Review and action
<GoabGrid minChildWidth="315px">
<GoabContainer accent="thin" type="non-interactive">
<GoabText size="heading-m" mt="none" mb="m">
Appearance details
</GoabText>
<GoabGrid minChildWidth="200px" gap="m">
<GoabBlock direction="column" gap="xs">
<GoabText size="body-s" color="secondary" mt="none" mb="none">
Accused name
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
Doe, John Scott
</GoabText>
</GoabBlock>
<GoabBlock direction="column" gap="xs">
<GoabText size="body-s" color="secondary" mt="none" mb="none">
Date of birth
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
Mar 14, 2021
</GoabText>
</GoabBlock>
<GoabBlock direction="column" gap="xs">
<GoabText size="body-s" color="secondary" mt="none" mb="none">
Court location
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
Calgary
</GoabText>
</GoabBlock>
<GoabBlock direction="column" gap="xs">
<GoabText size="body-s" color="secondary" mt="none" mb="none">
Upcoming appearance date{"(s)"}
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
Sep 20, 2021
</GoabText>
</GoabBlock>
</GoabGrid>
<GoabText size="heading-xs" mt="l" mb="s">
Docket number{"(s)"} & charges
</GoabText>
<GoabContainer type="non-interactive" padding="compact">
<GoabText size="heading-xs" mt="none" mb="xs">
{"1) 12345678"}
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
{"CC 334(1) - Theft under $5000"}
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
{"CC 268(1) - Aggravated assault"}
</GoabText>
</GoabContainer>
<GoabContainer type="non-interactive" padding="compact">
<GoabText size="heading-xs" mt="none" mb="xs">
{"2) 12345678"}
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
{"CC 334(1) - Theft under $5000"}
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
{"CC 268(1) - Aggravated assault"}
</GoabText>
</GoabContainer>
</GoabContainer>
<GoabContainer accent="thin" width="content">
<form>
<GoabText size="heading-m" mt="none" mb="m">
Adjournment request
</GoabText>
<GoabText size="body-m" mt="none" mb="none">
Keep track of the individuals who are placed in lodges and may qualify for the
Lodge Assistance Program subsidy.
</GoabText>
<GoabFormItem label="Case history and new request" mt="l">
<GoabRadioGroup name="case" orientation="horizontal" onChange={() => {}}>
<GoabRadioItem value="grant" label="Grant" />
<GoabRadioItem value="deny" label="Deny" />
</GoabRadioGroup>
</GoabFormItem>
<GoabFormItem label="Reason to deny" mt="l">
<GoabDropdown name="reason" width="100%" onChange={() => {}}>
<GoabDropdownItem value="1" label="Incomplete Application" />
<GoabDropdownItem value="2" label="Eligibility Criteria Not Met" />
<GoabDropdownItem value="3" label="Documentation Verification Failure" />
</GoabDropdown>
</GoabFormItem>
<GoabFormItem label="Message" mt="l">
<GoabTextArea
name="message"
rows={5}
width="100%"
value=""
onChange={() => {}}
/>
</GoabFormItem>
<GoabButton mt="xl" onClick={() => {}}>
Confirm adjournment
</GoabButton>
</form>
</GoabContainer>
</GoabGrid>form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
case: [""],
reason: [""],
message: [""],
});
}
onClick(): void {
console.log("Confirm clicked!");
}<goab-grid minChildWidth="315px">
<goab-container accent="thin" type="non-interactive">
<goab-text size="heading-m" mt="none" mb="m">Appearance details</goab-text>
<goab-grid minChildWidth="200px" gap="m">
<goab-block direction="column" gap="xs">
<goab-text size="body-s" color="secondary" mt="none" mb="none"
>Accused name</goab-text
>
<goab-text size="body-m" mt="none" mb="none">Doe, John Scott</goab-text>
</goab-block>
<goab-block direction="column" gap="xs">
<goab-text size="body-s" color="secondary" mt="none" mb="none"
>Date of birth</goab-text
>
<goab-text size="body-m" mt="none" mb="none">Mar 14, 2021</goab-text>
</goab-block>
<goab-block direction="column" gap="xs">
<goab-text size="body-s" color="secondary" mt="none" mb="none"
>Court location</goab-text
>
<goab-text size="body-m" mt="none" mb="none">Calgary</goab-text>
</goab-block>
<goab-block direction="column" gap="xs">
<goab-text size="body-s" color="secondary" mt="none" mb="none"
>Upcoming appearance date(s)</goab-text
>
<goab-text size="body-m" mt="none" mb="none">Sep 20, 2021</goab-text>
</goab-block>
</goab-grid>
<goab-text size="heading-xs" mt="l" mb="s">Docket number(s) & charges</goab-text>
<goab-container type="non-interactive" padding="compact">
<goab-text size="heading-xs" mt="none" mb="xs">1) 12345678</goab-text>
<goab-text size="body-m" mt="none" mb="none"
>CC 334(1) - Theft under $5000</goab-text
>
<goab-text size="body-m" mt="none" mb="none"
>CC 268(1) - Aggravated assault</goab-text
>
</goab-container>
<goab-container type="non-interactive" padding="compact">
<goab-text size="heading-xs" mt="none" mb="xs">2) 12345678</goab-text>
<goab-text size="body-m" mt="none" mb="none"
>CC 334(1) - Theft under $5000</goab-text
>
<goab-text size="body-m" mt="none" mb="none"
>CC 268(1) - Aggravated assault</goab-text
>
</goab-container>
</goab-container>
<goab-container accent="thin" width="content">
<form [formGroup]="form">
<goab-text size="heading-m" mt="none" mb="m">Adjournment request</goab-text>
<goab-text size="body-m" mt="none" mb="none">
Keep track of the individuals who are placed in lodges and may qualify for the
Lodge Assistance Program subsidy.
</goab-text>
<goab-form-item label="Case history and new request" mt="l">
<goab-radio-group name="case" orientation="horizontal" formControlName="case">
<goab-radio-item value="grant" label="Grant"></goab-radio-item>
<goab-radio-item value="deny" label="Deny"></goab-radio-item>
</goab-radio-group>
</goab-form-item>
<goab-form-item label="Reason to deny" mt="l">
<goab-dropdown name="reason" width="100%" formControlName="reason">
<goab-dropdown-item
value="1"
label="Incomplete Application"
></goab-dropdown-item>
<goab-dropdown-item
value="2"
label="Eligibility Criteria Not Met"
></goab-dropdown-item>
<goab-dropdown-item
value="3"
label="Documentation Verification Failure"
></goab-dropdown-item>
</goab-dropdown>
</goab-form-item>
<goab-form-item label="Message" mt="l">
<goab-textarea
name="message"
[rows]="5"
width="100%"
formControlName="message"
></goab-textarea>
</goab-form-item>
<goab-button mt="xl" (onClick)="onClick()">Confirm adjournment</goab-button>
</form>
</goab-container>
</goab-grid>document.getElementById("confirm-btn").addEventListener("_click", () => {
console.log("Confirm clicked!");
});<goa-grid minchildwidth="315px">
<goa-container accent="thin" type="non-interactive">
<goa-text size="heading-m" mt="none" mb="m">Appearance details</goa-text>
<goa-grid minchildwidth="200px" gap="m">
<goa-block direction="column" gap="xs">
<goa-text size="body-s" color="secondary" mt="none" mb="none"
>Accused name</goa-text
>
<goa-text size="body-m" mt="none" mb="none">Doe, John Scott</goa-text>
</goa-block>
<goa-block direction="column" gap="xs">
<goa-text size="body-s" color="secondary" mt="none" mb="none"
>Date of birth</goa-text
>
<goa-text size="body-m" mt="none" mb="none">Mar 14, 2021</goa-text>
</goa-block>
<goa-block direction="column" gap="xs">
<goa-text size="body-s" color="secondary" mt="none" mb="none"
>Court location</goa-text
>
<goa-text size="body-m" mt="none" mb="none">Calgary</goa-text>
</goa-block>
<goa-block direction="column" gap="xs">
<goa-text size="body-s" color="secondary" mt="none" mb="none"
>Upcoming appearance date(s)</goa-text
>
<goa-text size="body-m" mt="none" mb="none">Sep 20, 2021</goa-text>
</goa-block>
</goa-grid>
<goa-text size="heading-xs" mt="l" mb="s">Docket number(s) & charges</goa-text>
<goa-container type="non-interactive" padding="compact">
<goa-text size="heading-xs" mt="none" mb="xs">1) 12345678</goa-text>
<goa-text size="body-m" mt="none" mb="none">CC 334(1) - Theft under $5000</goa-text>
<goa-text size="body-m" mt="none" mb="none"
>CC 268(1) - Aggravated assault</goa-text
>
</goa-container>
<goa-container type="non-interactive" padding="compact">
<goa-text size="heading-xs" mt="none" mb="xs">2) 12345678</goa-text>
<goa-text size="body-m" mt="none" mb="none">CC 334(1) - Theft under $5000</goa-text>
<goa-text size="body-m" mt="none" mb="none"
>CC 268(1) - Aggravated assault</goa-text
>
</goa-container>
</goa-container>
<goa-container accent="thin" width="content">
<form>
<goa-text size="heading-m" mt="none" mb="m">Adjournment request</goa-text>
<goa-text size="body-m" mt="none" mb="none">
Keep track of the individuals who are placed in lodges and may qualify for the
Lodge Assistance Program subsidy.
</goa-text>
<goa-form-item version="2" label="Case history and new request" mt="l">
<goa-radio-group version="2" name="case" orientation="horizontal">
<goa-radio-item value="grant" label="Grant"></goa-radio-item>
<goa-radio-item value="deny" label="Deny"></goa-radio-item>
</goa-radio-group>
</goa-form-item>
<goa-form-item version="2" label="Reason to deny" mt="l">
<goa-dropdown version="2" name="reason" width="100%">
<goa-dropdown-item value="1" label="Incomplete Application"></goa-dropdown-item>
<goa-dropdown-item
value="2"
label="Eligibility Criteria Not Met"
></goa-dropdown-item>
<goa-dropdown-item
value="3"
label="Documentation Verification Failure"
></goa-dropdown-item>
</goa-dropdown>
</goa-form-item>
<goa-form-item version="2" label="Message" mt="l">
<goa-textarea version="2" name="message" rows="5" width="100%"></goa-textarea>
</goa-form-item>
<goa-button version="2" id="confirm-btn" mt="xl">Confirm adjournment</goa-button>
</form>
</goa-container>
</goa-grid>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 list to help answer a question
const handleChange = (event: GoabRadioGroupOnChangeDetail) => {
console.log("value is", event.value);
};<form>
<GoabFormItem
label="Do you have additional education expenses?"
helpText="You can request funding for these now or at any time during your program."
mb="m"
>
<GoabRadioGroup name="additional" onChange={handleChange}>
<GoabRadioItem label="Yes" value="yes" name="additional" />
<GoabRadioItem label="No" value="no" name="additional" />
</GoabRadioGroup>
</GoabFormItem>
<GoabDetails heading="What are additional education expenses?">
<GoabBlock gap="m" mt="m">
<div>
<strong>Examples of education expenses</strong>
<ul className="goa-unordered-list">
<li>Laptop and computer hardware</li>
<li>Computer apps and subscriptions</li>
<li>Home internet</li>
<li>Testing and exam fees</li>
<li>Work or school clothing, like work boots</li>
</ul>
</div>
<div>
<strong>Do not include</strong>
<ul className="goa-unordered-list">
<li>Tuition</li>
<li>Mandatory fees</li>
<li>Books and supplies</li>
<li>School association fees</li>
</ul>
</div>
</GoabBlock>
</GoabDetails>
</form>onRadioChange(event: GoabRadioGroupOnChangeDetail): void {
console.log("value is", event.value);
}<form [formGroup]="form">
<goab-form-item
label="Do you have additional education expenses?"
helpText="You can request funding for these now or at any time during your program."
mb="m"
>
<goab-radio-group name="additional" (onChange)="onRadioChange($event)">
<goab-radio-item label="Yes" value="yes" name="additional"></goab-radio-item>
<goab-radio-item label="No" value="no" name="additional"></goab-radio-item>
</goab-radio-group>
</goab-form-item>
<goab-details heading="What are additional education expenses?">
<goab-block gap="m" mt="m">
<div>
<strong>Examples of education expenses</strong>
<ul class="goa-unordered-list">
<li>Laptop and computer hardware</li>
<li>Computer apps and subscriptions</li>
<li>Home internet</li>
<li>Testing and exam fees</li>
<li>Work or school clothing, like work boots</li>
</ul>
</div>
<div>
<strong>Do not include</strong>
<ul class="goa-unordered-list">
<li>Tuition</li>
<li>Mandatory fees</li>
<li>Books and supplies</li>
<li>School association fees</li>
</ul>
</div>
</goab-block>
</goab-details>
</form>document.querySelector("goa-radio-group").addEventListener("_change", (e) => {
console.log("value is", e.detail.value);
});<form>
<goa-form-item
version="2"
label="Do you have additional education expenses?"
helptext="You can request funding for these now or at any time during your program."
mb="m"
>
<goa-radio-group version="2" name="additional">
<goa-radio-item label="Yes" value="yes" name="additional"></goa-radio-item>
<goa-radio-item label="No" value="no" name="additional"></goa-radio-item>
</goa-radio-group>
</goa-form-item>
<goa-details heading="What are additional education expenses?">
<goa-block gap="m" mt="m">
<div>
<strong>Examples of education expenses</strong>
<ul class="goa-unordered-list">
<li>Laptop and computer hardware</li>
<li>Computer apps and subscriptions</li>
<li>Home internet</li>
<li>Testing and exam fees</li>
<li>Work or school clothing, like work boots</li>
</ul>
</div>
<div>
<strong>Do not include</strong>
<ul class="goa-unordered-list">
<li>Tuition</li>
<li>Mandatory fees</li>
<li>Books and supplies</li>
<li>School association fees</li>
</ul>
</div>
</goa-block>
</goa-details>
</form>Show multiple actions in a compact table
const rows = [
{
status: "information",
statusText: "In progress",
name: "Darlene Robertson",
id: 45904,
},
{ status: "default", statusText: "Inactive", name: "Floyd Miles", id: 47838 },
{ status: "success", statusText: "Active", name: "Kathryn Murphy", id: 34343 },
{ status: "important", statusText: "Recent", name: "Annette Black", id: 89897 },
{ status: "success", statusText: "Active", name: "Esther Howard", id: 12323 },
{ status: "success", statusText: "Active", name: "Jane Cooper", id: 56565 },
];<GoabTable width="100%">
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th style={{ textAlign: "right" }}>Id Number</th>
<th style={{ width: "1%", whiteSpace: "nowrap" }}>Edit | Flag | Send</th>
</tr>
</thead>
<tbody>
{rows.map((row) => (
<tr key={row.id}>
<td>
<GoabBadge
type={row.status as "information" | "default" | "success" | "important"}
content={row.statusText}
icon={false}
/>
</td>
<td>{row.name}</td>
<td className="goa-table-number-column">{row.id}</td>
<td>
<GoabBlock>
<GoabIconButton size="small" icon="pencil" ariaLabel="Edit" />
<GoabIconButton size="small" icon="flag" ariaLabel="Flag" />
<GoabIconButton size="small" icon="mail" ariaLabel="Send" />
</GoabBlock>
</td>
</tr>
))}
</tbody>
</GoabTable>rows: TableRow[] = [
{
status: "information",
statusText: "In progress",
name: "Darlene Robertson",
id: 45904,
},
{ status: "default", statusText: "Inactive", name: "Floyd Miles", id: 47838 },
{ status: "success", statusText: "Active", name: "Kathryn Murphy", id: 34343 },
{ status: "important", statusText: "Recent", name: "Annette Black", id: 89897 },
{ status: "success", statusText: "Active", name: "Esther Howard", id: 12323 },
{ status: "success", statusText: "Active", name: "Jane Cooper", id: 56565 },
];<goab-table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th style="text-align: right">Id Number</th>
<th style="width: 1%; white-space: nowrap">Edit | Flag | Send</th>
</tr>
</thead>
<tbody>
@for (row of rows; track row.id) {
<tr>
<td>
<goab-badge
[type]="row.status"
[content]="row.statusText"
[icon]="false"
></goab-badge>
</td>
<td>{{ row.name }}</td>
<td class="goa-table-number-column">{{ row.id }}</td>
<td>
<goab-block>
<goab-icon-button
size="small"
icon="pencil"
ariaLabel="Edit"
></goab-icon-button>
<goab-icon-button size="small" icon="flag" ariaLabel="Flag"></goab-icon-button>
<goab-icon-button size="small" icon="mail" ariaLabel="Send"></goab-icon-button>
</goab-block>
</td>
</tr>
}
</tbody>
</goab-table><goa-table version="2" width="100%">
<table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th style="text-align: right">Id Number</th>
<th style="width: 1%; white-space: nowrap">Edit | Flag | Send</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<goa-badge
version="2"
type="information"
content="In progress"
icon="false"
></goa-badge>
</td>
<td>Darlene Robertson</td>
<td class="goa-table-number-column">45904</td>
<td>
<goa-block>
<goa-icon-button
size="small"
icon="pencil"
arialabel="Edit"
></goa-icon-button>
<goa-icon-button size="small" icon="flag" arialabel="Flag"></goa-icon-button>
<goa-icon-button size="small" icon="mail" arialabel="Send"></goa-icon-button>
</goa-block>
</td>
</tr>
<tr>
<td>
<goa-badge
version="2"
type="default"
content="Inactive"
icon="false"
></goa-badge>
</td>
<td>Floyd Miles</td>
<td class="goa-table-number-column">47838</td>
<td>
<goa-block>
<goa-icon-button
size="small"
icon="pencil"
arialabel="Edit"
></goa-icon-button>
<goa-icon-button size="small" icon="flag" arialabel="Flag"></goa-icon-button>
<goa-icon-button size="small" icon="mail" arialabel="Send"></goa-icon-button>
</goa-block>
</td>
</tr>
<tr>
<td>
<goa-badge version="2" type="success" content="Active" icon="false"></goa-badge>
</td>
<td>Kathryn Murphy</td>
<td class="goa-table-number-column">34343</td>
<td>
<goa-block>
<goa-icon-button
size="small"
icon="pencil"
arialabel="Edit"
></goa-icon-button>
<goa-icon-button size="small" icon="flag" arialabel="Flag"></goa-icon-button>
<goa-icon-button size="small" icon="mail" arialabel="Send"></goa-icon-button>
</goa-block>
</td>
</tr>
<tr>
<td>
<goa-badge
version="2"
type="important"
content="Recent"
icon="false"
></goa-badge>
</td>
<td>Annette Black</td>
<td class="goa-table-number-column">89897</td>
<td>
<goa-block>
<goa-icon-button
size="small"
icon="pencil"
arialabel="Edit"
></goa-icon-button>
<goa-icon-button size="small" icon="flag" arialabel="Flag"></goa-icon-button>
<goa-icon-button size="small" icon="mail" arialabel="Send"></goa-icon-button>
</goa-block>
</td>
</tr>
<tr>
<td>
<goa-badge version="2" type="success" content="Active" icon="false"></goa-badge>
</td>
<td>Esther Howard</td>
<td class="goa-table-number-column">12323</td>
<td>
<goa-block>
<goa-icon-button
size="small"
icon="pencil"
arialabel="Edit"
></goa-icon-button>
<goa-icon-button size="small" icon="flag" arialabel="Flag"></goa-icon-button>
<goa-icon-button size="small" icon="mail" arialabel="Send"></goa-icon-button>
</goa-block>
</td>
</tr>
<tr>
<td>
<goa-badge version="2" type="success" content="Active" icon="false"></goa-badge>
</td>
<td>Jane Cooper</td>
<td class="goa-table-number-column">56565</td>
<td>
<goa-block>
<goa-icon-button
size="small"
icon="pencil"
arialabel="Edit"
></goa-icon-button>
<goa-icon-button size="small" icon="flag" arialabel="Flag"></goa-icon-button>
<goa-icon-button size="small" icon="mail" arialabel="Send"></goa-icon-button>
</goa-block>
</td>
</tr>
</tbody>
</table>
</goa-table>Show multiple tags together
<GoabBlock gap="xs">
<GoabBadge type="information" content="In progress" />
<GoabBadge type="important" content="Priority" />
<GoabBadge type="emergency" content="Past deadline" />
</GoabBlock><goab-block gap="xs">
<goab-badge type="information" content="In progress"></goab-badge>
<goab-badge type="important" content="Priority"></goab-badge>
<goab-badge type="emergency" content="Past deadline"></goab-badge>
</goab-block><goa-block gap="xs">
<goa-badge version="2" type="information" content="In progress"></goa-badge>
<goa-badge version="2" type="important" content="Priority"></goa-badge>
<goa-badge version="2" type="emergency" content="Past deadline"></goa-badge>
</goa-block>Show number of results per page
interface User {
id: string;
firstName: string;
lastName: string;
age: number;
}
const [users] = useState<User[]>(() => generateUsers());
const [page, setPage] = useState<number>(1);
const [perPage, setPerPage] = useState<number>(10);
const offset = (page - 1) * perPage;
const pageUsers = users.slice(offset, offset + perPage);
function changePage(newPage: number) {
setPage(newPage);
}
function handlePerPageCountChangeEvent(event: GoabDropdownOnChangeDetail) {
setPage(1);
setPerPage(parseInt(event.value || "10"));
}<GoabTable width="100%" mb="xl">
<thead>
<tr>
<th>First name</th>
<th>Last name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
{pageUsers.map((u) => (
<tr key={u.id}>
<td>{u.firstName}</td>
<td>{u.lastName}</td>
<td>{u.age}</td>
</tr>
))}
</tbody>
</GoabTable>
<GoabBlock alignment="center" width="100%">
<GoabBlock mb="m" alignment="center">
Show
<GoabDropdown
onChange={handlePerPageCountChangeEvent}
value={perPage.toString()}
width="9ch"
>
<GoabDropdownItem value="10" label="10" />
<GoabDropdownItem value="20" label="20" />
<GoabDropdownItem value="30" label="30" />
</GoabDropdown>
<span style={{ width: "75px" }}>per page</span>
</GoabBlock>
<GoabSpacer hSpacing="fill" />
<GoabPagination
itemCount={users.length}
perPageCount={perPage}
pageNumber={page}
onChange={(event) => changePage(event.page)}
/>
</GoabBlock> users: User[] = generateUsers();
page = 1;
perPage = 10;
get pageUsers(): User[] {
const offset = (this.page - 1) * this.perPage;
return this.users.slice(offset, offset + this.perPage);
}
handlePageChange(event: GoabPaginationOnChangeDetail): void {
this.page = event.page;
}
handlePerPageCountChangeEvent(event: GoabDropdownOnChangeDetail): void {
this.page = 1;
this.perPage = Number(event.value);
}
}
function generateUsers(): User[] {
const firstNames = [
"Emma",
"Liam",
"Olivia",
"Noah",
"Ava",
"James",
"Sophia",
"William",
"Isabella",
"Oliver",
"Mia",
"Benjamin",
"Charlotte",
"Elijah",
"Amelia",
"Lucas",
"Harper",
"Mason",
"Evelyn",
"Logan",
];
const lastNames = [
"Smith",
"Johnson",
"Williams",
"Brown",
"Jones",
"Garcia",
"Miller",
"Davis",
"Rodriguez",
"Martinez",
"Wilson",
"Anderson",
"Taylor",
"Thomas",
"Moore",
"Jackson",
"Martin",
"Lee",
"Thompson",
"White",
];
const users: User[] = [];
for (let i = 1; i <= 100; i++) {
users.push({
id: `user-${i}`,
firstName: firstNames[(i - 1) % firstNames.length],
lastName: lastNames[(i - 1) % lastNames.length],
age: 20 + (i % 40),
});
}
return users;<goab-table width="100%" mb="xl">
<thead>
<tr>
<th>First name</th>
<th>Last name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
@for (user of pageUsers; track $index) {
<tr>
<td>{{ user.firstName }}</td>
<td>{{ user.lastName }}</td>
<td>{{ user.age }}</td>
</tr>
}
</tbody>
</goab-table>
<goab-block alignment="center" width="100%">
<goab-block mb="m" alignment="center">
Show
<goab-dropdown
(onChange)="handlePerPageCountChangeEvent($event)"
[value]="perPage.toString()"
width="9ch"
>
<goab-dropdown-item value="10" label="10"></goab-dropdown-item>
<goab-dropdown-item value="20" label="20"></goab-dropdown-item>
<goab-dropdown-item value="30" label="30"></goab-dropdown-item>
</goab-dropdown>
<span style="width: 75px">per page</span>
</goab-block>
<goab-spacer hSpacing="fill"></goab-spacer>
<goab-pagination
[itemCount]="users.length"
[perPageCount]="perPage"
[pageNumber]="page"
(onChange)="handlePageChange($event)"
>
</goab-pagination>
</goab-block>const firstNames = [
"Emma",
"Liam",
"Olivia",
"Noah",
"Ava",
"James",
"Sophia",
"William",
"Isabella",
"Oliver",
"Mia",
"Benjamin",
"Charlotte",
"Elijah",
"Amelia",
"Lucas",
"Harper",
"Mason",
"Evelyn",
"Logan",
];
const lastNames = [
"Smith",
"Johnson",
"Williams",
"Brown",
"Jones",
"Garcia",
"Miller",
"Davis",
"Rodriguez",
"Martinez",
"Wilson",
"Anderson",
"Taylor",
"Thomas",
"Moore",
"Jackson",
"Martin",
"Lee",
"Thompson",
"White",
];
const users = [];
for (let i = 1; i <= 100; i++) {
users.push({
id: "user-" + i,
firstName: firstNames[(i - 1) % firstNames.length],
lastName: lastNames[(i - 1) % lastNames.length],
age: 20 + (i % 40),
});
}
let page = 1;
let perPage = 10;
const tableBody = document.getElementById("table-body");
const pagination = document.getElementById("pagination");
const dropdown = document.getElementById("per-page-dropdown");
function renderTable() {
const offset = (page - 1) * perPage;
const pageUsers = users.slice(offset, offset + perPage);
tableBody.innerHTML = pageUsers
.map(
(u) => `
<tr>
<td>${u.firstName}</td>
<td>${u.lastName}</td>
<td>${u.age}</td>
</tr>
`,
)
.join("");
}
pagination.addEventListener("_change", (e) => {
page = e.detail.page;
renderTable();
});
dropdown.addEventListener("_change", (e) => {
perPage = parseInt(e.detail.value);
page = 1;
pagination.setAttribute("perpagecount", perPage);
pagination.setAttribute("pagenumber", "1");
renderTable();
});
renderTable();<goa-table version="2" width="100%" mb="xl">
<table width="100%">
<thead>
<tr>
<th>First name</th>
<th>Last name</th>
<th>Age</th>
</tr>
</thead>
<tbody id="table-body">
<!-- Rows populated by JavaScript -->
</tbody>
</table>
</goa-table>
<goa-block alignment="center" width="100%">
<goa-block mb="m" alignment="center">
Show
<goa-dropdown version="2" id="per-page-dropdown" value="10" width="9ch">
<goa-dropdown-item value="10" label="10"></goa-dropdown-item>
<goa-dropdown-item value="20" label="20"></goa-dropdown-item>
<goa-dropdown-item value="30" label="30"></goa-dropdown-item>
</goa-dropdown>
<span style="width: 75px">per page</span>
</goa-block>
<goa-spacer hspacing="fill"></goa-spacer>
<goa-pagination
version="2"
id="pagination"
itemcount="100"
perpagecount="10"
pagenumber="1"
>
</goa-pagination>
</goa-block>Workspace
Preview not available
No React code available
Other
Tip
Use Block for general layout and spacing. Use ButtonGroup for semantically related action buttons.
Header section
Main content area
Footer section
Don't
Don't use a container for general page layout. Containers are for visual emphasis and grouping content.