+
+
+
diff --git a/public/palettes/bliss_strategies.json b/public/palettes/bliss_strategies.json
new file mode 100644
index 0000000..c77da4d
--- /dev/null
+++ b/public/palettes/bliss_strategies.json
@@ -0,0 +1,203 @@
+{
+ "name": "Bliss Strategies",
+ "cells": {
+ "bliss-strategies-7c33c282-4103-4c1e-a872-e97ebd6468ea": {
+ "type": "LabelCell",
+ "options": {
+ "label": "Bliss Strategies",
+ "bciAvId": 23031,
+ "rowStart": 1,
+ "rowSpan": 1,
+ "columnStart": 1,
+ "columnSpan": 9
+ }
+ },
+ "abstract-37848ed0-cbff-450b-bb55-f91a0d1bebb0": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "abstract",
+ "bciAvId": 27001,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 1,
+ "columnSpan": 1
+ }
+ },
+ "answer-b7ed0181-bd57-4389-b2f1-b65baf09822d": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "answer",
+ "bciAvId": 12393,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 2,
+ "columnSpan": 1
+ }
+ },
+ "belongs-with-2cd58e48-1a85-4acf-bc70-1c509c346cdd": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "belongs with",
+ "bciAvId": [12663, ";", 8993],
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 3,
+ "columnSpan": 1
+ }
+ },
+ "combine-indicator-4b96fbf1-37fb-41e5-a5b5-05097e158e33": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "combine (indicator)",
+ "bciAvId": 13382,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 4,
+ "columnSpan": 1
+ }
+ },
+ "command-025a1cd8-73d9-4fff-bb83-f4664a7e1b8c": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "command",
+ "bciAvId": 8483,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 5,
+ "columnSpan": 1
+ }
+ },
+ "generalization-af769fa5-09d7-4e63-bf2e-d6e08fdcd446": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "generalization",
+ "bciAvId": 14430,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 6,
+ "columnSpan": 1
+ }
+ },
+ "group-of-3097898d-fa15-41cc-8848-af26d001e92e": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "group of",
+ "bciAvId": 14647,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 7,
+ "columnSpan": 1
+ }
+ },
+ "intensity-25f26791-580b-425e-8a16-3fc5b4bbc7d1": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "intensity",
+ "bciAvId": 14947,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 8,
+ "columnSpan": 1
+ }
+ },
+ "metaphor-94eddd4b-9e86-4f87-a80e-2b3254cd0426": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "metaphor",
+ "bciAvId": 15460,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 9,
+ "columnSpan": 1
+ }
+ },
+ "not-94eddd4b-9e86-4f87-a80e-2b3254cd0426": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "not",
+ "bciAvId": 15733,
+ "rowStart": 3,
+ "rowSpan": 1,
+ "columnStart": 1,
+ "columnSpan": 1
+ }
+ },
+ "opposite-a13f5d63-c4bb-4080-b256-add0a5171739": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "opposite",
+ "bciAvId": 15927,
+ "rowStart": 3,
+ "rowSpan": 1,
+ "columnStart": 2,
+ "columnSpan": 1
+ }
+ },
+ "meaning-d0c38fc5-6f27-4aec-9e0e-46a3a5e2c12f": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "meaning",
+ "bciAvId": 15441,
+ "rowStart": 3,
+ "rowSpan": 1,
+ "columnStart": 3,
+ "columnSpan": 1
+ }
+ },
+ "rhymes-with-4f8a3e5b-ddbd-42a3-ba37-b00aa8923df7": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "rhymes (with)",
+ "bciAvId": [16502, ";", 8993],
+ "rowStart": 3,
+ "rowSpan": 1,
+ "columnStart": 4,
+ "columnSpan": 1
+ }
+ },
+ "same-0dac5ebd-9fdb-4aa8-a80b-ed607e43a445": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "same",
+ "bciAvId": 25368,
+ "rowStart": 3,
+ "rowSpan": 1,
+ "columnStart": 5,
+ "columnSpan": 1
+ }
+ },
+ "similar-sound-8481d07c-cbbf-4a9c-acdd-d7de99ee05b4": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "similar sound",
+ "bciAvId": 16986,
+ "rowStart": 3,
+ "rowSpan": 1,
+ "columnStart": 6,
+ "columnSpan": 1
+ }
+ },
+ "similar-to-6005ae50-b518-4a2a-9106-0f48b8b3453c": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "similar (to)",
+ "bciAvId": 16984,
+ "rowStart": 3,
+ "rowSpan": 1,
+ "columnStart": 7,
+ "columnSpan": 1
+ }
+ },
+ "type-31efeefe-5d7a-471b-bcc0-1bc311699328": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "type",
+ "bciAvId": 17961,
+ "rowStart": 3,
+ "rowSpan": 1,
+ "columnStart": 8,
+ "columnSpan": 1
+ }
+ }
+ }
+}
diff --git a/public/palettes/grammar_strategies.json b/public/palettes/grammar_strategies.json
new file mode 100644
index 0000000..35d7c35
--- /dev/null
+++ b/public/palettes/grammar_strategies.json
@@ -0,0 +1,71 @@
+{
+ "name": "Grammar Strategies",
+ "cells": {
+ "grammar-strategies-56f542cf-0b58-4713-84d1-4772170e43f2": {
+ "type": "LabelCell",
+ "options": {
+ "label": "Grammar Strategies",
+ "bciAvId": 27060,
+ "rowStart": 1,
+ "rowSpan": 1,
+ "columnStart": 1,
+ "columnSpan": 5
+ }
+ },
+ "adjective-ab6e667a-807f-42f6-80aa-10d69582389b": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "adjective",
+ "bciAvId": 27002,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 1,
+ "columnSpan": 1
+ }
+ },
+ "adverb-d67d8cdd-eb28-4a88-99fb-1da2da4b91db": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "adverb",
+ "bciAvId": 27003,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 2,
+ "columnSpan": 1
+ }
+ },
+ "noun-a8e94a5b-e87e-4129-8d36-2b1eb126b422": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "noun",
+ "bciAvId": 27096,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 3,
+ "columnSpan": 1
+ }
+ },
+ "plural-a843e08e-b92a-4e51-bbe9-24d8f9694fd0": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "plural",
+ "bciAvId": 9011,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 4,
+ "columnSpan": 1
+ }
+ },
+ "verb-8ae2dfb4-f95e-4a37-9f9c-f18dff198dbc": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "verb",
+ "bciAvId": 27152,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 5,
+ "columnSpan": 1
+ }
+ }
+ }
+}
diff --git a/public/palettes/palette_file_map.json b/public/palettes/palette_file_map.json
index 24c54a1..03a8f4c 100644
--- a/public/palettes/palette_file_map.json
+++ b/public/palettes/palette_file_map.json
@@ -2,5 +2,9 @@
"My Family Palette": "/palettes/myfamily.json",
"People": "/palettes/people.json",
"BMW Palette": "/palettes/bmw_palette.json",
- "Palettes": "/palettes/palettes.json"
+ "Palettes": "/palettes/palettes.json",
+ "Strategies": "/palettes/strategies.json",
+ "Grammar Strategies": "/palettes/grammar_strategies.json",
+ "Search Strategies": "/palettes/search_strategies.json",
+ "Bliss Strategies": "/palettes/bliss_strategies.json"
}
diff --git a/public/palettes/search_strategies.json b/public/palettes/search_strategies.json
new file mode 100644
index 0000000..463885b
--- /dev/null
+++ b/public/palettes/search_strategies.json
@@ -0,0 +1,51 @@
+{
+ "name": "Search Strategies",
+ "cells": {
+ "search-strategies-4a922731-9781-4ab5-a645-4176d6d8edb9": {
+ "type": "LabelCell",
+ "options": {
+ "label": "Search Strategies",
+ "bciAvId": 16742,
+ "rowStart": 1,
+ "rowSpan": 1,
+ "columnStart": 1,
+ "columnSpan": 3
+ }
+ },
+ "word-that-means-4a922731-9781-4ab5-a645-4176d6d8edb9": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "Word that means",
+ "bciAvId": [18272, "/", 16482 , "/", 15441, ";", 8999, ";", 9004 ],
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 1,
+ "columnSpan": 1
+ }
+ },
+ "minspeak-personal-associations-622a33f2-b598-47ed-a6e2-6a5466859ccc": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "Minspeak personal associations",
+ "bciAvId": [16752, ";", 8998, "/", 12663, "/", 13380, ";", 9011 ],
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 2,
+ "columnSpan": 1
+ }
+ },
+ "personal-conventions-792c9146-309c-45ef-a645-026c69d0aa50": {
+ "type": "ActionBmwCodeCell",
+ "options": {
+ "label": "Personal conventions",
+ "bciAvId": [
+ 16752, ";", 8998, "/", 12663, "/", 13382, "/", 12334, ";", 9011, "/", 12354, "/", 13382
+ ],
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 3,
+ "columnSpan": 1
+ }
+ }
+ }
+}
diff --git a/public/palettes/strategies.json b/public/palettes/strategies.json
new file mode 100644
index 0000000..1d4ac6c
--- /dev/null
+++ b/public/palettes/strategies.json
@@ -0,0 +1,88 @@
+{
+ "name": "Strategies",
+ "cells": {
+ "strategies-label-6057d056-db6a-4f73-8259-0d28566e7388": {
+ "type": "LabelCell",
+ "options": {
+ "label": "Strategy",
+ "bciAvId": 25814,
+ "rowStart": 1,
+ "rowSpan": 1,
+ "columnStart": 1,
+ "columnSpan": 6
+ }
+ },
+ "bliss-37863659-0289-4c4d-a88f-e33e6582f565": {
+ "type": "ActionBranchToPaletteCell",
+ "options": {
+ "label": "Bliss strategies",
+ "branchTo": "Bliss Strategies",
+ "bciAvId": 23031,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 1,
+ "columnSpan": 1
+ }
+ },
+ "grammar-a9c75796-b5e0-43ca-8822-04d05e8a1309": {
+ "type": "ActionBranchToPaletteCell",
+ "options": {
+ "label": "Grammar strategies",
+ "branchTo": "Grammar Strategies",
+ "bciAvId": 27060,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 2,
+ "columnSpan": 1
+ }
+ },
+ "search-529841cf-3370-4365-b04e-ac88b0f0d5f2": {
+ "type": "ActionBranchToPaletteCell",
+ "options": {
+ "label": "Search strategies",
+ "branchTo": "Search Strategies",
+ "bciAvId": 16742,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 3,
+ "columnSpan": 1
+ }
+ },
+ "augment-14de9078-6f8d-489e-ac6e-27cee440722d": {
+ "type": "ActionBranchToPaletteCell",
+ "options": {
+ "label": "Augment with pictures",
+ "branchTo": "Augmentative Strategies",
+ "bciAvId": [29003, "/", 18267, "/", 16172, ";", 9011],
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 4,
+ "columnSpan": 1
+ }
+ },
+ "personal-a9cbb381-ad44-4af0-a24c-515fc5587b9d": {
+ "type": "ActionBranchToPaletteCell",
+ "options": {
+ "label": "Personal conventions",
+ "branchTo": "Personal Strategies",
+ "bciAvId": 16445,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 5,
+ "columnSpan": 1
+ }
+ },
+ "personal2-a9cbb381-ad44-4af0-a24c-515fc5587b9d": {
+ "type": "ActionBranchToPaletteCell",
+ "options": {
+ "label": "Personal conventions 2",
+ "branchTo": "Personal Strategies 2",
+ "bciAvId": 16445,
+ "rowStart": 2,
+ "rowSpan": 1,
+ "columnStart": 6,
+ "columnSpan": 1
+ }
+ }
+ }
+}
diff --git a/src/client/ActionBranchToPaletteCell.ts b/src/client/ActionBranchToPaletteCell.ts
index 4f1dd77..8b4d426 100644
--- a/src/client/ActionBranchToPaletteCell.ts
+++ b/src/client/ActionBranchToPaletteCell.ts
@@ -33,13 +33,15 @@ const navigateToPalette = async (event: Event): Promise => {
const button = event.currentTarget as HTMLElement;
speak(button.innerText);
+ const buttonsPaletteName = button.parentElement.getAttribute("data-palettename");
const branchToPaletteName = button.getAttribute("data-branchto");
const paletteDefinition = await paletteStore.getNamedPalette(branchToPaletteName, loadPaletteFromJsonFile);
if (paletteDefinition) {
const displayElement = button.parentElement.parentElement;
- navigationStack.push(navigationStack.currentPalette);
+ const goBackPalette = await paletteStore.getNamedPalette(buttonsPaletteName);
+ navigationStack.push({ palette: goBackPalette, htmlElement: displayElement });
render (html`<${Palette} json=${paletteDefinition}/>`, displayElement);
- navigationStack.currentPalette = paletteDefinition;
+ navigationStack.currentPalette = { palette: paletteDefinition, htmlElement: displayElement };
}
else {
console.error(`navigateToPalette(): Unable to locate the palette definition for ${branchToPaletteName}`);
diff --git a/src/client/CommandGoBackCell.test.ts b/src/client/CommandGoBackCell.test.ts
index 2e1f001..b089dd7 100644
--- a/src/client/CommandGoBackCell.test.ts
+++ b/src/client/CommandGoBackCell.test.ts
@@ -13,14 +13,12 @@ import { render, screen } from "@testing-library/preact";
import "@testing-library/jest-dom";
import { html } from "htm/preact";
-import { initAdaptivePaletteGlobals, adaptivePaletteGlobals } from "./GlobalData";
+import { initAdaptivePaletteGlobals } from "./GlobalData";
import { CommandGoBackCell } from "./CommandGoBackCell";
describe("CommandGoBackCell render tests", (): void => {
const TEST_CELL1_ID = "uuid-of-some-kind";
- const TEST_CELL2_ID = "uuid-of-another-kind";
- const TEST_CONTROL_ID = "non-empty-id";
const goBackCell = {
options: {
"label": "Back Up",
@@ -31,25 +29,12 @@ describe("CommandGoBackCell render tests", (): void => {
"bciAvId": 12612
}
};
- const goBackCell2 = {
- options: {
- "label": "Back Up non-empty aria-controls",
- "rowStart": "3",
- "rowSpan": "2",
- "columnStart": "2",
- "columnSpan": "1",
- "bciAvId": 12612
- }
- };
beforeAll(async () => {
- // Note: no id provided for the element that palettes are rendered inside.
- // The `aria-controls` attribute of the test CommandGoBackCell should be
- // the empty string, at first.
await initAdaptivePaletteGlobals();
});
- test("CommandGoBackCell rendering, empty aria-controls", async (): Promise => {
+ test("CommandGoBackCell rendering", async (): Promise => {
render(html`
<${CommandGoBackCell}
@@ -68,7 +53,6 @@ describe("CommandGoBackCell render tests", (): void => {
expect(button.id).toBe(TEST_CELL1_ID);
expect(button.getAttribute("class")).toBe("btn-command");
expect(button.textContent).toBe(goBackCell.options.label);
- expect(button.getAttribute("aria-controls")).toBe("");
// Check the grid cell styles.
expect(button.style["grid-column"]).toBe("2 / span 1");
@@ -77,19 +61,4 @@ describe("CommandGoBackCell render tests", (): void => {
// Check disabled state (should be enabled)
expect(button.getAttribute("disabled")).toBe(null);
});
-
- test("CommandGoBackCell rendering with non-empty aria-controls", async(): Promise => {
- // Give the main palette rendering area a non-empty id.
- adaptivePaletteGlobals.mainPaletteContainerId = TEST_CONTROL_ID;
- render(html`
- <${CommandGoBackCell}
- id="${TEST_CELL2_ID}"
- options=${goBackCell2.options}
- />`
- );
-
- const button = await screen.findByRole("button", {name: goBackCell2.options.label});
- expect(button.id).toBe(TEST_CELL2_ID);
- expect(button.getAttribute("aria-controls")).toBe(TEST_CONTROL_ID);
- });
});
diff --git a/src/client/CommandGoBackCell.ts b/src/client/CommandGoBackCell.ts
index 1e96dad..a6a6e87 100644
--- a/src/client/CommandGoBackCell.ts
+++ b/src/client/CommandGoBackCell.ts
@@ -34,15 +34,15 @@ const goBackToPalette = async (event: Event): Promise => {
speak(button.innerText);
const paletteToGoBackTo = navigationStack.peek();
- if (paletteToGoBackTo) {
- const paletteDefinition = await paletteStore.getNamedPalette(paletteToGoBackTo.name, loadPaletteFromJsonFile);
+ if (paletteToGoBackTo && paletteToGoBackTo.palette) {
+ const paletteDefinition = await paletteStore.getNamedPalette(paletteToGoBackTo.palette.name, loadPaletteFromJsonFile);
if (paletteDefinition) {
- const paletteContainer = document.getElementById(button.getAttribute("aria-controls")) || document.body;
- navigationStack.popAndSetCurrent(paletteDefinition);
+ const paletteContainer = paletteToGoBackTo.htmlElement || document.body;
+ navigationStack.popAndSetCurrent(paletteToGoBackTo);
render (html`<${Palette} json=${paletteDefinition}/>`, paletteContainer);
}
else {
- console.error(`goBackToPalette(): Unable to locate the palette definition for ${paletteToGoBackTo}`);
+ console.error(`goBackToPalette(): Unable to locate the palette definition for ${paletteToGoBackTo.palette.name}`);
}
}
};
@@ -52,7 +52,6 @@ export function CommandGoBackCell (props: CommandGoBackCellPropsType): VNode {
const {
columnStart, columnSpan, rowStart, rowSpan, bciAvId, label
} = props.options;
- const ariaControlsId = adaptivePaletteGlobals.mainPaletteContainerId;
const gridStyles = `
grid-column: ${columnStart} / span ${columnSpan};
@@ -62,7 +61,7 @@ export function CommandGoBackCell (props: CommandGoBackCellPropsType): VNode {
return html`
`;
diff --git a/src/client/GlobalData.ts b/src/client/GlobalData.ts
index cdd2181..a2f75da 100644
--- a/src/client/GlobalData.ts
+++ b/src/client/GlobalData.ts
@@ -24,6 +24,7 @@ import { CommandGoBackCell } from "./CommandGoBackCell";
import { ContentBmwEncoding } from "./ContentBmwEncoding";
import { CommandClearEncoding } from "./CommandClearEncoding";
import { CommandDelLastEncoding } from "./CommandDelLastEncoding";
+import { LabelCell } from "./LabelCell";
import { PaletteStore } from "./PaletteStore";
import { NavigationStack } from "./NavigationStack";
@@ -33,7 +34,8 @@ export const cellTypeRegistry = {
"CommandGoBackCell": CommandGoBackCell,
"ContentBmwEncoding": ContentBmwEncoding,
"CommandClearEncoding": CommandClearEncoding,
- "CommandDelLastEncoding": CommandDelLastEncoding
+ "CommandDelLastEncoding": CommandDelLastEncoding,
+ "LabelCell": LabelCell
};
/**
diff --git a/src/client/LabelCell.scss b/src/client/LabelCell.scss
new file mode 100644
index 0000000..0ac9a1e
--- /dev/null
+++ b/src/client/LabelCell.scss
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2024 Inclusive Design Research Centre, OCAD University
+ * All rights reserved.
+ *
+ * Licensed under the New BSD license. You may not use this file except in
+ * compliance with this License.
+ *
+ * You may obtain a copy of the License at
+ * https://github.com/inclusive-design/adaptive-palette/blob/main/LICENSE
+ */
+
+.labelCell {
+ border: 2px solid blue;
+ background-color: lightgrey;
+ padding-inline: 0.5rem;
+ text-align: center;
+}
diff --git a/src/client/LabelCell.test.ts b/src/client/LabelCell.test.ts
new file mode 100644
index 0000000..9e3eadd
--- /dev/null
+++ b/src/client/LabelCell.test.ts
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2024 Inclusive Design Research Centre, OCAD University
+ * All rights reserved.
+ *
+ * Licensed under the New BSD license. You may not use this file except in
+ * compliance with this License.
+ *
+ * You may obtain a copy of the License at
+ * https://github.com/inclusive-design/adaptive-palette/blob/main/LICENSE
+ */
+
+import { render, screen } from "@testing-library/preact";
+import "@testing-library/jest-dom";
+import { html } from "htm/preact";
+
+import { initAdaptivePaletteGlobals } from "./GlobalData";
+import { LabelCell } from "./LabelCell";
+
+describe("LabelCell render tests", (): void => {
+
+ const LABEL_CELL_ID = "uuid-of-label-element";
+ const testLabelCell = {
+ options: {
+ "label": "Verbs",
+ "rowStart": "3",
+ "rowSpan": "2",
+ "columnStart": "2",
+ "columnSpan": "1",
+ "bciAvId": [ 12335, ";", 9011 ] // Verb with plural indicator
+ }
+ };
+
+ beforeAll(async (): Promise => {
+ await initAdaptivePaletteGlobals();
+ });
+
+ test("Label cell rendering", async (): Promise => {
+
+ render(html`
+ <${LabelCell}
+ id=${LABEL_CELL_ID}
+ options=${testLabelCell.options}
+ />`
+ );
+
+ // Check the rendered cell
+ const labelElement = await screen.findByText(testLabelCell.options.label);
+
+ // Check that the LabelCell/labelElement is rendered and has the correct
+ // attributes and text.
+ expect(labelElement).toBeVisible();
+ expect(labelElement).toBeValid();
+ expect(labelElement.id).toBe(LABEL_CELL_ID);
+ expect(labelElement.getAttribute("class")).toBe("labelCell");
+
+ // Check the grid cell styles.
+ expect(labelElement.style["grid-column"]).toBe("2 / span 1");
+ expect(labelElement.style["grid-row"]).toBe("3 / span 2");
+ });
+});
diff --git a/src/client/LabelCell.ts b/src/client/LabelCell.ts
new file mode 100644
index 0000000..c1be822
--- /dev/null
+++ b/src/client/LabelCell.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2024 Inclusive Design Research Centre, OCAD University
+ * All rights reserved.
+ *
+ * Licensed under the New BSD license. You may not use this file except in
+ * compliance with this License.
+ *
+ * You may obtain a copy of the License at
+ * https://github.com/inclusive-design/adaptive-palette/blob/main/LICENSE
+ */
+
+import { VNode } from "preact";
+import { html } from "htm/preact";
+import { BlissSymbolInfoType, LayoutInfoType } from "./index.d";
+import { generateGridStyle } from "./GlobalUtils";
+import { BlissSymbol } from "./BlissSymbol";
+import "./LabelCell.scss";
+
+type LabelCellPropsType = {
+ id: string,
+ options: BlissSymbolInfoType & LayoutInfoType
+};
+
+export function LabelCell (props: LabelCellPropsType): VNode {
+
+ const {
+ columnStart, columnSpan, rowStart, rowSpan, bciAvId, label
+ } = props.options;
+
+ const gridStyles = generateGridStyle(columnStart, columnSpan, rowStart, rowSpan);
+ return html`
+
+ `;
+}
diff --git a/src/client/NavigationStack.test.ts b/src/client/NavigationStack.test.ts
index 79b5eee..8c0a897 100644
--- a/src/client/NavigationStack.test.ts
+++ b/src/client/NavigationStack.test.ts
@@ -9,8 +9,14 @@
* https://github.com/inclusive-design/adaptive-palette/blob/main/LICENSE
*/
+import { render, screen } from "@testing-library/preact";
+import "@testing-library/jest-dom";
+import { html } from "htm/preact";
+
import { NavigationStack } from "./NavigationStack";
+const RENDERING_TEST_ID = "renderingDiv";
+
const testPalette1 = {
"name": "testPalette1",
"cells": {
@@ -56,9 +62,16 @@ const testPalette2 = {
}
};
+
describe("NavigationStack module - basics", (): void => {
const navigation = new NavigationStack();
+ let renderingElement;
+
+ beforeAll(async (): Promise => {
+ render(html` => {
+ render(html`;
+ navigateBackStack: Array;
// The current palette in the palette display area
- currPalette: JsonPaletteType;
+ currPalette: NavStackItemType;
/**
* Initialize the navigation stack to have zero entries.
@@ -38,12 +38,13 @@ export class NavigationStack {
}
/**
- * Puah a palette onto the top of the navigation stack.
- * @param: {JsonPaletteType} palette - The palette to push. If `null` or
+ * Puah a palette onto the top of the navigation stack and also remember where
+ * it was rendered.
+ * @param: {NavStackItemType} palette - The palette to push. If `null` or
* `undefined`, the navigation stack is
* left untouched.
*/
- push (palette: JsonPaletteType): void {
+ push (palette: NavStackItemType): void {
if (!palette) {
return;
}
@@ -53,10 +54,10 @@ export class NavigationStack {
/**
* Pop and return the most recently pushed palette from the top of the
* navigation stack.
- * @return {JsonPaletteType} - reference to the popped palette; null if the
- * stack is empty.
+ * @return {NavStackItemType} - reference to the popped palette; null if the
+ * stack is empty.
*/
- pop (): JsonPaletteType | null {
+ pop (): NavStackItemType | null {
if (this.isEmpty()) {
return null;
} else {
@@ -65,18 +66,18 @@ export class NavigationStack {
}
/**
- * Return the palette at the top of the stack without changing the stack
+ * Return the stack item at the top of the stack without changing the stack
* itself. If an index is given, the palette at that index is returned. Note
* that an index of zero denotes the top of the stack.
* @param {integer} stackIndex - Optional: How far down the stack to peek,
* where zero is the top of the stack (default).
* If out of range, `undefined` is returned.
- * @return {JsonPaletteType} - Reference to the palette at the top of the
- * stack or at the given index; `undefined` if
- * the given stack index is invalid -- negative or
- * greater than the size of the stack.
+ * @return {NavStackItemType} - Reference to the palette at the top of the
+ * stack or at the given index; `undefined` if
+ * the given stack index is invalid -- negative
+ * or greater than the size of the stack.
*/
- peek (stackIndex:number = 0): JsonPaletteType | undefined {
+ peek (stackIndex:number = 0): NavStackItemType | undefined {
// Flip the index value since Array.push() puts the item at the end
// of the array.
let palette = undefined;
@@ -88,11 +89,11 @@ export class NavigationStack {
}
/**
- * Return the palette at the bottom of the stack without changing the stack.
- * @return {JsonPaletteType} - Reference to the palette at the bottom of the
- * stack, or `undefined` if the stack is empty.
+ * Return the stack item at the bottom of the stack without changing the stack.
+ * @return {NavStackItemType} - Reference to the palette at the bottom of the
+ * stack, or `undefined` if the stack is empty.
*/
- peekLast (): JsonPaletteType | undefined {
+ peekLast (): NavStackItemType | undefined {
if (this.isEmpty()) {
return undefined;
} else {
@@ -103,37 +104,37 @@ export class NavigationStack {
/**
* Pop/return the most recently pushed palette and set the currently displayed
* palette to the given one.
- * @param {JsonPaletteType} - The palette that is currently displayed, or
- * is about to be displayed.
- * @return {JsonPaletteType} - The most recently visited palette.
+ * @param {NavStackItemType} - The palette that is currently displayed, or
+ * is about to be displayed.
+ * @return {NavStackItemType} - The most recently visited palette.
*/
- popAndSetCurrent (currentPalette: JsonPaletteType): JsonPaletteType | null {
+ popAndSetCurrent (currentPalette: NavStackItemType): NavStackItemType | null {
this.currentPalette = currentPalette;
return this.pop();
}
/**
* Empty the navigation stack and reset the current palette displayed.
- * @param {JsonPaletteType} - The palette that is currently displayed.
+ * @param {NavStackItemType} - The palette that is currently displayed.
*/
- flushReset (currentPalette: JsonPaletteType): void {
+ flushReset (currentPalette: NavStackItemType): void {
this.currentPalette = currentPalette;
this.navigateBackStack.length = 0;
}
/**
* Accessor for setting the currently displayed palette.
- * @param: {JsonPaletteType} - the intended current palette.
+ * @param: {NavStackItemType} - the intended current palette.
*/
- set currentPalette (palette: JsonPaletteType) {
+ set currentPalette (palette: NavStackItemType) {
this.currPalette = palette;
}
/**
* Accessor for getting the currently displayed palette.
- * @return: {JsonPaletteType} - The current palette.
+ * @return: {NavStackItemType} - The current palette.
*/
- get currentPalette(): JsonPaletteType {
+ get currentPalette(): NavStackItemType {
return this.currPalette;
}
}
diff --git a/src/client/Palette.integration.test.ts b/src/client/Palette.integration.test.ts
index e322f83..247108c 100644
--- a/src/client/Palette.integration.test.ts
+++ b/src/client/Palette.integration.test.ts
@@ -158,7 +158,7 @@ describe("Palette integration test", () => {
// insure that the entire palette is in the DOM.
render(html`<${Palette} json=${testPalette}/>`);
const navStack = adaptivePaletteGlobals.navigationStack;
- navStack.currentPalette = testPalette;
+ navStack.currentPalette = { palette: testPalette, htmlElement: document.body };
const firstCell = await screen.findByText("First Cell");
expect(firstCell).toBeInTheDocument();
@@ -198,18 +198,22 @@ describe("Palette integration test", () => {
fireEvent.click(clearButton);
expect(contentArea.childNodes.length).toBe(0);
- // Trigger forward navigation
- const goForwardButton = await screen.findByText("Go To");
+ // Trigger forward navigation.
+ // Note: the element whose text is "Go To" is actually a
Rendering div
`);
+ renderingElement = await screen.findByTestId(RENDERING_TEST_ID);
+ });
test("Empty NavigationStack", (): void => {
expect(navigation.isEmpty()).toBe(true);
@@ -66,76 +79,90 @@ describe("NavigationStack module - basics", (): void => {
});
test("Current palette accessors", (): void => {
- navigation.currentPalette = testPalette1;
- expect(navigation.currentPalette).toBe(testPalette1);
+ const testStackItem1 = {
+ palette: testPalette1,
+ htmlElement: renderingElement
+ };
+ navigation.currentPalette = testStackItem1;
+ expect(navigation.currentPalette).toBe(testStackItem1);
navigation.currentPalette = null;
expect(navigation.currentPalette).toBe(null);
});
test("Flush and reset the navigation stack", (): void => {
- navigation.flushReset(testPalette2);
+ const testStackItem2 = {
+ palette: testPalette2,
+ htmlElement: renderingElement
+ };
+ navigation.flushReset(testStackItem2);
expect(navigation.isEmpty()).toBe(true);
- expect(navigation.currentPalette).toBe(testPalette2);
+ expect(navigation.currentPalette).toBe(testStackItem2);
});
});
describe("NavigationStack module - pushing and popping", (): void => {
const navigation = new NavigationStack();
+ let renderingElement, testStackItem1, testStackItem2;
- beforeEach ((): void => {
- navigation.flushReset(null);
+ beforeAll(async (): PromiseRendering div
`);
+ renderingElement = await screen.findByTestId(RENDERING_TEST_ID);
+ testStackItem1 = { palette: testPalette1, htmlElement: renderingElement };
+ testStackItem2 = { palette: testPalette2, htmlElement: renderingElement };
});
test("Non-empty NavigationStack", (): void => {
- navigation.push(testPalette1);
+ navigation.push(testStackItem1);
expect(navigation.isEmpty()).toBe(false);
- expect(navigation.peek()).toBe(testPalette1);
+ expect(navigation.peek()).toBe(testStackItem1);
expect(navigation.currentPalette).toBe(null);
});
test("Pop the top of the stack", (): void => {
- navigation.push(testPalette1);
+ navigation.flushReset(null);
+ navigation.push(testStackItem1);
const topPalette = navigation.pop();
- expect(topPalette).toBe(testPalette1);
+ expect(topPalette).toBe(testStackItem1);
expect(navigation.isEmpty()).toBe(true);
// The current palette should be unaffected by a pop operation.
expect(navigation.currentPalette).toBe(null);
});
test("Multiple layers and a current palette", (): void => {
- navigation.push(testPalette1);
- navigation.push(testPalette2);
- navigation.currentPalette = testPalette1;
+ navigation.push(testStackItem1);
+ navigation.push(testStackItem2);
+ navigation.currentPalette = testStackItem1;
expect(navigation.isEmpty()).toBe(false);
- expect(navigation.peek()).toBe(testPalette2);
- expect(navigation.peek(1)).toBe(testPalette1);
- expect(navigation.currentPalette).toBe(testPalette1);
+ expect(navigation.peek()).toBe(testStackItem2);
+ expect(navigation.peek(1)).toBe(testStackItem1);
+ expect(navigation.currentPalette).toBe(testStackItem1);
});
test("Check invalid peek()", (): void => {
- navigation.push(testPalette1);
- navigation.push(testPalette2);
+ navigation.push(testStackItem1);
+ navigation.push(testStackItem2);
expect(navigation.isEmpty()).toBe(false);
expect(navigation.peek(-1)).toBe(undefined);
expect(navigation.peek(1024)).toBe(undefined);
});
test("Check pop and set current utility function", (): void => {
- navigation.currentPalette = testPalette1;
- navigation.push(testPalette1);
- navigation.push(testPalette2);
- const poppedPalette = navigation.popAndSetCurrent(testPalette2);
- expect(poppedPalette).toBe(testPalette2);
- expect(navigation.peek()).toBe(testPalette1);
- expect(navigation.currentPalette).toBe(testPalette2);
+ navigation.currentPalette = testStackItem1;
+ navigation.push(testStackItem1);
+ navigation.push(testStackItem2);
+ const poppedPalette = navigation.popAndSetCurrent(testStackItem2);
+ expect(poppedPalette).toBe(testStackItem2);
+ expect(navigation.peek()).toBe(testStackItem1);
+ expect(navigation.currentPalette).toBe(testStackItem2);
});
test("Check peeking at the bottom of the stack", (): void => {
+ navigation.flushReset(null);
expect(navigation.isEmpty()).toBe(true);
expect(navigation.peekLast()).toBe(undefined);
- navigation.push(testPalette1);
- navigation.push(testPalette2);
- expect(navigation.peekLast()).toBe(testPalette1);
+ navigation.push(testStackItem1);
+ navigation.push(testStackItem2);
+ expect(navigation.peekLast()).toBe(testStackItem1);
});
});
diff --git a/src/client/NavigationStack.ts b/src/client/NavigationStack.ts
index a75eda9..51c2386 100644
--- a/src/client/NavigationStack.ts
+++ b/src/client/NavigationStack.ts
@@ -9,17 +9,17 @@
* https://github.com/inclusive-design/adaptive-palette/blob/main/LICENSE
*/
-import { JsonPaletteType } from "./index.d";
+import { NavStackItemType } from "./index.d";
export class NavigationStack {
// The actual stack keeping track of where the user was. The top-most palette
// is the most recent one the user was at before navigating to a new
// layer/palette.
- navigateBackStack: Array within the
+ //