diff --git a/src/examples/display-numbers-in-a-table-so-they-can-be-scanned-easily.tsx b/src/examples/display-numbers-in-a-table-so-they-can-be-scanned-easily.tsx
index ba87d5975..4e57cf46c 100644
--- a/src/examples/display-numbers-in-a-table-so-they-can-be-scanned-easily.tsx
+++ b/src/examples/display-numbers-in-a-table-so-they-can-be-scanned-easily.tsx
@@ -15,14 +15,24 @@ export const DisplayNumbersInATableSoTheyCanBeScannedEasily = () => {
- | Item 1 |
- Item 2 |
- 54 |
+ Christian |
+ Batz |
+ 54356456 |
- | Item 1 |
- Item 2 |
- 4567 |
+ Brian |
+ Wisozk |
+ 23212321 |
+
+
+ | Neha |
+ Jones |
+ 23197213 |
+
+
+ | Tristan |
+ Buckridge |
+ 76312313 |
diff --git a/src/examples/filter-data-in-a-table.tsx b/src/examples/filter-data-in-a-table.tsx
index e683be1c9..c1036e1e5 100644
--- a/src/examples/filter-data-in-a-table.tsx
+++ b/src/examples/filter-data-in-a-table.tsx
@@ -9,6 +9,9 @@ import {
GoabInput,
GoabTable,
GoabText,
+ GoabPopover,
+ GoabRadioGroup,
+ GoabRadioItem
} from "@abgov/react-components";
import type {
GoabBadgeType,
@@ -17,10 +20,12 @@ import type {
} from "@abgov/ui-components-common";
import { LanguageVersionContext } from "@contexts/LanguageVersionContext.tsx";
import { CodeSnippet } from "@components/code-snippet/CodeSnippet.tsx";
+import { GoabRadioGroupOnChangeDetail } from "@abgov/ui-components-common";
export const FilterDataInATable = () => {
const { version } = useContext(LanguageVersionContext);
+ const [selectedFilter, setSelectedFilter] = useState(null);
const [typedChips, setTypedChips] = useState([]);
const [inputValue, setInputValue] = useState("");
const [inputError, setInputError] = useState("");
@@ -63,6 +68,12 @@ export const FilterDataInATable = () => {
);
const [dataFiltered, setDataFiltered] = useState(data);
+ const target = (
+
+ Filter
+
+ );
+
const handleInputChange = (detail: GoabInputOnChangeDetail) => {
const newValue = detail.value.trim();
setInputValue(newValue);
@@ -103,31 +114,43 @@ export const FilterDataInATable = () => {
);
}, []);
+ function radioGroupOnChange(event: GoabRadioGroupOnChangeDetail) {
+ setSelectedFilter(event.value);
+ }
+
const getFilteredData = useCallback(
- (typedChips: string[]) => {
- if (typedChips.length === 0) {
- return data;
+ (typedChips: string[], selectedFilter: string | null) => {
+ let filteredData = data;
+
+ if (typedChips.length > 0) {
+ filteredData = filteredData.filter((item: any) =>
+ typedChips.every(chip => checkNested(item, chip))
+ );
+ }
+
+ if (selectedFilter) {
+ filteredData = filteredData.filter(
+ (item: any) => item.status && item.status.text === selectedFilter
+ );
}
- const filteredData = data.filter((item: object) =>
- typedChips.every(chip => checkNested(item, chip))
- );
return filteredData;
},
[checkNested, data]
);
+
useEffect(() => {
- setDataFiltered(getFilteredData(typedChips));
- }, [getFilteredData, typedChips]);
+ setDataFiltered(getFilteredData(typedChips, selectedFilter));
+ }, [getFilteredData, typedChips, selectedFilter]);
return (
// NOTE: Input onKeyPress functionality breaks when wrapped in Sandbox component
//
<>
-
-
+
+
{
onChange={handleInputChange}
onKeyPress={handleInputKeyPress}
/>
-
- Filter
-
+
+
+
+
- {typedChips.length > 0 && (
+ {(typedChips.length > 0 || selectedFilter) && (
-
+
Filter:
- {typedChips.length > 0 &&
- typedChips.map((typedChip, index) => (
- removeTypedChip(typedChip)}
- />
- ))}
- setTypedChips([])}>
- Clear all
-
+ {typedChips.map((typedChip, index) => (
+ removeTypedChip(typedChip)}
+ />
+ ))}
+ {selectedFilter && (
+ {
+ setSelectedFilter(null);
+ }}
+ />
+ )}
+ {(typedChips.length > 0 || selectedFilter) && (
+ {
+ setTypedChips([]);
+ setSelectedFilter(null);
+ }}>
+ Clear all
+
+ )}
)}
-
+
| Status |
@@ -198,102 +246,123 @@ export const FilterDataInATable = () => {
tags="angular"
allowCopy={true}
code={`
-export class TableComponent {
- typedChips: string[] = [];
- inputValue = "";
- inputError = "";
- readonly errorEmpty = "Empty filter";
- readonly errorDuplicate = "Enter a unique filter";
- readonly data = [
- {
- 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);
+ export class TablePopoverComponent {
+ typedChips: string[] = [];
- handleInputChange(event: Event): void {
- const newValue = (event.target as HTMLInputElement).value.trim();
- this.inputValue = newValue;
- }
+ inputValue = '';
+ inputError = '';
+ readonly errorEmpty = 'Empty filter';
+ readonly errorDuplicate = 'Enter a unique filter';
- handleInputKeyPress(event: KeyboardEvent): void {
- if (event.key === "Enter") {
- this.applyFilter();
- }
- }
+ // Radio filter state
+ selectedFilter: string | null = null;
- applyFilter() {
- 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);
- }
+ // Table data
+ popoverValues: PopoverValue[] = [
+ {
+ 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",
+ },
+ ];
- removeTypedChip(chip: string) {
- this.typedChips = this.typedChips.filter((c) => c !== chip);
- this.dataFiltered = this.getFilteredData(this.typedChips);
- this.inputError = "";
- }
+ get filteredData(): PopoverValue[] {
+ let filtered = this.popoverValues;
- removeAllTypedChips() {
- this.typedChips = [];
- this.dataFiltered = this.getFilteredData(this.typedChips);
- this.inputError = "";
- }
+ // Apply radio filter
+ if (this.selectedFilter) {
+ filtered = filtered.filter(item => item.status === this.selectedFilter);
+ }
- getFilteredData(typedChips: string[]) {
- if (typedChips.length === 0) {
- return this.data;
- }
- const filteredData = this.data.filter((item) =>
- typedChips.every((chip) => this.checkNested(item, chip)),
- );
- return filteredData;
- }
+ // Apply chip filters (all chips must match)
+ if (this.typedChips.length > 0) {
+ filtered = filtered.filter(item =>
+ this.typedChips.every(chip =>
+ Object.values(item).some(val =>
+ typeof val === 'string' && val.toLowerCase().includes(chip.toLowerCase())
+ )
+ )
+ );
+ }
- 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()),
- );
- }
-}
+ return filtered;
+ }
+
+ handleInputChange(event: any): void {
+ this.inputValue = event.target.value.trim();
+ }
+
+ handleInputKeyPress(event: KeyboardEvent): void {
+ if (event.key === 'Enter') {
+ this.applyFilter();
+ }
+ }
+
+ applyFilter() {
+ 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 = '';
+ }
+
+ removeTypedChip(chip: string) {
+ this.typedChips = this.typedChips.filter(c => c !== chip);
+ this.inputError = '';
+ }
+
+ removeAllTypedChips() {
+ this.typedChips = [];
+ this.inputError = '';
+ }
+
+ radioGroupOnChange(value: string) {
+ this.selectedFilter = value;
+ }
+
+ clearRadioFilter() {
+ this.selectedFilter = null;
+ }
+
+ 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()),
+ );
+ }
+ }
`}
/>
-
-
-
-
- Filter
-
-
-
-
- 0">
-
- Filter:
-
-
-
- Clear all
-
-
-
-
-
-
- | Status |
- Name |
- ID Number |
-
-
-
-
- |
-
- |
- {{ item.name }} |
- {{ item.id }} |
-
-
-
-
- 0">
- No results found
-
+
+
+
+
+
+
+
+
+ Filter
+
+
+
+
+ Filter
+
+
+
+
+ 0">
+
+ Filter:
+
+
+
+
+ Clear all
+
+
+
+
+
+
+ | Status |
+ Text |
+
+
+
+
+
+ |
+
+ |
+ Lorem ipsum |
+ {{ u.key }} |
+
+
+
+
+ 0">
+ No results found
+
`}
/>
([]);
- 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 GoABadgeType, text: "In progress" },
- name: "Ivan Schmidt",
- id: "7838576954",
- },
- {
- status: { type: "success" as GoABadgeType, text: "Completed" },
- name: "Luz Lakin",
- id: "8576953364",
- },
- {
- status: { type: "information" as GoABadgeType, text: "In progress" },
- name: "Keith McGlynn",
- id: "9846041345",
- },
- {
- status: { type: "success" as GoABadgeType, text: "Completed" },
- name: "Melody Frami",
- id: "7385256175",
- },
- {
- status: { type: "important" as GoABadgeType, text: "Updated" },
- name: "Frederick Skiles",
- id: "5807570418",
- },
- {
- status: { type: "success" as GoABadgeType, text: "Completed" },
- name: "Dana Pfannerstill",
- id: "5736306857",
- },
- ],
- [],
- );
- const [dataFiltered, setDataFiltered] = useState(data);
+ const [selectedFilter, setSelectedFilter] = useState(null);
+ const [typedChips, setTypedChips] = useState([]);
+ 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 GoABadgeType, text: "In progress" },
+ name: "Ivan Schmidt",
+ id: "7838576954",
+ },
+ {
+ status: { type: "success" as GoABadgeType, text: "Completed" },
+ name: "Luz Lakin",
+ id: "8576953364",
+ },
+ {
+ status: { type: "information" as GoABadgeType, text: "In progress" },
+ name: "Keith McGlynn",
+ id: "9846041345",
+ },
+ {
+ status: { type: "success" as GoABadgeType, text: "Completed" },
+ name: "Melody Frami",
+ id: "7385256175",
+ },
+ {
+ status: { type: "important" as GoABadgeType, text: "Updated" },
+ name: "Frederick Skiles",
+ id: "5807570418",
+ },
+ {
+ status: { type: "success" as GoABadgeType, text: "Completed" },
+ name: "Dana Pfannerstill",
+ id: "5736306857",
+ },
+ ],
+ [],
+ );
+ const [dataFiltered, setDataFiltered] = useState(data);
- const handleInputChange = (_name: string, value: string) => {
- const newValue = value.trim();
- setInputValue(newValue);
- };
+ const target = (
+
+ Filter
+
+ );
- const handleInputKeyPress = (_name: string, _value: string, key: string) => {
- if (key === "Enter") {
- applyFilter();
- }
- };
+ const handleInputChange = (_name: string, value: string) => {
+ const newValue = value.trim();
+ setInputValue(newValue);
+ };
- 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 handleInputKeyPress = (_name: string, _value: string, key: string) => {
+ if (key === "Enter") {
+ applyFilter();
+ }
+ };
- const removeTypedChip = (chip: string) => {
- setTypedChips(typedChips.filter((c) => c !== chip));
- setInputError("");
- };
+ 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 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 removeTypedChip = (chip: string) => {
+ setTypedChips(typedChips.filter((c) => c !== chip));
+ setInputError("");
+ };
- const getFilteredData = useCallback(
- (typedChips: string[]) => {
- if (typedChips.length === 0) {
- return data;
- }
- const filteredData = data.filter((item: object) =>
- typedChips.every((chip) => checkNested(item, chip)),
- );
+ 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()),
+ );
+ }, []);
- return filteredData;
- },
- [checkNested, data],
- );
+ const handleInputChange = (_name: string, value: string) => {
+ setSelectedFilter(value);
+ };
- useEffect(() => {
- setDataFiltered(getFilteredData(typedChips));
- }, [getFilteredData, typedChips]);
+ const getFilteredData = useCallback(
+ (typedChips: string[], selectedFilter: string | null) => {
+ let filteredData = data;
+
+ if (typedChips.length > 0) {
+ filteredData = filteredData.filter((item: any) =>
+ typedChips.every(chip => checkNested(item, chip))
+ );
+ }
+
+ if (selectedFilter) {
+ filteredData = filteredData.filter(
+ (item: any) => item.status && item.status.text === selectedFilter
+ );
+ }
+
+ return filteredData;
+ },
+ [checkNested, data]
+ );
+
+ useEffect(() => {
+ setDataFiltered(getFilteredData(typedChips, selectedFilter));
+ }, [getFilteredData, typedChips, selectedFilter]);
`}
/>
@@ -476,78 +583,96 @@ export class TableComponent {
tags="react"
allowCopy={true}
code={`
- <>
-
-
-
-
- Filter
-
-
-
-
- {typedChips.length > 0 && (
-
-
- Filter:
-
- {typedChips.length > 0 &&
- typedChips.map((typedChip, index) => (
- removeTypedChip(typedChip)}
- />
- ))}
- setTypedChips([])}
- >
- Clear all
-
-
- )}
+
+
+
+
+
+
+
+
+
+
-
-
-
- | Status |
- Name |
- ID Number |
-
-
-
- {dataFiltered.map((item) => (
-
- |
-
- |
- {item.name} |
- {item.id} |
-
- ))}
-
-
+ {(typedChips.length > 0 || selectedFilter) && (
+
+
+ Filter:
+
+ {typedChips.map((typedChip, index) => (
+ removeTypedChip(typedChip)}
+ />
+ ))}
+ {selectedFilter && (
+ {
+ setSelectedFilter(null);
+ }}
+ />
+ )}
+ {(typedChips.length > 0 || selectedFilter) && (
+ {
+ setTypedChips([]);
+ setSelectedFilter(null);
+ }}>
+ Clear all
+
+ )}
+
+ )}
- {dataFiltered.length === 0 && data.length > 0 && (
- No results found
- )}
- >
+
+
+
+ | Status |
+ Name |
+ ID Number |
+
+
+
+ {dataFiltered.map(item => (
+
+ |
+
+ |
+ {item.name} |
+ {item.id} |
+
+ ))}
+
+
+
+ {dataFiltered.length === 0 && data.length > 0 && (
+
+ No results found
+
+ )}
+
`}
/>
>
@@ -560,102 +685,125 @@ export class TableComponent {
tags="angular"
allowCopy={true}
code={`
-export class TableComponent {
- typedChips: string[] = [];
- inputValue = "";
- inputError = "";
- readonly errorEmpty = "Empty filter";
- readonly errorDuplicate = "Enter a unique filter";
- readonly data = [
- {
- 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",
- },
- ];
- dataFiltered = this.getFilteredData(this.typedChips);
+
+ export class TablePopoverComponent {
+ typedChips: string[] = [];
- handleInputChange(detail: GoabInputOnChangeDetail): void {
- const newValue = detail.value.trim();
- this.inputValue = newValue;
- }
+ inputValue = '';
+ inputError = '';
+ readonly errorEmpty = 'Empty filter';
+ readonly errorDuplicate = 'Enter a unique filter';
- handleInputKeyPress(detail: GoabInputOnKeyPressDetail): void {
- if (detail.key === "Enter") {
- this.applyFilter();
- }
- }
+ // Radio filter state
+ selectedFilter: string | null = null;
- applyFilter() {
- 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);
- }
+ // Table data
+ popoverValues: PopoverValue[] = [
+ {
+ 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",
+ },
+ ];
- removeTypedChip(chip: string) {
- this.typedChips = this.typedChips.filter((c) => c !== chip);
- this.dataFiltered = this.getFilteredData(this.typedChips);
- this.inputError = "";
- }
+ get filteredData(): PopoverValue[] {
+ let filtered = this.popoverValues;
- removeAllTypedChips() {
- this.typedChips = [];
- this.dataFiltered = this.getFilteredData(this.typedChips);
- this.inputError = "";
- }
+ // Apply radio filter
+ if (this.selectedFilter) {
+ filtered = filtered.filter(item => item.status === this.selectedFilter);
+ }
- getFilteredData(typedChips: string[]) {
- if (typedChips.length === 0) {
- return this.data;
- }
- const filteredData = this.data.filter((item) =>
- typedChips.every((chip) => this.checkNested(item, chip)),
- );
- return filteredData;
- }
+ // Apply chip filters (all chips must match)
+ if (this.typedChips.length > 0) {
+ filtered = filtered.filter(item =>
+ this.typedChips.every(chip =>
+ Object.values(item).some(val =>
+ typeof val === 'string' && val.toLowerCase().includes(chip.toLowerCase())
+ )
+ )
+ );
+ }
- 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()),
- );
- }
-}
+ return filtered;
+ }
+
+ handleInputChange(detail: GoabInputOnChangeDetail): void {
+ const newValue = detail.value.trim();
+ this.inputValue = newValue;
+ }
+
+ handleInputKeyPress(detail: GoabInputOnKeyPressDetail): void {
+ if (detail.key === "Enter") {
+ this.applyFilter();
+ }
+ }
+
+ applyFilter() {
+ 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 = '';
+ }
+
+ removeTypedChip(chip: string) {
+ this.typedChips = this.typedChips.filter(c => c !== chip);
+ this.inputError = '';
+ }
+
+ removeAllTypedChips() {
+ this.typedChips = [];
+ this.inputError = '';
+ }
+
+ radioGroupOnChange(event: GoabRadioGroupOnChangeDetail) {
+ this.selectedFilter = event.value;
+ }
+
+ clearRadioFilter() {
+ this.selectedFilter = null;
+ }
+
+ 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()),
+ );
+ }
+ }
`}
/>
-
-
-
-
- Filter
-
-
-
-
- 0">
-
- Filter:
-
-
-
- Clear all
-
-
-
-
-
-
- | Status |
- Name |
- ID Number |
-
-
-
-
- |
-
- |
- {{ item.name }} |
- {{ item.id }} |
-
-
-
-
- 0">
- No results found
-
+
+
+
+
+
+
+
+
+ Filter
+
+
+
+
+ Filter
+
+
+
+
+ 0">
+
+ Filter:
+
+
+
+
+ Clear all
+
+
+
+
+
+
+ | Status |
+ Text |
+
+
+
+
+
+ |
+
+ |
+ Lorem ipsum |
+ {{ u.key }} |
+
+
+
+
+ 0">
+ No results found
+
`}
/>
([]);
- 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 [selectedFilter, setSelectedFilter] = useState(null);
+ const [typedChips, setTypedChips] = useState([]);
+ 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 target = (
+
+ Filter
+
+ );
- const handleInputKeyPress = (detail: GoabInputOnKeyPressDetail) => {
- if (detail.key === "Enter") {
- applyFilter();
- }
- };
+ const handleInputChange = (detail: GoabInputOnChangeDetail) => {
+ const newValue = detail.value.trim();
+ setInputValue(newValue);
+ };
- 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 handleInputKeyPress = (detail: GoabInputOnKeyPressDetail) => {
+ if (detail.key === "Enter") {
+ applyFilter();
+ }
+ };
- const removeTypedChip = (chip: string) => {
- setTypedChips(typedChips.filter(c => c !== chip));
- setInputError("");
- };
+ 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 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 removeTypedChip = (chip: string) => {
+ setTypedChips(typedChips.filter(c => c !== chip));
+ setInputError("");
+ };
- const getFilteredData = useCallback(
- (typedChips: string[]) => {
- if (typedChips.length === 0) {
- return data;
- }
- const filteredData = data.filter((item: object) =>
- typedChips.every(chip => checkNested(item, chip))
- );
+ 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())
+ );
+ }, []);
- return filteredData;
- },
- [checkNested, data]
- );
+ function radioGroupOnChange(event: GoabRadioGroupOnChangeDetail) {
+ setSelectedFilter(event.value);
+ }
- useEffect(() => {
- setDataFiltered(getFilteredData(typedChips));
- }, [getFilteredData, typedChips]);
+ const getFilteredData = useCallback(
+ (typedChips: string[], selectedFilter: string | null) => {
+ let filteredData = data;
+
+ if (typedChips.length > 0) {
+ filteredData = filteredData.filter((item: any) =>
+ typedChips.every(chip => checkNested(item, chip))
+ );
+ }
+
+ if (selectedFilter) {
+ filteredData = filteredData.filter(
+ (item: any) => item.status && item.status.text === selectedFilter
+ );
+ }
+
+ return filteredData;
+ },
+ [checkNested, data]
+ );
+
+
+ useEffect(() => {
+ setDataFiltered(getFilteredData(typedChips, selectedFilter));
+ }, [getFilteredData, typedChips, selectedFilter]);
`}
/>
@@ -838,72 +1022,96 @@ export class TableComponent {
tags="react"
allowCopy={true}
code={`
- <>
-
-
-
-
- Filter
-
-
-
-
- {typedChips.length > 0 && (
-
-
- Filter:
-
- {typedChips.length > 0 &&
- typedChips.map((typedChip, index) => (
- removeTypedChip(typedChip)}
- />
- ))}
- setTypedChips([])}>
- Clear all
-
-
- )}
+
+
+
+
+
+
+
+
+
+
-
-
-
- | Status |
- Name |
- ID Number |
-
-
-
- {dataFiltered.map(item => (
-
- |
-
- |
- {item.name} |
- {item.id} |
-
- ))}
-
-
+ {(typedChips.length > 0 || selectedFilter) && (
+
+
+ Filter:
+
+ {typedChips.map((typedChip, index) => (
+ removeTypedChip(typedChip)}
+ />
+ ))}
+ {selectedFilter && (
+ {
+ setSelectedFilter(null);
+ }}
+ />
+ )}
+ {(typedChips.length > 0 || selectedFilter) && (
+ {
+ setTypedChips([]);
+ setSelectedFilter(null);
+ }}>
+ Clear all
+
+ )}
+
+ )}
- {dataFiltered.length === 0 && data.length > 0 && (
- No results found
- )}
- >
+
+
+
+ | Status |
+ Name |
+ ID Number |
+
+
+
+ {dataFiltered.map(item => (
+
+ |
+
+ |
+ {item.name} |
+ {item.id} |
+
+ ))}
+
+
+
+ {dataFiltered.length === 0 && data.length > 0 && (
+
+ No results found
+
+ )}
+
`}
/>
>
diff --git a/src/examples/tables/TablesExamples.tsx b/src/examples/tables/TablesExamples.tsx
index 6bdf55899..50bbb70f9 100644
--- a/src/examples/tables/TablesExamples.tsx
+++ b/src/examples/tables/TablesExamples.tsx
@@ -1,28 +1,29 @@
import SortDataInATable from "@examples/sort-data-in-a-table.tsx";
-import DisplayNumbersInATableSoTheyCanBeScannedEasily from "@examples/display-numbers-in-a-table-so-they-can-be-scanned-easily.tsx";
+import ZebraStripesInATable from "@examples/zebra-stripes-in-a-table.tsx";
import FilterDataInATable from "@examples/filter-data-in-a-table.tsx";
import { SandboxHeader } from "@components/sandbox/sandbox-header/sandboxHeader.tsx";
+import './tables-page-examples.css';
export const TablesExamples = () => {
return (
<>
+ exampleTitle="Table with filters"
+ figmaExample="https://www.figma.com/design/aIRjvBzpIUH0GbkffjbL04/%E2%9D%96-Patterns-library-%7C-DDD?node-id=7104-1626357&t=WrSJODVw0mryQrrA-4">
-
+
+ exampleTitle="Table with zebra stripes"
+ figmaExample="">
-
+
+ exampleTitle="Table with sortable columns"
+ figmaExample="https://www.figma.com/design/aIRjvBzpIUH0GbkffjbL04/%E2%9D%96-Patterns-library-%7C-DDD?node-id=6312-97462&t=X0IQW5flDDaj8Vyg-4">
-
+
>
);
};
diff --git a/src/examples/tables/tables-page-examples.css b/src/examples/tables/tables-page-examples.css
new file mode 100644
index 000000000..d34b17df1
--- /dev/null
+++ b/src/examples/tables/tables-page-examples.css
@@ -0,0 +1,3 @@
+.goa-table-zebra-stripes > tr:nth-child(even) {
+ background-color: var(--goa-color-greyscale-50);
+}
diff --git a/src/examples/zebra-stripes-in-a-table.tsx b/src/examples/zebra-stripes-in-a-table.tsx
new file mode 100644
index 000000000..806c602f7
--- /dev/null
+++ b/src/examples/zebra-stripes-in-a-table.tsx
@@ -0,0 +1,88 @@
+import {
+ GoabButton,
+ GoabBadge,
+ GoabTable
+} from "@abgov/react-components";
+import type {
+ GoabBadgeType,
+} from "@abgov/ui-components-common";
+import { Sandbox } from "@components/sandbox";
+import { CodeSnippet } from "@components/code-snippet/CodeSnippet.tsx";
+
+export const ZebraStripesInATable = () => {
+ const filteredData = [
+ {
+ status: { type: "information" as GoabBadgeType, text: "In progress" },
+ name: "Ivan Schmidt",
+ id: "76954",
+ },
+ {
+ status: { type: "success" as GoabBadgeType, text: "Completed" },
+ name: "Luz Lakin",
+ id: "53364",
+ },
+ {
+ status: { type: "information" as GoabBadgeType, text: "In progress" },
+ name: "Keith McGlynn",
+ id: "41345",
+ },
+ {
+ status: { type: "success" as GoabBadgeType, text: "Completed" },
+ name: "Melody Frami",
+ id: "56175",
+ },
+ {
+ status: { type: "important" as GoabBadgeType, text: "Updated" },
+ name: "Frederick Skiles",
+ id: "70418",
+ },
+ {
+ status: { type: "success" as GoabBadgeType, text: "Completed" },
+ name: "Dana Pfannerstill",
+ id: "06857",
+ },
+ ];
+
+ return (
+ <>
+
+ {/*CSS Code Snippet*/}
+ tr:nth-child(even) {
+ background-color: var(--goa-color-greyscale-50);
+ }
+ `}
+ />
+
+
+
+ | Status |
+ Assigned to |
+ Number |
+ Actions |
+
+
+
+ {filteredData.map((item) => (
+
+ |
+
+ |
+ {item.name} |
+ {item.id} |
+
+ Action
+ |
+
+ ))}
+
+
+
+ >
+ );
+};
+
+export default ZebraStripesInATable;