diff --git a/.github/workflows/lighthouserc.json b/.github/workflows/lighthouserc.json index a40703d6..495f3d93 100644 --- a/.github/workflows/lighthouserc.json +++ b/.github/workflows/lighthouserc.json @@ -9,9 +9,9 @@ }, "assert": { "assertions": { - "categories:performance": ["error", { "minScore": 0.85 }], - "categories:accessibility": ["error", { "minScore": 0.85 }], - "categories:best-practices": ["error", { "minScore": 0.85 }] + "categories:performance": ["error", { "minScore": 0.84 }], + "categories:accessibility": ["error", { "minScore": 0.84 }], + "categories:best-practices": ["error", { "minScore": 0.84 }] } } } diff --git a/docs/conf.py b/docs/conf.py index 22bc47f5..57a0e8ca 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -97,7 +97,7 @@ # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] html_css_files = ["custom.css"] -jupyter_execute_notebooks = "cache" +nb_execution_mode = "cache" thebe_config = { "repository_url": "https://github.com/binder-examples/jupyter-stacks-datascience", "repository_branch": "master", @@ -129,9 +129,7 @@ # For testing # "use_fullscreen_button": False, # "home_page_in_toc": True, - # "single_page": True, # "extra_footer": "Test", # DEPRECATED KEY - # "extra_navbar": "Test", # "show_navbar_depth": 2, } @@ -142,12 +140,12 @@ fontawesome_included = True post_auto_image = 1 post_auto_excerpt = 2 -execution_show_tb = "READTHEDOCS" in os.environ +nb_execution_show_tb = "READTHEDOCS" in os.environ bibtex_bibfiles = ["references.bib"] # To test that style looks good with common bibtex config bibtex_reference_style = "author_year" bibtex_default_style = "plain" - +numpydoc_show_class_members = False # for automodule:: urllib.parse stub file issue linkcheck_ignore = [ "http://someurl/release", # This is a fake link "https://doi.org", # These don't resolve properly and cause SSL issues diff --git a/docs/customize/footer-content.md b/docs/customize/footer-content.md new file mode 100644 index 00000000..80ef2efc --- /dev/null +++ b/docs/customize/footer-content.md @@ -0,0 +1,26 @@ +# Customize the content footer + +There is a content footer that spans the width of the page, and is visibile when you scroll to the bottom of the content. + +By default, the content footer has the following items: + +- `author.html`: Display the author of the page, if present. +- `copyright.html`: Display copyright information about the website. +- `last-updated.html`: Display the latest date that the website was updated. +- `extra-footer.html`: A placeholder for arbitrary HTML you may add (see [](content-footer:extra-footer)). + +(content-footer:extra-footer)= +## Add extra HTML to your content footer + +You may add custom HTML to the content footer via `conf.py`. +This is a shortcut in case you wish to avoid defining your own HTML template. + +To do so, use the `extra_footer` configuration and provide any HTML that you wish. +For example: + +```python +html_theme_options = { + ... + "extra_footer": "
hi there!
", +} +``` diff --git a/docs/customize/index.md b/docs/customize/index.md index d3c0f58a..f613b8b3 100644 --- a/docs/customize/index.md +++ b/docs/customize/index.md @@ -12,9 +12,6 @@ The following options are available via `html_theme_options` * - Key - Type - Description -* - `single_page` - - bool - - Remove the left sidebar and treat the site as a single page. See [](customize:single-page). * - `path_to_docs` - string - Path to the documentation, relative to the repository root (e.g. `docs/`). See [](customize:source-files). @@ -48,9 +45,6 @@ The following options are available via `html_theme_options` * - `show_navbar_depth` - int - Show children in the navigation bar down to the depth listed here. See [](sidebar:navbar-depth). -* - `extra_navbar` - - str - - Extra HTML to add below the sidebar footer. See [](custom-footer). * - `extra_footer` - str - Extra HTML to add in the footer of each page. @@ -66,10 +60,10 @@ The following sections describe a few ways to customize the theme in more depth. ```{toctree} sidebar-primary.md sidebar-secondary.md +footer-content.md announcements.md header.md download.md source-files.md custom-css.md -single-page.md ``` diff --git a/docs/customize/sidebar-primary.md b/docs/customize/sidebar-primary.md index b959aab4..a762f3ad 100644 --- a/docs/customize/sidebar-primary.md +++ b/docs/customize/sidebar-primary.md @@ -36,22 +36,6 @@ By default, this theme comes with these three theme-specific sidebar elements en - `sidebar-logo.html`: Displays the logo and site title. - `search-field.html`: A bootstrap-based search bar (from the [PyData Sphinx Theme](https://pydata-sphinx-theme.readthedocs.io/)) - `sbt-sidebar-nav.html`: A bootstrap-based navigation menu for your book. -- `sbt-sidebar-footer`: A [configurable](custom-footer) snippet of HTML to add to the sidebar (by default it is placed at the bottom). - -(custom-footer)= -## Customize the sidebar footer - -You may choose your own HTML to include in the footer of your sidebar (or set it to be empty). To do so, set the following option in `conf.py`: - -```python -html_theme_options = { - ... - "extra_navbar": "

Your HTML

