diff --git a/.github/workflows/lighthouserc.json b/.github/workflows/lighthouserc.json index 36c304e95..a17ac0fb5 100644 --- a/.github/workflows/lighthouserc.json +++ b/.github/workflows/lighthouserc.json @@ -11,7 +11,7 @@ "categories:performance": ["error", { "minScore": 0.5 }], "categories:accessibility": ["error", { "minScore": 0.8 }], "categories:best-practices": ["error", { "minScore": 0.8 }], - "categories:seo": ["error", { "minScore": 0.8 }] + "categories:seo": ["error", { "minScore": 0.7 }] } } } diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2c5fb74a1..16ea6ec08 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -66,7 +66,7 @@ jobs: # Run tests under coverage - name: Run the tests - run: pytest --cov pydata_sphinx_theme --cov-branch --cov-report term-missing:skip-covered --cov-fail-under ${{ env.COVERAGE_THRESHOLD }} + run: pytest --color=yes --cov pydata_sphinx_theme --cov-branch --cov-report term-missing:skip-covered --cov-fail-under ${{ env.COVERAGE_THRESHOLD }} - name: Upload coverage if: ${{ always() }} diff --git a/docs/conf.py b/docs/conf.py index 70f5a070c..672e8e972 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -61,7 +61,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "**.ipynb_checkpoints"] # -- Extension options ------------------------------------------------------- @@ -126,7 +126,7 @@ # "navbar_align": "left", # [left, content, right] For testing that the navbar items align properly # "navbar_start": ["navbar-logo", "navbar-version"], # "navbar_center": ["navbar-nav", "navbar-version"], # Just for testing - "navbar_end": ["version-switcher", "navbar-icon-links"], + "navbar_end": ["theme-switcher", "version-switcher", "navbar-icon-links"], # "left_sidebar_end": ["custom-template.html", "sidebar-ethical-ads.html"], # "footer_items": ["copyright", "sphinx-version", ""] "switcher": { diff --git a/docs/user_guide/configuring.rst b/docs/user_guide/configuring.rst index 2f4b83f99..b2c878650 100644 --- a/docs/user_guide/configuring.rst +++ b/docs/user_guide/configuring.rst @@ -10,7 +10,7 @@ in your ``conf.py`` file. This is a dictionary with ``key: val`` pairs that you can configure in various ways. This page describes the options available to you. Configure project logo -============================== +====================== To add a logo that's placed at the left of your nav bar, put a logo file under your doc path's _static folder, and use the following configuration: @@ -31,6 +31,35 @@ If you'd like it to link to another page or use an external link instead, use th .. _icon-links: +Configure default theme +======================= + +The theme mode can be changed by the user. By default landing on the documentation will switch the mode to ``auto``. You can specified this value to be one of ``auto``, ``dark``, ``light``. + +.. code-block:: python + + html_context = { + ... + "default_mode": "auto" + } + +Configure pygment theme +======================= + +As the Sphinx theme supports multiple modes, the code highlighting colors can be modified for each one of them by modifying the `pygment_light_style`and `pygment_style_style`. You can check available Pygments colors on this `page `__. + +.. code-block:: python + + html_contexts = { + ... + "pygment_light_style": "tango", + "pygment_dark_style": "native" + } + +.. danger:: + + The native Sphinx option `pygments_style` will be overwritten by this theme. + Configure icon links ==================== diff --git a/docs/user_guide/customizing.rst b/docs/user_guide/customizing.rst index 574b8fb14..25c4d578f 100644 --- a/docs/user_guide/customizing.rst +++ b/docs/user_guide/customizing.rst @@ -7,6 +7,13 @@ Customizing the theme In addition to the configuration options detailed at :ref:`configuration`, it is also possible to customize the HTML layout and CSS style of the theme. +.. danger:: + + This theme is still under active development, and we make no promises + about the stability of any specific HTML structure, CSS variables, etc. + Make these customizations at your own risk, and pin versions if you're + worried about breaking changes! + .. _custom-css: Custom CSS Stylesheets @@ -30,6 +37,41 @@ To add a custom stylesheet, follow these steps: When you build your documentation, this stylesheet should now be activated. +.. _manage-themes: + +Manage themes +============= + +.. danger:: + + Theming is still a beta feature so the variables related to the theme switch are likely to change in the future. No backward compatibily is guaranteed when customization is done. + +Pydata sphinx theme embed 3 different theming mode: + +- ``auto``: the documentation theme will follow the one provided by your computer +- ``dark``: the documentation is displayed with the dark theme +- ``light``: the documentation is displayed with the light theme + +In order to customize the display of any of the theme element you need to encaspulate your modifications in the approriate css rules: + +.. code-block:: css + + /* anything related to the light theme */ + html[data-theme="light"] { + + /* whatever you want to change */ + background: white; + } + + /* anything related to the dark theme */ + html[data-theme="dark"] { + + /* whatever you want to change */ + background: black; + } + +A complete list of the used colors for this theme can be found in the `pydata default css colors file `__. + .. _css-variables: CSS Theme variables @@ -58,7 +100,8 @@ In order to change a variable, follow these steps: Note that these are `CSS variables `_ and not `SASS variables `_. - The theme is defined with CSS variables, not SASS variables! + The theme is defined with CSS variables, not SASS variables! Refer to the previous section if + you desire a different behavior between the light and dark theme. For a complete list of the theme variables that you may override, see the `theme variables defaults CSS file `_: @@ -126,6 +169,7 @@ The default body and header fonts can be changed as follows: before waiting for the CSS to be parsed, but should be used with care. .. _pydata-css-variables: https://github.com/pydata/pydata-sphinx-theme/blob/master/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/static/styles/theme.css +.. _pydata-css-colors: https://github.com/pydata/pydata-sphinx-theme/blob/master/src/pydata_sphinx_theme/assets/style/color.scss .. _css-variable-help: https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties .. meta:: diff --git a/docs/user_guide/sections.rst b/docs/user_guide/sections.rst index 6042b32a4..18df968b2 100644 --- a/docs/user_guide/sections.rst +++ b/docs/user_guide/sections.rst @@ -138,6 +138,7 @@ will be named accordingly). - ``sidebar-nav-bs.html`` - ``sphinx-version.html`` - ``version-switcher.html`` +- ``theme-switcher.html`` Add your own HTML templates to theme sections ============================================= diff --git a/src/pydata_sphinx_theme/__init__.py b/src/pydata_sphinx_theme/__init__.py index 8675b87c1..b57b8fb1b 100644 --- a/src/pydata_sphinx_theme/__init__.py +++ b/src/pydata_sphinx_theme/__init__.py @@ -10,6 +10,8 @@ from sphinx.environment.adapters.toctree import TocTree from sphinx.errors import ExtensionError from sphinx.util import logging +from pygments.formatters import HtmlFormatter +from pygments.styles import get_all_styles from .bootstrap_html_translator import BootstrapHTML5Translator @@ -547,6 +549,87 @@ def get_edit_url(): context["theme_show_toc_level"] = int(context.get("theme_show_toc_level", 1)) +# ------------------------------------------------------------------------------ +# handle pygment css +# ------------------------------------------------------------------------------ + +# inspired by the Furo theme +# https://github.com/pradyunsg/furo/blob/main/src/furo/__init__.py + + +def _get_styles(formatter, prefix): + """ + Get styles out of a formatter, where everything has the correct prefix. + """ + + for line in formatter.get_linenos_style_defs(): + yield f"{prefix} {line}" + yield from formatter.get_background_style_defs(prefix) + yield from formatter.get_token_style_defs(prefix) + + +def get_pygments_stylesheet(light_style, dark_style): + """ + Generate the theme-specific pygments.css. + There is no way to tell Sphinx how the theme handles modes + """ + light_formatter = HtmlFormatter(style=light_style) + dark_formatter = HtmlFormatter(style=dark_style) + + lines = [] + + light_prefix = 'html[data-theme="light"] .highlight' + lines.extend(_get_styles(light_formatter, prefix=light_prefix)) + + dark_prefix = 'html[data-theme="dark"] .highlight' + lines.extend(_get_styles(dark_formatter, prefix=dark_prefix)) + + return "\n".join(lines) + + +def _overwrite_pygments_css(app, exception=None): + """ + Sphinx is not build to host multiple sphinx formatter and there is no way + to tell which one to use and when. + So yes, at build time we overwrite the pygment.css file so that it embeds + 2 versions: + - the light theme prefixed with "[data-theme="light"]" using tango + - the dark theme prefixed with "[data-theme="dark"]" using native + + When the theme is switched, Pygments will be using one of the preset css + style. + """ + default_light_theme = "tango" + default_dark_theme = "native" + + if exception is not None: + return + + assert app.builder + + # check the theme specified in the theme options + theme_options = app.config["html_theme_options"] + pygments_styles = list(get_all_styles()) + light_theme = theme_options.get("pygment_light_style", default_light_theme) + if light_theme not in pygments_styles: + logger.warn( + f"{light_theme}, is not part of the available pygments style," + f' defaulting to "{default_light_theme}".' + ) + light_theme = default_light_theme + dark_theme = theme_options.get("pygment_dark_style", default_dark_theme) + if dark_theme not in pygments_styles: + logger.warn( + f"{dark_theme}, is not part of the available pygments style," + f' defaulting to "{default_dark_theme}".' + ) + dark_theme = default_dark_theme + + pygment_css = Path(app.builder.outdir) / "_static" / "pygments.css" + with pygment_css.open("w") as f: + f.write(get_pygments_stylesheet(light_theme, dark_theme)) + + # ----------------------------------------------------------------------------- @@ -567,6 +650,7 @@ def setup(app): app.connect("html-page-context", setup_edit_url) app.connect("html-page-context", add_toctree_functions) app.connect("html-page-context", update_templates) + app.connect("build-finished", _overwrite_pygments_css) # Include templates for sidebar app.config.templates_path.append(str(theme_path / "_templates")) diff --git a/src/pydata_sphinx_theme/assets/scripts/index.js b/src/pydata_sphinx_theme/assets/scripts/index.js index c3d8f2a20..8c61f999f 100644 --- a/src/pydata_sphinx_theme/assets/scripts/index.js +++ b/src/pydata_sphinx_theme/assets/scripts/index.js @@ -9,6 +9,89 @@ import "bootstrap"; import "../styles/index.scss"; +/******************************************************************************* + * Theme interaction + */ + +var prefersDark = window.matchMedia("(prefers-color-scheme: dark)"); + +/** + * set the the body theme to the one specified by the user browser + * @param {event} e + */ +function autoTheme(e) { + document.documentElement.dataset.theme = prefersDark.matches + ? "dark" + : "light"; +} + +/** + * Set the theme using the specified mode. + * It can be one of ["auto", "dark", "light"] + * @param {str} mode + */ +function setTheme(mode) { + if (mode !== "light" && mode !== "dark" && mode !== "auto") { + console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`); + mode = "auto"; + } + + // get the theme + var colorScheme = prefersDark.matches ? "dark" : "light"; + document.documentElement.dataset.mode = mode; + var theme = mode == "auto" ? colorScheme : mode; + document.documentElement.dataset.theme = theme; + + // save mode and theme + localStorage.setItem("mode", mode); + localStorage.setItem("theme", theme); + console.log(`Changed to ${mode} mode using the ${theme} theme.`); + + // add a listener if set on auto + prefersDark.onchange = mode == "auto" ? autoTheme : ""; +} + +/** + * Change the theme option order so that clicking on the btn is always a change + * from "auto" + */ +function cycleMode() { + const defaultMode = document.documentElement.dataset.defaultMode || "auto"; + const currentMode = localStorage.getItem("mode") || defaultMode; + + var loopArray = (arr, current) => { + var nextPosition = arr.indexOf(current) + 1; + if (nextPosition === arr.length) { + nextPosition = 0; + } + return arr[nextPosition]; + }; + + // make sure the next theme after auto is always a change + var modeList = prefersDark.matches + ? ["auto", "light", "dark"] + : ["auto", "dark", "light"]; + var newMode = loopArray(modeList, currentMode); + setTheme(newMode); +} + +/** + * add the theme listener on the btns of the navbar + */ +function addModeListener() { + // the theme was set a first time using the initial mini-script + // running setMode will ensure the use of the dark mode if auto is selected + setTheme(document.documentElement.dataset.mode); + + // Attach event handlers for toggling themes colors + const btn = document.getElementById("theme-switch"); + btn.addEventListener("click", cycleMode); +} + +/******************************************************************************* + * TOC interactivity + */ + function addTOCInteractivity() { // TOC sidebar - add "active" class to parent list // @@ -31,6 +114,10 @@ function addTOCInteractivity() { }); } +/******************************************************************************* + * Scroll + */ + // Navigation sidebar scrolling to active page function scrollToActive() { var sidebar = document.querySelector("div.bd-sidebar"); @@ -73,5 +160,6 @@ function scrollToActive() { // This is equivalent to the .ready() function as described in // https://api.jquery.com/ready/ +$(addModeListener); $(scrollToActive); $(addTOCInteractivity); diff --git a/src/pydata_sphinx_theme/assets/styles/_admonitions.scss b/src/pydata_sphinx_theme/assets/styles/_admonitions.scss index f7be182a3..1ebd974b7 100644 --- a/src/pydata_sphinx_theme/assets/styles/_admonitions.scss +++ b/src/pydata_sphinx_theme/assets/styles/_admonitions.scss @@ -7,11 +7,12 @@ div.admonition, overflow: hidden; page-break-inside: avoid; border-left: 0.2rem solid; - border-color: rgba(var(--pst-color-admonition-default), 1); + border-color: var(--pst-color-admonition-default); border-radius: 0.2rem; - box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), - 0 0 0.0625rem rgba(0, 0, 0, 0.1); + box-shadow: 0 0.2rem 0.5rem var(--pst-color-admonition-shadow), + 0 0 0.0625rem var(--pst-color-admonition-shadow); transition: color 250ms, background-color 250ms, border-color 250ms; + background-color: var(--pst-color-admonition-background); // Last item should have no spacing since we'll control that w/ padding *:last-child { @@ -36,17 +37,30 @@ div.admonition, margin: 0 -0.6rem; padding: 0.4rem 0.6rem 0.4rem 2rem; font-weight: 700; - background-color: rgba(var(--pst-color-admonition-default), 0.1); &:before { position: absolute; left: 0.6rem; width: 1rem; height: 1rem; - color: rgba(var(--pst-color-admonition-default), 1); + color: var(--pst-color-admonition-default); font-family: "Font Awesome 5 Free"; font-weight: 900; content: var(--pst-icon-admonition-default); + opacity: 1; + } + + // This is a hack to control the opacity for admonitions with our color variables + // ref: https://stackoverflow.com/a/56951626/6734243 + &:after { + content: ""; + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + background-color: var(--pst-color-admonition-default); + opacity: 0.1; } // Next element after title needs some extra upper-space @@ -56,108 +70,126 @@ div.admonition, } &.attention { - border-color: rgba(var(--pst-color-admonition-attention), 1); + border-color: var(--pst-color-admonition-attention); > .admonition-title { - background-color: rgba(var(--pst-color-admonition-attention), 0.1); + &:after { + background-color: var(--pst-color-admonition-attention); + } &:before { - color: rgba(var(--pst-color-admonition-attention), 1); + color: var(--pst-color-admonition-attention); content: var(--pst-icon-admonition-attention); } } } &.caution { - border-color: rgba(var(--pst-color-admonition-caution), 1); + border-color: var(--pst-color-admonition-caution); > .admonition-title { - background-color: rgba(var(--pst-color-admonition-caution), 0.1); + &:after { + background-color: var(--pst-color-admonition-caution); + } &:before { - color: rgba(var(--pst-color-admonition-caution), 1); + color: var(--pst-color-admonition-caution); content: var(--pst-icon-admonition-caution); } } } &.warning { - border-color: rgba(var(--pst-color-admonition-warning), 1); + border-color: var(--pst-color-admonition-warning); > .admonition-title { - background-color: rgba(var(--pst-color-admonition-warning), 0.1); + &:after { + background-color: var(--pst-color-admonition-warning); + } &:before { - color: rgba(var(--pst-color-admonition-warning), 1); + color: var(--pst-color-admonition-warning); content: var(--pst-icon-admonition-warning); } } } &.danger { - border-color: rgba(var(--pst-color-admonition-danger), 1); + border-color: var(--pst-color-admonition-danger); > .admonition-title { - background-color: rgba(var(--pst-color-admonition-danger), 0.1); + &:after { + background-color: var(--pst-color-admonition-danger); + } &:before { - color: rgba(var(--pst-color-admonition-danger), 1); + color: var(--pst-color-admonition-danger); content: var(--pst-icon-admonition-danger); } } } &.error { - border-color: rgba(var(--pst-color-admonition-error), 1); + border-color: var(--pst-color-admonition-error); > .admonition-title { - background-color: rgba(var(--pst-color-admonition-error), 0.1); + &:after { + background-color: var(--pst-color-admonition-error); + } &:before { - color: rgba(var(--pst-color-admonition-error), 1); + color: var(--pst-color-admonition-error); content: var(--pst-icon-admonition-error); } } } &.hint { - border-color: rgba(var(--pst-color-admonition-hint), 1); + border-color: var(--pst-color-admonition-hint); > .admonition-title { - background-color: rgba(var(--pst-color-admonition-hint), 0.1); + &:after { + background-color: var(--pst-color-admonition-hint); + } &:before { - color: rgba(var(--pst-color-admonition-hint), 1); + color: var(--pst-color-admonition-hint); content: var(--pst-icon-admonition-hint); } } } &.tip { - border-color: rgba(var(--pst-color-admonition-tip), 1); + border-color: var(--pst-color-admonition-tip); > .admonition-title { - background-color: rgba(var(--pst-color-admonition-tip), 0.1); + &:after { + background-color: var(--pst-color-admonition-tip); + } &:before { - color: rgba(var(--pst-color-admonition-tip), 1); + color: var(--pst-color-admonition-tip); content: var(--pst-icon-admonition-tip); } } } &.important { - border-color: rgba(var(--pst-color-admonition-important), 1); + border-color: var(--pst-color-admonition-important); > .admonition-title { - background-color: rgba(var(--pst-color-admonition-important), 0.1); + &:after { + background-color: var(--pst-color-admonition-important); + } &:before { - color: rgba(var(--pst-color-admonition-important), 1); + color: var(--pst-color-admonition-important); content: var(--pst-icon-admonition-important); } } } &.note { - border-color: rgba(var(--pst-color-admonition-note), 1); + border-color: var(--pst-color-admonition-note); > .admonition-title { - background-color: rgba(var(--pst-color-admonition-note), 0.1); + &:after { + background-color: var(--pst-color-admonition-note); + } &:before { - color: rgba(var(--pst-color-admonition-note), 1); + color: var(--pst-color-admonition-note); content: var(--pst-icon-admonition-note); } } diff --git a/src/pydata_sphinx_theme/assets/styles/_api.scss b/src/pydata_sphinx_theme/assets/styles/_api.scss index 0060997fa..e522d3325 100644 --- a/src/pydata_sphinx_theme/assets/styles/_api.scss +++ b/src/pydata_sphinx_theme/assets/styles/_api.scss @@ -13,7 +13,7 @@ table.field-list { th.field-name { padding: 1px 8px 1px 5px; white-space: nowrap; - background-color: rgb(238, 238, 238); + background-color: var(--pst-color-background-up); } /* italic font for parameter types */ @@ -62,28 +62,33 @@ table.field-list { .sig.c .kt, .sig.cpp .k, .sig.cpp .kt { - color: rgba(var(--pst-color-text-base), 1); + color: var(--pst-color-text-base); } .sig.c .m, .sig.cpp .m { - color: rgba(var(--pst-color-text-base), 1); + color: var(--pst-color-text-base); } .sig.c .s, .sig.c .sc, .sig.cpp .s, .sig.cpp .sc { - color: rgba(var(--pst-color-text-base), 1); + color: var(--pst-color-text-base); } // addition // .sig.c .sig-name .n, // .sig.cpp .sig-name .n { -// color: rgba(var(--pst-color-inline-code), 1); +// color: var(--pst-color-inline-code); // } .sig-name { - color: rgba(var(--pst-color-inline-code), 1); + color: var(--pst-color-inline-code); +} + +// change target color for dark theme +dt:target { + background-color: var(--pst-color-target); } diff --git a/src/pydata_sphinx_theme/assets/styles/_base.scss b/src/pydata_sphinx_theme/assets/styles/_base.scss index 8d783f4ad..519b57b6f 100644 --- a/src/pydata_sphinx_theme/assets/styles/_base.scss +++ b/src/pydata_sphinx_theme/assets/styles/_base.scss @@ -6,41 +6,41 @@ html { body { padding-top: var(--pst-header-height); - background-color: white; + background-color: var(--pst-color-background); font-family: var(--pst-font-family-base); font-weight: 400; line-height: 1.65; - color: rgba(var(--pst-color-text-base), 1); + color: var(--pst-color-text-base); } p { margin-bottom: 1.15rem; font-size: 1em; - color: rgba(var(--pst-color-paragraph), 1); + color: var(--pst-color-paragraph); /* section header in docstring pages */ &.rubric { - border-bottom: 1px solid rgb(201, 201, 201); + border-bottom: 1px solid var(--pst-color-border); } } a { - color: rgba(var(--pst-color-link), 1); + color: var(--pst-color-link); text-decoration: none; &:hover { - color: rgba(var(--pst-color-link-hover), 1); + color: var(--pst-color-link-hover); text-decoration: underline; } &.headerlink { - color: rgba(var(--pst-color-headerlink), 1); + color: var(--pst-color-headerlink); opacity: 0.4; font-size: 0.8em; padding: 0 4px 0 4px; margin-left: 0.2em; text-decoration: none; - transition: all 0.3s ease-out; + transition: all 0.2s ease-out; user-select: none; &:hover { @@ -60,37 +60,37 @@ h1 { @extend .heading-style; margin-top: 0; font-size: var(--pst-font-size-h1); - color: rgba(var(--pst-color-h1), 1); + color: var(--pst-color-h1); } h2 { @extend .heading-style; font-size: var(--pst-font-size-h2); - color: rgba(var(--pst-color-h2), 1); + color: var(--pst-color-h2); } h3 { @extend .heading-style; font-size: var(--pst-font-size-h3); - color: rgba(var(--pst-color-h3), 1); + color: var(--pst-color-h3); } h4 { @extend .heading-style; font-size: var(--pst-font-size-h4); - color: rgba(var(--pst-color-h4), 1); + color: var(--pst-color-h4); } h5 { @extend .heading-style; font-size: var(--pst-font-size-h5); - color: rgba(var(--pst-color-h5), 1); + color: var(--pst-color-h5); } h6 { @extend .heading-style; font-size: var(--pst-font-size-h6); - color: rgba(var(--pst-color-h6), 1); + color: var(--pst-color-h6); } small, @@ -100,7 +100,7 @@ small, hr { border: 0; - border-top: 1px solid #e5e5e5; + border-top: 1px solid var(pst-color-border); } pre, @@ -111,18 +111,18 @@ samp { } code { - color: rgba(var(--pst-color-inline-code), 1); + color: var(--pst-color-inline-code); } pre { margin: 1.5em 0 1.5em 0; padding: 10px; - background-color: rgba(var(--pst-color-preformatted-background), 1); - color: rgba(var(--pst-color-preformatted-text), 1); + background-color: var(--pst-color-preformatted-background); + color: var(--pst-color-preformatted-text); line-height: 1.2em; - border: 1px solid rgb(201, 201, 201); + border: 1px solid var(--pst-color-preformatted-border); border-radius: 0.2rem; - box-shadow: 1px 1px 1px #d8d8d8; + box-shadow: 1px 1px 1px var(--pst-color-preformatted-shadow); } // Override bootstrap by restoring the basic theme default. diff --git a/src/pydata_sphinx_theme/assets/styles/_color.scss b/src/pydata_sphinx_theme/assets/styles/_color.scss new file mode 100644 index 000000000..1ef0490ef --- /dev/null +++ b/src/pydata_sphinx_theme/assets/styles/_color.scss @@ -0,0 +1,289 @@ +/******************************************************************************* +* light theme +* +* all the variables used for light theme coloring +*/ +html[data-theme="light"] { + /***************************************************************************** + * colors + */ + + // main colors + --pst-color-primary: rgb(19, 6, 84); + --pst-color-success: rgb(40, 167, 69); + --pst-color-info: rgb(0, 123, 255); /*23, 162, 184;*/ + --pst-color-warning: rgb(255, 193, 7); + --pst-color-danger: rgb(220, 53, 69); + --pst-color-text-base: rgb(51, 51, 51); + --pst-color-background: rgb(255, 255, 255); + --pst-color-background-up: rgb(240, 240, 240); // for 3D effects + --pst-color-background-up-up: rgb(255, 255, 238); // for 3D effects + --pst-color-deactivate: rgb(77, 77, 77); + --pst-color-border: rgb(201, 201, 201); + --pst-color-shadow: rgb(216, 216, 216); + + // headers + --pst-color-h1: var(--pst-color-primary); + --pst-color-h2: var(--pst-color-primary); + --pst-color-h3: var(--pst-color-text-base); + --pst-color-h4: var(--pst-color-text-base); + --pst-color-h5: var(--pst-color-text-base); + --pst-color-h6: var(--pst-color-text-base); + --pst-color-paragraph: var(--pst-color-text-base); + + // links + --pst-color-link: rgb(0, 91, 129); + --pst-color-link-hover: rgb(227, 46, 0); + --pst-color-target: rgb(251, 229, 78); + + // headerlinks (the anchors at the end of titles) + --pst-color-headerlink: rgb(198, 15, 15); + + // navigation + --pst-color-active-navigation: var(--pst-color-primary); + --pst-color-deactive-navigation: var(--pst-color-deactivate); + + /***************************************************************************** + * roles + */ + + // inline code + --pst-color-inline-code: rgb(232, 62, 140); + + // guilabel + --pst-color-guilabel-background: rgb(231, 242, 250); + --pst-color-guilabel-border: rgb(127, 187, 227); + --pst-color-guilabel-text: var(--pst-color-guilabel-border); + + // kbd + --pst-color-kbd-text: rgb(255, 255, 255); + --pst-color-kbd-background: rgb(33, 37, 41); + + /***************************************************************************** + * directives + */ + + // admonitions + --pst-color-admonition-default: var(--pst-color-info); + --pst-color-admonition-note: var(--pst-color-info); + --pst-color-admonition-attention: var(--pst-color-warning); + --pst-color-admonition-caution: var(--pst-color-warning); + --pst-color-admonition-warning: var(--pst-color-warning); + --pst-color-admonition-danger: var(--pst-color-danger); + --pst-color-admonition-error: var(--pst-color-danger); + --pst-color-admonition-hint: var(--pst-color-success); + --pst-color-admonition-tip: var(--pst-color-success); + --pst-color-admonition-important: var(--pst-color-success); + --pst-color-admonition-background: var(--pst-color-background); + --pst-color-admonition-shadow: var(--pst-color-shadow); + + // viersion modified + --pst-color-versionmodified-default: var(--pst-color-info); + --pst-color-versionmodified-added: var(--pst-color-success); + --pst-color-versionmodified-changed: var(--pst-color-warning); + --pst-color-versionmodified-deprecated: var(--pst-color-danger); + + // preformatted + --pst-color-preformatted-text: rgb(34, 34, 34); + --pst-color-preformatted-border: var(--pst-color-border); + --pst-color-preformatted-background: var(--pst-color-background-up); + --pst-color-preformatted-shadow: var(--pst-color-shadow); + + /***************************************************************************** + * layout + */ + + // navbar + --pst-color-navbar-background: var(--pst-color-background); + --pst-color-navbar-link: var(--pst-color-deactivate); + --pst-color-navbar-link-hover: var(--pst-color-active-navigation); + --pst-color-navbar-link-active: var(--pst-color-active-navigation); + + // toc + --pst-color-toc-link: var(--pst-color-deactivate); + --pst-color-toc-link-hover: var(--pst-color-active-navigation); + --pst-color-toc-link-active: var(--pst-color-active-navigation); + --pst-color-toc-border: var(--pst-color-border); + + // sidebar + --pst-color-sidebar-link: var(--pst-color-deactivate); + --pst-color-sidebar-link-hover: var(--pst-color-active-navigation); + --pst-color-sidebar-link-active: var(--pst-color-active-navigation); + --pst-color-sidebar-expander-background-hover: var(--pst-color-background-up); + --pst-color-sidebar-caption: var(--pst-color-text-base); + --pst-color-sidebar-border: var(--pst-color-border); + + // footer + --pst-color-footer-border: var(--pst-color-border); + + // alert + // higher contrast of links in info boxes + --pst-color-alert-link: rgb(232, 62, 140); + + // prev-next + --pst-color-prev-next: var(--pst-color-primary); + --pst-color-prev-next-btn: var(--pst-color-deactivate); + + // search + --pst-color-search-background: var(--pst-color-background); + --pst-color-search: var(--pst-color-border); + --pst-color-search-border: var(--pst-color-border); + + // ethical add + --pst-color-add-text: var(--pst-color-text-base); + --pst-color-add-background: var(--pst-color-background); + --pst-color-add-border: var(--pst-color-border); + + // navbar-toogler + --pst-color-navbar-toggler: var(--pst-color-deactivate); + + // blockquote + --pst-color-blockquote-border: rgb(221, 221, 221); +} + +/******************************************************************************* +* dark theme +* +* all the variables used for dark theme coloring +*/ +html[data-theme="dark"] { + /***************************************************************************** + * theme colors + */ + + // main colors + --pst-color-primary: rgb(76, 145, 219); + --pst-color-success: rgb(72, 135, 87); + --pst-color-info: rgb(64, 125, 191); + --pst-color-warning: rgb(193, 162, 69); + --pst-color-danger: rgb(203, 70, 83); + --pst-color-text-base: rgb(201, 209, 217); + --pst-color-background: rgb(18, 18, 18); + --pst-color-background-up: rgb(22, 22, 22); // for 3D effect in dark theme + --pst-color-background-up-up: rgb(55, 55, 55); // for 3D effects + --pst-color-deactivate: rgb(192, 192, 192); + --pst-color-border: var(--pst-color-deactivate); + --pst-color-shadow: var(--pst-color-background); + + // headers + --pst-color-h1: var(--pst-color-primary); + --pst-color-h2: var(--pst-color-primary); + --pst-color-h3: var(--pst-color-text-base); + --pst-color-h4: var(--pst-color-text-base); + --pst-color-h5: var(--pst-color-text-base); + --pst-color-h6: var(--pst-color-text-base); + --pst-color-paragraph: var(--pst-color-text-base); + + // links + --pst-color-link: var(--pst-color-primary); + --pst-color-link-hover: rgb(170, 103, 196); + --pst-color-target: rgb(117, 148, 195); + + // headerlinks (the anchors at the end of titles) + --pst-color-headerlink: rgb(221, 90, 90); + + // navigation + --pst-color-active-navigation: var(--pst-color-primary); + --pst-color-deactive-navigation: var(--pst-color-deactivate); + + /***************************************************************************** + * roles + */ + + // inline code + --pst-color-inline-code: rgb(221, 158, 194); + + // guilabel + --pst-color-guilabel-background: rgb(242, 196, 166); + --pst-color-guilabel-border: rgb(83, 56, 38); + --pst-color-guilabel-text: var(--pst-color-guilabel-border); + + // kbd + --pst-color-kbd-text: rgb(33, 37, 41); + --pst-color-kbd-background: rgb(245, 245, 245); + + /***************************************************************************** + * directives + */ + + // admonitions + --pst-color-admonition-default: var(--pst-color-info); + --pst-color-admonition-note: var(--pst-color-info); + --pst-color-admonition-attention: var(--pst-color-warning); + --pst-color-admonition-caution: var(--pst-color-warning); + --pst-color-admonition-warning: var(--pst-color-warning); + --pst-color-admonition-danger: var(--pst-color-danger); + --pst-color-admonition-error: var(--pst-color-danger); + --pst-color-admonition-hint: var(--pst-color-success); + --pst-color-admonition-tip: var(--pst-color-success); + --pst-color-admonition-important: var(--pst-color-success); + --pst-color-admonition-background: var(--pst-color-background-up); + --pst-color-admonition-shadow: var(--pst-color-shadow); + + // viersion modified + --pst-color-versionmodified-default: var(--pst-color-info); + --pst-color-versionmodified-added: var(--pst-color-success); + --pst-color-versionmodified-changed: var(--pst-color-warning); + --pst-color-versionmodified-deprecated: var(--pst-color-danger); + + // preformatted + --pst-color-preformatted-text: rgb(210, 210, 210); + --pst-color-preformatted-border: rgb(83, 83, 83); + --pst-color-preformatted-background: var(--pst-color-background-up); + --pst-color-preformatted-shadow: var(--pst-color-shadow); + + /***************************************************************************** + * layout + */ + + // navbar + --pst-color-navbar-background: var(--pst-color-background-up); + --pst-color-navbar-link: var(--pst-color-deactivate); + --pst-color-navbar-link-hover: var(--pst-color-active-navigation); + --pst-color-navbar-link-active: var(--pst-color-active-navigation); + + // toc + --pst-color-toc-link: var(--pst-color-deactivate); + --pst-color-toc-link-hover: var(--pst-color-active-navigation); + --pst-color-toc-link-active: var(--pst-color-active-navigation); + --pst-color-toc-border: var(--pst-color-border); + + // sidebar + --pst-color-sidebar-link: var(--pst-color-deactivate); + --pst-color-sidebar-link-hover: var(--pst-color-active-navigation); + --pst-color-sidebar-link-active: var(--pst-color-active-navigation); + --pst-color-sidebar-expander-background-hover: var(--pst-color-background-up); + --pst-color-sidebar-caption: var(--pst-color-text-base); + --pst-color-sidebar-border: var(--pst-color-border); + + // footer + --pst-color-footer-border: var(--pst-color-border); + + // alert + --pst-color-alert-link: rgb(232, 62, 140); // higher contrast of links + + // prev-next + --pst-color-prev-next: var(--pst-color-link); + --pst-color-prev-next-btn: var(--pst-color-deactivate); + + // search + --pst-color-search-background: var(--pst-color-background); + --pst-color-search: var(--pst-color-border); + --pst-color-search-border: var(--pst-color-border); + + // ethical add + --pst-color-add-text: var(--pst-color-text-base); + --pst-color-add-background: var(--pst-color-background); + --pst-color-add-border: var(--pst-color-border); + + // navbar-toogler + --pst-color-navbar-toggler: var(--pst-color-deactivate); + + // blockquote + --pst-color-blockquote-border: rgb(117, 117, 117); + + // specific brighness applied on images + img { + filter: brightness(0.8) contrast(1.2); + } +} diff --git a/src/pydata_sphinx_theme/assets/styles/_ethical-ads.scss b/src/pydata_sphinx_theme/assets/styles/_ethical-ads.scss new file mode 100644 index 000000000..301f4b78c --- /dev/null +++ b/src/pydata_sphinx_theme/assets/styles/_ethical-ads.scss @@ -0,0 +1,21 @@ +// adapt ethical add to the theme +.ethical-sidebar a, +.ethical-sidebar a:visited, +.ethical-sidebar a:hover, +.ethical-sidebar a:active, +.ethical-footer a, +.ethical-footer a:visited, +.ethical-footer a:hover, +.ethical-footer a:active { + color: var(--pst-color-add-text); +} + +.ethical-sidebar, +.ethical-footer { + background-color: var(--pst-color-add-background); + border: 1px solid var(--pst-color-add-border); + border-radius: 5px; + color: var(--pst-color-add-text); + font-size: 14px; + line-height: 20px; +} diff --git a/src/pydata_sphinx_theme/assets/styles/_navbar.scss b/src/pydata_sphinx_theme/assets/styles/_navbar.scss index 9e72f5afe..bca407870 100644 --- a/src/pydata_sphinx_theme/assets/styles/_navbar.scss +++ b/src/pydata_sphinx_theme/assets/styles/_navbar.scss @@ -16,6 +16,8 @@ button.navbar-toggler { margin-right: 1em; + border-color: var(--pst-color-navbar-toggler); + color: var(--pst-color-navbar-toggler); } } @@ -51,22 +53,28 @@ // If we want the shadow to only point downward in the future, set // box-shadow to: 0 0.125rem 0.25rem -0.125rem rgba(0, 0, 0, 0.11); .navbar-light { - background: #fff !important; // Overrides bootstrap + background: var( + --pst-color-navbar-background + ) !important; // Overrides bootstrap box-shadow: 0 0.125rem 0.25rem 0 rgba(0, 0, 0, 0.11); .navbar-nav { li a.nav-link { padding: 0 0.5rem; - color: rgba(var(--pst-color-navbar-link), 1); + color: var(--pst-color-navbar-link); &:hover { - color: rgba(var(--pst-color-navbar-link-hover), 1); + color: var(--pst-color-navbar-link-hover); + } + + &:focus { + color: var(--pst-color-navbar-link-hover); } } > .active > .nav-link { font-weight: 600; - color: rgba(var(--pst-color-navbar-link-active), 1); + color: var(--pst-color-navbar-link-active); } } } @@ -74,3 +82,45 @@ .navbar-header a { padding: 0 15px; } + +// inline the element in the navbar as long as they fit and use display block when colapsing +@media (min-width: 768px) { + .navbar-center-item { + display: inline-block; + } +} + +// the icons for theme change +#theme-switch { + border-color: var(--pst-color-navbar-link-hover); + margin-right: 0.4rem; + + a { + color: var(--pst-color-navbar-link-hover); + display: none; + } + + &:hover { + border-color: var(--pst-color-navbar-background); + background-color: var(--pst-color-navbar-link-hover); + + a { + color: var(--pst-color-navbar-background); + } + } +} + +html[data-mode="auto"] #theme-switch a[data-mode="auto"] { + display: block; +} +html[data-mode="light"] #theme-switch a[data-mode="light"] { + display: block; +} +html[data-mode="dark"] #theme-switch a[data-mode="dark"] { + display: block; +} + +#version_switcher_button { + background-color: var(--pst-color-active-navigation); + border-color: var(--pst-color-active-navigation); +} diff --git a/src/pydata_sphinx_theme/assets/styles/_versionmodified.scss b/src/pydata_sphinx_theme/assets/styles/_versionmodified.scss index f9cebfc82..50408b341 100644 --- a/src/pydata_sphinx_theme/assets/styles/_versionmodified.scss +++ b/src/pydata_sphinx_theme/assets/styles/_versionmodified.scss @@ -7,32 +7,54 @@ div.deprecated { overflow: hidden; page-break-inside: avoid; border-left: 0.2rem solid; - border-color: rgba(var(--pst-color-versionmodified-default), 1); + border-color: var(--pst-color-versionmodified-default); border-radius: 0.2rem; box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1); transition: color 250ms, background-color 250ms, border-color 250ms; - background-color: rgba(var(--pst-color-admonition-default), 0.1); + position: relative; > p { margin-bottom: 0.6rem; margin-top: 0.6rem; + + // This is a hack to control the opacity for admonitions with our color variables + // ref: https://stackoverflow.com/a/56951626/6734243 + &:before { + content: ""; + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + background-color: var(--pst-color-admonition-default); + opacity: 0.1; + } } } div.versionadded { - border-color: rgba(var(--pst-color-versionmodified-added), 1); - background-color: rgba(var(--pst-color-versionmodified-added), 0.1); + border-color: var(--pst-color-versionmodified-added); + + p:before { + background-color: var(--pst-color-versionmodified-added); + } } div.versionchanged { - border-color: rgba(var(--pst-color-versionmodified-changed), 1); - background-color: rgba(var(--pst-color-versionmodified-changed), 0.1); + border-color: var(--pst-color-versionmodified-changed); + + p:before { + background-color: var(--pst-color-versionmodified-changed); + } } div.deprecated { - border-color: rgba(var(--pst-color-versionmodified-deprecated), 1); - background-color: rgba(var(--pst-color-versionmodified-deprecated), 0.1); + border-color: var(--pst-color-versionmodified-deprecated); + + p:before { + background-color: var(--pst-color-versionmodified-deprecated); + } } span.versionmodified { @@ -41,7 +63,7 @@ span.versionmodified { &:before { font-style: normal; margin-right: 0.6rem; - color: rgba(var(--pst-color-versionmodified-default), 1); + color: var(--pst-color-versionmodified-default); font-family: "Font Awesome 5 Free"; font-weight: 900; content: var(--pst-icon-versionmodified-default); @@ -50,21 +72,21 @@ span.versionmodified { span.versionmodified.added { &:before { - color: rgba(var(--pst-color-versionmodified-added), 1); + color: var(--pst-color-versionmodified-added); content: var(--pst-icon-versionmodified-added); } } span.versionmodified.changed { &:before { - color: rgba(var(--pst-color-versionmodified-changed), 1); + color: var(--pst-color-versionmodified-changed); content: var(--pst-icon-versionmodified-changed); } } span.versionmodified.deprecated { &:before { - color: rgba(var(--pst-color-versionmodified-deprecated), 1); + color: var(--pst-color-versionmodified-deprecated); content: var(--pst-icon-versionmodified-deprecated); } } diff --git a/src/pydata_sphinx_theme/assets/styles/index.scss b/src/pydata_sphinx_theme/assets/styles/index.scss index 00deae819..f9e6173f1 100644 --- a/src/pydata_sphinx_theme/assets/styles/index.scss +++ b/src/pydata_sphinx_theme/assets/styles/index.scss @@ -19,19 +19,21 @@ $grid-breakpoints: ( // Import Bootstrap core @import "~bootstrap/scss/bootstrap"; +@import "./color"; @import "./base"; @import "./navbar"; @import "./admonitions"; @import "./api"; @import "./markdown"; @import "./versionmodified"; +@import "./ethical-ads"; // Custom css, TODO: to be refactored in different partials // GitHub blockquote style blockquote { padding: 0 1em; - color: #6a737d; - border-left: 0.25em solid #dfe2e5; + color: var(--pst-color-deactivate); + border-left: 0.25em solid var(--pst-color-blockquote-border); } // For consistency, add bracket around footnotes/citations which are @@ -51,7 +53,13 @@ a.footnote-reference { } .topic { - background-color: #eee; + background-color: var(--pst-color-background-up); + border-color: var(--pst-color-border); +} + +aside.sidebar { + background-color: var(--pst-color-background-up-up); + border-color: var(--pst-color-border); } .seealso dd { @@ -70,8 +78,9 @@ a.footnote-reference { } span.guilabel { - border: 1px solid #7fbbe3; - background: #e7f2fa; + border: 1px solid var(--pst-color-guilabel-border); + background: var(--pst-color-guilabel-background); + color: var(--pst-color-guilabel-text); font-size: 80%; font-weight: 700; border-radius: 4px; @@ -85,7 +94,7 @@ span.guilabel { footer { width: 100%; - border-top: 1px solid #ccc; + border-top: 1px solid var(--pst-color-footer-border); padding: 10px; .footer-item p { @@ -103,14 +112,26 @@ footer { .icon { position: absolute; - color: #a4a6a7; + color: var(--pst-color-search); left: 25px; } input { + background-color: var(--pst-color-search-background); border-radius: 0.2rem; - border: 1px solid #e5e5e5; + border: 1px solid var(--pst-color-search-border); padding-left: 35px; + + // Inner-text of the search bar + &::placeholder { + color: var(--pst-color-search); + } + + // Background should always be same color regardless of active or nor + &:active, + &:focus { + background-color: var(--pst-color-search-background); + } } } @@ -132,13 +153,13 @@ footer { } .onthispage { - color: #a4a6a7; + color: var(--pst-color-text-base); } } .section-nav { padding-left: 0; - border-left: 1px solid #eee; + border-left: 1px solid var(--pst-color-toc-border); border-bottom: none; ul { @@ -152,19 +173,47 @@ footer { a { display: block; padding: 0.125rem 1.5rem; - color: rgba(var(--pst-color-toc-link), 1); + color: var(--pst-color-toc-link); @include media-breakpoint-up(xl) { padding-right: 0; } &:hover { - color: rgba(var(--pst-color-toc-link-hover), 1); + color: var(--pst-color-toc-link-hover); text-decoration: none; } } } +.bd-sidebar { + padding-top: 1em; + overflow-y: auto; + display: flex; + flex-direction: column; + + @include media-breakpoint-up(md) { + border-right: 1px solid var(--pst-color-sidebar-border); + + @supports (position: -webkit-sticky) or (position: sticky) { + position: -webkit-sticky; + position: sticky; + top: var(--pst-header-height); + z-index: 1000; + height: calc(100vh - var(--pst-header-height)); + } + } + + &.no-sidebar { + border-right: 0; + } + + .sidebar-end-items { + margin-top: auto; + margin-bottom: 1em; + } +} + .bd-links { padding-top: 1rem; padding-bottom: 1rem; @@ -237,7 +286,7 @@ nav.bd-links { margin-top: 1.25em; margin-bottom: 0.5em; padding: 0 1.5rem; - color: rgba(var(--pst-color-sidebar-caption), 1); + color: var(--pst-color-sidebar-caption); &:first-child { margin-top: 0; } @@ -255,10 +304,10 @@ nav.bd-links { li > a { display: block; padding: 0.25rem 1.5rem; - color: rgba(var(--pst-color-sidebar-link), 1); + color: var(--pst-color-sidebar-link); &:hover { - color: rgba(var(--pst-color-sidebar-link-hover), 1); + color: var(--pst-color-sidebar-link-hover); text-decoration: none; background-color: transparent; } @@ -278,7 +327,7 @@ nav.bd-links { > a, &:hover > a { font-weight: 600; - color: rgba(var(--pst-color-sidebar-link-active), 1); + color: var(--pst-color-sidebar-link-active); } } } @@ -298,10 +347,9 @@ nav.bd-links { .toc-entry > .nav-link.active { font-weight: 600; - color: #130654; - color: rgba(var(--pst-color-toc-link-active), 1); + color: var(--pst-color-toc-link-active); background-color: transparent; - border-left: 2px solid rgba(var(--pst-color-toc-link-active), 1); + border-left: 2px solid var(--pst-color-toc-link-active); } .nav-link:hover { @@ -356,11 +404,11 @@ nav.bd-links { padding: 10px; max-width: 45%; overflow-x: hidden; - color: rgba(0, 0, 0, 0.65); + color: var(--pst-color-prev-next-btn); text-decoration: none; p.prev-next-title { - color: rgba(var(--pst-color-link), 1); + color: var(--pst-color-prev-next); font-weight: 600; font-size: 1.1em; } @@ -401,7 +449,7 @@ nav.bd-links { .alert-info a { /* higher contrast for links in info boxes. */ - color: #e83e8c; + color: var(--pst-color-alert-link); } /* Icon Links */ @@ -419,10 +467,6 @@ nav.bd-links { } /* Social media buttons */ - &.fa-github-square:before { - color: #333; - } - &.fa-twitter-square:before { color: #55acee; } @@ -445,7 +489,7 @@ nav.bd-links { .tocsection { padding-left: 10px; - border-left: 1px solid #eee; + border-left: 1px solid var(--pst-color-toc-border); padding: 0.3rem 1.5rem; i { @@ -550,7 +594,7 @@ nav.bd-links { align-items: center; &:hover { - background: rgba(var(--pst-color-sidebar-expander-background-hover), 1); + background: var(--pst-color-sidebar-expander-background-hover); } i { @@ -558,7 +602,7 @@ nav.bd-links { font-size: 0.75rem; text-align: center; &:hover { - color: rgba(var(--pst-color-sidebar-link-hover), 1); + color: var(--pst-color-sidebar-link-hover); } } } diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/_templates/theme-switcher.html b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/_templates/theme-switcher.html new file mode 100644 index 000000000..306a65728 --- /dev/null +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/_templates/theme-switcher.html @@ -0,0 +1,5 @@ + + + + + diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/docs-navbar.html b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/docs-navbar.html index defcd4d7f..443fdbb1d 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/docs-navbar.html +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/docs-navbar.html @@ -7,7 +7,7 @@ {% set navbar_class, navbar_align = navbar_align_class() %} diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html index cff38d03c..6359ee071 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html @@ -2,6 +2,10 @@ {%- import "static/webpack-macros.html" as _webpack with context %} {%- block css %} + {{ _webpack.head_pre_assets() }} {{ _webpack.head_pre_icons() }} {{- css() }} @@ -30,7 +34,7 @@ {% block sidebarsourcelink %}{% endblock %} {% block body_tag %} - + {%- endblock %} {%- block content %} {# Added to support a banner with an alert #} diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/static/styles/theme.css b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/static/styles/theme.css index 22779d965..d1bbe2cc3 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/static/styles/theme.css +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/static/styles/theme.css @@ -40,46 +40,6 @@ --pst-font-family-heading: var(--pst-font-family-base); --pst-font-family-monospace: var(--pst-font-family-monospace-system); - /***************************************************************************** - * Color - * - * Colors are defined in rgb string way, "red, green, blue" - **/ - --pst-color-primary: 19, 6, 84; - --pst-color-success: 40, 167, 69; - --pst-color-info: 0, 123, 255; /*23, 162, 184;*/ - --pst-color-warning: 255, 193, 7; - --pst-color-danger: 220, 53, 69; - --pst-color-text-base: 51, 51, 51; - - --pst-color-h1: var(--pst-color-primary); - --pst-color-h2: var(--pst-color-primary); - --pst-color-h3: var(--pst-color-text-base); - --pst-color-h4: var(--pst-color-text-base); - --pst-color-h5: var(--pst-color-text-base); - --pst-color-h6: var(--pst-color-text-base); - --pst-color-paragraph: var(--pst-color-text-base); - --pst-color-link: 0, 91, 129; - --pst-color-link-hover: 227, 46, 0; - --pst-color-headerlink: 198, 15, 15; - --pst-color-headerlink-hover: 255, 255, 255; - --pst-color-preformatted-text: 34, 34, 34; - --pst-color-preformatted-background: 250, 250, 250; - --pst-color-inline-code: 232, 62, 140; - - --pst-color-active-navigation: 19, 6, 84; - --pst-color-navbar-link: 77, 77, 77; - --pst-color-navbar-link-hover: var(--pst-color-active-navigation); - --pst-color-navbar-link-active: var(--pst-color-active-navigation); - --pst-color-sidebar-link: 77, 77, 77; - --pst-color-sidebar-link-hover: var(--pst-color-active-navigation); - --pst-color-sidebar-link-active: var(--pst-color-active-navigation); - --pst-color-sidebar-expander-background-hover: 244, 244, 244; - --pst-color-sidebar-caption: 77, 77, 77; - --pst-color-toc-link: 119, 117, 122; - --pst-color-toc-link-hover: var(--pst-color-active-navigation); - --pst-color-toc-link-active: var(--pst-color-active-navigation); - /***************************************************************************** * Icon **/ @@ -96,17 +56,6 @@ * Admonitions **/ - --pst-color-admonition-default: var(--pst-color-info); - --pst-color-admonition-note: var(--pst-color-info); - --pst-color-admonition-attention: var(--pst-color-warning); - --pst-color-admonition-caution: var(--pst-color-warning); - --pst-color-admonition-warning: var(--pst-color-warning); - --pst-color-admonition-danger: var(--pst-color-danger); - --pst-color-admonition-error: var(--pst-color-danger); - --pst-color-admonition-hint: var(--pst-color-success); - --pst-color-admonition-tip: var(--pst-color-success); - --pst-color-admonition-important: var(--pst-color-success); - --pst-icon-admonition-default: var(--pst-icon-info-circle); --pst-icon-admonition-note: var(--pst-icon-info-circle); --pst-icon-admonition-attention: var(--pst-icon-exclamation-circle); @@ -122,11 +71,6 @@ * versionmodified **/ - --pst-color-versionmodified-default: var(--pst-color-info); - --pst-color-versionmodified-added: var(--pst-color-success); - --pst-color-versionmodified-changed: var(--pst-color-warning); - --pst-color-versionmodified-deprecated: var(--pst-color-danger); - --pst-icon-versionmodified-default: var(--pst-icon-exclamation-circle); --pst-icon-versionmodified-added: var(--pst-icon-exclamation-circle); --pst-icon-versionmodified-changed: var(--pst-icon-exclamation-circle); diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf index 1de2beafa..444cf6e4a 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf @@ -31,8 +31,10 @@ show_toc_level = 1 navbar_align = content navbar_start = navbar-logo.html navbar_center = navbar-nav.html -navbar_end = navbar-icon-links.html +navbar_end = theme-switcher.html, navbar-icon-links.html left_sidebar_end = sidebar-ethical-ads.html footer_items = copyright.html, sphinx-version.html page_sidebar_items = page-toc.html, edit-this-page.html switcher = +pygment_light_style = tango +pygment_dark_style = native diff --git a/tests/test_build.py b/tests/test_build.py index 1b6088bdb..d103dc36b 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -526,3 +526,13 @@ def test_version_switcher(sphinx_build_factory, file_regression): file_regression.check( switcher.prettify(), basename="navbar_switcher", extension=".html" ) + + +def test_theme_switcher(sphinx_build_factory, file_regression): + """Regression test the theme switcher btn HTML""" + + sphinx_build = sphinx_build_factory("base").build() + switcher = sphinx_build.html_tree("index.html").select("#theme-switch")[0] + file_regression.check( + switcher.prettify(), basename="navbar_theme", extension=".html" + ) diff --git a/tests/test_build/navbar_theme.html b/tests/test_build/navbar_theme.html new file mode 100644 index 000000000..cc250fd0b --- /dev/null +++ b/tests/test_build/navbar_theme.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + + +