From 6f6a6694afa130bfe2d93305ead2be430459de58 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Wed, 2 Feb 2022 12:36:26 -0800 Subject: [PATCH 01/16] Use chevrons for toggle buttons --- docs/index.md | 2 +- docs/{reference.md => reference/index.md} | 0 setup.py | 2 +- .../_static/togglebutton-chevron.svg | 4 +++ .../_static/togglebutton.css_t | 28 ++++++------------- sphinx_togglebutton/_static/togglebutton.js | 21 ++++++++++++-- 6 files changed, 33 insertions(+), 24 deletions(-) rename docs/{reference.md => reference/index.md} (100%) create mode 100644 sphinx_togglebutton/_static/togglebutton-chevron.svg diff --git a/docs/index.md b/docs/index.md index a622a3c..ab61516 100644 --- a/docs/index.md +++ b/docs/index.md @@ -40,7 +40,7 @@ For a bootstrap-based "dropdown" directive that uses pure CSS, check out ```{toctree} use -reference +reference/index ``` ## Installation diff --git a/docs/reference.md b/docs/reference/index.md similarity index 100% rename from docs/reference.md rename to docs/reference/index.md diff --git a/setup.py b/setup.py index 751d10b..aadf627 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ license="MIT License", packages=find_packages(), package_data={ - "sphinx_togglebutton": ["_static/togglebutton.css_t", "_static/togglebutton.js"] + "sphinx_togglebutton": ["_static/togglebutton.css_t", "_static/togglebutton.js", "_static/togglebutton-chevron.svg"] }, install_requires=["setuptools", "wheel", "sphinx", "docutils"], extras_require={"sphinx": ["matplotlib", "myst_nb", "sphinx_book_theme", "sphinx_design"]}, diff --git a/sphinx_togglebutton/_static/togglebutton-chevron.svg b/sphinx_togglebutton/_static/togglebutton-chevron.svg new file mode 100644 index 0000000..6686bac --- /dev/null +++ b/sphinx_togglebutton/_static/togglebutton-chevron.svg @@ -0,0 +1,4 @@ + + + + diff --git a/sphinx_togglebutton/_static/togglebutton.css_t b/sphinx_togglebutton/_static/togglebutton.css_t index aa1e443..e27c4bc 100644 --- a/sphinx_togglebutton/_static/togglebutton.css_t +++ b/sphinx_togglebutton/_static/togglebutton.css_t @@ -38,7 +38,7 @@ } .toggle.admonition.admonition-title:after { - content: "" !important; + content: ""; } /* Note, we'll over-ride this in sphinx-book-theme */ @@ -51,16 +51,13 @@ /* General button style */ button.toggle-button { - background: #999; + background: none; border: none; - z-index: 100; right: -2.5em; margin-left: -2.5em; /* A hack to keep code blocks from being pushed left */ position: relative; float: right; - border-radius: 100%; width: 1.5em; - height: 1.5em; padding: 0px; } @@ -74,22 +71,15 @@ button.toggle-button { } } - -/* Plus / minus toggles */ -.toggle-button .bar { - background-color: white; - position: absolute; - left: 15%; - top: 43%; - width: 16px; - height: 3px; +img.tb-icon { + transition: transform .2s ease-out; } -.toggle-button .vertical { - transition: all 0.25s ease-in-out; - transform-origin: center; +img.tb-icon:focus-visible { + outline: none; } -.toggle-button-hidden .vertical { - transform: rotate(-90deg); +.toggle-button-hidden img.tb-icon { + transform: rotate(90deg); } + diff --git a/sphinx_togglebutton/_static/togglebutton.js b/sphinx_togglebutton/_static/togglebutton.js index 41b77f9..c2454c6 100644 --- a/sphinx_togglebutton/_static/togglebutton.js +++ b/sphinx_togglebutton/_static/togglebutton.js @@ -1,3 +1,14 @@ +/** + * Add Toggle Buttons to elements + */ + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +const path_static = `${doc_url_root}_static/`; + var initToggleItems = () => { var itemsToToggle = document.querySelectorAll(togglebuttonSelector); console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) @@ -15,8 +26,7 @@ var initToggleItems = () => { // This is the button that will be added to each item to trigger the toggle var collapseButton = ` `; // Add the button HTML to this element and assign it as a variable to use later @@ -60,7 +70,12 @@ var toggleHidden = (button) => { } var toggleClickHandler = (click) => { - button = document.getElementById(click.target.dataset['button']); + if (click.target.tagName == "IMG") { + parent = click.target.parentElement; + } else { + parent = click.target; + } + button = document.getElementById(parent.dataset['button']); toggleHidden(button); } From 2109a9c02b103e266ddd41910f5f72b803ddabe5 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Wed, 2 Feb 2022 13:20:10 -0800 Subject: [PATCH 02/16] Update css --- sphinx_togglebutton/_static/togglebutton.css_t | 2 +- sphinx_togglebutton/_static/togglebutton.js | 2 +- tox.ini | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sphinx_togglebutton/_static/togglebutton.css_t b/sphinx_togglebutton/_static/togglebutton.css_t index e27c4bc..cecab09 100644 --- a/sphinx_togglebutton/_static/togglebutton.css_t +++ b/sphinx_togglebutton/_static/togglebutton.css_t @@ -46,7 +46,7 @@ margin-right: 0.5em; right: 0em; position: absolute; - top: .2em; + top: .3em; } /* General button style */ diff --git a/sphinx_togglebutton/_static/togglebutton.js b/sphinx_togglebutton/_static/togglebutton.js index c2454c6..c0819ba 100644 --- a/sphinx_togglebutton/_static/togglebutton.js +++ b/sphinx_togglebutton/_static/togglebutton.js @@ -25,7 +25,7 @@ var initToggleItems = () => { // This is the button that will be added to each item to trigger the toggle var collapseButton = ` - `; diff --git a/tox.ini b/tox.ini index c9d307c..e5ac620 100644 --- a/tox.ini +++ b/tox.ini @@ -11,6 +11,8 @@ recreate = false description = Build the documentation extras = sphinx +deps = + -e. commands = sphinx-build \ -n -b {posargs:html} docs/ docs/_build/{posargs:html} @@ -19,6 +21,7 @@ commands = description = Auto-build and preview the documentation in the browser deps = sphinx-autobuild + -e. extras = sphinx commands = From 56d6eaa022eebb26778361e04fc327d866cd9dcb Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Wed, 2 Feb 2022 14:25:09 -0800 Subject: [PATCH 03/16] Fixing outline --- sphinx_togglebutton/_static/togglebutton.css_t | 12 ++++++++---- sphinx_togglebutton/_static/togglebutton.js | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/sphinx_togglebutton/_static/togglebutton.css_t b/sphinx_togglebutton/_static/togglebutton.css_t index cecab09..a561c2a 100644 --- a/sphinx_togglebutton/_static/togglebutton.css_t +++ b/sphinx_togglebutton/_static/togglebutton.css_t @@ -51,8 +51,16 @@ /* General button style */ button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ background: none; + border-radius: 100%; border: none; + outline: none; + + /* Positioning just to the right of elements */ right: -2.5em; margin-left: -2.5em; /* A hack to keep code blocks from being pushed left */ position: relative; @@ -75,10 +83,6 @@ img.tb-icon { transition: transform .2s ease-out; } -img.tb-icon:focus-visible { - outline: none; -} - .toggle-button-hidden img.tb-icon { transform: rotate(90deg); } diff --git a/sphinx_togglebutton/_static/togglebutton.js b/sphinx_togglebutton/_static/togglebutton.js index c0819ba..365c6cc 100644 --- a/sphinx_togglebutton/_static/togglebutton.js +++ b/sphinx_togglebutton/_static/togglebutton.js @@ -25,7 +25,7 @@ var initToggleItems = () => { // This is the button that will be added to each item to trigger the toggle var collapseButton = ` - `; From f17a8201d34b344273e8d608d3e69c1b74ff176d Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Wed, 2 Feb 2022 14:35:55 -0800 Subject: [PATCH 04/16] Fixing colors --- docs/use.md | 14 ++++++++++++++ sphinx_togglebutton/_static/togglebutton.css_t | 2 ++ 2 files changed, 16 insertions(+) diff --git a/docs/use.md b/docs/use.md index baa9d55..0fb5f51 100644 --- a/docs/use.md +++ b/docs/use.md @@ -121,6 +121,20 @@ This will generate the following block: This is my note. ::: +### Change the toggle button's background + +You can apply some extra styles to the toggle button to achieve the look you want. +This is particularly useful if the color of the toggle button does not contrast with the background of an admonition. + +To style the toggle button, [add a custom CSS file to your documentation](https://docs.readthedocs.io/en/stable/guides/adding-custom-css.html) and include a custom CSS selector like so: + +```scss +// Turn the background light grey +button.toggle-button { + background: lightgrey; +} +``` + (toggle-directive)= ## Toggle any content with the toggle directive diff --git a/sphinx_togglebutton/_static/togglebutton.css_t b/sphinx_togglebutton/_static/togglebutton.css_t index a561c2a..222f50b 100644 --- a/sphinx_togglebutton/_static/togglebutton.css_t +++ b/sphinx_togglebutton/_static/togglebutton.css_t @@ -66,7 +66,9 @@ button.toggle-button { position: relative; float: right; width: 1.5em; + height: 1.5em; padding: 0px; + display: flex; } @media (min-width: 768px) { From 1e88582be7707991b6524d4a936f6791e4810a55 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Wed, 2 Feb 2022 14:39:14 -0800 Subject: [PATCH 05/16] Extra themes for testing --- docs/conf.py | 3 ++- tox.ini | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 967814f..8f53669 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -74,8 +74,9 @@ # a list of builtin themes. # html_theme = "sphinx_book_theme" -# html_theme = "sphinx_rtd_theme" +# html_theme = "sphinx_rtd_theme" # These are just for testing # html_theme = "alabaster" +# html_theme = "furo" html_theme_options = { "repository_url": "https://github.com/executablebooks/sphinx-togglebutton", diff --git a/tox.ini b/tox.ini index e5ac620..5539595 100644 --- a/tox.ini +++ b/tox.ini @@ -13,6 +13,9 @@ extras = sphinx deps = -e. + sphinx_rtd_theme + furo + alabaster commands = sphinx-build \ -n -b {posargs:html} docs/ docs/_build/{posargs:html} @@ -20,8 +23,11 @@ commands = [testenv:docs-live] description = Auto-build and preview the documentation in the browser deps = - sphinx-autobuild -e. + sphinx-autobuild + sphinx_rtd_theme + furo + alabaster extras = sphinx commands = From ab7af60881a20bc784d47123fdb5583122fd3995 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Wed, 2 Feb 2022 14:42:22 -0800 Subject: [PATCH 06/16] Sphinx Design --- docs/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index ab61516..60ed6ab 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,11 +31,11 @@ a = "wow, very python" See {ref}`usage` for more information. -:::{admonition} Check out sphinx-panels as well! +:::{admonition} Check out sphinx-design as well! :class: tip For a bootstrap-based "dropdown" directive that uses pure CSS, check out -[Sphinx Panels](https://sphinx-panels.readthedocs.io/en/latest/#dropdown-usage) +[Sphinx Design](https://sphinx-design.readthedocs.io/en/latest/dropdowns.html) ::: ```{toctree} From 5dd15110821cfb855492924b6563d7e044714f5e Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Wed, 2 Feb 2022 17:09:05 -0800 Subject: [PATCH 07/16] Wide toggle buttons instead of margin --- .../_static/togglebutton.css_t | 107 +++++++++++------- sphinx_togglebutton/_static/togglebutton.js | 77 +++++++------ 2 files changed, 114 insertions(+), 70 deletions(-) diff --git a/sphinx_togglebutton/_static/togglebutton.css_t b/sphinx_togglebutton/_static/togglebutton.css_t index 222f50b..1f74d58 100644 --- a/sphinx_togglebutton/_static/togglebutton.css_t +++ b/sphinx_togglebutton/_static/togglebutton.css_t @@ -1,25 +1,27 @@ +/** + * Admonition-based toggles + */ + /* Visibility of the target */ -.toggle, .admonition.toggle .admonition-title ~ * { +.admonition.toggle .admonition-title ~ * { transition: opacity .5s, height .5s; } -.toggle-hidden:not(.admonition) { - visibility: hidden; - opacity: 0; - height: 1.5em; - margin: 0px; - padding: 0px; -} - /* Overrides for admonition toggles */ +/* Toggle buttons inside admonitions so we see the title */ +.toggle.admonition { + position: relative; +} + /* Titles should cut off earlier to avoid overlapping w/ button */ -.admonition.toggle p.admonition-title { +.toggle.admonition .admonition-title { padding-right: 25%; + cursor: pointer; } /* hides all the content of a page until de-toggled */ -.admonition.toggle-hidden .admonition-title ~ * { +.toggle-hidden.admonition .admonition-title ~ * { height: 0; margin: 0; float: left; /* so they overlap when hidden */ @@ -27,29 +29,7 @@ visibility: hidden; } -/* Toggle buttons inside admonitions so we see the title */ -.toggle.admonition { - position: relative; -} - -/* Clicking the title will toggle the admonition, so a pointer makes this clearer */ -.toggle.admonition .admonition-title { - cursor: pointer; -} - -.toggle.admonition.admonition-title:after { - content: ""; -} - -/* Note, we'll over-ride this in sphinx-book-theme */ -.toggle.admonition button.toggle-button { - margin-right: 0.5em; - right: 0em; - position: absolute; - top: .3em; -} - -/* General button style */ +/* General button style and position*/ button.toggle-button { /** * Background and shape. By default there's no background @@ -60,10 +40,11 @@ button.toggle-button { border: none; outline: none; - /* Positioning just to the right of elements */ - right: -2.5em; - margin-left: -2.5em; /* A hack to keep code blocks from being pushed left */ - position: relative; + /* Positioning just inside the amonition title */ + margin-right: 0.5em; + position: absolute; + right: 0em; + top: .3em; float: right; width: 1.5em; height: 1.5em; @@ -71,6 +52,7 @@ button.toggle-button { display: flex; } +/* Display the toggle hint on wide screens */ @media (min-width: 768px) { button.toggle-button.toggle-button-hidden:before { content: "{{ togglebutton_hint }}"; @@ -81,6 +63,7 @@ button.toggle-button { } } +/* Icon behavior */ img.tb-icon { transition: transform .2s ease-out; } @@ -89,3 +72,51 @@ img.tb-icon { transform: rotate(90deg); } +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; + height: auto; + max-height: 2.5em; + overflow-y: hidden; + transition: max-height .5s ease-out; +} + +details.toggle-details summary { + list-style: none; + border-radius: .2em; + border: 1px solid #ccc; + background: #f8f8f8; + padding: 0.2em .5em .2em .5em; +} + +details.toggle-details summary img { + float: right; + height: 1.5em; + transition: transform .2s ease-out; +} + +details.toggle-details summary ~ * { + transition: opacity .2s ease-out; + opacity: 0; +} + +details.toggle-details[open] { + max-height: 99em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary img { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + opacity: 1; +} diff --git a/sphinx_togglebutton/_static/togglebutton.js b/sphinx_togglebutton/_static/togglebutton.js index 365c6cc..3da5c5e 100644 --- a/sphinx_togglebutton/_static/togglebutton.js +++ b/sphinx_togglebutton/_static/togglebutton.js @@ -14,44 +14,57 @@ var initToggleItems = () => { console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) // Add the button to each admonition and hook up a callback to toggle visibility itemsToToggle.forEach((item, index) => { - // Generate unique IDs for this item - var toggleID = `toggle-${index}`; - var buttonID = `button-${toggleID}`; - - item.setAttribute('id', toggleID); - if (!item.classList.contains("toggle")){ - item.classList.add("toggle"); - } + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; - // This is the button that will be added to each item to trigger the toggle - var collapseButton = ` - `; + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; - // Add the button HTML to this element and assign it as a variable to use later - if (item.classList.contains("admonition")) { - // If it's an admonition block, then we'll add the button inside item.insertAdjacentHTML("afterbegin", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + thisButton.addEventListener('click', toggleClickHandler); + + // If admonition has a single direct-child title make it clickable. + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } } else { - item.insertAdjacentHTML('beforebegin', collapseButton); - } - thisButton = document.getElementById(buttonID); - - // Add click handlers for the button + admonition title (if admonition) - thisButton.addEventListener('click', toggleClickHandler); + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ Click to toggle +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); - // If admonition has a single direct-child title make it clickable. - admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) - if (admonitionTitle) { - admonitionTitle.addEventListener('click', toggleClickHandler); - admonitionTitle.dataset.target = toggleID - admonitionTitle.dataset.button = buttonID - } + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) - // Now hide the item for this toggle button unless explicitly noted to show - if (!item.classList.contains("toggle-shown")) { - toggleHidden(thisButton); + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.open = true; + } } }) }; From 203dea2b508dbd3d18a4de2088980758dfdeaed0 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Wed, 2 Feb 2022 17:14:46 -0800 Subject: [PATCH 08/16] Summary border --- sphinx_togglebutton/_static/togglebutton.css_t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx_togglebutton/_static/togglebutton.css_t b/sphinx_togglebutton/_static/togglebutton.css_t index 1f74d58..324df26 100644 --- a/sphinx_togglebutton/_static/togglebutton.css_t +++ b/sphinx_togglebutton/_static/togglebutton.css_t @@ -89,7 +89,7 @@ details.toggle-details { details.toggle-details summary { list-style: none; border-radius: .2em; - border: 1px solid #ccc; + border: 1px solid #eee; background: #f8f8f8; padding: 0.2em .5em .2em .5em; } From b3000287df545261d42a86fc9b81a81d906926e2 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Wed, 2 Feb 2022 17:25:26 -0800 Subject: [PATCH 09/16] Fade --- sphinx_togglebutton/_static/togglebutton.css_t | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sphinx_togglebutton/_static/togglebutton.css_t b/sphinx_togglebutton/_static/togglebutton.css_t index 324df26..adfe124 100644 --- a/sphinx_togglebutton/_static/togglebutton.css_t +++ b/sphinx_togglebutton/_static/togglebutton.css_t @@ -4,7 +4,7 @@ /* Visibility of the target */ .admonition.toggle .admonition-title ~ * { - transition: opacity .5s, height .5s; + transition: opacity .3s, height .3s; } /* Overrides for admonition toggles */ @@ -97,12 +97,7 @@ details.toggle-details summary { details.toggle-details summary img { float: right; height: 1.5em; - transition: transform .2s ease-out; -} - -details.toggle-details summary ~ * { - transition: opacity .2s ease-out; - opacity: 0; + transition: transform .3s ease-out; } details.toggle-details[open] { @@ -118,5 +113,10 @@ details.toggle-details[open] summary img { } details.toggle-details[open] summary ~ * { - opacity: 1; + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} } From c2397cac04e74245b1b2aba75c56c90fa9595d1c Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Wed, 2 Feb 2022 17:32:30 -0800 Subject: [PATCH 10/16] Fade --- sphinx_togglebutton/_static/togglebutton.css_t | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sphinx_togglebutton/_static/togglebutton.css_t b/sphinx_togglebutton/_static/togglebutton.css_t index adfe124..be60fe5 100644 --- a/sphinx_togglebutton/_static/togglebutton.css_t +++ b/sphinx_togglebutton/_static/togglebutton.css_t @@ -80,10 +80,6 @@ img.tb-icon { /* Details blocks */ details.toggle-details { margin: 1em 0; - height: auto; - max-height: 2.5em; - overflow-y: hidden; - transition: max-height .5s ease-out; } details.toggle-details summary { @@ -100,10 +96,6 @@ details.toggle-details summary img { transition: transform .3s ease-out; } -details.toggle-details[open] { - max-height: 99em; -} - details.toggle-details[open] summary { margin-bottom: .5em; } From 58a4be0281ab5db944a7843ccc7fd43576df0d33 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Thu, 3 Feb 2022 10:38:29 -0800 Subject: [PATCH 11/16] Clean up design --- docs/conf.py | 1 - docs/use.md | 178 ++++++++---------- setup.py | 2 +- sphinx_togglebutton/__init__.py | 10 +- .../_static/togglebutton-chevron.svg | 4 - .../{togglebutton.css_t => togglebutton.css} | 27 +-- sphinx_togglebutton/_static/togglebutton.js | 55 ++++-- 7 files changed, 138 insertions(+), 139 deletions(-) delete mode 100644 sphinx_togglebutton/_static/togglebutton-chevron.svg rename sphinx_togglebutton/_static/{togglebutton.css_t => togglebutton.css} (81%) diff --git a/docs/conf.py b/docs/conf.py index 8f53669..fb638ce 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -103,7 +103,6 @@ # # html_sidebars = {} - # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. diff --git a/docs/use.md b/docs/use.md index 0fb5f51..2465d61 100644 --- a/docs/use.md +++ b/docs/use.md @@ -3,140 +3,98 @@ This page covers how to use and configure / customize `sphinx-togglebutton`. -There are two main ways to use `sphinx-togglebutton`: +There are three main ways to use `sphinx-togglebutton`: +- Wrap arbitrary objects in a toggle button via a CSS selector - Collapse admonitions with the `dropdown` class - Make arbitrary chunks of content "toggle-able" with the `toggle` directive -Both are described below +Each is described below -(dropdown-admonitions)= -## Collapse admonitions with the `dropdown` class - -Making dropdown admonitions allows you to insert extra information in your document -without forcing the user to see that content. For example: +(use:css-selector)= +## Collapse a block of content with a CSS selector -:::{admonition} What could be inside this warning? -:class: warning, dropdown +You can hide any content and display a toggle button to show it by using certain CSS classes. +`sphinx-togglebutton` will wrap elements with these classes in a `
` block like so: -A whale of a joke! - -```{image} https://media.giphy.com/media/FaKV1cVKlVRxC/giphy.gif +```html +
+ Click to show + +
``` -::: - -Create a dropdown admonition by adding the `dropdown` class to an admonition directive. -For example, like so: -::::{tab-set} - -:::{tab-item} MyST +:::{admonition} example +:class: tip +This MyST Markdown: ````md - -```{note} -:class: dropdown - -My note +```{image} https://media.giphy.com/media/FaKV1cVKlVRxC/giphy.gif +:class: toggle ``` ```` - -::: - -:::{tab-item} reStructuredText - -```rst -.. note:: - :class: dropdown - - My note +results in: +```{image} https://media.giphy.com/media/FaKV1cVKlVRxC/giphy.gif +:class: toggle ``` - ::: -:::: - -You can use a custom admonition title and apply the style of a "built-in" -admonition (e.g., `note`, `warning`, etc) with the `admonition::` directive: -::::{tab-set} +### Configure the CSS selector used to insert toggle buttons -:::{tab-item} MyST - -````md -```{admonition} Here's my title -:class: dropdown, warning +By default, `sphinx-togglebutton` will use this selector: -My note ``` -```` - -::: - -:::{tab-item} reStructuredText - -```rst -.. admonition:: Here's my title - :class: dropdown, warning - - My note +.toggle, .admonition.dropdown ``` -::: -:::: - -Creates: +However, you can customize this behavior with the `togglebutton_selector` configuration value. +To specify the selector to use, pass a valid CSS selector as a string: -:::{admonition} Here's my title -:class: dropdown, warning +:::{admonition} example +:class: tip +Configure `sphinx-togglebutton` to look for a `.toggle-this-element` class and an element with ID `#my-special-id` **instead of** `.toggle` and `.admonition.dropdown`. -My custom admonition! +```python +sphinx_togglebutton_selector = ".toggle-this-element, #my-special-id" +``` ::: -To show the content by default, add a `toggle-shown` class as well. - -:::{tab-set-code} +(dropdown-admonitions)= +## Collapse admonitions with the `dropdown` class -````markdown -```{note} -:class: dropdown, toggle-shown +`sphinx-togglebutton` treats admonitions as a special case if they are selected. +If a Sphinx admonition matches the toggle button selector, then its title will be displayed with a button to reveal its content. -This is my note. +:::{admonition} example +:class: tip +````md +```{admonition} This will be shown +:class: dropdown +And this will be hidden! ``` ```` - -```rst -.. note:: - :class: dropdown, toggle-shown - - This is my note. +results in +```{admonition} This will be shown +:class: dropdown +And this will be hidden! ``` - ::: -This will generate the following block: +This works for any kind of Sphinx admoniton: :::{note} -:class: dropdown, toggle-shown - -This is my note. +:class: dropdown +A note! ::: -### Change the toggle button's background - -You can apply some extra styles to the toggle button to achieve the look you want. -This is particularly useful if the color of the toggle button does not contrast with the background of an admonition. - -To style the toggle button, [add a custom CSS file to your documentation](https://docs.readthedocs.io/en/stable/guides/adding-custom-css.html) and include a custom CSS selector like so: +:::{warning} +:class: dropdown +A warning! +::: -```scss -// Turn the background light grey -button.toggle-button { - background: lightgrey; -} -``` (toggle-directive)= -## Toggle any content with the toggle directive +## Use the `{toggle}` directive to toggle blocks of content To add toggle-able content, use the **toggle directive**. This directive will wrap its content in a toggle-able container. You can call it like so: @@ -183,12 +141,32 @@ It results in the following: Here is my toggle-able content! ::: -## Control the togglebutton hover text +## Control the togglebutton hint text -You can control the "hint" text that is displayed next to togglebuttons when -their content is collapsed. To do so, use the following configuration variable -in your `conf.py` file: +You can control the "hint" text that is displayed next to togglebuttons. +To do so, use the following configuration variable in your `conf.py` file: ```python -togglebutton_hint = "My text" +togglebutton_hint = "Displayed when the toggle is closed." +togglebutton_hint_hide = "Displayed when the toggle is open." ``` + +## Change the toggle icon color + +You can apply some extra styles to the toggle button to achieve the look you want. +This is particularly useful if the color of the toggle button does not contrast with the background of an admonition. + +To style the toggle button, [add a custom CSS file to your documentation](https://docs.readthedocs.io/en/stable/guides/adding-custom-css.html) and include a custom CSS selector like so: + +```scss +// Turn the color red... +// ...with admonition toggle buttons +button.toggle-button { + color: red; +} + +// ...with content block toggle buttons +.toggle-button summary { + color: red; +} +``` \ No newline at end of file diff --git a/setup.py b/setup.py index aadf627..cafd6ff 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ license="MIT License", packages=find_packages(), package_data={ - "sphinx_togglebutton": ["_static/togglebutton.css_t", "_static/togglebutton.js", "_static/togglebutton-chevron.svg"] + "sphinx_togglebutton": ["_static/togglebutton.css", "_static/togglebutton.js", "_static/togglebutton-chevron.svg"] }, install_requires=["setuptools", "wheel", "sphinx", "docutils"], extras_require={"sphinx": ["matplotlib", "myst_nb", "sphinx_book_theme", "sphinx_design"]}, diff --git a/sphinx_togglebutton/__init__.py b/sphinx_togglebutton/__init__.py index 4172aba..6cbeba9 100644 --- a/sphinx_togglebutton/__init__.py +++ b/sphinx_togglebutton/__init__.py @@ -11,9 +11,11 @@ def st_static_path(app): app.config.html_static_path.append(static_path) -def add_to_context(app, config): +def initialize_js_assets(app, config): # Update the global context - config.html_context.update({"togglebutton_hint": config.togglebutton_hint}) + app.add_js_file(None, body=f"let toggleHintShow = '{config.togglebutton_hint}';") + app.add_js_file(None, body=f"let toggleHintHide = '{config.togglebutton_hint_hide}';") + app.add_js_file("togglebutton.js") # This function reads in a variable and inserts it into JavaScript @@ -56,11 +58,11 @@ def setup(app): # Tell Sphinx about this configuration variable app.add_config_value("togglebutton_selector", ".toggle, .admonition.dropdown", "html") app.add_config_value("togglebutton_hint", "Click to show", "html") - app.add_js_file("togglebutton.js") + app.add_config_value("togglebutton_hint_hide", "Click to hide", "html") # Run the function after the builder is initialized app.connect("builder-inited", insert_custom_selection_config) - app.connect("config-inited", add_to_context) + app.connect("config-inited", initialize_js_assets) app.add_directive("toggle", Toggle) return { "version": __version__, diff --git a/sphinx_togglebutton/_static/togglebutton-chevron.svg b/sphinx_togglebutton/_static/togglebutton-chevron.svg deleted file mode 100644 index 6686bac..0000000 --- a/sphinx_togglebutton/_static/togglebutton-chevron.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/sphinx_togglebutton/_static/togglebutton.css_t b/sphinx_togglebutton/_static/togglebutton.css similarity index 81% rename from sphinx_togglebutton/_static/togglebutton.css_t rename to sphinx_togglebutton/_static/togglebutton.css index be60fe5..0bad5d4 100644 --- a/sphinx_togglebutton/_static/togglebutton.css_t +++ b/sphinx_togglebutton/_static/togglebutton.css @@ -36,7 +36,6 @@ button.toggle-button { * but users can style as they wish */ background: none; - border-radius: 100%; border: none; outline: none; @@ -44,7 +43,7 @@ button.toggle-button { margin-right: 0.5em; position: absolute; right: 0em; - top: .3em; + top: .5em; float: right; width: 1.5em; height: 1.5em; @@ -55,7 +54,7 @@ button.toggle-button { /* Display the toggle hint on wide screens */ @media (min-width: 768px) { button.toggle-button.toggle-button-hidden:before { - content: "{{ togglebutton_hint }}"; + content: attr(data-toggle-hint); /* This will be filled in by JS */ position: absolute; font-size: .8em; left: -6.5em; @@ -64,11 +63,14 @@ button.toggle-button { } /* Icon behavior */ -img.tb-icon { +.tb-icon { transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ } -.toggle-button-hidden img.tb-icon { +.toggle-button-hidden .tb-icon { transform: rotate(90deg); } @@ -83,24 +85,25 @@ details.toggle-details { } details.toggle-details summary { + display: flex; + align-items: center; + width: fit-content; list-style: none; border-radius: .2em; - border: 1px solid #eee; + border: 1px solid #ccc; background: #f8f8f8; - padding: 0.2em .5em .2em .5em; + padding: 0.2em 1em .2em 0; } -details.toggle-details summary img { - float: right; - height: 1.5em; - transition: transform .3s ease-out; +details.toggle-details .tb-icon { + margin-left: .2em; } details.toggle-details[open] summary { margin-bottom: .5em; } -details.toggle-details[open] summary img { +details.toggle-details[open] summary .tb-icon { transform: rotate(90deg); } diff --git a/sphinx_togglebutton/_static/togglebutton.js b/sphinx_togglebutton/_static/togglebutton.js index 3da5c5e..1ce6047 100644 --- a/sphinx_togglebutton/_static/togglebutton.js +++ b/sphinx_togglebutton/_static/togglebutton.js @@ -2,12 +2,11 @@ * Add Toggle Buttons to elements */ -let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; -if (doc_url_root == '#') { - doc_url_root = ''; -} - -const path_static = `${doc_url_root}_static/`; +let toggleChevron = ` + + + +`; var initToggleItems = () => { var itemsToToggle = document.querySelectorAll(togglebuttonSelector); @@ -26,8 +25,8 @@ var initToggleItems = () => { } // This is the button that will be added to each item to trigger the toggle var collapseButton = ` - `; item.insertAdjacentHTML("afterbegin", collapseButton); @@ -35,8 +34,6 @@ var initToggleItems = () => { // Add click handlers for the button + admonition title (if admonition) thisButton.addEventListener('click', toggleClickHandler); - - // If admonition has a single direct-child title make it clickable. admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) if (admonitionTitle) { admonitionTitle.addEventListener('click', toggleClickHandler); @@ -53,7 +50,10 @@ var initToggleItems = () => { // Define the structure of the details block and insert it as a sibling var detailsBlock = `
- Click to toggle + + ${toggleChevron} + ${toggleHintShow} +
`; item.insertAdjacentHTML("beforebegin", detailsBlock); @@ -61,9 +61,28 @@ var initToggleItems = () => { details = item.previousElementSibling details.appendChild(item) + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span").innerText = toggleHintShow; + } else { + summary.querySelector("span").innerText = toggleHintHide; + } + + }); + // If we have a toggle-shown class, open details block should be open if (item.classList.contains("toggle-shown")) { - details.open = true; + details.click(); } } }) @@ -83,13 +102,15 @@ var toggleHidden = (button) => { } var toggleClickHandler = (click) => { - if (click.target.tagName == "IMG") { - parent = click.target.parentElement; + if (click.target.classList.contains("admonition-title")) { + // If it's an admonition title, the button will be just before + button = click.target.previousElementSibling; } else { - parent = click.target; + // If not, we've clicked the button itself or its content, so search upwards + button = click.currentTarget; } - button = document.getElementById(parent.dataset['button']); - toggleHidden(button); + target = document.getElementById(button.dataset['button']); + toggleHidden(target); } // If we want to blanket-add toggle classes to certain cells From a456c7bc2426569ff912442be30acced91c8a573 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Thu, 3 Feb 2022 12:09:45 -0800 Subject: [PATCH 12/16] Update sphinx_togglebutton/_static/togglebutton.css --- sphinx_togglebutton/_static/togglebutton.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx_togglebutton/_static/togglebutton.css b/sphinx_togglebutton/_static/togglebutton.css index 0bad5d4..38d2e53 100644 --- a/sphinx_togglebutton/_static/togglebutton.css +++ b/sphinx_togglebutton/_static/togglebutton.css @@ -89,7 +89,7 @@ details.toggle-details summary { align-items: center; width: fit-content; list-style: none; - border-radius: .2em; + border-radius: .4em; border: 1px solid #ccc; background: #f8f8f8; padding: 0.2em 1em .2em 0; From a19fab6aa46ea5099b6e958ff3a4887e4f9dca58 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Fri, 4 Feb 2022 11:44:32 -0800 Subject: [PATCH 13/16] Minor spacing changes --- docs/use.md | 2 +- sphinx_togglebutton/_static/togglebutton.css | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/use.md b/docs/use.md index 2465d61..0d98352 100644 --- a/docs/use.md +++ b/docs/use.md @@ -141,7 +141,7 @@ It results in the following: Here is my toggle-able content! ::: -## Control the togglebutton hint text +## Change the button hint text You can control the "hint" text that is displayed next to togglebuttons. To do so, use the following configuration variable in your `conf.py` file: diff --git a/sphinx_togglebutton/_static/togglebutton.css b/sphinx_togglebutton/_static/togglebutton.css index 38d2e53..20e6c85 100644 --- a/sphinx_togglebutton/_static/togglebutton.css +++ b/sphinx_togglebutton/_static/togglebutton.css @@ -45,8 +45,6 @@ button.toggle-button { right: 0em; top: .5em; float: right; - width: 1.5em; - height: 1.5em; padding: 0px; display: flex; } @@ -70,6 +68,11 @@ button.toggle-button { stroke: currentColor; /* So that we inherit the color of other text */ } +details.toggle-details .tb-icon { + height: 1.3em; + width: 1.3em; +} + .toggle-button-hidden .tb-icon { transform: rotate(90deg); } @@ -92,7 +95,8 @@ details.toggle-details summary { border-radius: .4em; border: 1px solid #ccc; background: #f8f8f8; - padding: 0.2em 1em .2em 0; + padding: 0.4em 1em 0.4em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: .9em; } details.toggle-details .tb-icon { From 1f7a3464f83a61ee481a6e2b2ff3282fee8522f2 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Fri, 4 Feb 2022 12:07:23 -0800 Subject: [PATCH 14/16] Padding --- sphinx_togglebutton/_static/togglebutton.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sphinx_togglebutton/_static/togglebutton.css b/sphinx_togglebutton/_static/togglebutton.css index 20e6c85..2c86bb4 100644 --- a/sphinx_togglebutton/_static/togglebutton.css +++ b/sphinx_togglebutton/_static/togglebutton.css @@ -99,10 +99,6 @@ details.toggle-details summary { font-size: .9em; } -details.toggle-details .tb-icon { - margin-left: .2em; -} - details.toggle-details[open] summary { margin-bottom: .5em; } From 38b3dec2f7d3bd39ed14e5bb6720b73d17fb0776 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Fri, 4 Feb 2022 14:08:02 -0800 Subject: [PATCH 15/16] Landing page --- docs/index.md | 59 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/docs/index.md b/docs/index.md index 60ed6ab..c4e8704 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,35 +1,50 @@ # `sphinx-togglebutton` A small sphinx extension to add "toggle button" elements to sections of your page. -This allows you to: +For example: -- Collapse admonitions (notes, warnings, etc) so that their content is hidden - until users click a toggle button. See {ref}`dropdown-admonitions`. -- Collapse arbitrary chunks of content on your page with a `toggle` directive. - See {ref}`toggle-directive`. +## Collapse admonitions -:::{admonition} For example, click the "+" button to the right: +You can collapse admonitions (notes, warnings, etc) so that their content is hidden until users click the admonition title. + +:::{admonition} Example: click this title to toggle the content +:class: dropdown +You can toggle any admonition to hide its content behind a user click! +Do so by adding a `dropdown` class to the admonition, like this: + +```` +```{note} :class: dropdown -Here's a toggled note! You can put all kinds of stuff in here! +Some content +``` +```` ::: -You can also add a toggle button to arbitrary chunks of content. -For example, click the toggle button to the right just below. +See {ref}`dropdown-admonitions` for more information. + +## Hide any content behind a toggle button + +You can also hide arbitrary content behind a toggle button. +When users press the button, they will see the content. +For example: ::::{toggle} -:::{admonition} Wow! -:class: tip -It's a code block! +This is a toggled content block! +It was added like this: -```python -a = "wow, very python" +```` +```{toggle} +This is a toggled content block! ``` -::: +```` + :::: -See {ref}`usage` for more information. +You can either do this with a `{toggle}` directive, or by adding a `toggle` CSS class to any elements you'd like hidden behind a toggle button. + +See [](use:css-selector) for more details. :::{admonition} Check out sphinx-design as well! :class: tip @@ -38,11 +53,6 @@ For a bootstrap-based "dropdown" directive that uses pure CSS, check out [Sphinx Design](https://sphinx-design.readthedocs.io/en/latest/dropdowns.html) ::: -```{toctree} -use -reference/index -``` - ## Installation You can install `sphinx-togglebutton` with `pip`: @@ -65,3 +75,10 @@ extensions = [ ``` See {ref}`usage` for information about how to use `sphinx-togglebutton`. + + +```{toctree} +:maxdepth: 2 +use +reference/index +``` \ No newline at end of file From 84b305dda7baf6d19f415aa53be54c90c75d97d3 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Fri, 4 Feb 2022 14:33:16 -0800 Subject: [PATCH 16/16] Docs --- docs/use.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/use.md b/docs/use.md index 0d98352..3df27fc 100644 --- a/docs/use.md +++ b/docs/use.md @@ -169,4 +169,9 @@ button.toggle-button { .toggle-button summary { color: red; } -``` \ No newline at end of file +``` + +## Printing behavior with toggle buttons + +When you print the screen while using `sphinx-togglebutton`, the toggle-able content will not show up. +To reveal it for printing, you must manually un-toggle the items and then print.