", - ... -} -``` - -This text will be placed at the bottom of the sidebar by default. ## Add a header to your Table of Contents diff --git a/docs/customize/single-page.md b/docs/customize/single-page.md deleted file mode 100644 index 5b1bd571..00000000 --- a/docs/customize/single-page.md +++ /dev/null @@ -1,14 +0,0 @@ -(customize:single-page)= -# Use a single-page version of this theme - -If your documentation only has a single page, and you don't need the left -navigation bar, then you may configure `sphinx-book-theme` to run in **single page mode** -with the following configuration: - -```python -html_theme_options = { - ... - "single_page": True - ... -} -``` diff --git a/docs/reference/special-theme-elements.md b/docs/reference/special-theme-elements.md index 3b805c22..a44261bb 100644 --- a/docs/reference/special-theme-elements.md +++ b/docs/reference/special-theme-elements.md @@ -218,7 +218,7 @@ how does it look? Markdown cell with images in sidebar - + ```` +++ diff --git a/pyproject.toml b/pyproject.toml index fb4e4d11..a3ba6f39 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ readme = "README.md" requires-python = ">=3.7" dependencies = [ "sphinx>=4,<6", - "pydata-sphinx-theme~=0.10.1", + "pydata-sphinx-theme~=0.12.0", "pyyaml", ] @@ -53,11 +53,11 @@ doc = [ "numpy", "matplotlib", "numpydoc", - "myst-nb~=0.13.2", + "myst-nb~=0.16.0", "nbclient", "pandas", "plotly", - "sphinx~=4.0", + "sphinx>=4.0,<6", "sphinx-design", "sphinx-examples", "sphinx-copybutton", @@ -67,11 +67,14 @@ doc = [ "sphinxcontrib-bibtex~=2.2", "sphinxcontrib-youtube", "sphinxext-opengraph", + # 8.7.0 broke the `ipython3` lexer in Sphinx so we want to avoid it + # remove this when 8.7.1 is released (and see below for another instance) + "ipython!=8.7.0", ] test = [ "beautifulsoup4>=4.6.1,<5", "coverage", - "myst-nb~=0.13.2", + "myst-nb~=0.16.0", "pytest~=7.1", "pytest-cov>=3,<5", "pytest-regressions>=2.0.1,<2.5.0", diff --git a/src/sphinx_book_theme/__init__.py b/src/sphinx_book_theme/__init__.py index 1e627e64..9469020a 100644 --- a/src/sphinx_book_theme/__init__.py +++ b/src/sphinx_book_theme/__init__.py @@ -19,6 +19,7 @@ """sphinx-book-theme version""" SPHINX_LOGGER = logging.getLogger(__name__) +DEFAULT_LOG_TYPE = "sphinxbooktheme" MESSAGE_CATALOG_NAME = "booktheme" @@ -59,7 +60,7 @@ def add_metadata_to_page(app, pagename, templatename, context, doctree): context["translate"] = translation # this is set in the html_theme context["theme_search_bar_text"] = translation( - context.get("theme_search_bar_text", "Search the docs ...") + context.get("theme_search_bar_text", "Search...") ) @@ -151,6 +152,19 @@ def update_mode_thebe_config(app): app.config.html_context["default_mode"] = "light" +def check_deprecation_keys(app): + """Warns about the deprecated keys.""" + + deprecated_config_list = ["single_page"] + for key in deprecated_config_list: + if key in app.env.config.html_theme_options: + SPHINX_LOGGER.warning( + f"'{key}' was deprecated from version 0.3.4 onwards. See the CHANGELOG for more information: https://github.com/executablebooks/sphinx-book-theme/blob/master/CHANGELOG.md" # noqa: E501 + f"[{DEFAULT_LOG_TYPE}]", + type=DEFAULT_LOG_TYPE, + ) + + class Margin(Sidebar): """Goes in the margin to the right of the page.""" @@ -180,6 +194,28 @@ def update_general_config(app, config): config.templates_path.append(os.path.join(theme_dir, "components")) +def update_templates(app, pagename, templatename, context, doctree): + """Update template names and assets for page build. + + This is a copy of what the pydata theme does here to include a new section + - https://github.com/pydata/pydata-sphinx-theme/blob/0a4894fab49befc59eb497811949a1d0ede626eb/src/pydata_sphinx_theme/__init__.py#L173 # noqa: E501 + """ + # Allow for more flexibility in template names + template_sections = ["theme_footer_content_items"] + for section in template_sections: + if context.get(section): + # Break apart `,` separated strings so we can use , in the defaults + if isinstance(context.get(section), str): + context[section] = [ + ii.strip() for ii in context.get(section).split(",") + ] + + # Add `.html` to templates with no suffix + for ii, template in enumerate(context.get(section)): + if not os.path.splitext(template)[1]: + context[section][ii] = template + ".html" + + def setup(app: Sphinx): # Register theme theme_dir = get_html_theme_path() @@ -192,9 +228,11 @@ def setup(app: Sphinx): # Events app.connect("builder-inited", update_mode_thebe_config) + app.connect("builder-inited", check_deprecation_keys) app.connect("config-inited", update_general_config) app.connect("html-page-context", add_metadata_to_page) app.connect("html-page-context", hash_html_assets) + app.connect("html-page-context", update_templates) # Nodes SideNoteNode.add_node(app) diff --git a/src/sphinx_book_theme/_transforms.py b/src/sphinx_book_theme/_transforms.py index f97aee6f..d30c8e3d 100644 --- a/src/sphinx_book_theme/_transforms.py +++ b/src/sphinx_book_theme/_transforms.py @@ -3,7 +3,6 @@ from docutils import nodes as docutil_nodes from sphinx import addnodes as sphinx_nodes from .nodes import SideNoteNode -import copy class HandleFootnoteTransform(SphinxPostTransform): @@ -64,7 +63,7 @@ def run(self, **kwargs: Any) -> None: # so it works w/ margin. Only show one or another depending on # screen width. node_parent = ref_node.parent - para_dup = copy.deepcopy(para) + para_dup = para.deepcopy() # looping to check parent node while not isinstance( node_parent, (docutil_nodes.section, sphinx_nodes.document) diff --git a/src/sphinx_book_theme/assets/scripts/index.js b/src/sphinx_book_theme/assets/scripts/index.js index eadafd0a..3ebfda12 100644 --- a/src/sphinx_book_theme/assets/scripts/index.js +++ b/src/sphinx_book_theme/assets/scripts/index.js @@ -97,9 +97,9 @@ var initTocHide = () => { // Hide the TOC if any margin content is displayed on the screen if (onScreenItems.length > 0) { - $("div.bd-sidebar-secondary").removeClass("show"); + $("div.bd-sidebar-secondary").addClass("hide"); } else { - $("div.bd-sidebar-secondary").addClass("show"); + $("div.bd-sidebar-secondary").removeClass("hide"); } }; let manageScrolledClassOnBody = (entries, observer) => { @@ -159,50 +159,13 @@ var initThebeSBT = () => { initThebe(); }; -/** - * Use Bootstrap helper function to enable tooltips. - */ -var initTooltips = () => { - $(document).ready(function () { - $('[data-toggle="tooltip"]').tooltip({ - trigger: "hover", - delay: { show: 500, hide: 100 }, - }); - }); -}; - -/** - * MutationObserver to move the ReadTheDocs button - */ -function initRTDObserver() { - const mutatedCallback = (mutationList, observer) => { - mutationList.forEach((mutation) => { - // Check whether the mutation is for RTD, which will have a specific structure - if (mutation.addedNodes.length === 0) { - return; - } - if (mutation.addedNodes[0].data === undefined) { - return; - } - if (mutation.addedNodes[0].data.search("Inserted RTD Footer") != -1) { - mutation.addedNodes.forEach((node) => { - document.getElementById("rtd-footer-container").append(node); - }); - } - }); - }; - - const observer = new MutationObserver(mutatedCallback); - const config = { childList: true }; - observer.observe(document.body, config); -} - /** * Add no print class to certain DOM elements */ function addNoPrint() { $("div.bd-sidebar-primary").addClass("noprint"); + $("div.bd-sidebar-secondary").addClass("noprint"); $("div.bd-header-article").addClass("noprint"); $("div.bd-header-announcement").addClass("noprint"); $("footer.bd-footer-article").addClass("noprint"); @@ -228,8 +191,6 @@ window.toggleFullScreen = toggleFullScreen; /** * Set up functions to load when the DOM is ready */ -sbRunWhenDOMLoaded(initTooltips); sbRunWhenDOMLoaded(initTocHide); -sbRunWhenDOMLoaded(initRTDObserver); sbRunWhenDOMLoaded(addNoPrint); sbRunWhenDOMLoaded(setMode); diff --git a/src/sphinx_book_theme/assets/styles/abstracts/_mixins.scss b/src/sphinx_book_theme/assets/styles/abstracts/_mixins.scss index 42eb45b8..c93f19c0 100644 --- a/src/sphinx_book_theme/assets/styles/abstracts/_mixins.scss +++ b/src/sphinx_book_theme/assets/styles/abstracts/_mixins.scss @@ -2,26 +2,8 @@ * SASS Mixins *********************************************/ /** -* Scrollbars should be thinner and slightly rounded, with a grey background -*/ -@mixin scrollbar-style() { - &::-webkit-scrollbar { - width: 0.3rem; - height: 0.3rem; - } - - &::-webkit-scrollbar-thumb { - background: #c1c1c1; - border-radius: 0.25rem; - - &:hover { - background: #a0a0a0; - } - } -} - -/** -* Hide the scrollbar until the element is overed, so keep the page clean +* Hide the scrollbar until the element is hovered, so keep the page clean +* Use this sparingly because it's not a great UX pattern. */ @mixin scrollbar-on-hover() { &:not(:hover) { @@ -30,24 +12,3 @@ } } } - -/** - * Header behavior on mobile - */ -@mixin header-height-mobile { - @media (max-width: $breakpoint-md) { - height: $header-article-height + 0.75em; - } -} - -/** - * Forces an element to fill the vertical screen space, - * but uses % on mobile because `vh` units behave weirdly on mobile. - * ref: https://stackoverflow.com/questions/37112218/css3-100vh-not-constant-in-mobile-browser - */ -@mixin fill-vertical-screen-space { - height: 100vh; // On wide screens force this to take up the whole viewport - @media (max-width: $breakpoint-md) { - height: 100%; // So that height behaves properly on mobile - } -} diff --git a/src/sphinx_book_theme/assets/styles/abstracts/_variables.scss b/src/sphinx_book_theme/assets/styles/abstracts/_variables.scss index b046618b..ef3694e0 100644 --- a/src/sphinx_book_theme/assets/styles/abstracts/_variables.scss +++ b/src/sphinx_book_theme/assets/styles/abstracts/_variables.scss @@ -7,58 +7,46 @@ $breakpoint-lg: 992px; $breakpoint-md: 768px; $breakpoint-sm: 576px; -// Colors -$grey--dark: #5a5a5a; -$grey--medium: #aaa; -$grey--light: #ccc; -$non-content-grey: $grey--dark; - // Z-index stacking (from Bootstrap) // ref: https://getbootstrap.com/docs/5.0/layout/z-index/ $zindex-sticky: 1020; $zindex-offcanvas: 1100; // We increase this to be over the tooltips +// A few semantic z-indices +$zindex-bottom: 1; +$zindex-middle: 2; +$zindex-top: 3; + // Spacing -$header-article-height: 3em; -$leftbar-width-mobile: 75%; -$leftbar-width-wide: 275px; +$header-article-height: 3rem; +$sidebar-primary-width-widescreen: 20%; $toc-width-mobile: 75%; -// Main content, to leave room for the margin -$content-max-width: 75%; // Consistent styling for page elements $box-border-radius: 0.4em; $animation-time: 0.25s; -$border-thin: 1px solid rgba(0, 0, 0, 0.1); +// Font sizes +$sbt-font-size-small-1: 87.5%; -// Overrides for pydata sphinx theme. -// See https://github.com/pydata/pydata-sphinx-theme/blob/master/pydata_sphinx_theme/static/css/theme.css -:root[data-theme="light"] { +/** + * Variables that aren't impacted by light/dark + */ +html { // Over-ride the pydata theme so that readers can use their system base --pst-font-size-base: none; + --pst-header-height: 0px; +} +// Overrides for pydata sphinx theme. +// See https://github.com/pydata/pydata-sphinx-theme/blob/master/pydata_sphinx_theme/static/css/theme.css +html[data-theme="light"] { --pst-color-primary: rgb(87, 154, 202); - --pst-color-link: rgb(0, 113, 188); - --pst-color-border: rgb(238, 238, 238); - - // Font sizes - --sbt-font-size-regular: 100%; - --sbt-font-size-large: 112.5%; - --sbt-font-size-small-1: 87.5%; - --sbt-font-size-small-2: 70%; - - // Variables for this theme - --sbt-sidebar-font-size: var(--sbt-font-size-small-1); - --sbt-header-article-font-size: var(--sbt-font-size-small-1); - --sbt-prevnext-font-size: var(--sbt-font-size-small-1); - --sbt-footer-font-size: var(--sbt-font-size-small-1); - - // Search variables - --sbt-color-search-highlighted: rgb(243, 119, 38); - --sbt-color-search-icon: rgb(164, 166, 167); - // Announcement --sbt-color-announcement: rgb(97, 97, 97); } + +html[data-theme="dark"] { + --pst-color-primary: rgb(87, 154, 202); +} diff --git a/src/sphinx_book_theme/assets/styles/base/_base.scss b/src/sphinx_book_theme/assets/styles/base/_base.scss index b80896e6..8a00b1c4 100644 --- a/src/sphinx_book_theme/assets/styles/base/_base.scss +++ b/src/sphinx_book_theme/assets/styles/base/_base.scss @@ -10,29 +10,11 @@ left: 0; } -// Hide an element without display: none but so that it takes no space -.visually-hidden { - clip: rect(0, 0, 0, 0) !important; - border: 0 !important; - height: 1px !important; - margin: -1px !important; - overflow: hidden !important; - padding: 0 !important; - position: absolute !important; - white-space: nowrap !important; - width: 1px !important; -} - // We define our own display-none class since bootstrap uses !important and we want to be able to over-ride .d-n { display: none; } -// default color for all the links -a { - color: var(--pst-color-link); -} - // Print-specific utility classes .onlyprint { display: none; diff --git a/src/sphinx_book_theme/assets/styles/base/_bootstrap.scss b/src/sphinx_book_theme/assets/styles/base/_bootstrap.scss deleted file mode 100644 index 5d79176e..00000000 --- a/src/sphinx_book_theme/assets/styles/base/_bootstrap.scss +++ /dev/null @@ -1,9 +0,0 @@ -/** -* Bootstrap-specific hacks -*/ - -// Prevent columns w/ wide content from breaking the grid -// ref: https://github.com/twbs/bootstrap/pull/30049/files -.col { - min-width: 0; -} diff --git a/src/sphinx_book_theme/assets/styles/base/_typography.scss b/src/sphinx_book_theme/assets/styles/base/_typography.scss index 41b0bf0f..c88ae5c3 100644 --- a/src/sphinx_book_theme/assets/styles/base/_typography.scss +++ b/src/sphinx_book_theme/assets/styles/base/_typography.scss @@ -3,57 +3,22 @@ *********************************************/ .bd-article-container { - // Content links and link color - a.headerlink { - opacity: 0; - margin-left: 0.2em; - - &:hover { - background-color: transparent; - color: var(--pst-color-link); - opacity: 1 !important; - } - } - - a, - a.nav-link, // to be more specific, so that pst style doesn't override - a:visited { - color: var(--pst-color-link); - } - h1, h2, h3, h4, h5 { - color: black; - &:hover a.headerlink { - opacity: 0.5; - } - // Make sure titles don't become hyperlink color when there are labels - a.toc-backref { - color: inherit; - } - } - - // Over-rides the pydata theme's large margins - h3, - h4, - h5, - h6 { - margin-top: 1em; + color: var(--pst-color-text-muted); } +} - // Lists - ul, - ol { - p { - margin-bottom: 0; - } - } +// counteracting pydata style on a::before, for citation style +a.brackets::before { + color: inherit; + font-family: inherit; + margin-right: 0rem; +} - // Misc text and directives - p.centered { - text-align: center; - } +table { + position: relative; } diff --git a/src/sphinx_book_theme/assets/styles/components/_buttons.scss b/src/sphinx_book_theme/assets/styles/components/_buttons.scss deleted file mode 100644 index ab7acdb6..00000000 --- a/src/sphinx_book_theme/assets/styles/components/_buttons.scss +++ /dev/null @@ -1,119 +0,0 @@ -/********************************************* -* Buttons, mostly for the headers * -*********************************************/ -/** - * Basic button style - */ -.headerbtn { - display: flex; - align-items: center; - justify-content: center; - - background-color: white; - color: $non-content-grey; - cursor: pointer; - border: none; - padding: 0.1rem 0.5rem; // Horizontal padding since labels have none - margin: 0 0.1rem; - - span { - display: flex; - align-items: center; - } - - // Icons and image icons - img, - i { - margin: auto; - width: 1em; - text-align: center; - font-size: 1.5em; // Slightly larger for icons - } -} - -/** - * Dropdown groups of buttons - */ -.menu-dropdown__trigger:hover + .menu-dropdown__content, -.menu-dropdown__content:hover { - visibility: visible; - opacity: 1; -} - -.menu-dropdown__content { - // Hide by default, we'll show on hover - position: absolute; - visibility: hidden; - opacity: 0; - transform: translateX(-75%); - transition: opacity 0.2s ease-out; - - // Spacing and position - width: 10rem; - border-radius: $box-border-radius; - box-shadow: 0px 3px 10px 0px rgba(0, 0, 0, 0.25); - padding: 0.5em; - - // Style - background-color: white; - - .headerbtn { - justify-content: left; - padding: 0.1rem 0rem; - } - - ul { - list-style: none; - padding-left: 0; - margin-bottom: 0; - } - - span { - display: flex; - - &.headerbtn__icon-container { - width: 2em; - } - - &.headerbtn__text-container { - flex-grow: 1; - margin-left: 0.5em; - } - } - - i, - img { - font-size: 1.2em; // Slightly smaller icons in a dropdown - } -} - -// HACK: Need this to be extra-selective to over-ride some too-specific PST CSS -div.header-article-main { - .header-article__left, - .header-article__right { - a, - button, - label { - color: $non-content-grey; - - // Over-ride bootstrap defaults for clicking - &:hover, - &:focus { - color: black; - box-shadow: none; - text-decoration: none; - } - } - } -} - -/** - * In-page table of contents - */ -.headerbtn-secondary { - // Hide the button on wide screens since we display the TOC. - display: block; - @media (min-width: $breakpoint-md) { - display: none; - } -} diff --git a/src/sphinx_book_theme/assets/styles/components/_search.scss b/src/sphinx_book_theme/assets/styles/components/_search.scss index 2ecf07aa..eaae68b4 100644 --- a/src/sphinx_book_theme/assets/styles/components/_search.scss +++ b/src/sphinx_book_theme/assets/styles/components/_search.scss @@ -1,18 +1,15 @@ -/********************************************* -* Search bar and text styling from searches * -*********************************************/ - -// Highlighted search items are a slightly lighter version of Jupyter orange -dt:target, -span.highlighted { - background-color: var(--sbt-color-search-highlighted); -} - -.bd-search { - .icon { - color: var(--sbt-color-search-icon); - } - .search-button__kbd-shortcut { +.bd-search-container { + margin: 2em; + // Remove the search field on the search page since we have one in the sidebar + h1:first-child { display: none; } + #search-results { + h2:first-child { + display: none; + } + } + .bd-search { + display: none !important; + } } diff --git a/src/sphinx_book_theme/assets/styles/content/_code.scss b/src/sphinx_book_theme/assets/styles/content/_code.scss index d0484b9d..b539f0e6 100644 --- a/src/sphinx_book_theme/assets/styles/content/_code.scss +++ b/src/sphinx_book_theme/assets/styles/content/_code.scss @@ -1,47 +1,5 @@ -/********************************************* -* Code and pre styling * -*********************************************/ - -code { - font-size: 87.5% !important; -} - -pre { - border-radius: $box-border-radius; - @include scrollbar-style(); -} - // Over-ride Sphinx default so that content fills whitespace w/ margin content pre, div[class*="highlight-"] { clear: none; } - -.highlighttable { - .linenos { - vertical-align: baseline; - } -} - -// Code blocks should have a margin, but code *cells* get margin from a parent -div.highlight { - background: none; - margin-bottom: 1em; -} - -// CodeMirror styles for live thebe cells. -.cm-s-default { - font-family: var(--jp-code-font-family); - font-size: var(--jp-code-font-size); - line-height: var(--jp-code-line-height); -} - -.CodeMirror-focused { - background-color: var(--jp-cell-editor-active-background) !important; - border: var(--jp-border-width) solid var(--jp-cell-editor-active-border-color); - margin: -1px; -} - -div.literal-block-wrapper { - border: none; -} diff --git a/src/sphinx_book_theme/assets/styles/content/_field-lists.scss b/src/sphinx_book_theme/assets/styles/content/_field-lists.scss deleted file mode 100644 index 88a9637c..00000000 --- a/src/sphinx_book_theme/assets/styles/content/_field-lists.scss +++ /dev/null @@ -1,10 +0,0 @@ -// Field lists -// See: https://docutils.sourceforge.io/docs/user/rst/quickref.html#definition-lists -// TODO the field list should be a different format, -// but be wary of issues like https://github.com/pandas-dev/pydata-sphinx-theme/issues/193 -dl.simple, -dl.field-list { - & dd { - margin-left: 1.5em; - } -} diff --git a/src/sphinx_book_theme/assets/styles/content/_footnotes.scss b/src/sphinx_book_theme/assets/styles/content/_footnotes.scss deleted file mode 100644 index 196572e2..00000000 --- a/src/sphinx_book_theme/assets/styles/content/_footnotes.scss +++ /dev/null @@ -1,18 +0,0 @@ -dl.footnote { - span.fn-backref { - font-size: 1em; - padding-left: 0.1em; - } - - // To ensure that the footnote text is aligned across lines - dd { - font-size: 0.9em; - margin-left: 3em; - } -} - -// Footnotes and Citations -.footnote-reference, -a.bibtex.internal { - font-size: 1em; -} diff --git a/src/sphinx_book_theme/assets/styles/content/_glossary.scss b/src/sphinx_book_theme/assets/styles/content/_glossary.scss deleted file mode 100644 index e51f375a..00000000 --- a/src/sphinx_book_theme/assets/styles/content/_glossary.scss +++ /dev/null @@ -1,5 +0,0 @@ -dl.glossary { - dd { - margin-left: 1.5em; - } -} diff --git a/src/sphinx_book_theme/assets/styles/content/_margin.scss b/src/sphinx_book_theme/assets/styles/content/_margin.scss index dc4b40d3..264f01fe 100644 --- a/src/sphinx_book_theme/assets/styles/content/_margin.scss +++ b/src/sphinx_book_theme/assets/styles/content/_margin.scss @@ -1,43 +1,62 @@ -// Margin variables -// The % is relative to our parent container, which has width == max-width -// full-width = 100% = content-max-width + margin-width -// We must express margin-width as a percentage of max-width. So: -// So the width we want is: -// max-width * x = 100% - max-width, so we solve for x. -// Will be a decimal -$content-margin-gutter: 3%; -$content-margin-width: percentage( - (100% - $content-max-width) / $content-max-width - ) - $content-margin-gutter; -$content-margin-offset: (-$content-margin-width - $content-margin-gutter); - -// Express 100% in parent container in % units of the child container. -$content-fullwidth-width: percentage(100% / $content-max-width); - -// Note: Need to add a few specifics for `tag_` because these won't have a parent `.sidebar` class -// On narrow screens, margin content behaves like a sidebar - -// On wide screens, it "pops out" to the right margin +/** + * Margin content + * This is the area to the right of the main content + * normally covered by the in-page table of contents + * but if `.margin` classes are present, it shows up to the right in the margin + * and the in-page TOC is hidden. + * On narrow screens, margin content behaves like a sidebar + */ +/** + * Variables for calculating margin widths + */ +// We want our margin content to be 1/3 the width of the main page content +// after factoring in a small margin +$margin-width-relative-to-content: 36%; +$margin-gutter: 3%; +$margin-width-width-gutter: $margin-width-relative-to-content - $margin-gutter; + +// re-subtract the gutter width because we want it to leave a white-space +// This is how much to offset the margin content. +$margin-offset: -$margin-width-relative-to-content; + +/** + * This mixin will cause something to "pop out" to the margin on wide screens + */ @mixin margin-content() { + // On narrow screens this is the width of margin content width: 40%; float: right; background-color: unset; - border-left: 1px #a4a6a7 solid; font-size: 0.9em; - @media (min-width: $breakpoint-md) { - border: none; - width: $content-margin-width; - margin: 0 $content-margin-offset 0 0; - clear: right; // Prevent sequential margin content from overlapping + margin-left: 0.5rem; + + // This is the wide-screen behavior + @media (min-width: $breakpoint-lg) { + width: $margin-width-width-gutter; + margin: 0 $margin-offset 0 0; + + // Prevent sequential margin content from overlapping + clear: right; p.sidebar-title { - margin-bottom: 0.1em; + margin-bottom: -1rem; + border-bottom: none; + padding-left: 0px; + + // Content of admonitions has fewer horizontal white space to save space + ~ * { + padding-left: 0px; + padding-right: 0px; + } } } } -// Sidenotes and marginnotes +/** + * Sidenotes and marginnotes + * over-rides the "footnote" behavior to pop out to the margin instead. + */ label.margin-toggle { margin-bottom: 0em; &.marginnote-label { @@ -46,7 +65,7 @@ label.margin-toggle { sup { user-select: none; } - @media (max-width: $breakpoint-md) { + @media (max-width: $breakpoint-lg) { cursor: pointer; color: rgb(0, 113, 188); &.marginnote-label { @@ -60,7 +79,7 @@ label.margin-toggle { input.margin-toggle { display: none; - @media (max-width: $breakpoint-md) { + @media (max-width: $breakpoint-lg) { &:checked + .sidenote, &:checked + .marginnote { display: block; @@ -76,21 +95,75 @@ input.margin-toggle { span.sidenote, span.marginnote { + z-index: $zindex-middle; + position: relative; sup { user-select: none; } @include margin-content(); border-left: none; - @media (max-width: $breakpoint-md) { + @media (max-width: $breakpoint-lg) { display: none; } } +aside.sidebar { + .note { + // styling for notes inside sidebars + margin: 1rem; + padding: 0rem 0rem 1rem 0rem; + } + // The titles sticking + .admonition-title { + margin: 0rem -1rem 0rem 0rem; + } +} + +/** + * Sidebar content in the margin. + * This will be added by the `margin` directive or the `sidebar` directive + */ +aside.sidebar.margin { + // Margin content can have an empty title so this prevents an empty title block + // from showing up on mobile + .sidebar-title:empty { + display: none; + } + + // On narrow screens padding is added to all sidebar content + // This replaces padding w/ margin for admonitions because padding is used + // for the title background color + .admonition { + margin: 0.5rem; + padding-left: 0; + padding-right: 0; + + // Remove the title margin so it + .admonition-title { + margin-left: 0; + margin-right: 0; + } + } + + @media (min-width: $breakpoint-lg) { + // No border for margin sidebars on wide screen + border: none; + + // Admonitions don't need the extra whitespace in the margin + .admonition { + margin: 1rem 0rem; + padding: 0rem 0rem 1rem 0rem; + } + } +} + div.margin, -aside.margin, figure.margin, +aside.margin, .cell.tag_popout, .cell.tag_margin { + z-index: $zindex-middle; + position: relative; @include margin-content(); // Make cell outputs take up more space if they're in the margin @@ -103,21 +176,31 @@ figure.margin, div.figure.margin-caption p.caption, div.figure.margin-caption figcaption, figure.margin-caption figcaption { + z-index: $zindex-middle; + position: relative; @include margin-content(); } -// Full-width content +// Margin captions +.margin-caption figcaption { + text-align: left; +} + +/** + * Full width content + */ + +// Grow 100% by the ratio of the margin to the content width. +$content-fullwidth-width: 100% + $margin-width-relative-to-content; + div.cell.tag_full-width, div.cell.tag_full_width, div.full_width, div.full-width { - @media (min-width: $breakpoint-md) { + z-index: $zindex-middle; + position: relative; + @media (min-width: $breakpoint-lg) { max-width: $content-fullwidth-width; width: $content-fullwidth-width; } } - -// Margin captions -.margin-caption figcaption { - text-align: left; -} diff --git a/src/sphinx_book_theme/assets/styles/content/_math.scss b/src/sphinx_book_theme/assets/styles/content/_math.scss deleted file mode 100644 index 900d9faa..00000000 --- a/src/sphinx_book_theme/assets/styles/content/_math.scss +++ /dev/null @@ -1,43 +0,0 @@ -// Math and equations -div.math { - position: relative; - display: flex; - flex-direction: row-reverse; - align-items: center; - - .headerlink { - font-size: 1em; - padding: 0 0.2em; - margin-left: 0; - - &:hover { - opacity: 1; - } - } - - &:hover .headerlink { - opacity: 0.5; - } -} - -// Equation labels to the right -span.eqno { - font-size: 1.2em; - margin-left: 0.5em; -} - -.MathJax { - overflow-x: auto; - margin-right: auto !important; // HACK: to over-ride MathJax default behavior - margin-left: auto !important; - @include scrollbar-style(); - - // HACK: Prevents vertical scroll-bar due to tiny padding bug - // The div should be high enough to fit all math anyway, so no vertical scroll needed - overflow-y: hidden; -} - -// Compensate for the extra bottom margin of a preceding paragraph -p ~ div.math { - margin-top: -1.15rem; -} diff --git a/src/sphinx_book_theme/assets/styles/content/_notebooks.scss b/src/sphinx_book_theme/assets/styles/content/_notebooks.scss new file mode 100644 index 00000000..3c08a02e --- /dev/null +++ b/src/sphinx_book_theme/assets/styles/content/_notebooks.scss @@ -0,0 +1,6 @@ +// MyST-NB and Jupyter Notebooks +div.cell.tag_output_scroll div.cell_output, +div.cell.tag_scroll-output div.cell_output { + max-height: 24em; + overflow-y: auto; +} diff --git a/src/sphinx_book_theme/assets/styles/content/_quotes.scss b/src/sphinx_book_theme/assets/styles/content/_quotes.scss index 229993f2..f203aed5 100644 --- a/src/sphinx_book_theme/assets/styles/content/_quotes.scss +++ b/src/sphinx_book_theme/assets/styles/content/_quotes.scss @@ -1,17 +1,14 @@ -blockquote { - margin: 1em; - padding: 0.2em 1.5em; - border-left: 4px solid #ccc; +/** + * Epigraphs and other "special" quote blocks + */ +blockquote { &.pull-quote, &.epigraph, &.highlights { font-size: 1.25em; border-left: none; - } - - div > p { - margin-bottom: 0.5em; + background-color: var(--pst-color-background); } div > p + p.attribution { diff --git a/src/sphinx_book_theme/assets/styles/content/_sidebar.scss b/src/sphinx_book_theme/assets/styles/content/_sidebar.scss deleted file mode 100644 index 97c08b4c..00000000 --- a/src/sphinx_book_theme/assets/styles/content/_sidebar.scss +++ /dev/null @@ -1,24 +0,0 @@ -// Sidebar-specific CSS -div.sidebar, -aside.sidebar { - &:not(.margin) { - background-color: unset; - padding: 1em; - border-radius: $box-border-radius; - border-color: $grey--medium; - - // On wide screens, the sidebar straddles margin and content - @media (min-width: $breakpoint-lg) { - width: 65%; - margin: 0 -35% 0 $content-margin-gutter; - } - } - .admonition { - padding-left: 0.6rem; - padding-right: 0.8rem; - } - > p { - padding-left: 0rem; - padding-right: 0rem; - } -} diff --git a/src/sphinx_book_theme/assets/styles/content/_tableofcontents.scss b/src/sphinx_book_theme/assets/styles/content/_tableofcontents.scss deleted file mode 100644 index f34f49e3..00000000 --- a/src/sphinx_book_theme/assets/styles/content/_tableofcontents.scss +++ /dev/null @@ -1,49 +0,0 @@ -// Table of Contents in the UI -div.tableofcontents-wrapper p.caption { - font-weight: 600 !important; - margin-bottom: 0em !important; -} - -// Table of Contents wrapper in page content -div.toctree-wrapper { - p.caption { - font-size: 1.4em; - } - - > ul { - padding-left: 1.5em; - - // Top-level links should be a bit bigger - > li > a { - font-size: 1.1em; - } - } -} - -// In-page contents -div.contents { - border-radius: $box-border-radius; - padding: 1em 1em 2em 1em; // More padding on bottom to match whitespace from title - p.topic-title { - font-size: 1.5em; - padding: 0 0 0 0.5em; - margin-bottom: 0; - } - - // Style the first few levels of this so it looks nice - > ul { - list-style: none; - padding-left: 1em; - - > li { - > ul { - padding-left: 1.5em; - } - - > p > a { - font-size: 1.2em; - margin-bottom: 0.5em; - } - } - } -} diff --git a/src/sphinx_book_theme/assets/styles/extensions/_ablog.scss b/src/sphinx_book_theme/assets/styles/extensions/_ablog.scss deleted file mode 100644 index b8856560..00000000 --- a/src/sphinx_book_theme/assets/styles/extensions/_ablog.scss +++ /dev/null @@ -1,41 +0,0 @@ -/********************************************* -* ABlog * -*********************************************/ -ul.ablog-archive { - padding-left: 0px; -} - -/* In-page post lists */ -ul.postlist { - padding-left: 0; - - > li > p:first-child { - font-size: 1.5em; - } - - li { - + li { - margin-top: 2em; - } - - > p > a { - font-style: normal; - font-size: 1.3em; - } - } -} - -// Sidebar rules specifically for ABlog -div.bd-sidebar { - h2 { - font-size: 1.5em; - } - h3 { - font-size: 1.4em; - } - - > ul { - list-style: none; - padding-left: 0; - } -} diff --git a/src/sphinx_book_theme/assets/styles/extensions/comments.scss b/src/sphinx_book_theme/assets/styles/extensions/_comments.scss similarity index 100% rename from src/sphinx_book_theme/assets/styles/extensions/comments.scss rename to src/sphinx_book_theme/assets/styles/extensions/_comments.scss diff --git a/src/sphinx_book_theme/assets/styles/extensions/_myst-nb.scss b/src/sphinx_book_theme/assets/styles/extensions/_myst-nb.scss deleted file mode 100644 index ca94928d..00000000 --- a/src/sphinx_book_theme/assets/styles/extensions/_myst-nb.scss +++ /dev/null @@ -1,41 +0,0 @@ -/********************************************* -* MyST NB and Jupyter Notebooks * -* ref: https://github.com/executablebooks/myst-nb -*********************************************/ -div.cell { - div.highlight { - margin-bottom: 0em; - } - - div.cell_input, - div.cell_output pre { - border-radius: $box-border-radius; - border: 1px #ccc solid; - } - - div.cell_output { - padding-right: 0; - } - - // On screens, we want to scoll, but on print show all - @mixin cell-scroll { - @include scrollbar-style(); - max-height: 24em; - overflow-y: auto; - @media print { - max-height: unset; - overflow-y: visible; - } - } - &.tag_output_scroll, - &.tag_scroll-output { - div.cell_output { - @include cell-scroll; - } - } - &.tag_scroll-input { - div.cell_input { - @include cell-scroll; - } - } -} diff --git a/src/sphinx_book_theme/assets/styles/extensions/_readthedocs.scss b/src/sphinx_book_theme/assets/styles/extensions/_readthedocs.scss deleted file mode 100644 index 82059ad9..00000000 --- a/src/sphinx_book_theme/assets/styles/extensions/_readthedocs.scss +++ /dev/null @@ -1,64 +0,0 @@ -/** - * ReadTheDocs pop-up menu over-rides. - * We nest everything under `.bd-sidebar-primary` so that we use more selective - * selectors than what RTD CSS uses. - */ -.bd-sidebar-primary { - // Parent container for everything else - div#rtd-footer-container { - position: sticky; - bottom: 0; - } - // Extra selective selector to over-ride RTD - .rst-versions.rst-badge { - position: unset; - font-size: 0.9em; - - // This is the top part of the dropdown, lists the current versions - .rst-current-version { - display: flex; - align-items: center; - gap: 0.2rem; - height: 2.5rem; - transition: background-color 0.2s ease-out; - background-color: white; - color: $non-content-grey; - border-top: $border-thin; - - @media (max-width: $breakpoint-md) { - // Slightly bigger on mobile so the button is more noticeable. - height: 3rem; - } - - &:hover { - background-color: rgba( - var(--pst-color-sidebar-expander-background-hover), - 1 - ); - cursor: pointer; - } - - .fa { - color: $non-content-grey; - } - - .fa-book { - float: unset; - margin-right: auto; - - &:after { - content: "Read the Docs"; - font-family: sans-serif; - font-weight: bold; - margin-left: 0.2em; - } - } - } - - .rst-other-versions { - dt { - color: #ccc; - } - } - } -} diff --git a/src/sphinx_book_theme/assets/styles/extensions/_sphinx-tabs.scss b/src/sphinx_book_theme/assets/styles/extensions/_sphinx-tabs.scss deleted file mode 100644 index 8d036838..00000000 --- a/src/sphinx_book_theme/assets/styles/extensions/_sphinx-tabs.scss +++ /dev/null @@ -1,12 +0,0 @@ -/********************************************* -* Sphinx Tabs * -* ref: https://github.com/executablebooks/sphinx-tabs -*********************************************/ -div.sphinx-tabs > div.sphinx-menu { - padding: 0; -} - -div.sphinx-tabs > div.sphinx-menu > a.item { - width: auto; - margin: 0px 0px -1px 0px; -} diff --git a/src/sphinx_book_theme/assets/styles/index.scss b/src/sphinx_book_theme/assets/styles/index.scss index ea51490b..ab7be4b2 100644 --- a/src/sphinx_book_theme/assets/styles/index.scss +++ b/src/sphinx_book_theme/assets/styles/index.scss @@ -12,44 +12,31 @@ // Basic styling applied throughout site @import "base/base"; -@import "base/bootstrap"; @import "base/typography"; @import "base/print"; // Major theme layout, skeleton, and whitespace @import "sections/announcement"; @import "sections/article"; -@import "sections/footer-article"; -@import "sections/footer-content"; +@import "sections/article-container"; @import "sections/header-article"; -@import "sections/headers"; +@import "sections/header-primary"; @import "sections/sidebar-primary"; @import "sections/sidebar-secondary"; -@import "sections/sidebars-toggle"; +@import "sections/footer-content"; +@import "sections/footer-article"; // Re-usable components across the theme -@import "components/buttons"; -@import "components/search.scss"; +@import "components/search"; // Content blocks in standard Sphinx -@import "content/code"; -@import "content/field-lists"; -@import "content/footnotes"; -@import "content/glossary"; @import "content/images"; @import "content/margin"; -@import "content/math"; @import "content/quotes"; -@import "content/sidebar"; -@import "content/tableofcontents"; +@import "content/code"; +@import "content/notebooks"; // Content blocks from Sphinx extensions -@import "extensions/ablog"; + @import "extensions/comments"; -@import "extensions/myst-nb"; -@import "extensions/sphinx-tabs"; -@import "extensions/readthedocs"; @import "extensions/thebe"; - -// Page-specific CSS -@import "pages/search"; diff --git a/src/sphinx_book_theme/assets/styles/pages/_search.scss b/src/sphinx_book_theme/assets/styles/pages/_search.scss deleted file mode 100644 index 5bfceb8b..00000000 --- a/src/sphinx_book_theme/assets/styles/pages/_search.scss +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Search page special-cases - */ - -#search-input::placeholder { - color: var(--pst-color-text-muted); -} - -// Turn off the extra search UI at the top of the page -.bd-search-container { - padding: 2rem; - h1 { - display: none; - } - form:first-of-type { - display: none !important; - } - - // Whitespace - div#search-results { - padding: 2rem; - > h2 { - margin-top: 0; - } - } - // The results of a search - ul.search { - margin: 0; - list-style: none; - - li { - background-image: none; - padding: 0; - margin-bottom: 1em; - padding-bottom: 1em; - border-bottom: $border-thin; - border-top: none; - - // First link is the page title, it should be a bit bigger - > a { - font-size: 1.2em; - } - - div.context, - p.context { - margin: 0.5em 0 0 0; - - // Add a # before page section titles to make it clear they are sections - a:before { - content: "#"; - padding-right: 0.2em; - color: $grey--medium; - } - } - } - } -} diff --git a/src/sphinx_book_theme/assets/styles/sections/_article-container.scss b/src/sphinx_book_theme/assets/styles/sections/_article-container.scss new file mode 100644 index 00000000..7248e1bd --- /dev/null +++ b/src/sphinx_book_theme/assets/styles/sections/_article-container.scss @@ -0,0 +1,12 @@ +.bd-main .bd-content .bd-article-container { + // Re-adjust padding defaults to be flush on the top and right + padding: 0rem; + + // Unset overflow x so that sticky: top works for the article header + overflow-x: unset; + min-width: 0; // prevent from overflowing the flex container + .bd-article { + padding-right: 2rem; + padding-left: 2rem; + } +} diff --git a/src/sphinx_book_theme/assets/styles/sections/_article.scss b/src/sphinx_book_theme/assets/styles/sections/_article.scss index 5e8ac3ae..7d5ee93d 100644 --- a/src/sphinx_book_theme/assets/styles/sections/_article.scss +++ b/src/sphinx_book_theme/assets/styles/sections/_article.scss @@ -1,22 +1,3 @@ -/********************************************* -* Main content layout * -*********************************************/ .bd-main { - .bd-content { - padding: 0rem; - justify-content: revert; - .bd-article-container { - position: relative; // needed for postion:sticky header-article - overflow-x: unset; // needed for postion:sticky header-article - padding: 0%; - min-width: 0; // to prevent overflow in mobile website for flex containers - } - .bd-article { - padding-right: 2rem; - @media (max-width: $breakpoint-md) { - padding-left: 1rem; - padding-right: 1rem; - } - } - } + flex-grow: 0; } diff --git a/src/sphinx_book_theme/assets/styles/sections/_footer-article.scss b/src/sphinx_book_theme/assets/styles/sections/_footer-article.scss index 77a1285a..1d2e412e 100644 --- a/src/sphinx_book_theme/assets/styles/sections/_footer-article.scss +++ b/src/sphinx_book_theme/assets/styles/sections/_footer-article.scss @@ -1,17 +1,3 @@ -/********************************************* -* Footer - article * -*********************************************/ - -// Previous and next area at the bottom -footer.bd-footer-article { - border-top: none; - padding: 0; - - .prev-next-area { - font-size: var(--sbt-prevnext-font-size); - - p.prev-next-title { - color: var(--pst-color-link); - } - } +.bd-footer-article { + padding: 0rem 1rem; } diff --git a/src/sphinx_book_theme/assets/styles/sections/_footer-content.scss b/src/sphinx_book_theme/assets/styles/sections/_footer-content.scss index 24ea7d9c..067b020b 100644 --- a/src/sphinx_book_theme/assets/styles/sections/_footer-content.scss +++ b/src/sphinx_book_theme/assets/styles/sections/_footer-content.scss @@ -8,5 +8,12 @@ footer { flex-wrap: wrap; padding: 15px; border-top: 1px solid #ccc; + font-size: $sbt-font-size-small-1; + .bd-footer-content__inner { + padding-left: 0px; + p { + margin-bottom: 0px; + } + } } } diff --git a/src/sphinx_book_theme/assets/styles/sections/_header-article.scss b/src/sphinx_book_theme/assets/styles/sections/_header-article.scss index 1917bf46..53a0b5be 100644 --- a/src/sphinx_book_theme/assets/styles/sections/_header-article.scss +++ b/src/sphinx_book_theme/assets/styles/sections/_header-article.scss @@ -1,25 +1,61 @@ /********************************************* * Top Bar * -* TODO: Rename much of these to article-header to conform with sphinx-basic-ng *********************************************/ +/** + * Mixin: + * Header behavior on mobile + */ +@mixin header-height-mobile { + @media (max-width: $breakpoint-md) { + height: $header-article-height + 0.75rem; + } +} + +/** + * Sidebar toggle over-rides for PST + */ +// Primary toggle is always visible +label.sidebar-toggle.primary-toggle { + @media (min-width: $breakpoint-md) { + display: inline-block; + } + @media (max-width: $breakpoint-md) { + margin-bottom: 0px; + } +} + +// Secondary toggle mimics behavior of "persistent header" div of PST +label.sidebar-toggle.secondary-toggle { + @media (min-width: $breakpoint-lg) { + display: none; + } + @media (max-width: $breakpoint-md) { + margin-bottom: 0px; + } +} + +// Wrapper container .bd-header-article { height: $header-article-height; // Fix the height so the TOC doesn't grow it - background-color: white; + background-color: var(--pst-color-background); transition: left 0.2s; - font-size: var(--sbt-header-article-font-size); + font-size: 0.9em; position: sticky; top: 0; + padding: 0 1rem; z-index: 1018; @include header-height-mobile; .scrolled & { - box-shadow: 0 6px 6px -6px rgba(0, 0, 0, 0.3); + box-shadow: 0 6px 6px -6px var(--pst-color-shadow); } + // Inner container with content .header-article-main { height: $header-article-height; @include header-height-mobile; + padding: 0 !important; // Override bootstrap default .header-article__left, .header-article__right { @@ -32,3 +68,82 @@ } } } + +/** + * Buttons in the header + */ +div.header-article-main { + .btn { + // Basic button size + font-size: 1.3rem; + color: var(--pst-color-text-muted); + border: none; + padding: 0 0.75rem; + + // Hover / active behavior + &.show, + &:hover { + color: var(--pst-color-text-base); + border: none; + & + .dropdown-menu { + display: block; + } + } + &:focus { + box-shadow: none; + } + + &.dropdown-toggle { + // Hide the bootstrap caret + &:after { + display: none; + } + } + } + + // The menu that is normally hidden until you hover + .dropdown-menu { + // Positioning and layout of dropdown items to be standardized + margin-top: 0px; + transform: translateX(-75%); + &:hover { + display: block; + } + .dropdown-item { + display: inline-flex; + align-items: center; + padding-left: 0.5em; + + // To prevent link underline from showing up + &:hover { + text-decoration: none; + background-color: initial; + } + + // Slightly smaller font for everything + font-size: 1em; + + // Image icons should be the same height as icons + span img { + height: 1em; + } + + span.btn__icon-container { + width: 1.7em; + align-items: center; + display: inline-flex; + justify-content: center; + } + } + } +} + +/** + * Tooltips added by bootstrap + * These are added to the bottom of the `` block by JavaScript. + * We should consider removing custom tooltips as this is pretty hacky... + */ +// Ensure that tooltips are *below* the sidebar toggles on mobile +div.tooltip { + z-index: 1049; +} diff --git a/src/sphinx_book_theme/assets/styles/sections/_header-primary.scss b/src/sphinx_book_theme/assets/styles/sections/_header-primary.scss new file mode 100644 index 00000000..94fd454d --- /dev/null +++ b/src/sphinx_book_theme/assets/styles/sections/_header-primary.scss @@ -0,0 +1,3 @@ +.bd-header { + display: none; +} diff --git a/src/sphinx_book_theme/assets/styles/sections/_headers.scss b/src/sphinx_book_theme/assets/styles/sections/_headers.scss deleted file mode 100644 index e8504158..00000000 --- a/src/sphinx_book_theme/assets/styles/sections/_headers.scss +++ /dev/null @@ -1,22 +0,0 @@ -/** - * A few different header CSS rules - */ -.header-item { - width: 100%; - text-align: center; - - &:empty { - display: none; - } - - &.announcement { - background-color: #616161; - color: white; - padding: 0.4em 12.5%; // Horizontal padding so the width is 75% - - @media (max-width: $breakpoint-md) { - // Announcements can take a bit more width on mobile - padding: 0.4em 2%; - } - } -} diff --git a/src/sphinx_book_theme/assets/styles/sections/_sidebar-primary.scss b/src/sphinx_book_theme/assets/styles/sections/_sidebar-primary.scss index b0f054e1..5d4bc2fa 100644 --- a/src/sphinx_book_theme/assets/styles/sections/_sidebar-primary.scss +++ b/src/sphinx_book_theme/assets/styles/sections/_sidebar-primary.scss @@ -1,122 +1,39 @@ /********************************************* * Left Nav Bar * *********************************************/ + .bd-sidebar-primary { - padding-top: 0; - padding: 0em; - flex-basis: $leftbar-width-wide; - font-size: var(--sbt-sidebar-font-size); - top: 0px !important; - max-height: 100vh; - max-width: 100%; - background: white; - border-right: $border-thin; transition: margin-left $animation-time ease 0s, opacity $animation-time ease 0s, visibility $animation-time ease 0s; - overflow-y: unset; // To over-ride the pydata theme and allow for sticky items - @include fill-vertical-screen-space(); - - // On mobile, behave like a slide-out drawer - @media (max-width: $breakpoint-md) { - position: fixed; - width: $leftbar-width-mobile; - max-width: 300px; - font-size: 1.2em; - z-index: $zindex-offcanvas; - } - - // The container for the sidebar content (stuff that isn't the RTD button) - .bd-sidebar__content { - overflow-y: auto; - flex-grow: 1; - display: flex; - flex-direction: column; - @include scrollbar-style(); - @include scrollbar-on-hover(); - } - - // Apply some basic padding so the dropdown buttons don't overlap w/ scrollbar - .sidebar-start-items, - .sidebar-end-items { - padding: 1rem 1rem 1rem 1.5rem; - } - - // This should always snap to the bottom even if there's no sidebar content - .sidebar-end-items { - margin-top: auto; - margin-bottom: 2em; - } - - nav ul.nav { - // Sidebar link color - li a, - ul li a { - color: $non-content-grey; - padding-right: 1.5rem; - } - a:hover, - li.active > a, - li.active > a:hover { - color: var(--pst-color-link); - } - - // Adjust padding to be a bit tighter - ul { - padding-left: 1rem; - } - } + font-size: $sbt-font-size-small-1; - h1.site-logo { - margin: 0.5em 0 0 0; - font-size: 1.1em; - color: black; - text-align: center; + .navbar-brand { + height: unset; } - div.navbar_extra_footer { - text-align: center; - font-size: 0.9em; - color: $non-content-grey; - margin-bottom: 3em; + // Remove the header items that pop into the sidebar in the pydata theme + .sidebar-header-items { + display: none; } - // Single page - &.single-page { - border-right: 0; + // Remove the top border since there's no header items above + .sidebar-start-items { + border-top: none; } -} -div.navbar-brand-box { + // On wide screens we have a smaller sidebar width than PST @media (min-width: $breakpoint-md) { - padding-top: 2em; - } - - a.navbar-brand { - width: 100%; - height: auto; - flex-direction: column; - - img { - display: block; - height: auto; - width: auto; - max-height: 10vh; - max-width: 100%; - margin: 0 auto; - @media (min-width: $breakpoint-md) { - max-height: 15vh !important; - } - } + flex-basis: $sidebar-primary-width-widescreen; } } -nav.bd-links { - margin-left: 0px; // Because the PST adds margin by default - p.caption, - .toctree-l1 a { - padding-left: 0em; +// Default visibility for left sidebar is the reverse of what it is on mobile. +// It is shown by default, and hidden with a click. +// Mobile behavior is defined in the pydata sphinx theme +@media (min-width: $breakpoint-md) { + input#__primary:checked ~ .bd-container .bd-sidebar-primary { + margin-left: -$sidebar-primary-width-widescreen; + visibility: hidden; + opacity: 0; } - // Overriding PyData Theme Defaults so the navigation is always visible - overflow-y: visible; - max-height: none; } diff --git a/src/sphinx_book_theme/assets/styles/sections/_sidebar-secondary.scss b/src/sphinx_book_theme/assets/styles/sections/_sidebar-secondary.scss index 413e5afa..4dfa6475 100644 --- a/src/sphinx_book_theme/assets/styles/sections/_sidebar-secondary.scss +++ b/src/sphinx_book_theme/assets/styles/sections/_sidebar-secondary.scss @@ -3,131 +3,68 @@ *********************************************/ .bd-sidebar-secondary { - padding: 0px !important; - right: -1em; - height: auto; - position: static; // .toc-item is made sticky so that z-index works well, for margin content - max-height: unset; - overflow-y: unset; - max-width: 25%; - flex: 0 0 25%; - transition: margin-right 0.25s ease 0s, opacity 0.25s ease 0s, - visibility 0.25s ease 0s; - - .tocsection { - padding: 0.5rem 1rem !important; - .scrolled & { - box-shadow: 0 6px 6px -6px rgba(0, 0, 0, 0.3); - } - - &:after { - content: "\f107"; - font-family: "Font Awesome 5 Free"; - font-weight: 900; - padding-left: 0.5em; - transition: opacity 0.3s ease; - } - } - - // Show / hide the in-page TOC items - @mixin show-inpage-toc { - nav { - max-height: 90vh; - opacity: 1; - overflow-y: auto; - } - - // Hide the arrow when we display the toc - .tocsection:after { - opacity: 0; - } - } - - .toc-item { - padding: 0rem; - position: sticky; // this is made sticky so that z-index works well, for margin content - z-index: 3; - top: 0; - height: auto; - background: white; - // On wide screens, show the TOC with hover or w/ a show class - &:hover { - @include show-inpage-toc; - } - } - - &.show { - @include show-inpage-toc; - } - - .toc-h2 { - font-size: 0.85rem; - } - // Colors - div.onthispage, - .toc-entry a { - color: $non-content-grey; - } - - // On narrow screens, this should be offset to the right side until button is clicked - @media (max-width: $breakpoint-md) { - z-index: $zindex-offcanvas; - top: 0; - right: 0; - position: fixed; - height: 100%; - width: $toc-width-mobile; - max-width: 300px; - background-color: white; - border-left: $border-thin; + // Wide screen behavior + @media (min-width: $breakpoint-md) { + background: var(--pst-color-background); + height: fit-content; + transition: max-height 0.4s ease; - // Fonts are a bit bigger on mobile, and nested headers get smaller - font-size: 1.4em; + // To make sure it shows above the page content + z-index: $zindex-middle; - li { - font-size: 0.8em; - } - } + // Remove padding so that it's flush on the top and left + padding: 0; - // By default the nav is hidden unless a few conditions are met - nav { - opacity: 1; - max-height: 0; - overflow-y: hidden; - background: white; - transition: opacity 0.4s ease, max-height 0.7s ease; - @include scrollbar-style(); - @include scrollbar-on-hover(); - // TOC link color - a:hover, - li.active > a.active { - color: var(--pst-color-link); - } - - li.active > a.active { - border-left: 2px solid var(--pst-color-link); - } - } - - // On narrow screens, it should always be shown because it's off to the right - @media (max-width: $breakpoint-md) { - @include show-inpage-toc; - } - - @media (min-width: $breakpoint-md) { - max-width: 25%; // taken from col-md-3 used in prev HTML + // This is the container div for the secondary sidebar nav .toc-item { - border-left: 1px solid var(--pst-color-border); + // Border is a bit less prominent + border-left-color: var(--pst-color-surface); + // Flush with the top so that we can fix the height of the toc header div + padding-top: 0; + + // The 'on this page' title div should take up the full header + .onthispage { + height: $header-article-height; + display: flex; + align-items: center; + } + + // The table of contents {% endmacro %} @@ -73,6 +60,5 @@ "group" : render_button_group, "javascript" : render_js_button, "link": render_link_button, - "input_label": render_label_input_button, } -%} diff --git a/src/sphinx_book_theme/theme/sphinx_book_theme/sections/footer-content.html b/src/sphinx_book_theme/theme/sphinx_book_theme/sections/footer-content.html index c6d94894..1f7140d3 100644 --- a/src/sphinx_book_theme/theme/sphinx_book_theme/sections/footer-content.html +++ b/src/sphinx_book_theme/theme/sphinx_book_theme/sections/footer-content.html @@ -1,20 +1,9 @@ -

