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

Experimental Header Navigation #3589

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

G-Ambatte
Copy link
Collaborator

This PR adds a button to the BrewRenderer. When clicked, this exposes the header navigation window, which lists all of the elements with IDs in the document.
It generates this information by calling querySelectorAll('[id]') to acquire a list of all elements that have an id attribute, then parsing these for the following conditions:

  • has the class page - depth: 0; text: 'Page' + page number
  • is h1 through h6 - depth: heading value, i.e. h1 => 1, h6 => 6; text: innerText value
  • all other elements - depth: 7; text: innerText value

From one of the documents in my local install DB:

CLOSED:
image

OPEN:
image

HOVERING OVER "PAGE 2:
image

@G-Ambatte G-Ambatte self-assigned this Jul 21, 2024
@G-Ambatte G-Ambatte added P2 - minor feature or not urgent Minor bugs or less-popular features 🔍 R0 - Needs first review 👀 PR ready but has not been reviewed labels Jul 21, 2024
@G-Ambatte
Copy link
Collaborator Author

@calculuschild We might want a deployment on this one for testing

@G-Ambatte
Copy link
Collaborator Author

Example of a custom element with custom ID:
image

@G-Ambatte
Copy link
Collaborator Author

Some further tweaks:
image

@5e-Cleric
Copy link
Member

Once a deployment is ready, i will suggest some style options, maybe we could even pull something from the codemirror theme chosen.

@Gazook89
Copy link
Collaborator

My thought is that this is another reason for a unified template for Share and Edit pages— share pages could even have a split panel as well. The left panel would have tabs including the table of contents/outline.

@G-Ambatte
Copy link
Collaborator Author

In case it's not clear: this navigation lives in the BrewRenderer, so exists on both Edit and Share pages. I just realized that I've only posted screen shots from Edit pages, and that might cause some confusion.

@Gazook89
Copy link
Collaborator

Yeah I know where it is currently in the PR. I am suggesting an alternate future, whether it’s done in this PR or not. It just feels like we already have a hideable sidebar/drawer interface available to us, and we might not need to invent another expanding component. Just my two cents.

@Gazook89
Copy link
Collaborator

More thoughts on this in this one-person discussion: #2951

@5e-Cleric
Copy link
Member

5e-Cleric commented Aug 25, 2024

Is this PR's popup supposed to take the entire space?

image

And please do include some way to close it at all times, this is a long document and the navigation is at least 10 pages long, and the only way to close is with a small button at the top?

Copy link
Member

@5e-Cleric 5e-Cleric left a comment

Choose a reason for hiding this comment

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

Overall i would make the requested changes, and following style changes.

Comment on lines 68 to 76
const HeaderNavItem = ({ link, text, depth, className })=>{
return <p>
<a href={`#${link}`} target='_self' className={className}>
{`${'-'.repeat(depth)}${text}`}
</a>
</p>;
};

export default HeaderNav;
Copy link
Member

Choose a reason for hiding this comment

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

This syntax needs improvement, this is a navigation, so please do implement proper HTML, a <nav> element, with <ul> and <li>, or something like that, maybe even with some classes or attributes.

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps add a border- after pages, or an HR element too.

Also please add a title to this navigation, a simple ## Header Navigation will suffice, like the title attrb on the button.

Copy link
Member

Choose a reason for hiding this comment

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

Every link should have a class to indicate depth to be able to style this properly, not just the dash option (which i don't particularly like the look of)

Copy link
Member

Choose a reason for hiding this comment

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

Recommended addition/change:

.headerNav {
    padding: 25px 30px 5px 10px;
    
    .navIcon {
          position:fixed;
          top:0px;
          padding-top:5px;
          
        &.active {
          width:470px;
          background:#dadada;
          z-index:10;
        }
    }
    &.active {
        padding: 25px 10px 5px 10px;
        height:100vh;
        width:500px;
        
        background:#dadada;
        
        p:has(.pageLink) {
          margin-block:10px 5px;
          &:after {
            content:'';
            height:2px;
            background:#929292;
            display:block;
            position:relative;
            top:4px;
          }
        }
        
        &::-webkit-scrollbar {
          width: 10px;
        }
        &::-webkit-scrollbar-corner {
          visibility: hidden;
        }
        &::-webkit-scrollbar-thumb {
            background: #929292;
            border-radius:5px;
        }
    }
}

to achieve:

Show image

image

@G-Ambatte
Copy link
Collaborator Author

Is this PR's popup supposed to take the entire space?

image

And please do include some way to close it at all times, this is a long document and the navigation is at least 10 pages long, and the only way to close is with a small button at the top?

I suspect it's a case of a really long title is causing the element to cover 100% of the viewable width. Some styling like max-width: 10vw; might be all that's required to stop it covering the whole BrewRenderer.

@dbolack-ab
Copy link
Collaborator

I am very concerned that this pulls too many headers. Would adding a pulldown to set the "Max" Header level be practical?

This PR has a natural extension to do the same navigation to the editing window.

@ericscheid
Copy link
Collaborator

ericscheid commented Aug 26, 2024

I am very concerned that this pulls too many headers. Would adding a pulldown to set the "Max" Header level be practical?

This PR has a natural extension to do the same navigation to the editing window.

I can imagine a future PR could address this, perhaps by providing little h1h5 buttons across the top that auto-expand/collapse all headings to that level. (And have each heading that is a parent also be expando enabled).

Lets get this simpler version deployed first though.

@Gazook89
Copy link
Collaborator

I think you can just put the button in the new toolbar, on the far left. Rather than floating as it's own button.

@5e-Cleric
Copy link
Member

Further testing reveals somehow table headers are included in the previous h5 header text:

image
For reference:

image

Also, i am not sure about the width being proportional to window size (iframe size in this case), but if we can get to close it whenever we want it is not a big issue.

@dbolack-ab
Copy link
Collaborator

The error looks to be from picking up the div containing the table's full content.


const renderHeaderLinks = ()=>{
if(!pagesRef.current) return;
const elements = pagesRef.current.querySelectorAll('[id]');
Copy link
Member

Choose a reason for hiding this comment

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

Right, we can let CSS do the heavy lifting here:

Suggested change
const elements = pagesRef.current.querySelectorAll('[id]');
const elements = pagesRef.current.querySelectorAll('*:is(h1,h2,h3,h4,h5,h6)[id]');

We could even use this to leverage the depth level later.

Copy link
Member

Choose a reason for hiding this comment

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

This should fix the aforementioned issue.

Copy link
Collaborator Author

@G-Ambatte G-Ambatte Sep 1, 2024

Choose a reason for hiding this comment

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

From my initial testing, the suggested change here does not work - the returned NodeList has a length of 0 when the previous query returned a length of 4.

Also, my initial thought is that the :is() limits the results to headers only, when id can exist on any element - like <div class='page' id='p1'>, for example.

Copy link
Member

Choose a reason for hiding this comment

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

Right, i thought we only wanted headings, but.. right, so the issue here is that any block with id gets caught, with all contents too, including in this case the table

@@ -424,6 +424,7 @@ const EditPage = createClass({
lang={this.state.brew.lang}
currentEditorPage={this.state.currentEditorPage}
allowPrint={true}
showHeaderNav={true}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this component really need to stretch all the way to up to editPage.jsx and sharePage.jsx files? It seems like we could just assume that the headerNav is always going to present in both pages (not always visible, of course), so we don't need to pass it in as a boolean prop on BrewRenderer-- it could just be included in BrewRenderer unconditionally.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It could, if we also want it to appear on every other page, like New, Home, Change Log, Welcome...

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't really see a problem with that. For something like the changelog, especially, it'd be nice to just have a list of dates/versions. Same deal with FAQ (though it's obviously not very long at this point). The point of the site is to create documents, and I'm not sure we need to say "some documents have these tools, others don't".

If there are pages where navigation by header isn't desired, then we should maybe consider stop making everything out of special-case brews and just make normal pages.

Copy link
Member

Choose a reason for hiding this comment

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

I agree with G-Ambatte here, FAQ perhaps, but the rest don't need navigation at all, 2 page documents....

Copy link
Collaborator

Choose a reason for hiding this comment

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

I’m not sure why there needs to be a distinction between short and long documents here. For all documents are we going to make the button disappear if it’s shorter than 2 pages? What if it is 10 pages but has no headers?

The goal should be to have a consistent, unified UI as much as possible. If a button exists for one brew, it should be available on all brews. If, for whatever reason, a button really surely doesn’t do anything on a particular brew, then it should still be there but be disabled. That isn’t the case here, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
experiment P2 - minor feature or not urgent Minor bugs or less-popular features 🔍 R0 - Needs first review 👀 PR ready but has not been reviewed
Projects
Status: Waiting for Calc's First Review
Development

Successfully merging this pull request may close these issues.

6 participants