diff --git a/package-lock.json b/package-lock.json
index 29c14b951..9ad951bc5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,9 +8,9 @@
"name": "code-sandbox",
"version": "0.0.0",
"dependencies": {
- "@abgov/react-components": "6.8.0-alpha.3",
- "@abgov/ui-components-common": "1.8.0-alpha.3",
- "@abgov/web-components": "1.38.0-alpha.5",
+ "@abgov/react-components": "6.9.0-alpha.2",
+ "@abgov/ui-components-common": "1.9.0-alpha.1",
+ "@abgov/web-components": "1.39.0-alpha.2",
"@faker-js/faker": "^8.3.1",
"highlight.js": "^11.8.0",
"js-cookie": "^3.0.5",
@@ -68,9 +68,9 @@
}
},
"node_modules/@abgov/react-components": {
- "version": "6.8.0-alpha.3",
- "resolved": "https://registry.npmjs.org/@abgov/react-components/-/react-components-6.8.0-alpha.3.tgz",
- "integrity": "sha512-BMEMhhJiNF/QaVHXG4yCO/fQaLUy6d7nYZS0h6cKFHCeCmd5ZZVpuZI3E/wdWDO1HgZH+HLpNtUyi7G7BpYfkA==",
+ "version": "6.9.0-alpha.2",
+ "resolved": "https://registry.npmjs.org/@abgov/react-components/-/react-components-6.9.0-alpha.2.tgz",
+ "integrity": "sha512-mBlGM/u/wsHLTPpZxiVhdES9Ra+Hj6JaVGzQuWm3JI+Jqz5wwCRLeGzLZD03fAlfnEhMshXpPuKtQxphVLQNPg==",
"peerDependencies": {
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
@@ -78,14 +78,14 @@
}
},
"node_modules/@abgov/ui-components-common": {
- "version": "1.8.0-alpha.3",
- "resolved": "https://registry.npmjs.org/@abgov/ui-components-common/-/ui-components-common-1.8.0-alpha.3.tgz",
- "integrity": "sha512-RW53rqOfP0gd8W2OoWOZnj8U8Q5L4KL9V2staZswqm+O7D3AXQUAslmXImGUPd922Xn8hkPNzDEq1CPuoAcaXw=="
+ "version": "1.9.0-alpha.1",
+ "resolved": "https://registry.npmjs.org/@abgov/ui-components-common/-/ui-components-common-1.9.0-alpha.1.tgz",
+ "integrity": "sha512-5ZSV7XuVJ+NMNCJd9LTQzAGwLERGUig/L1WlIn+1n0OOxonYo4df4jhinj2VyJRQ/XiNYa1vYlh59NRlAyu8pg=="
},
"node_modules/@abgov/web-components": {
- "version": "1.38.0-alpha.5",
- "resolved": "https://registry.npmjs.org/@abgov/web-components/-/web-components-1.38.0-alpha.5.tgz",
- "integrity": "sha512-YqVXvd8KkCc/oy2rcfiuL89RB0kJ+x/y94vm0azPLL1iKyhw1xCQBIXhJIkeGeEcLGZHUNYGV2DIPupHHOnb5Q=="
+ "version": "1.39.0-alpha.2",
+ "resolved": "https://registry.npmjs.org/@abgov/web-components/-/web-components-1.39.0-alpha.2.tgz",
+ "integrity": "sha512-eY66yYlJTkqoDDQWj6p0rcywcjvwExa6mDJoBpVwp325Guki10l59xUeC78WwYaVTFZP7nmTB1OXKuV3+Vnkhg=="
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.21.5",
diff --git a/package.json b/package.json
index 6feeb98df..c4e5befb4 100644
--- a/package.json
+++ b/package.json
@@ -12,9 +12,9 @@
"prettier": "npx prettier . --write"
},
"dependencies": {
- "@abgov/react-components": "6.8.0-alpha.3",
- "@abgov/ui-components-common": "1.8.0-alpha.3",
- "@abgov/web-components": "1.38.0-alpha.5",
+ "@abgov/react-components": "6.9.0-alpha.2",
+ "@abgov/ui-components-common": "1.9.0-alpha.1",
+ "@abgov/web-components": "1.39.0-alpha.2",
"@faker-js/faker": "^8.3.1",
"highlight.js": "^11.8.0",
"js-cookie": "^3.0.5",
diff --git a/src/examples/app-header/AppHeaderExamples.tsx b/src/examples/app-header/AppHeaderExamples.tsx
index 160267ff8..8bafb11e0 100644
--- a/src/examples/app-header/AppHeaderExamples.tsx
+++ b/src/examples/app-header/AppHeaderExamples.tsx
@@ -1,5 +1,7 @@
import { HeaderWithNavigation } from "@examples/header-with-navigation.tsx";
import { HeaderWithMenuClickEvent } from "@examples/header-with-menu-click-event.tsx";
+import { HeaderSignIn } from "@examples/header-with-sign-in.tsx";
+import { HeaderLoggedInMenu } from "@examples/header-logged-in-menu.tsx";
import { SandboxHeader } from "@components/sandbox/sandbox-header/sandboxHeader.tsx";
export const AppHeaderExamples = () => {
@@ -16,6 +18,18 @@ export const AppHeaderExamples = () => {
figmaExample="">
+
+
+
+
+
+
+
+
>
);
};
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/header-logged-in-menu.tsx b/src/examples/header-logged-in-menu.tsx
new file mode 100644
index 000000000..fa8bea433
--- /dev/null
+++ b/src/examples/header-logged-in-menu.tsx
@@ -0,0 +1,126 @@
+import { Sandbox } from "@components/sandbox";
+import { CodeSnippet } from "@components/code-snippet/CodeSnippet.tsx";
+import { GoabAppHeader, GoabAppHeaderMenu, GoabMicrositeHeader } from "@abgov/react-components";
+import { useContext } from "react";
+import { LanguageVersionContext } from "@contexts/LanguageVersionContext.tsx";
+
+export const HeaderLoggedInMenu = () => {
+ const {version} = useContext(LanguageVersionContext);
+ return (
+
+
+
+ Services
+
+ Manage account
+ Request new staff account
+ System admin
+ Sign out
+
+
+
+ {version === "old" && (
+
+
+ Services
+
+ Manage account
+ Request new staff account
+ System admin
+ Sign out
+
+
+ `}
+ />
+ )}
+
+ {version === "new" && (
+
+
+ Services
+
+ Manage account
+ Request new staff account
+ System admin
+ Sign out
+
+
+ `}
+ />
+ )}
+
+ {version === "old" && (
+
+
+ Services
+
+ Manage account
+ Request new staff account
+ System admin
+ Sign out
+
+
+ `}
+ />
+ )}
+ {version === "new" && (
+
+
+ Services
+
+ Manage account
+ Request new staff account
+ System admin
+ Sign out
+
+
+ `}
+ />
+ )}
+
+ )
+}
+
+export default HeaderLoggedInMenu;
diff --git a/src/examples/header-with-sign-in.tsx b/src/examples/header-with-sign-in.tsx
new file mode 100644
index 000000000..db671ea77
--- /dev/null
+++ b/src/examples/header-with-sign-in.tsx
@@ -0,0 +1,94 @@
+import { Sandbox } from "@components/sandbox";
+import { CodeSnippet } from "@components/code-snippet/CodeSnippet.tsx";
+import { GoabAppHeader, GoabMicrositeHeader } from "@abgov/react-components";
+import { useContext } from "react";
+import { LanguageVersionContext } from "@contexts/LanguageVersionContext.tsx";
+
+export const HeaderSignIn = () => {
+ const {version} = useContext(LanguageVersionContext);
+ return (
+
+
+
+ Sign in
+
+
+ {version === "old" && (
+
+
+ Sign in
+
+ `}
+ />
+ )}
+
+ {version === "new" && (
+
+
+ Sign in
+
+ `}
+ />
+ )}
+
+ {version === "old" && (
+
+
+ Sign in
+
+ `}
+ />
+ )}
+ {version === "new" && (
+
+
+ Sign in
+
+ `}
+ />
+ )}
+
+ )
+}
+
+export default HeaderSignIn;
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;
diff --git a/src/global-constants.ts b/src/global-constants.ts
index a5c6ac850..79fbc368e 100644
--- a/src/global-constants.ts
+++ b/src/global-constants.ts
@@ -1,5 +1,5 @@
export const MAX_CONTENT_WIDTH = "1440px";
-export const DEFAULT_VERSION = "old";
+export const DEFAULT_VERSION = "new";
export const DEFAULT_LANGUAGE = "react";
// Array of 'New' components
diff --git a/src/routes/components/AppHeader.tsx b/src/routes/components/AppHeader.tsx
index dcb0ea00c..0818fb92d 100644
--- a/src/routes/components/AppHeader.tsx
+++ b/src/routes/components/AppHeader.tsx
@@ -231,7 +231,7 @@ export default function AppHeaderPage() {
heading={
<>
Examples
-
+
>
}
>
diff --git a/src/routes/components/Dropdown.tsx b/src/routes/components/Dropdown.tsx
index af111a26a..da729e00e 100644
--- a/src/routes/components/Dropdown.tsx
+++ b/src/routes/components/Dropdown.tsx
@@ -1,4 +1,4 @@
-import { useContext, useState } from "react";
+import { useContext, useEffect, useState } from "react";
import {
GoabBadge,
GoabDropdown,
@@ -81,16 +81,43 @@ export default function DropdownPage() {
name: "width",
value: "",
},
+ {
+ label: "Max width",
+ type: "string",
+ name: "maxWidth",
+ value: "",
+ hidden: version === "old", // Hide in LTS (old) version
+ },
{ label: "Disabled", type: "boolean", name: "disabled", value: false },
{ label: "Error", type: "boolean", name: "error", value: false },
{ label: "Native", type: "boolean", name: "native", value: false },
{ label: "Filterable", type: "boolean", name: "filterable", value: false },
{ label: "ARIA label", type: "string", name: "ariaLabel", value: "" },
]);
+
const { formItemBindings, formItemProps, onFormItemChange } = useSandboxFormItem({
label: "Basic dropdown",
});
+ // Hide the maxWidth control and remove the prop when LTS version is selected
+ useEffect(() => {
+ setDropdownBindings(prev =>
+ prev.map(b => {
+ if (b.name === "maxWidth" && b.type === "string") {
+ return { ...b, hidden: version === "old", value: version === "old" ? "" : b.value };
+ }
+ return b;
+ })
+ );
+
+ if (version === "old") {
+ setDropdownProps(prev => {
+ const { maxWidth, ...rest } = prev as unknown as Record;
+ return rest as ComponentPropsType;
+ });
+ }
+ }, [version]);
+
const oldDropdownProperties: ComponentProperty[] = [
{
name: "name",
@@ -252,6 +279,11 @@ export default function DropdownPage() {
type: "string",
description: "Overrides the autosized menu width. Non-native only.",
},
+ {
+ name: "maxWidth",
+ type: "string",
+ description: "Maximum width of the dropdown. Non-native only.",
+ },
{
name: "disabled",
type: "boolean",
diff --git a/src/routes/components/MenuButton.tsx b/src/routes/components/MenuButton.tsx
index 199c44601..70218b81e 100644
--- a/src/routes/components/MenuButton.tsx
+++ b/src/routes/components/MenuButton.tsx
@@ -7,6 +7,7 @@ import {
GoabTab,
GoabTabs,
} from "@abgov/react-components";
+import { GoabMenuButtonOnActionDetail } from "@abgov/ui-components-common";
import { Category, ComponentHeader } from "@components/component-header/ComponentHeader.tsx";
import { ComponentContent } from "@components/component-content/ComponentContent";
import {
@@ -82,7 +83,7 @@ export default function MenuButtonPage() {
TestIdProperty,
{
name: "onAction",
- type: "(action: string) => void",
+ type: "(detail: GoabMenuButtonOnActionDetail) => void",
description:
"Callback fired when a menu action is selected. Receives the action identifier from the clicked item.",
},
@@ -118,8 +119,8 @@ export default function MenuButtonPage() {
setMenuButtonProps(props as CastingType);
}
- function handleAction(action: string) {
- console.log("Last action: ", action);
+ function handleAction(detail: GoabMenuButtonOnActionDetail) {
+ console.log("Last action: ", detail.action);
}
return (
diff --git a/src/routes/components/TextArea.tsx b/src/routes/components/TextArea.tsx
index f737f4eea..3d18a5eb2 100644
--- a/src/routes/components/TextArea.tsx
+++ b/src/routes/components/TextArea.tsx
@@ -1,4 +1,4 @@
-import { useContext, useState } from "react";
+import { useContext, useEffect, useState } from "react";
import { ComponentBinding, Sandbox } from "@components/sandbox";
import {
ComponentProperties,
@@ -88,6 +88,13 @@ export default function TextAreaPage() {
name: "maxCount",
type: "number",
},
+ {
+ label: "Max width",
+ name: "maxWidth",
+ type: "string",
+ value: "",
+ hidden: version === "old", // Hide in LTS (old) version
+ },
{
name: "value",
type: "string",
@@ -97,10 +104,30 @@ export default function TextAreaPage() {
label: "Value",
},
]);
+
const { formItemBindings, formItemProps, onFormItemChange } = useSandboxFormItem({
label: "Basic",
});
+ // Hide the maxWidth control and remove the prop when LTS version is selected
+ useEffect(() => {
+ setTextAreaBindings(prev =>
+ prev.map(b => {
+ if (b.name === "maxWidth" && b.type === "string") {
+ return { ...b, hidden: version === "old", value: version === "old" ? "" : b.value };
+ }
+ return b;
+ })
+ );
+
+ if (version === "old") {
+ setComponentProps(prev => {
+ const { maxWidth, ...rest } = prev as unknown as Record;
+ return rest as CastingType;
+ });
+ }
+ }, [version]);
+
const oldComponentProperties: ComponentProperty[] = [
{
name: "name",
@@ -328,6 +355,11 @@ export default function TextAreaPage() {
type: "(event: GoabTextAreaOnKeyPressDetail) => void",
description: "Function invoked when a key is pressed",
},
+ {
+ name: "onBlur",
+ type: "(event: GoabTextAreaOnBlurDetail) => void",
+ description: "Callback when the textarea loses focus",
+ },
MarginProperty,
];
diff --git a/src/routes/components/Tooltip.tsx b/src/routes/components/Tooltip.tsx
index 8a1997568..1b1f35838 100644
--- a/src/routes/components/Tooltip.tsx
+++ b/src/routes/components/Tooltip.tsx
@@ -1,6 +1,6 @@
import { Category, ComponentHeader } from "@components/component-header/ComponentHeader.tsx";
import { ComponentBinding, Sandbox } from "@components/sandbox";
-import { useState } from "react";
+import { useContext, useEffect, useState } from "react";
import {
ComponentProperties,
ComponentProperty,
@@ -23,6 +23,7 @@ import {
import { TooltipExamples } from "@examples/tooltip/TooltipExamples.tsx";
import { DesignEmpty } from "@components/empty-states/design-empty/DesignEmpty.tsx";
import { AccessibilityEmpty } from "@components/empty-states/accessibility-empty/AccessibilityEmpty.tsx";
+import { LanguageVersionContext } from "@contexts/LanguageVersionContext.tsx";
// == Page props ==
@@ -42,6 +43,7 @@ type CastingType = {
};
export default function TooltipPage() {
+ const { version } = useContext(LanguageVersionContext);
const [componentProps, setComponentProps] = useState({
content: "Tooltip",
@@ -68,8 +70,36 @@ export default function TooltipPage() {
options: ["left", "center", "right"],
value: "",
},
+ {
+ label: "Max width",
+ type: "string",
+ name: "maxWidth",
+ value: "",
+ hidden: version === "old", // ensure hidden on initial render when LTS selected
+ },
]);
+ // Hide the maxWidth control and remove the prop when LTS version is selected
+ useEffect(() => {
+ // Toggle the visibility of the Max width binding
+ setComponentBindings(prev =>
+ prev.map(b => {
+ if (b.name === "maxWidth" && b.type === "string") {
+ return { ...b, hidden: version === "old", value: version === "old" ? "" : b.value };
+ }
+ return b;
+ })
+ );
+
+ // Ensure the component props do not include maxWidth when LTS is selected
+ if (version === "old") {
+ setComponentProps(prev => {
+ const { maxWidth, ...rest } = prev as Record;
+ return rest as ComponentPropsType;
+ });
+ }
+ }, [version]);
+
const oldComponentProperties: ComponentProperty[] = [
{
name: "content",
@@ -122,6 +152,11 @@ export default function TooltipPage() {
description: "Horizontal alignment to the child element",
defaultValue: "center",
},
+ {
+ name: "maxWidth",
+ type: "string",
+ description: "Maximum width of the tooltip",
+ },
TestIdProperty,
MarginProperty
];
@@ -143,7 +178,6 @@ export default function TooltipPage() {
/>
-
Playground