- {% if author %} - {{ translate('By') }} {{ author }}
- {% endif %} - {%- if show_copyright %} - {%- if hasdoc('copyright') %} - {% trans prefix=translate('Copyright'), path=pathto('copyright'), copyright=copyright|e %}© {{ prefix }} {{ copyright }}.{% endtrans %}
- {%- else %} - {% trans prefix=translate('Copyright'), copyright=copyright|e %}© {{ prefix }} {{ copyright }}.{% endtrans %}
- {%- endif %} - {%- endif %} - {%- if last_updated %} - {% trans prefix=translate('Last updated on'), last_updated=last_updated|e %}{{ prefix }} {{ last_updated }}.{% endtrans %}
- {%- endif %} - {%- if theme_extra_footer %} -

- {%- endif %} -

+{#- This is essentially sections/footer.html but in the content footer #} +{# because we don't have a full-width footer in this theme-#} + diff --git a/src/sphinx_book_theme/theme/sphinx_book_theme/sections/header-article.html b/src/sphinx_book_theme/theme/sphinx_book_theme/sections/header-article.html index 8863d125..2e158d46 100644 --- a/src/sphinx_book_theme/theme/sphinx_book_theme/sections/header-article.html +++ b/src/sphinx_book_theme/theme/sphinx_book_theme/sections/header-article.html @@ -1,12 +1,12 @@ {# To trigger whether the TOC and its button show up #} {% set page_toc = generate_toc_html() %} -{% from "../macros/buttons.html" import render_funcs, render_label_input_button with context %} +{% from "../macros/buttons.html" import render_funcs with context %}
- {% if theme_single_page != True %} - {{ render_label_input_button(for_input="__primary", tooltip="Toggle navigation", icon="fas fa-bars", tooltip_placement="right") }} - {% endif %} +
{%- for button in header_buttons -%} @@ -14,7 +14,9 @@ {%- endfor -%} {% if page_toc -%} - {{ render_label_input_button("__secondary", icon="fas fa-list", label="secondary") }} + {%- endif %}
diff --git a/src/sphinx_book_theme/theme/sphinx_book_theme/sections/sidebar-primary.html b/src/sphinx_book_theme/theme/sphinx_book_theme/sections/sidebar-primary.html deleted file mode 100644 index 4fbed576..00000000 --- a/src/sphinx_book_theme/theme/sphinx_book_theme/sections/sidebar-primary.html +++ /dev/null @@ -1,24 +0,0 @@ -{% block docs_sidebar %} - -{% if sidebars and not is_single_page%} -
- - -
- -{% endif %} -{% endblock %} diff --git a/src/sphinx_book_theme/theme/sphinx_book_theme/sections/sidebar-secondary.html b/src/sphinx_book_theme/theme/sphinx_book_theme/sections/sidebar-secondary.html deleted file mode 100644 index e083adaf..00000000 --- a/src/sphinx_book_theme/theme/sphinx_book_theme/sections/sidebar-secondary.html +++ /dev/null @@ -1,16 +0,0 @@ - -{% set page_toc = generate_toc_html() %} -{% block docs_toc %} -
- {%- if page_toc | length >= 1 %} -
-
- {{ translate(theme_toc_title) }} -
- -
- {%- endif %} -
-{% endblock %} diff --git a/src/sphinx_book_theme/theme/sphinx_book_theme/sections/sidebar.html b/src/sphinx_book_theme/theme/sphinx_book_theme/sections/sidebar.html deleted file mode 100644 index e69de29b..00000000 diff --git a/src/sphinx_book_theme/theme/sphinx_book_theme/theme.conf b/src/sphinx_book_theme/theme/sphinx_book_theme/theme.conf index 122d36ba..f0f8ea41 100644 --- a/src/sphinx_book_theme/theme/sphinx_book_theme/theme.conf +++ b/src/sphinx_book_theme/theme/sphinx_book_theme/theme.conf @@ -1,25 +1,22 @@ [theme] inherit = pydata_sphinx_theme pygments_style = tango -sidebars = sidebar-logo.html, search-field.html, sbt-sidebar-nav.html +sidebars = navbar-logo.html, search-field.html, sbt-sidebar-nav.html stylesheet = styles/sphinx-book-theme.css [options] announcement = -single_page = False -# DEPRECATE after a few release cycles -expand_toc_sections = [] +# Removes the extra page-specific links from sidebar +secondary_sidebar_items = page-toc.html +footer_content_items = author.html, copyright.html, last-updated.html, extra-footer.html path_to_docs = repository_url = repository_branch = launch_buttons = {} home_page_in_toc = False logo_only = -# DEPRECATE after a few release cycles -navbar_footer_text = show_navbar_depth = 1 toc_title = Contents -extra_navbar = Theme by the Executable Book Project extra_footer = use_download_button = True use_fullscreen_button = True @@ -28,3 +25,6 @@ use_issues_button = False use_repository_button = False use_sidenotes = False # Note: We also inherit use_edit_page_button from the PyData theme + +# DEPRECATE after a few release cycles +expand_toc_sections = [] diff --git a/tests/sites/base/conf.py b/tests/sites/base/conf.py index c778039b..0bffb0c3 100644 --- a/tests/sites/base/conf.py +++ b/tests/sites/base/conf.py @@ -15,7 +15,7 @@ html_theme = "sphinx_book_theme" html_copy_source = True html_sourcelink_suffix = "" -jupyter_execute_notebooks = "auto" +nb_execution_mode = "auto" # Base options, we can add other key/vals later html_theme_options = { diff --git a/tests/sites/base/index.md b/tests/sites/base/index.md index a1186b5b..c08e5daf 100644 --- a/tests/sites/base/index.md +++ b/tests/sites/base/index.md @@ -7,5 +7,5 @@ page1 page2 section1/index titles/index -https://google.com +Google ``` diff --git a/tests/sites/base/section1/ntbk.ipynb b/tests/sites/base/section1/ntbk.ipynb index bee4eb63..cebfdbb6 100644 --- a/tests/sites/base/section1/ntbk.ipynb +++ b/tests/sites/base/section1/ntbk.ipynb @@ -40,7 +40,6 @@ "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", "version": "3.8.0" } }, diff --git a/tests/test_build.py b/tests/test_build.py index f05c2350..1ee5a940 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -128,12 +128,16 @@ def test_build_book(sphinx_build_factory, file_regression): for page in sphinx_build.outdir.joinpath("titles").rglob("**/page-*"): page_html = BeautifulSoup(page.read_text("utf8"), "html.parser") page_toc = page_html.find("div", attrs={"class": "bd-toc"}) - file_regression.check( - page_toc.prettify(), - basename=f"build__pagetoc--{page.with_suffix('').name}", - extension=".html", - encoding="utf8", - ) + if page_toc: + file_regression.check( + page_toc.prettify(), + basename=f"build__pagetoc--{page.with_suffix('').name}", + extension=".html", + encoding="utf8", + ) + else: + # page with no subheadings now does not have the secondary sidebar markup + assert len(page_html.find_all("section")) == 1 def test_navbar_options_home_page_in_toc(sphinx_build_factory): @@ -149,27 +153,9 @@ def test_navbar_options_home_page_in_toc(sphinx_build_factory): assert "Index with code in title" in str(li) -def test_navbar_options_single_page(sphinx_build_factory): - """Test that""" - sphinx_build = sphinx_build_factory( - "base", confoverrides={"html_theme_options.single_page": True} - ).build( - assert_pass=True - ) # type: SphinxBuild - sidebar = sphinx_build.html_tree("section1", "ntbk.html").find( - "div", attrs={"class": "bd-sidebar-primary"} - ) - assert len(sidebar.find_all("div")) == 0 # Sidebar should be empty - # HTML structure for below assertion is not supported in the latest version, - # the class just removes a border as of now, which we can do without. - # assert "single-page" in sidebar.attrs["class"] # Class added on single page - - @pytest.mark.parametrize( "option,value", [ - ("extra_navbar", "
EXTRA NAVBAR
"), - ("navbar_footer_text", "
EXTRA NAVBAR
"), ("extra_footer", "
EXTRA FOOTER
"), ], ) @@ -221,7 +207,7 @@ def test_header_launchbtns(sphinx_build_factory, file_regression): """Test launch buttons.""" sphinx_build = sphinx_build_factory("base").build(assert_pass=True) launch_btns = sphinx_build.html_tree("section1", "ntbk.html").select( - ".menu-dropdown-launch-buttons" + ".dropdown-launch-buttons" ) file_regression.check(launch_btns[0].prettify(), extension=".html", encoding="utf8") diff --git a/tests/test_build/build__header-article.html b/tests/test_build/build__header-article.html index 9af46817..f6d19f81 100644 --- a/tests/test_build/build__header-article.html +++ b/tests/test_build/build__header-article.html @@ -1,112 +1,106 @@
-
- - -
diff --git a/tests/test_build/build__pagetoc--page-multipletitles.html b/tests/test_build/build__pagetoc--page-multipletitles.html index 81f29615..8eb96899 100644 --- a/tests/test_build/build__pagetoc--page-multipletitles.html +++ b/tests/test_build/build__pagetoc--page-multipletitles.html @@ -1,11 +1,11 @@ -
+
- + - Contents + On this page
-
-
diff --git a/tests/test_build/header__repo-buttons--custom-branch.html b/tests/test_build/header__repo-buttons--custom-branch.html index 72528702..8e93d2c0 100644 --- a/tests/test_build/header__repo-buttons--custom-branch.html +++ b/tests/test_build/header__repo-buttons--custom-branch.html @@ -1,66 +1,62 @@
- - - - + + -
diff --git a/tests/test_build/header__repo-buttons--one-on.html b/tests/test_build/header__repo-buttons--one-on.html index cd8fc950..a33b6a3e 100644 --- a/tests/test_build/header__repo-buttons--one-on.html +++ b/tests/test_build/header__repo-buttons--one-on.html @@ -1,46 +1,44 @@
- - - + + -
diff --git a/tests/test_build/test_header_launchbtns.html b/tests/test_build/test_header_launchbtns.html index 0cc5b051..f7ad68a3 100644 --- a/tests/test_build/test_header_launchbtns.html +++ b/tests/test_build/test_header_launchbtns.html @@ -1,61 +1,59 @@ - diff --git a/tests/test_build/test_right_sidebar_title.html b/tests/test_build/test_right_sidebar_title.html index 37e4ce6a..cfb30025 100644 --- a/tests/test_build/test_right_sidebar_title.html +++ b/tests/test_build/test_right_sidebar_title.html @@ -1,5 +1,5 @@
- + - My Contents + On this page
diff --git a/tox.ini b/tox.ini index 75757c5b..00432d0b 100644 --- a/tox.ini +++ b/tox.ini @@ -43,9 +43,9 @@ deps = commands = stb serve docs --open-browser -[testenv:py{37,38,39}-sphinx{3,4}] +[testenv:py{37,38,39}-sphinx{4,5}] extras = test deps = - sphinx3: sphinx>=3,<4 sphinx4: sphinx>=4,<5 + sphinx5: sphinx>=5,<6 commands = pytest {posargs}