-
-
Notifications
You must be signed in to change notification settings - Fork 977
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
Rework tabset-dropdown to use regular Bootstrap dropdowns #2054
base: main
Are you sure you want to change the base?
Conversation
Headers using the tabset-dropdown class now work similarly to regular tabsets: all subheaders are included in a bootstrap dropdown. This dropdown will be included inside the tabset just above.
|
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.
For reference while reviewing this PR, bslib is in the process of coming up with new UI function for creating navs & tabs : rstudio/bslib#296 I believe this will be possible to use it in R Markdown document using Bootstrap also. |
Thanks for pointing out the new features from bslib, they will help me a lot! Please note that I am not a regular JS user: feel free to be as critical with my implementation as needed. |
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.
Thanks for this PR.
I made very few comments on the code. Overall, it seems to work fine.
I test with bslib and without.
What I am not sure about is what the previous behavior was supposed to be.
I tested your example without the PR (using dev rmarkdown) and I got a very different result - it puzzles me because I did not know about this hidden feature of rmarkdown 😅
But being different, this would mean than any user already using .tabset-dropdown
would have its document broke with this PR probably. However, the result of this PR seems closer to Bootstrap dropdown's in tabsets.
For reference, the previous design looked somewhat like this #1405 (comment)
The aim was to fix #1116 by offering a dropdown feature in tabs. So if the design is different, the same feature can be achieved using this new interface. @yihui you seemed ok for the change, did you thought of this ?
Also, we are now in a mix of Boostrap 3 and Bootstrap 4 support, with different version : brought by rmarkdown itself or by bslib. That is a lot of things to test and the HTML come written by the JS script is a mix of BS3 and BS4 syntax to me.
I asked @cpsievert to have a look and give its thoughts on this one. We need to think this through correctly on what it is supposed to be.
@yihui this tabsets feature is something we may consider doing using Lua filter maybe instead of using only JS to post process the HTML directly. Changing to a Fenced div syntax is also an option.
For the record, while reviewing this PR, I can now confirm that the tabset feature is only working currently with --section-divs
activated for Pandoc with HTML 4 output. (section_divs = TRUE
in html_document()
).
} | ||
|
||
// check if this is a dropdown tab and process it accordingly | ||
var dropdown = tab.hasClass("tabset-dropdown"); |
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 comestic maybe but I would put this variable with the others defined above (l. 54) so that all variables are based on class are in the same place in code
li.addClass('dropdown'); | ||
|
||
// build and append the dropdown toggle | ||
var a = $('<a class="dropdown-toggle" data-toggle="dropdown" href="#">' |
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.
var a = $('<a class="dropdown-toggle" data-toggle="dropdown" href="#">' | |
var a = $('<a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-expanded="false">' |
as in bootstrap doc - I think it is better for accessibility
var dropdownId = dropdownTab.attr('id'); | ||
|
||
// remove any table of contents entries associated with | ||
// this ID (since we'll be removing the heading element) | ||
$("div#" + tocID + " li a[href='#" + dropdownId + "']") | ||
.parent().remove(); | ||
|
||
// sanitize the id for use with bootstrap tabs | ||
dropdownId = dropdownId | ||
.replace(/[.\/?&!#<>]/g, '') | ||
.replace(/\s/g, '_'); | ||
dropdownTab.attr('id', dropdownId); | ||
|
||
// get the heading element within it, grab it's text, then remove it | ||
var dropdownHeading = dropdownTab | ||
.find('h' + dropdownTabLevel + ':first'); | ||
var dropdownHeadingText = dropdownHeading.html(); | ||
dropdownHeading.remove(); | ||
|
||
// build and append the dropdown tab list item | ||
var dropdownLi = $('<li role="presentation"></li>'); | ||
dropdownMenu.append(dropdownLi); |
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.
Could we make a JS function as this is the same process as for other tabs above but with different parameter ? Refactoring would help later maintaining
// build and append the tab link | ||
var a = $('<a role="tab" data-toggle="tab">' + tabHeadingText + '</a>'); |
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.
// build and append the tab link | |
var a = $('<a role="tab" data-toggle="tab">' + tabHeadingText + '</a>'); | |
// build and append the tab link | |
var a = $('<a role="tab" data-toggle="tab" role="button" aria-expanded="false">' + tabHeadingText + '</a>'); |
Same as above
I would be more conservative here and not intentionally break the existing On a larger note, if the plan is to require Bootstrap 4+ sometime in the near future, maybe it's time to use the same lua filters as quarto (or bslib via remarker) to implement tabsets. The bslib way should be able to support Bootstrap 3 out-of-the-box, but the quarto way would probably require Bootstrap 4+ (unless, at run-time, you have some way of knowing what version in relevant). |
We could indeed try to support both using a new class. 🤔 I am really wondering how many people use this feature that was never documented. It see a few though : https://github.com/search?q=.tabset-dropdown+extension%3ARmd&type=Code&ref=advsearch&l=&l=
Using bslib by default is a plan yes. Default to 4 for
The syntax for tabsets in Quarto is different (using fenced div) so this would break the current usage. And Quarto does not support all the option for tabset that are supported in R Markdown (likes pills or fade).
I'll ask Winston about this project to know more. Being able in some way to sure bslib directly without re-doing any bootstrap feature directly would be great. Thanks for your feedback @cpsievert |
@cderv I don't care about the implementation. Either JS or Lua is fine to me. I'm also okay with changing the syntax. This is an undocumented feature and doesn't seem to be widely used. If a breaking change can make it easier to maintain in the future (and more compatible with quarto), I'm okay with making a breaking change. |
This PR reworks the
.tabset-dropdown
class to work similarly to regular tabsets. It should also close #1697.I wasn't satisfied with the current
.tabset-dropdown
class and wanted to use regular Boostrap dropdowns included in navs. This lead me to remove the.tabset-dropdown
CSS and improve thebuildTabsets
JS function to include the.tabset-dropdown
class.The
.tabset-dropdown
class can now be added to any sub-header of a header with class.tabset
or.tabset-pills
. Thetabset-dropdown
header will determine the dropdown's name and all of its sub-headers will be added as dropdown tabs.Example