Skip to content
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: basic implementation for navigation among palette layers (resolves #5) #6

Merged
merged 39 commits into from
Mar 14, 2024

Conversation

klown
Copy link
Contributor

@klown klown commented Feb 15, 2024

This basic implementation uses a stack to keep track of the palette layers that the user has chosen. When a user activates a cell that leads to another layer, the palette containing the activated "go-to-layer" cell is pushed onto the stack. Whenever the user activates a "go-back" cell, the palette at top of the stack is popped off and navigated to.

klown added 27 commits October 30, 2023 16:09
Also, clean up index.html and move most of the functionality to index.js.
- renamed `ActionBranchToPalette` component to` ActionBranchToPaletteCell`,
- adjusted file names, code, and palette json files as apprppriate for
  the name change.
Copy link

netlify bot commented Feb 15, 2024

Deploy Preview for adaptive-palette ready!

Name Link
🔨 Latest commit 2e4c520
🔍 Latest deploy log https://app.netlify.com/sites/adaptive-palette/deploys/65f0a9a7df7bd20008b7b5f8
😎 Deploy Preview https://deploy-preview-6--adaptive-palette.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

import { initAdaptivePaletteGlobals } from "./GlobalData";
import { ActionBranchToPaletteCell } from "./ActionBranchToPaletteCell";

describe("ActionBranchToPaletteCell render tests", () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to also test the click event of the ActionBranchToPaletteCell that leads to the rendering of the palette at the next layer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and I decided that the best place to do that is in Palette.integration.test since the go-to button affects other areas of the screen and involves other objects.

import { initAdaptivePaletteGlobals } from "./GlobalData";
import { CommandGoBackCell } from "./CommandGoBackCell";

describe("ActionBmwCodeDell render tests", () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to test the click event of the go back button. Since this test involves paletteStore and navigationStack, it may fit better in the integration test file Palette.integration.test.ts?

The same idea applies in the comment above about testing the click event for ActionBranchToPaletteCell.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above with the ActionBranchToPaletteCell, the go-back button test is in Palette.integration.test.

Comment on lines 21 to 22
// TODO: this is identical to `ActionBmwCodeCellPropsType`. Should it be?
type ActionBranchToPalettePropsType = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking if we should expand the options section for every type component as this part is not defined and verified by typescript. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, and will start work on it next. I also noticed that we don't define the return type of many of our functions. Should we?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a great idea to define the return type for functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done them all. The one that was problematic was the return type for the htm() template function used by all of the component Functions. I thought htm returned a string type, but it does not. Its return type is something like TemplateStringsArray, but when I looked into the project's repository, I found issue #73, Question: How well does this work with TypeScript?. The main answer is given in the first response: "there aren't typings for htm / html, but there are extremely basic types for the react and preact integrations." The rest of the discussion is about TypeScript's effort to support a tagged template type. That work is ongoing.

I did some more debugging and it looks like, in the case of Preact, the htm return type is VNode, or "virtual DOM node". I'm currently using that for the return type.

As for the expanding the options, I'm still working on that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking if we should expand the options section for every type component as this part is not defined and verified by typescript. What do you think?

For "expanding the options section", I took the full BlissSymbolCellType and created new types from its parts. Since these are not palette cell types, I used "Info" in their type names; for example, a LayoutInfoType that contains only the grid-styles information. Then, one can define cell types by combining the info types as needed.

Let me know what you think.

* @return {JsonPaletteType} - The palette itself, or `null` if it could not be
* loaded.
*/
export async function importPaletteFromJsonFile (jsonFile: string, path: string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this function better belong to GlobalUtils.ts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that makes sense. I moved it there.


/**
* Return the palette at the top of the stack without changing the stack
* tself. If an index is given, the palette at that index is returned. Note
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "tself -> itself".

Another question is, if an index of zero denotes the top of the stack, what if someone wants to peek the palette at the bottom of the stack that actually uses the index zero?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a peekLast() function to look at the bottom of the stack. I first thought that a special index value such as -1 defined as the constant LAST_INDEX could be used, e.g., const palette = navStack.peek(LAST_INDEX), but that felt less transparent than a function for peeking at the bottom of the stack. So I switched to peekLast().

src/index.js Outdated

adaptivePaletteGlobals.navigationStack.currentPalette = firstLayer;
render(html`<${Palette} json=${goBackCell} />`, document.getElementById("backup_palette"));
//render(html`<${Palette} json=${outputPalette} />`, document.getElementById("output_palette"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commented line can be removed? Same as other related spots: line 29 in this file and this div container in index.html?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. All of them have been removed.

@cindyli
Copy link
Contributor

cindyli commented Feb 21, 2024

When loading the palette page in a browser, the console log reports this error:

TypeError: bciToBlissaryId(...) is undefined
    bciAvIdToString SvgUtils.ts:27
    getSvgBuilder SvgUtils.ts:56
    getSvgElement SvgUtils.ts:91
    BlissSymbol BlissSymbol.ts:31
    Preact 19
    <anonymous> index.js:35
SvgUtils.ts:60:12

Unknown bci-av-id = 1 SvgUtils.ts:61:12

The error might come from this line.

…tion

- initialize the globals with an optional id (of the main palette area),
- set the `aria-controls` attribute of all go-back buttons to this id,
- when going back use the `aria-controls` to find the container element
  to render the palette into.
@klown
Copy link
Contributor Author

klown commented Mar 1, 2024

When loading the palette page in a browser, the console log reports this error:

TypeError: bciToBlissaryId(...) is undefined
    bciAvIdToString SvgUtils.ts:27
    getSvgBuilder SvgUtils.ts:56
    getSvgElement SvgUtils.ts:91
    BlissSymbol BlissSymbol.ts:31
    Preact 19
    <anonymous> index.js:35
SvgUtils.ts:60:12

Unknown bci-av-id = 1 SvgUtils.ts:61:12

The error might come from this line.

The error does come from that line. As far as I can tell, "BMW" does not have a blissary id nor Blissymbol. If it does, let me know.

But this points to another issue: Since the BlissSymbolCellType requires a bciAvId, some id has to be passed and in this case I chose a value that would not result in any symbol. And that causes the TypeError.

Should the bciAvId field of the BlissSymbolCellType be optional? Then the BlissSymbol component could check and if missing, make no attempt to get a Blissymbol. That is, the blissaryIdMap is not consulted, nor is the BlissSVGBuilder asked for a symbol that cannot exist.

@klown
Copy link
Contributor Author

klown commented Mar 1, 2024

@cindyli Ready for another round of review.

I decided to change the click handlers for both the ActionBranchToPaletteCell and CommandGoBackCell: to remove the hard-coded document.getElementById("mainPaletteDisplayArea") that finds the container to render the new palette into. Instead I set that in the adaptivePaletteGlobals structure. In addition, when a CommandGoBackCell is rendered, its aria-controls attribute is set to that container element and is used by its click handler to pass to the renderer. The aria-controls is a nice way to store the information and it adds some accessibility information as well. I think we should add aria-controls to the CommandClearEncoding and the CommandDelLastEncoding elements for accessibility purposes where they point to the ContentBmwEncoding element. What do you think? (Link to info about aria-controls).

@cindyli
Copy link
Contributor

cindyli commented Mar 4, 2024

Should the bciAvId field of the BlissSymbolCellType be optional? Then the BlissSymbol component could check and if missing, make no attempt to get a Blissymbol. That is, the blissaryIdMap is not consulted, nor is the BlissSVGBuilder asked for a symbol that cannot exist.

I feel if there isn't a value for the bciAvId field, this cell probably should not be a BlissSymbolCellType, which meant to display a bliss symbol.

The cell that has bciAvId==1 is the button that leads to the BMW palette. Do you think if it's a good idea to display bliss symbols of "B"(8552), "M"(8563), "W"(8573), so the bciAvId would be [8552, "/", 6563, "/", 8573]?

@cindyli
Copy link
Contributor

cindyli commented Mar 4, 2024

I think we should add aria-controls to the CommandClearEncoding and the CommandDelLastEncoding elements for accessibility purposes where they point to the ContentBmwEncoding element. What do you think?

I think adding aria-controls is a great idea too. Are you going to add for the CommandClearEncoding and the CommandDelLastEncoding? Let me know if you want me to add. Thanks.

@klown
Copy link
Contributor Author

klown commented Mar 11, 2024

Should the bciAvId field of the BlissSymbolCellType be optional? Then the BlissSymbol component could check and if missing, make no attempt to get a Blissymbol. That is, the blissaryIdMap is not consulted, nor is the BlissSVGBuilder asked for a symbol that cannot exist.

I feel if there isn't a value for the bciAvId field, this cell probably should not be a BlissSymbolCellType, which meant to display a bliss symbol.

The cell that has bciAvId==1 is the button that leads to the BMW palette. Do you think if it's a good idea to display bliss symbols of "B"(8552), "M"(8563), "W"(8573), so the bciAvId would be [8552, "/", 6563, "/", 8573]?

You meant ``[8552, "/", 8563, "/", 8573]` :-).

After thinking about it, I agree that a BlissSymbolCellType must have a Bliss symbol, otherwise, it's a different type of cell. Your solution works for me, although it looks a little odd when rendered since the Bliss symbol "BMW" looks similar to the English label text. But, that's okay.

@klown
Copy link
Contributor Author

klown commented Mar 11, 2024

I think we should add aria-controls to the CommandClearEncoding and the CommandDelLastEncoding elements for accessibility purposes where they point to the ContentBmwEncoding element. What do you think?

I think adding aria-controls is a great idea too. Are you going to add for the CommandClearEncoding and the CommandDelLastEncoding? Let me know if you want me to add. Thanks.

I came up with a solution that adds another property in the .json palette definition called ariaControls. Its value is the id of the cell it controls. So far, that cell and its id are in the same .json file. The cell's id is already copied into the DOM element's @id attribute. It's easy to set an @aria-controls attribute to refer to the appropriate DOM element's @id.

Let me know what you think.

};

export type BlissSymbolCellType = LayoutInfoType & BranchToInfoType & BlissSymbolInfoType;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great finding of this useful feature.

@klown
Copy link
Contributor Author

klown commented Mar 13, 2024

Ready for another review, @cindyli.

@cindyli cindyli merged commit 100b474 into inclusive-design:main Mar 14, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants