-
Notifications
You must be signed in to change notification settings - Fork 60
Add anchor for section titles for quick sharing of sections #408
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
Add anchor for section titles for quick sharing of sections #408
Conversation
@swift-ci test |
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.
This looks great, very nice! 🚀
One thing I noticed is if I tab through, it does not show the anchors, deff something we should fix.
Need to check if we should disable this for IDE environments.
Also we may check with the DocC team if they plan to provide anchors for those Topic subsections, instead of us generating them - #190
Other than that, looks great :)
Thanks @dobromir-hristov !
Fixed! Good catch!
Why would we? it should scroll in the same way, right?
Yeah, that would be much better than the generation I'm doing in the frontend! Give it another review. I still need to add final tests for the |
I don't see a point in having a clickable link in the ide, since there is no URL bar |
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.
I think it looks good now. How does VO handle the hidden anchor item? Do we need anything special for it?
tag: { | ||
type: String, | ||
default: () => 'h2', | ||
}, | ||
}, | ||
mounted() { | ||
if (!this.anchor) return; | ||
const element = document.getElementById(`${this.anchor}`); |
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.
This is pretty clever though I am not sure how I feel about it.
All headings would be rendered initially without an id
and would then re-render to add the id
, if there is no element with that anchor
. This makes the component easier to user, but a bit more unpredictable.
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.
Unpredictable? We use dynamic ids in many more components across the app... 🤔
But if you have any better approach, happy to look into it :)
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.
Well you may be right. I would have probably just made this logic user controllable, via some boolean whether to apply an id
to the element or not.
We are hiding it from VO because I think it's not providing any value to VO users. https://vuejs.org/guide/introduction.html#what-is-vue does it in the same way |
True, I don't render it anymore on IDEs f6bd656 |
@swift-ci test |
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.
Looks good. @mportiz08 can you look into the anchor logic if you are fine with it and we can merge this one I think
tag: { | ||
type: String, | ||
default: () => 'h2', | ||
}, | ||
}, | ||
mounted() { | ||
if (!this.anchor) return; | ||
const element = document.getElementById(`${this.anchor}`); |
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.
Well you may be right. I would have probably just made this logic user controllable, via some boolean whether to apply an id
to the element or not.
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.
Very cool to see this in action, and I love that it just works as expected in places where no anchor data is provided.
I have a minor concern about the anchor generation, but I think the majority of my other comments are pretty small things that will be easy to fix.
}, | ||
mounted() { | ||
if (!this.anchor) return; | ||
const element = document.getElementById(`${this.anchor}`); |
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.
const element = document.getElementById(`${this.anchor}`); | |
const element = document.getElementById(this.anchor); |
As a more general comment though, I don't totally understand the need for why this hook is needed. Why are there separate id
and anchor
values and how are they used differently?
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.
There are cases where the ID is applied on a section that wraps the heading (like in TopicsSection), but in other cases, the heading has to hold the ID.
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.
I'm not totally following how that requires the mounted hook here (probably just missing something).
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.
I think she wanted it to be more magical. Thats one of the points I raised that I wanted your input on :D
The component tries to find an already existing element with that id
in the DOM, and if it doesnt, it adds that id
to itself.
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.
I guess I just don't understand the magical part, to be more clear. Why would this logic have to happen after the initial render?
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.
So all possible items that may have that ID are rendered? As I said I would probably control this through a prop instead.
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.
@mportiz08 I had this logic to check if the document has already an id
on it where we want to link to. This happens in components that have the id in the beginning of the section itself instead of having it in the title.
Also in this way, we avoid duplication of id
s in the HTML, since ID attributes must be unique in the document.
Controlling through a prop, as @dobromir-hristov suggested, would allow us more flexibility but would open the component for possible HTML's errors because we wouldn't prevent the document from duplication of HTML id
s.
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.
I understand why we might choose to sometimes assign the ID attribute to a non-heading element instead of a heading, but I don't understand why we couldn't prevent the ID from being assigned in multiple places in the components themselves—it seems like that is controlled by our app and not outside forces. If that's the case, then we should be able to programmatically decide where the anchor uniquely goes before any mounted
hook gets called after the initial render.
I think we both agree on the goal of only having unique IDs but maybe there's a little confusion about how to ensure it within the components themselves. Let me know if you want to talk about this offline—I may be missing a subtle thing here that might make this approach necessary.
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.
@mportiz08 I set a meeting to continue discussing this. Interesting debate! Thanks :)
.header-anchor { | ||
margin-left: -0.73em; | ||
padding-right: 0.23em; | ||
transition: opacity .25s; |
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.
You may want to have someone from the design team review this new feature and test the experience in different browsers. The scrolling animation specifically (not this one) feels a little different in Safari but that may be a limitation of the JS scroll function itself.
Just noting that we may want to close #190 when this gets merged. |
@swift-ci test |
5c89246
to
4f2840c
Compare
Hey Marina!
Screen.Recording.2022-09-01.at.4.24.57.PM.mov
|
Hey @hqhhuang ! thanks a lot for your comments!
URL are always case sensitive. You will see that some anchors are in lowercase and others aren't. This is because some come directly from docc (some have uppercase initials) and other we add them depending on the title (these ones are in lowercase). The anchor's names don't matter if they are in lowercase or not, as long as they point to an existing id with the same name.
This is because of the way we scroll to the section. We first scroll into the view where the title is, and then we scrollBy to overcome the navigation height. You can see it here: https://github.com/apple/swift-docc-render/blob/f5c1b7fd271518503e85f7a5d2dd5f993ded17be/src/mixins/scrollToElement.js#L26-L27
Very good catch! Maybe this could a separate feature since it uses the ids but it doesn't depend on the new LinkableHeadinds, could you fill a radar or Github issue for it? Thanks! |
URL capitalization:
What are some existing examples of ones coming directly from docc? I think if we opted for all lowercase for Docc-render generated anchors, docc should also provide all lower case anchors. Is there a particular reason some of the docc ones have upper case initials? Scroll jump:
Is there a difference between how Chrome and Safari handles the scroll? If this is the issue, I would sort of expect it to happen in both places. Updating URL based on anchors:
rdar://99584817 I can try to work on this one in the coming weeks if we have a thumbs up from design. |
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.
I tested and it works OK. I think you havent missed any places where we use headings.
Just make sure you fix what Marcus pointed out, with the jumping text on hover.
@mportiz08 oh true, fixed: 23fd3c7 but yes, the design specs aren't closed yet |
Thanks for the feedback, @hqhhuang !
For example in the {
"anchor": "Overview",
"level": 2,
"type": "heading",
"text": "Overview"
}
I don't know. It shouldn't matter anyways
It may be a difference between browsers, yes! I will investigate those differences.
Thanks! |
@swift-ci test |
…ot dissapear when hovering on it
@swift-ci test |
@swift-ci test |
@swift-ci test |
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.
Awesome work @marinaaisa! This is working great, and I think it's almost ready to merge.
I just noticed one minor potential issue to look at with the color of the new linkable heading element.
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.
This looks good to me, just check the things that Marcus pointed out.
New design approved. |
@swift-ci test |
Bug/issue #96943502, if applicable:
Summary
Add anchor for section titles for quick sharing of sections.
This anchor shows when user hovers the title section.
Issue: #273
Dependencies
NA
Testing
Steps:
Checklist
Make sure you check off the following items. If they cannot be completed, provide a reason.
npm test
, and it succeeded