-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: Create palette from JSON file (resolves #1) #2
Changes from all commits
43ba41e
2485833
f1ac9e0
9542e87
808b7d8
47ab98c
3906b19
25ab172
98aecfb
a1a318d
7a2c857
126de89
d3db085
3592783
ea5e80c
a0080ca
a58d0fb
58ed03d
43eafe7
77c240e
6be1737
fc594f6
1088f9e
6a32931
4b05f39
fd3f054
0b54137
fdb3d67
8b7f61d
f2b4048
0639ece
406d52f
cb4afb8
3cbdbee
278a67e
bc98779
106fb01
7900134
380dd91
b398c6b
0a97b2a
f5e7136
da78a8b
36f197e
2819b29
8118cd7
0c73c0d
d75020b
4c20fcd
eeb4e77
e252bea
7dfdf63
184498a
8038d14
dd57a24
d0d5237
cabf34d
352ce6c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Developer Documentation | ||
|
||
## How to render a palette | ||
|
||
`Palette.ts` constructs a palette based on a JSON file that contains a list | ||
of the cells in the palette. An example is found in | ||
[`src/keyboards/bmw_palette.json`](../src/keyboards/bmw_palette.json). The | ||
`cells` object is the list of all of the cells. Each cell has a `type` key and | ||
an `options` key. The `type` value indicates which Preact component should be | ||
used to render this cell. The `options` contains information to be passed to the | ||
component. | ||
|
||
## How to add a new cell type | ||
|
||
When a new `type` value is introduced, developers need to: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it clearer to add a h2 title "How to add a new cell type" to the section starting from this line to the end of the document? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay. |
||
|
||
1. Create a new component to render the new cell type; | ||
2. In `GlobalData.ts`, update `cellTypeRegistry` to add the entry that maps the | ||
new type value to the actual component. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,17 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<meta name="color-scheme" content="light dark" /> | ||
<title>Adaptive Palette</title> | ||
</head> | ||
<body> | ||
<div id="app"></div> | ||
</body> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<meta name="color-scheme" content="light dark" /> | ||
<title>Adaptive Palette</title> | ||
</head> | ||
<body> | ||
<h2>Palette Based on JSON</h1> | ||
<div id="bmwKeyCodes"> | ||
<script type="module"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do think about the idea that moves the javascript in this <script> tag to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've moved the code. |
||
import "./src/index.js"; | ||
</script> | ||
</div> | ||
</body> | ||
</html> |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* Copyright 2023 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 | ||
*/ | ||
|
||
// There is an issue requesting the additions adding the fetch API to jest-dom | ||
// for testing with node. Node.js Core has had an implementation of the fetch | ||
// API since v17.5. However, jest-dom removes it. This comment in the issue | ||
// suggests using whatwg's version of fetch() instead: | ||
// https://github.com/jsdom/jsdom/issues/1724#issuecomment-720727999 | ||
|
||
import { fetch } from "whatwg-fetch"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you happen to have the solution article about using this npm package to fix the use of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. I have added a comment/link. |
||
|
||
module.exports = { | ||
globals: { | ||
fetch: fetch | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* Copyright 2023 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 | ||
*/ | ||
|
||
.actionBmwCodeCell { | ||
border: 2px solid blue; | ||
background-color: gray; | ||
border-radius: 5px; | ||
padding: 1rem; | ||
font-size: 1rem; | ||
text-align: center; | ||
|
||
&:hover, &:focus { | ||
background-color: lightblue; | ||
color: #0000aa; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright 2023 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 { ActionBmwCodeCell } from "./ActionBmwCodeCell"; | ||
|
||
describe("ActionBmwCodeDell render tests", () => { | ||
|
||
const TEST_CELL_ID = "uuid-of-some-kind"; | ||
const testCell = { | ||
options: { | ||
"label": "Bliss Language", | ||
"rowStart": "3", | ||
"rowSpan": "2", | ||
"columnStart": "2", | ||
"columnSpan": "1", | ||
"bciAvId": [ 12335, "/", 8499 ] // VERB+EN | ||
} | ||
}; | ||
|
||
beforeAll(async () => { | ||
await initAdaptivePaletteGlobals(); | ||
}); | ||
|
||
test("Single ActionBmwCodeCell rendering", async () => { | ||
|
||
render(html` | ||
<${ActionBmwCodeCell} | ||
id="${TEST_CELL_ID}" | ||
options=${testCell.options} | ||
/>` | ||
); | ||
|
||
// Check the rendered cell | ||
const button = await screen.findByRole("button", {name: testCell.options.label}); | ||
|
||
// Check that the ActionBmwCodeCell/button is rendered and has the correct | ||
// attributes and text. | ||
expect(button).toBeVisible(); | ||
expect(button).toBeValid(); | ||
expect(button.id).toBe(TEST_CELL_ID); | ||
expect(button.getAttribute("class")).toBe("actionBmwCodeCell"); | ||
expect(button.textContent).toBe(testCell.options.label); | ||
|
||
// Check the grid cell styles. | ||
expect(button.style["grid-column"]).toBe("2 / span 1"); | ||
expect(button.style["grid-row"]).toBe("3 / span 2"); | ||
|
||
// Check disabled state (should be enabled) | ||
expect(button.getAttribute("disabled")).toBe(null); | ||
}); | ||
|
||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* Copyright 2023 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 { html } from "htm/preact"; | ||
import { OptionsType } from "./index.d"; | ||
import { BlissSymbol } from "./BlissSymbol"; | ||
import "./ActionBmwCodeCell.scss"; | ||
|
||
|
||
type ActionBmwCodeCellPropsType = { | ||
id: string, | ||
options: OptionsType | ||
}; | ||
|
||
export function ActionBmwCodeCell (props: ActionBmwCodeCellPropsType) { | ||
const { | ||
columnStart, columnSpan, rowStart, rowSpan, bciAvId, label | ||
} = props.options; | ||
|
||
const gridStyles = ` | ||
grid-column: ${columnStart} / span ${columnSpan}; | ||
grid-row: ${rowStart} / span ${rowSpan}; | ||
`; | ||
|
||
return html` | ||
<button id="${props.id}" class="actionBmwCodeCell" style="${gridStyles}" > | ||
<${BlissSymbol} | ||
bciAvId=${bciAvId} | ||
label=${label} | ||
isPresentation=true | ||
/> | ||
</button> | ||
`; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* | ||
* Copyright 2023 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 { BlissSymbol, GRAPHIC_ROLE } from "./BlissSymbol"; | ||
|
||
describe("BlissSymbol render tests", () => { | ||
const singleBciAvId = { | ||
bciAvId: 12335, | ||
label: "VERB" | ||
}; | ||
|
||
const arrayBciAvId = { | ||
bciAvId: [12335, "/", 8499], | ||
label: "VERB+S" | ||
}; | ||
Comment on lines
+20
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be clearer to split this test into two sections or two tests, one for testing the number bciAvId and the other for testing the array bciAvId. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, done. |
||
|
||
const MOCK_LABEL_ID = "mockLabelId"; | ||
const UNKNOWN_BCI_AV_ID = -1; | ||
|
||
beforeAll(async () => { | ||
await initAdaptivePaletteGlobals(); | ||
}); | ||
|
||
test(`BlissSymbol defined by a single BCI_AV_ID (${singleBciAvId.label})`, async () => { | ||
render(html` | ||
<${BlissSymbol} | ||
bciAvId="${singleBciAvId.bciAvId}" | ||
label="${singleBciAvId.label}" | ||
isPresentation=true | ||
/>` | ||
); | ||
const blissSymbolLabelDiv = await screen.findByText(singleBciAvId.label); | ||
expect(blissSymbolLabelDiv).toBeVisible(); | ||
expect(blissSymbolLabelDiv).toBeValid(); | ||
|
||
// Expect an <svg ...> element as the only sibling | ||
const parentChildren = blissSymbolLabelDiv.parentNode.childNodes; | ||
expect(parentChildren.length).toBe(2); | ||
expect(parentChildren[0].nodeName).toBe("svg"); | ||
}); | ||
|
||
test("BlissSymbol when the SVG is unknown", async () => { | ||
render(html` | ||
<${BlissSymbol} | ||
bciAvId="${UNKNOWN_BCI_AV_ID}" | ||
label="${arrayBciAvId.label}" | ||
isPresentation=true | ||
/>` | ||
); | ||
const blissSymbolLabelDiv = await screen.findByText(arrayBciAvId.label); | ||
const svgElement = blissSymbolLabelDiv.parentNode.querySelector("svg"); | ||
const parentChildren = blissSymbolLabelDiv.parentNode.childNodes; | ||
expect(parentChildren.length).toBe(1); | ||
expect(svgElement).toBe(null); | ||
}); | ||
|
||
test(`BlissSymbol defined by an of BCI_AV_IDs (${arrayBciAvId.label})`, async () => { | ||
render(html` | ||
<${BlissSymbol} | ||
bciAvId="${arrayBciAvId.bciAvId}" | ||
label="${arrayBciAvId.label}" | ||
isPresentation=true | ||
/>` | ||
); | ||
const blissSymbolLabelDiv = await screen.findByText(arrayBciAvId.label); | ||
expect(blissSymbolLabelDiv).toBeVisible(); | ||
expect(blissSymbolLabelDiv).toBeValid(); | ||
const parentChildren = blissSymbolLabelDiv.parentNode.childNodes; | ||
expect(parentChildren.length).toBe(2); | ||
expect(parentChildren[0].nodeName).toBe("svg"); | ||
}); | ||
|
||
test("BlissSymbol aria: when svg has no role)", async () => { | ||
render(html` | ||
<${BlissSymbol} | ||
bciAvId="${arrayBciAvId.bciAvId}" | ||
label="${arrayBciAvId.label}" | ||
isPresentation=true | ||
/>` | ||
); | ||
const blissSymbolLabelDiv = await screen.findByText(arrayBciAvId.label); | ||
const svgElement = blissSymbolLabelDiv.parentNode.querySelector("svg"); | ||
expect(svgElement.getAttribute("aria-hidden")).toBe("true"); | ||
expect(svgElement.getAttribute("role")).toBe(null); | ||
expect(svgElement.getAttribute("aria-labelledby")).toBe(null); | ||
}); | ||
|
||
test("BlissSymbol aria: when svg has a graphic role)", async () => { | ||
render(html` | ||
<${BlissSymbol} | ||
bciAvId="${arrayBciAvId.bciAvId}" | ||
label="${arrayBciAvId.label}" | ||
isPresentation=false | ||
labelledBy=${MOCK_LABEL_ID} | ||
/>` | ||
); | ||
const blissSymbolLabelDiv = await screen.findByText(arrayBciAvId.label); | ||
const svgElement = blissSymbolLabelDiv.parentNode.querySelector("svg"); | ||
expect(svgElement.getAttribute("role")).toBe(GRAPHIC_ROLE); | ||
expect(svgElement.getAttribute("aria-labelledby")).toBe(MOCK_LABEL_ID); | ||
expect(svgElement.getAttribute("aria-hidden")).toBe(null); | ||
}); | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"An example is found ..." -> "An example can be found ..."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The active voice is preferable to the passive. The use of "can be" is passive. It might be better to say, "An example is available ...".