Skip to content

Comments

feat(content-docs): allow setting class name for category link#6249

Closed
Josh-Cena wants to merge 5 commits intomainfrom
jc/category-index-class-name
Closed

feat(content-docs): allow setting class name for category link#6249
Josh-Cena wants to merge 5 commits intomainfrom
jc/category-index-class-name

Conversation

@Josh-Cena
Copy link
Collaborator

Motivation

Close #6232.

Have you read the Contributing Guidelines on pull requests?

Yes

Test Plan

Added a dogfood example

@Josh-Cena Josh-Cena added the pr: new feature This PR adds a new API or behavior. label Jan 2, 2022
@facebook-github-bot facebook-github-bot added the CLA Signed Signed Facebook CLA label Jan 2, 2022
@netlify
Copy link

netlify bot commented Jan 2, 2022

@github-actions
Copy link

github-actions bot commented Jan 2, 2022

⚡️ Lighthouse report for the changes in this PR:

Category Score
🟠 Performance 62
🟢 Accessibility 98
🟢 Best practices 100
🟢 SEO 100
🟢 PWA 95

Lighthouse ran on https://deploy-preview-6249--docusaurus-2.netlify.app/

@github-actions
Copy link

github-actions bot commented Jan 2, 2022

Size Change: +2.23 kB (0%)

Total Size: 672 kB

Filename Size Change
website/.docusaurus/globalData.json 40.7 kB +588 B (+1%)
website/build/assets/js/main.********.js 499 kB +1.64 kB (0%)
ℹ️ View Unchanged
Filename Size
website/build/assets/css/styles.********.css 102 kB
website/build/index.html 29.6 kB

compressed-size-action

Copy link
Collaborator

@slorber slorber left a comment

Choose a reason for hiding this comment

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

Thanks 👍

We can probably simplify this PR a bit: just use category.className instead of category.link.className

Note that there's a very similar issue: #6254
Probably simple enough to be solved in this PR.

type: 'doc',
id: categoryLinkedDocId, // We "remap" a potentially "local id" to a "qualified id"
className:
categoryMetadata?.link?.className ??
Copy link
Collaborator

Choose a reason for hiding this comment

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

we already have categoryMetadata?.className and it solves user reported use-case, why introduce a new categoryMetadata?.link?.className here?

You could do this instead:

category.className = categoryMetadata?.className ?? getDoc(link.id).frontMatter.sidebar_class_name

export type SidebarItemCategoryLinkDoc = {
type: 'doc';
id: string;
className?: string;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this new attribute really necessary? What's the advantage of having it instead of reusing the existing category className? Will this be applied to something else that is not the category?

ThemeClassNames.docs.docSidebarItemCategoryLink,
ThemeClassNames.docs.docSidebarItemCategoryLinkLevel(level),
'menu__list-item-collapsible',
linkClassName,
Copy link
Collaborator

Choose a reason for hiding this comment

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

The user wanted the className to be applied to the <li> item, so may not exactly solve the user problem

<div
className={clsx(
ThemeClassNames.docs.docSidebarItemCategoryLink,
ThemeClassNames.docs.docSidebarItemCategoryLinkLevel(level),
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we really need those extra classes stable? What's the purpose?

I know we want stable selectors but IMHO on parent it's good enough, it's quite easy to target the first child div once we can target the parent reliably

frontMatter: {sidebar_label: sidebarLabel},
frontMatter: {
sidebar_label: sidebarLabel,
sidebar_class_name: sidebarClassName,
Copy link
Collaborator

Choose a reason for hiding this comment

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

sidebar_class_name intuitively implies to me that it will apply as well to doc items in the sidebar, and not just category

Maybe we should make it more explicit?

sidebar_category_class_name ? Or apply to doc and categories both?

@Josh-Cena
Copy link
Collaborator Author

So we have a category class name already, but this one targets the entire category dropdown rather than the link itself. (I designed it like that initially because at that time there wasn't the extra div around the link, and targeting the entire dropdown allows people to customize margins, etc.) The changes in the DOM structure after the category index pages have caused troubles on the TS-eslint website. Adding another class name helps ensure a stable semantic selector, since otherwise if you want to style the category link, you have do .theme-doc-sidebar-item-category > div > a which looks like subjecting to another breaking change in the future. A new link class name makes it more consistent.

@slorber
Copy link
Collaborator

slorber commented Jan 6, 2022

Adding another class name helps ensure a stable semantic selector,

Agree that we could add another semantic selector here, but that seems like a different subject.

Does a new .theme-doc-sidebar-item-category-group for the parent li makes sense to you? (breaking change, not sure how to find a better semantic className for the child div 🤷‍♂️ )


When using sidebar_class_name: green the user expect this class to be applied to the "li" item, not the child div.

This frontmatter should allow customizing a whole category li item, including subitems.

If it's only applied to the child div, it's less powerful and it's definitively not what the original issue asked for.

We should be able to write something like:

.theme-doc-sidebar-item-category-group.green > .theme-doc-sidebar-item-category > a {
  color: green;
}

But also

.theme-doc-sidebar-item-category-group.green {
  border-left: solid green;
}

image


Also I think the current desing/API is mixing 2 things: the category linking feature, and the sidebar category label link. Those share some "link" terminology but are not strictly related. And it's even weird that you have a link.className and don't even apply this className to the <a> element in the end 🤪

@Josh-Cena
Copy link
Collaborator Author

Josh-Cena commented Jan 6, 2022

Wait, eh? I didn't realize they wanted it on the <li> element...

In that case, maybe that issue is actually related to #6254?

Can we guarantee DOM stability in the future? In that case we may just recommend .theme-doc-sidebar-item-category > div > a and make all category class names target the entire dropdown rather than the category link.

I implemented the link class name as targeting <li> rather than <a> because it's always easier to select a children (particularly when there can only be one) than select a parent. Targeting a block element also sounds like a useful thing for sizing

@slorber
Copy link
Collaborator

slorber commented Jan 6, 2022

Wait, eh? I didn't realize they wanted it on the

  • element...
    In that case, maybe that issue is actually related to Autogenerated category with doc link: use doc frontmatter for category metadata #6254?

  • Yes it's related, see my previous comment :)

    We should apply sidebar_label and sidebar_class_name as fallbacks for _category_.json


    Can we guarantee DOM stability in the future? In that case we may just recommend .theme-doc-sidebar-item-category > div > a and make all category class names target the entire dropdown rather than the category link.

    I don't really like to guarantee DOM structure stability, so there's probably still value in creating a sub-selector for the category "row" (excluding child), but not sure how to find good names 🤷‍♂️ However I don't think this selector is likely to be refactored so it should be pretty stable anyway.

    In general, I think our public API surface is the theme components interface and stable CSS classNames. All other CSS and HTML structures should be considered as implementation details, subject to change.

    @slorber
    Copy link
    Collaborator

    slorber commented Jan 6, 2022

    I implemented the link class name as targeting

  • rather than

  • You mean <div>?

    because it's always easier to select a children (particularly when there can only be one) than select a parent.

    Same reason for applying the className on <li> instead: you can still select the first div quite easily, but the opposite is not true

    @Josh-Cena
    Copy link
    Collaborator Author

    You mean <div>?

    No, I mean <li> of each doc link in the dropdown, before we had category indexes

    Same reason for applying the className on <li> instead: you can still select the first div quite easily, but the opposite is not true

    Yes, absolutely no objection to applying class name to <li> (which we do already). Just that "you can still select the first div" is defeated if we change DOM structure in the future.

    So the resolution is:

    • Let the sidebar_class_name of index pages target the entire category (which will be consistent with other metadata once we allow using category index page metadata to set category metadata)
    • Give a new stable class name to category links, without letting users define a custom one because the equivalent can be achieved by using .category > div > a?

    @slorber
    Copy link
    Collaborator

    slorber commented Jan 6, 2022

    yes 👍

    But should the new stable selector apply to the div or the a? What could be a good name for it?

    @Josh-Cena
    Copy link
    Collaborator Author

    Going to close this as it's not in the right direction

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Labels

    CLA Signed Signed Facebook CLA pr: new feature This PR adds a new API or behavior.

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    sidebar_class_name not applied for index pages

    3 participants