From 678e84346d4caddedcc62bb53cf545d9bcf74999 Mon Sep 17 00:00:00 2001 From: Julie Muzina Date: Wed, 8 May 2024 14:34:39 -0400 Subject: [PATCH 01/14] request, set, & persist color theme with all JS --- scss/_utilities_baseline-grid.scss | 15 --- scss/_utilities_example_controls.scss | 25 +++++ scss/_utilities_theme-toggle.scss | 39 ------- scss/_vanilla.scss | 4 +- scss/docs/example.scss | 2 +- templates/static/js/example-tools.js | 142 ++++++++++++++++++++------ 6 files changed, 140 insertions(+), 87 deletions(-) create mode 100644 scss/_utilities_example_controls.scss delete mode 100644 scss/_utilities_theme-toggle.scss diff --git a/scss/_utilities_baseline-grid.scss b/scss/_utilities_baseline-grid.scss index 6b59470b28..32bc5e6ed1 100644 --- a/scss/_utilities_baseline-grid.scss +++ b/scss/_utilities_baseline-grid.scss @@ -34,19 +34,4 @@ } } // stylelint-enable selector-max-type - - .u-baseline-grid__toggle { - bottom: $spv--x-large; - color: $colors--light-theme--text-default; // Force light theme colour because of baseline grid background - position: fixed; - right: $sp-unit * 3; - z-index: 201; - } - - // hide the theme toggle in Percy - @media only percy { - .u-baseline-grid__toggle { - visibility: hidden !important; - } - } } diff --git a/scss/_utilities_example_controls.scss b/scss/_utilities_example_controls.scss new file mode 100644 index 0000000000..54096c2cb9 --- /dev/null +++ b/scss/_utilities_example_controls.scss @@ -0,0 +1,25 @@ +@import 'settings'; + +@include vf-base; +@include vf-p-segmented-control; +@include vf-p-forms; +@include vf-p-forms-inline; + +@mixin vf-u-example-controls { + .u-example-controls { + position: fixed; + bottom: $spv--x-large; + right: $sp-unit * 3; + align-items: center; + padding: $spv--small 0 $spv--small $sph--x-large; + background-color: $colors--theme--background-default; + + @media (max-width: $breakpoint-large) { + padding-right: $sph--x-large; + } + + @media only percy { + visibility: hidden !important; + } + } +} \ No newline at end of file diff --git a/scss/_utilities_theme-toggle.scss b/scss/_utilities_theme-toggle.scss deleted file mode 100644 index f1dfad7bbd..0000000000 --- a/scss/_utilities_theme-toggle.scss +++ /dev/null @@ -1,39 +0,0 @@ -@import 'settings'; - -@mixin vf-u-theme-toggle { - .u-theme-toggle { - bottom: $spv--x-large; - position: fixed; - right: $sp-unit * 30; - z-index: 100; - - .u-theme-toggle__button { - margin: 0; - - &:not(:last-child) { - border-right: 0; - } - } - - .u-theme-toggle__dark { - background-color: $colors--dark-theme--background-default; - color: $colors--dark-theme--text-default; - } - - .u-theme-toggle__light { - background-color: $colors--light-theme--background-default; - color: $colors--light-theme--text-default; - } - .u-theme-toggle__paper { - background-color: $color-paper; - color: $color-x-dark; - } - } - - // hide the theme toggle in Percy - @media only percy { - .u-theme-toggle { - visibility: hidden !important; - } - } -} diff --git a/scss/_vanilla.scss b/scss/_vanilla.scss index e290cf0e6b..28a7b6a9ee 100644 --- a/scss/_vanilla.scss +++ b/scss/_vanilla.scss @@ -89,7 +89,7 @@ @import 'utilities_no-print'; @import 'utilities_text-max-width'; @import 'utilities_text-figures'; -@import 'utilities_theme-toggle'; +@import 'utilities_example_controls'; // Include all the CSS @mixin vanilla { @@ -183,5 +183,5 @@ @include vf-u-no-print; @include vf-u-text-max-width; @include vf-u-text-figures; - @include vf-u-theme-toggle; + @include vf-u-example-controls; } diff --git a/scss/docs/example.scss b/scss/docs/example.scss index 512590db1a..4c004befd4 100644 --- a/scss/docs/example.scss +++ b/scss/docs/example.scss @@ -2,7 +2,7 @@ @import '../vanilla'; @include vf-u-baseline-grid; -@include vf-u-theme-toggle; +@include vf-u-example-controls; // stylelint-disable selector-max-type -- examples can use type selectors body { diff --git a/templates/static/js/example-tools.js b/templates/static/js/example-tools.js index 993944c920..ffe5870b7a 100644 --- a/templates/static/js/example-tools.js +++ b/templates/static/js/example-tools.js @@ -1,3 +1,8 @@ +const SUPPORTED_THEMES = ['Light', 'Dark', 'Paper']; +const [DEFAULT_COLOR_THEME] = SUPPORTED_THEMES; +const COLOR_THEME_QUERY_PARAM_NAME = 'theme'; +var activeTheme = DEFAULT_COLOR_THEME; + (function () { function inIframe() { try { @@ -13,19 +18,110 @@ return temp.content; } + /** + * Gets the current query parameters + * @returns {URLSearchParams} + */ + function getQueryParameters() { + return new URLSearchParams(window.location.search); + } + + /** + * Sets the query parameter value of `key` to `value` + * @param {String} key + * @param {String} value + * @param {Boolean} reload Whether to cause a page load after updating the query parameter + * @returns {URLSearchParams} Query parameters after update + */ + function setQueryParameter(key, value, reload = false) { + var currentQueryParams = getQueryParameters(); + + if (reload && currentQueryParams.get(key) !== value) { + currentQueryParams.set(key, value); + window.location.search = currentQueryParams.toString(); + } + else { + var url = new URL(window.location.href); + url.searchParams.set(key, value); + window.history.pushState(null, '', url.toString()); + } + return getQueryParameters(); + } + + /** + * Converts a theme name to its document class name, used for applying that color theme to the body + * @param {String} themeName + * @returns {string} + */ + function convertThemeNameToClassName(themeName) { + return `is-${themeName.toLowerCase()}`; + } + + /** + * Converts a theme name to its JS toggler class name, used for targeting it with JS events + * @param {String} themeName + * @returns {string} + */ + function convertThemeNameToJsTogglerClassName(themeName) { + return `js-${themeName.toLowerCase()}-theme-toggle`; + } + + /** + * Converts a theme name to its toggler utility class name, used for applying style to the toggler button + * @param {String} themeName + * @returns {string} + */ + function convertThemeNameToTogglerUtilityClassName(themeName) { + return `u-theme-toggle__${themeName.toLowerCase()}` + } + + /** + * Sets a color theme as active; removes all other color themes from active status + * @param {String} themeToSelect + */ + function selectColorTheme(themeToSelect) { + // Apply the color theme to the document body + document.body.classList.add(convertThemeNameToClassName(themeToSelect)); + // Remove the old color theme from the document body + if (themeToSelect !== activeTheme) document.body.classList.remove(convertThemeNameToClassName(activeTheme)); + + // Update address bar to reflect the newly selected color theme + setQueryParameter(COLOR_THEME_QUERY_PARAM_NAME, themeToSelect.toLowerCase()); + + // Update theme selector button states to reflect which one is currently active + var themeButtonToSelect = document.querySelector(`.${convertThemeNameToJsTogglerClassName(themeToSelect)}`); + themeButtonToSelect?.setAttribute('aria-selected', "true"); + var themeButtonCurrentlySelected = document.querySelector(`.${convertThemeNameToJsTogglerClassName(activeTheme)}`); + themeButtonCurrentlySelected?.setAttribute('aria-selected', 'false'); + + activeTheme = themeToSelect; + } + if (!inIframe()) { document.documentElement.classList.add('u-baseline-grid'); document.addEventListener('DOMContentLoaded', function () { var body = document.body; - var controls = fragmentFromString( - '
', - ); - var themes = fragmentFromString( - '
', - ); - - body.appendChild(themes); + var requestedColorTheme = getQueryParameters().get(COLOR_THEME_QUERY_PARAM_NAME); + + // Validate requested color theme + if ( + requestedColorTheme + && SUPPORTED_THEMES.some(supportedTheme => supportedTheme.toLowerCase() === requestedColorTheme.toLowerCase()) + ) { + selectColorTheme(requestedColorTheme); + } else { + selectColorTheme(DEFAULT_COLOR_THEME); + } + + var themeSwitcherControls = SUPPORTED_THEMES.map(themeLabel => ``); + var themeSwitcherSegmentedControl = fragmentFromString(`
${themeSwitcherControls.join('')}
`) + var baselineGridControl = fragmentFromString('
') + + var controls = document.createElement('div'); + controls.classList.add('u-example-controls', 'p-form', 'p-form--inline'); + controls.appendChild(themeSwitcherSegmentedControl); + controls.appendChild(baselineGridControl); body.appendChild(controls); var toggle = document.querySelector('.js-baseline-toggle'); @@ -33,32 +129,18 @@ body.classList.toggle('u-baseline-grid'); }); - var themeToggles = document.querySelector('.u-theme-toggle'); + var themeToggleContainer = document.querySelector('.u-theme-toggle'); if (!SHOW_THEME_SWITCH) { - themeToggles.classList.add('u-hide'); + themeToggleContainer.classList.add('u-hide'); } - var darkTheme = document.querySelector('.js-dark-theme-toggle'); - darkTheme.addEventListener('click', function (event) { - body.classList.add('is-dark'); - body.classList.remove('is-paper'); - body.classList.remove('is-light'); - }); - - var lightTheme = document.querySelector('.js-light-theme-toggle'); - lightTheme.addEventListener('click', function (event) { - body.classList.add('is-light'); - body.classList.remove('is-dark'); - body.classList.remove('is-paper'); - }); - - var paperTheme = document.querySelector('.js-paper-theme-toggle'); - paperTheme.addEventListener('click', function (event) { - body.classList.add('is-paper'); - body.classList.remove('is-dark'); - body.classList.remove('is-light'); - }); + var themeToggleButtons = document.querySelectorAll('.u-theme-toggle__button'); + themeToggleButtons.forEach(themeToggleButton => { + themeToggleButton.addEventListener('click', () => { + selectColorTheme(themeToggleButton.getAttribute('data-color-theme-name')) + }) + }) }); } })(); From ec40c5c4b0c97f411c2d48ddcd7a1d8f58c1a2a6 Mon Sep 17 00:00:00 2001 From: Julie Muzina Date: Wed, 8 May 2024 17:43:37 -0400 Subject: [PATCH 02/14] Back-end passes in and validates color themes instead of front end --- requirements.txt | 2 +- scss/_utilities_example_controls.scss | 4 ++ templates/static/js/example-tools.js | 24 +++++------ webapp/app.py | 58 ++++++++++++++++++++++++++- 4 files changed, 71 insertions(+), 17 deletions(-) diff --git a/requirements.txt b/requirements.txt index 0a5d135c0d..3ed6bad8b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,4 @@ canonicalwebteam.templatefinder==1.0.0 canonicalwebteam.search==1.3.0 canonicalwebteam.image-template==1.3.1 mistune==0.8.4 -pyyaml==6.0.1 +pyyaml==6.0.1 \ No newline at end of file diff --git a/scss/_utilities_example_controls.scss b/scss/_utilities_example_controls.scss index 54096c2cb9..c82de7dedd 100644 --- a/scss/_utilities_example_controls.scss +++ b/scss/_utilities_example_controls.scss @@ -14,6 +14,10 @@ padding: $spv--small 0 $spv--small $sph--x-large; background-color: $colors--theme--background-default; + .u-theme-toggle__button { + text-transform: capitalize; + } + @media (max-width: $breakpoint-large) { padding-right: $sph--x-large; } diff --git a/templates/static/js/example-tools.js b/templates/static/js/example-tools.js index ffe5870b7a..8add1f7e6c 100644 --- a/templates/static/js/example-tools.js +++ b/templates/static/js/example-tools.js @@ -1,7 +1,7 @@ -const SUPPORTED_THEMES = ['Light', 'Dark', 'Paper']; -const [DEFAULT_COLOR_THEME] = SUPPORTED_THEMES; const COLOR_THEME_QUERY_PARAM_NAME = 'theme'; -var activeTheme = DEFAULT_COLOR_THEME; +const COLOR_THEMES_SUPPORTED_QUERY_PARAM_NAME = 'available_themes'; +var availableThemes = []; +var activeTheme; (function () { function inIframe() { @@ -102,19 +102,13 @@ var activeTheme = DEFAULT_COLOR_THEME; document.addEventListener('DOMContentLoaded', function () { var body = document.body; - var requestedColorTheme = getQueryParameters().get(COLOR_THEME_QUERY_PARAM_NAME); - - // Validate requested color theme - if ( - requestedColorTheme - && SUPPORTED_THEMES.some(supportedTheme => supportedTheme.toLowerCase() === requestedColorTheme.toLowerCase()) - ) { - selectColorTheme(requestedColorTheme); - } else { - selectColorTheme(DEFAULT_COLOR_THEME); - } + availableThemes = getQueryParameters()?.get(COLOR_THEMES_SUPPORTED_QUERY_PARAM_NAME)?.split(','); + var requestedTheme = getQueryParameters()?.get(COLOR_THEME_QUERY_PARAM_NAME) || availableThemes[0]; + activeTheme = requestedTheme; + console.log({requestedTheme, availableThemes}); + selectColorTheme(requestedTheme); - var themeSwitcherControls = SUPPORTED_THEMES.map(themeLabel => ``); + var themeSwitcherControls = availableThemes.map(themeLabel => ``); var themeSwitcherSegmentedControl = fragmentFromString(`
${themeSwitcherControls.join('')}
`) var baselineGridControl = fragmentFromString('
') diff --git a/webapp/app.py b/webapp/app.py index 1fb9de765b..905b4e2c2b 100644 --- a/webapp/app.py +++ b/webapp/app.py @@ -3,6 +3,9 @@ import json import os import random +import re + +import werkzeug.routing import yaml import urllib import markupsafe @@ -30,6 +33,9 @@ with open("releases.yml") as releases_file: FEATURES_LIST = yaml.load(releases_file.read(), Loader=yaml.FullLoader) +SUPPORTED_COLOR_THEMES = {"light", "dark", "paper"} +DEFAULT_COLOR_THEME = "light" + # Read side-navigation.yaml with open("side-navigation.yaml") as side_navigation_file: # maps values of `side_navigation_file.subheadings.ordering` to their implementations @@ -84,12 +90,19 @@ def alphabetize_heading_items(heading, by_attribute="title"): {"login": "jmuzina", "role": "Web Engineer"} ] - # Helpers # === def _get_title(title): yield title +def _add_query_param_to_url(url, param_name, param_value): + parsed_url = urllib.parse.urlparse(url) + query_params = urllib.parse.parse_qs(parsed_url.query) + query_params[param_name] = param_value + encoded_query_params = urllib.parse.urlencode(query_params, doseq=True) + new_url_parts = (parsed_url.scheme, parsed_url.netloc, parsed_url.path, parsed_url.params, encoded_query_params, parsed_url.fragment) + + return urllib.parse.urlunparse(new_url_parts) def _get_examples(): # get all example files (but ignore partials that start with _) @@ -124,6 +137,15 @@ def _get_examples(): return examples +def _all_examples_to_paths_flat(): + paths = set() + examples = _get_examples() + for ex_type in examples: + for example in examples[ex_type]: + paths.add(example['path']) + + return paths + def _make_github_request(endpoint): github_secret = os.getenv("GITHUB_TOKEN") @@ -254,6 +276,7 @@ def utility_processor(): @app.route("/docs/examples") def examples_index(): + print("examples index") return flask.render_template( "docs/examples/index.html", examples=_get_examples() ) @@ -261,6 +284,7 @@ def examples_index(): @app.route("/docs/examples/standalone") def standalone_examples_index(): + print("standalone index") return flask.render_template( "docs/examples/standalone.html", examples=_get_examples() ) @@ -268,11 +292,13 @@ def standalone_examples_index(): @app.route("/docs/examples/standalone/") def standalone_example(example_path): + print("standalone") try: return flask.render_template( f"docs/examples/{example_path}.html", is_standalone=True ) except jinja2.exceptions.TemplateNotFound: + print("standalone 404") return flask.abort(404) @@ -295,6 +321,36 @@ def contribute_index(): return response +def get_available_themes_for_endpoint(): + return SUPPORTED_COLOR_THEMES + +def process_color_theme(): + requested_color_theme = flask.request.args.get("theme") + supported_themes_for_endpoint = get_available_themes_for_endpoint() + apply_color_theme = None + if requested_color_theme is not None and requested_color_theme in SUPPORTED_COLOR_THEMES: + apply_color_theme = requested_color_theme + else: + apply_color_theme = DEFAULT_COLOR_THEME + + redirect_url = _add_query_param_to_url(flask.request.url, "theme", apply_color_theme) + redirect_url = _add_query_param_to_url(redirect_url, "available_themes", ','.join(supported_themes_for_endpoint)) + if flask.request.url != redirect_url: + return flask.redirect(redirect_url, code=307) + +with app.app_context(): + exs = _all_examples_to_paths_flat() + exs_res = '|'.join([re.escape(ex) for ex in exs]) + exs_match = rf'^/docs/examples/(?:standalone/)?(?:{exs_res})$' + + @flask.current_app.before_request + def preprocess(): + if flask.request.endpoint == 'static': + return + + if re.match(exs_match, flask.request.path): + return process_color_theme() + app.add_url_rule("/", view_func=template_finder_view) app.add_url_rule( From 9f8241d5d1e018f9abddd1895b1c158416e61ff8 Mon Sep 17 00:00:00 2001 From: Julie Muzina Date: Thu, 9 May 2024 13:40:33 -0400 Subject: [PATCH 03/14] example color theme python cleanup --- color-themes.yml | 5 +++ webapp/app.py | 87 +++++++++++++++++++++++++++++------------------- 2 files changed, 58 insertions(+), 34 deletions(-) create mode 100644 color-themes.yml diff --git a/color-themes.yml b/color-themes.yml new file mode 100644 index 0000000000..f6f548ffd5 --- /dev/null +++ b/color-themes.yml @@ -0,0 +1,5 @@ +themes: + - "light" + - "dark" + - "paper" +default_theme: "light" \ No newline at end of file diff --git a/webapp/app.py b/webapp/app.py index 905b4e2c2b..379fc70c38 100644 --- a/webapp/app.py +++ b/webapp/app.py @@ -33,8 +33,10 @@ with open("releases.yml") as releases_file: FEATURES_LIST = yaml.load(releases_file.read(), Loader=yaml.FullLoader) -SUPPORTED_COLOR_THEMES = {"light", "dark", "paper"} -DEFAULT_COLOR_THEME = "light" +with open("color-themes.yml") as color_themes_file: + color_theme_file_content = yaml.load(color_themes_file.read(), Loader=yaml.FullLoader) + SUPPORTED_COLOR_THEMES = color_theme_file_content["themes"] + DEFAULT_COLOR_THEME = color_theme_file_content["default_theme"] # Read side-navigation.yaml with open("side-navigation.yaml") as side_navigation_file: @@ -96,6 +98,13 @@ def _get_title(title): yield title def _add_query_param_to_url(url, param_name, param_value): + """ + Modifies a `url` by adding `param_name=param_value` to the query string. + :param url: + :param param_name: + :param param_value: + :return: `url` after adding `param_name=param_value` to the query string. + """ parsed_url = urllib.parse.urlparse(url) query_params = urllib.parse.parse_qs(parsed_url.query) query_params[param_name] = param_value @@ -137,7 +146,10 @@ def _get_examples(): return examples -def _all_examples_to_paths_flat(): +def _get_all_examples_paths(): + """ + :return: Set of all paths to example component files from the root of the site. I.E., /docs/examples/patterns/buttons/alignment + """ paths = set() examples = _get_examples() for ex_type in examples: @@ -207,6 +219,32 @@ def _filter_contributors(contributors): ] +def _get_available_themes_for_path(example_path): + print(example_path) + return SUPPORTED_COLOR_THEMES + +def _apply_color_theme(): + """ + Applies color theme and supported color theme to the requested route. + """ + requested_color_theme = flask.request.args.get("theme") + supported_color_themes_for_path = _get_available_themes_for_path(flask.request.path) + + # Valid color theme requested + if requested_color_theme is not None and requested_color_theme in supported_color_themes_for_path: + apply_color_theme = requested_color_theme + else: + apply_color_theme = DEFAULT_COLOR_THEME + + # Construct a new URL with the query parameters updated + redirect_url = _add_query_param_to_url(flask.request.url, "theme", apply_color_theme) + redirect_url = _add_query_param_to_url(redirect_url, "available_themes", ','.join(supported_color_themes_for_path)) + + # Redirect the user to the modified URL if they are not currently at that address + if flask.request.url != redirect_url: + return flask.redirect(redirect_url, code=307) + + # Global context settings @app.context_processor def global_template_context(): @@ -249,6 +287,18 @@ def global_template_context(): "updatedFeatures": updated_features, } +# Request preprocessing +with app.app_context(): + example_paths = _get_all_examples_paths() + all_examples_regex = '|'.join([re.escape(example_path) for example_path in example_paths]) + example_match = rf'^/docs/examples/(?:standalone/)?(?:{all_examples_regex})$' + + @app.before_request + def preprocess(): + # Only care about applying color theme for example component pages + if re.match(example_match, flask.request.path): + return _apply_color_theme() + @app.template_filter() def markdown(text): @@ -321,37 +371,6 @@ def contribute_index(): return response -def get_available_themes_for_endpoint(): - return SUPPORTED_COLOR_THEMES - -def process_color_theme(): - requested_color_theme = flask.request.args.get("theme") - supported_themes_for_endpoint = get_available_themes_for_endpoint() - apply_color_theme = None - if requested_color_theme is not None and requested_color_theme in SUPPORTED_COLOR_THEMES: - apply_color_theme = requested_color_theme - else: - apply_color_theme = DEFAULT_COLOR_THEME - - redirect_url = _add_query_param_to_url(flask.request.url, "theme", apply_color_theme) - redirect_url = _add_query_param_to_url(redirect_url, "available_themes", ','.join(supported_themes_for_endpoint)) - if flask.request.url != redirect_url: - return flask.redirect(redirect_url, code=307) - -with app.app_context(): - exs = _all_examples_to_paths_flat() - exs_res = '|'.join([re.escape(ex) for ex in exs]) - exs_match = rf'^/docs/examples/(?:standalone/)?(?:{exs_res})$' - - @flask.current_app.before_request - def preprocess(): - if flask.request.endpoint == 'static': - return - - if re.match(exs_match, flask.request.path): - return process_color_theme() - - app.add_url_rule("/", view_func=template_finder_view) app.add_url_rule( "/docs/search", From 82522ed862387a04b0852f8815c22bf32368c0a0 Mon Sep 17 00:00:00 2001 From: Julie Muzina Date: Thu, 9 May 2024 18:36:57 -0400 Subject: [PATCH 04/14] example color theme rework supports pre-existing example theme defaults / restrictions --- color-themes.yml | 98 ++++++++++++- scss/_utilities_example_controls.scss | 2 +- templates/_layouts/examples.html | 12 +- .../docs/examples/base/code-inline-dark.html | 2 +- templates/docs/examples/base/hr-dark.html | 2 +- .../examples/base/paper/input-on-paper.html | 2 +- .../base/paper/search-box-on-paper.html | 2 +- templates/docs/examples/brochure/index.html | 2 +- .../examples/layouts/application/JAAS.html | 2 +- .../examples/layouts/application/default.html | 2 +- .../examples/layouts/application/split.html | 2 +- templates/docs/examples/layouts/docs.html | 2 +- .../examples/patterns/article-pagination.html | 2 +- .../docs/examples/patterns/buttons/dark.html | 2 +- .../docs/examples/patterns/card/overlay.html | 2 +- .../docs/examples/patterns/chip/dark.html | 2 +- .../patterns/code-snippet/default-dark.html | 2 +- .../code-snippet/dropdown-multiple-dark.html | 2 +- .../patterns/code-snippet/icon-dark.html | 2 +- .../patterns/contextual-menu/dark.html | 2 +- .../docs/examples/patterns/divider/dark.html | 2 +- .../patterns/forms/form-validation-dark.html | 2 +- .../examples/patterns/forms/forms-dark.html | 2 +- .../docs/examples/patterns/hero/hero-404.html | 2 +- .../examples/patterns/hero/hero-blog.html | 2 +- .../patterns/hero/hero-heading-1.html | 2 +- .../patterns/hero/hero-heading-2.html | 2 +- .../patterns/hero/hero-line-breaks.html | 2 +- .../patterns/hero/hero-nested-grid.html | 2 +- .../examples/patterns/hero/hero-rules.html | 2 +- .../patterns/hero/hero-sections-search.html | 2 +- .../examples/patterns/hero/hero-sections.html | 2 +- .../examples/patterns/hero/hero-signpost.html | 2 +- .../examples/patterns/icons/icons-dark.html | 2 +- .../examples/patterns/links/links-dark.html | 2 +- .../patterns/links/links-inverted.html | 2 +- .../patterns/lists/lists-mid-dot-dark.html | 2 +- .../patterns/lists/lists-stepped-dark.html | 2 +- .../logo-section/logo-section-dark.html | 2 +- .../notifications/notifications-dark.html | 2 +- .../patterns/notifications/variants-dark.html | 2 +- .../pagination/pagination-deprecated.html | 2 +- .../docs/examples/patterns/rule/dark.html | 2 +- .../search-and-filter/chip-overflow.html | 2 +- .../patterns/search-and-filter/default.html | 2 +- .../patterns/search-and-filter/expanded.html | 2 +- .../search-and-filter/with-chips.html | 2 +- .../search-and-filter/with-search-prompt.html | 2 +- .../patterns/search-box/default-dark.html | 2 +- .../patterns/side-navigation/_icons.html | 6 +- .../side-navigation/accordion-dark.html | 2 +- .../patterns/side-navigation/application.html | 2 +- .../patterns/side-navigation/dark.html | 2 +- .../side-navigation/expandable-dark.html | 2 +- .../patterns/side-navigation/paper.html | 2 +- .../docs/examples/patterns/strips/dark.html | 4 +- .../docs/examples/patterns/strips/deep.html | 2 +- .../examples/patterns/strips/highlighted.html | 2 +- .../examples/patterns/strips/shallow.html | 2 +- .../docs/examples/patterns/strips/white.html | 2 +- .../examples/patterns/suru/50-50-dark.html | 2 +- .../docs/examples/patterns/suru/50-50.html | 2 +- .../docs/examples/patterns/suru/dark.html | 2 +- .../docs/examples/patterns/suru/default.html | 2 +- .../docs/examples/patterns/suru/divider.html | 2 +- .../examples/patterns/suru/fan-bottom.html | 2 +- .../patterns/suru/fan-pyramid-left.html | 2 +- .../patterns/suru/fan-pyramid-right.html | 2 +- .../docs/examples/patterns/suru/fan-top.html | 2 +- .../examples/patterns/suru/standalone.html | 2 +- .../docs/examples/patterns/suru/variants.html | 2 +- .../tables/table-mobile-card-dark.html | 2 +- .../patterns/tables/table-sortable-dark.html | 2 +- .../examples/patterns/tabs/content-dark.html | 2 +- templates/static/js/example-tools.js | 72 +++++----- webapp/__init__.py | 0 webapp/app.py | 73 ++-------- webapp/color_theme.py | 132 ++++++++++++++++++ webapp/util.py | 25 ++++ 79 files changed, 379 insertions(+), 183 deletions(-) create mode 100644 webapp/__init__.py create mode 100644 webapp/color_theme.py create mode 100644 webapp/util.py diff --git a/color-themes.yml b/color-themes.yml index f6f548ffd5..9316332289 100644 --- a/color-themes.yml +++ b/color-themes.yml @@ -1,5 +1,95 @@ +default_theme: 'light' themes: - - "light" - - "dark" - - "paper" -default_theme: "light" \ No newline at end of file + light: + dark: + paper: +path_overrides: + 'docs/examples/layouts/application/structure': + is_not_themed: true + 'docs/examples/layouts/application/default': + is_not_themed: true + 'docs/examples/layouts/application/jaas': + is_not_themed: true + 'docs/examples/layouts/application/split': + is_not_themed: true + 'docs/examples/patterns/card/overlay': + is_not_themed: true + 'docs/examples/patterns/article-pagination': + is_not_themed: true + 'docs/examples/patterns/pagination/pagination-deprecated': + is_not_themed: true + 'docs/examples/patterns/search-and-filter/chip-overflow': + is_not_themed: true + 'docs/examples/patterns/search-and-filter/default': + is_not_themed: true + 'docs/examples/patterns/search-and-filter/expanded': + is_not_themed: true + 'docs/examples/patterns/search-and-filter/with-chips': + is_not_themed: true + 'docs/examples/patterns/search-and-filter/with-search-prompt': + is_not_themed: true + 'docs/examples/patterns/suru/50-50': + available_themes: + - 'paper' + - 'dark' + 'docs/examples/patterns/suru/default': + available_themes: + - 'paper' + - 'dark' + 'docs/examples/patterns/suru/divider': + available_themes: + - 'paper' + - 'dark' + 'docs/examples/patterns/suru/fan-bottom': + available_themes: + - 'paper' + - 'dark' + 'docs/examples/patterns/suru/fan-pyramid-left': + available_themes: + - 'paper' + - 'dark' + 'docs/examples/patterns/suru/fan-pyramid-right': + available_themes: + - 'paper' + - 'dark' + 'docs/examples/patterns/suru/fan-top': + available_themes: + - 'paper' + - 'dark' + 'docs/examples/patterns/suru/variants': + available_themes: + - 'paper' + - 'dark' + 'docs/examples/patterns/strips/white': + available_themes: + - 'paper' + 'docs/examples/patterns/strips/shallow': + default_theme: 'paper' + 'docs/examples/patterns/strips/deep': + default_theme: 'paper' + 'docs/examples/patterns/strips/highlighted': + default_theme: 'paper' + 'docs/examples/patterns/hero/hero-404': + default_theme: 'paper' + 'docs/examples/patterns/hero/hero-blog': + default_theme: 'paper' + 'docs/examples/patterns/hero/hero-heading-1': + default_theme: 'paper' + 'docs/examples/patterns/hero/hero-heading-2': + default_theme: 'paper' + 'docs/examples/patterns/hero/hero-line-breaks': + default_theme: 'paper' + 'docs/examples/patterns/hero/hero-nested-grid': + default_theme: 'paper' + 'docs/examples/patterns/hero/hero-rules': + default_theme: 'paper' + 'docs/examples/patterns/hero/hero-sections-search': + default_theme: 'paper' + 'docs/examples/patterns/hero/hero-sections': + default_theme: 'paper' + 'docs/examples/patterns/hero/hero-signpost': + default_theme: 'paper' + 'docs/examples/brochure/index': + default_theme: 'paper' + 'docs/examples/layouts/docs': + default_theme: 'paper' diff --git a/scss/_utilities_example_controls.scss b/scss/_utilities_example_controls.scss index c82de7dedd..a80aa38a23 100644 --- a/scss/_utilities_example_controls.scss +++ b/scss/_utilities_example_controls.scss @@ -26,4 +26,4 @@ visibility: hidden !important; } } -} \ No newline at end of file +} diff --git a/templates/_layouts/examples.html b/templates/_layouts/examples.html index 4810172f2a..ae119a3b3b 100644 --- a/templates/_layouts/examples.html +++ b/templates/_layouts/examples.html @@ -15,21 +15,11 @@ {% block style %}{% endblock %} - {% if is_not_themed %} - - {% else %} - - {% endif %} - - + {% block content %}{% endblock %} diff --git a/templates/docs/examples/base/code-inline-dark.html b/templates/docs/examples/base/code-inline-dark.html index 9f76fd3274..09b94de9cc 100644 --- a/templates/docs/examples/base/code-inline-dark.html +++ b/templates/docs/examples/base/code-inline-dark.html @@ -3,7 +3,7 @@ {% block standalone_css %}base{% endblock %} -{% set is_dark = True %} + {% block content %}

The quick brown fox jumps over the lazy dog

{% endblock %} diff --git a/templates/docs/examples/base/hr-dark.html b/templates/docs/examples/base/hr-dark.html index 6c10a893c8..d170850e2a 100644 --- a/templates/docs/examples/base/hr-dark.html +++ b/templates/docs/examples/base/hr-dark.html @@ -11,7 +11,7 @@ {% endblock %} -{% set is_dark = True %} + {% block content %}
{% endblock %} diff --git a/templates/docs/examples/base/paper/input-on-paper.html b/templates/docs/examples/base/paper/input-on-paper.html index 69c9b7c9ef..a329541f71 100644 --- a/templates/docs/examples/base/paper/input-on-paper.html +++ b/templates/docs/examples/base/paper/input-on-paper.html @@ -2,7 +2,7 @@ {% block title %}Paper background / Inputs{% endblock %} {% block standalone_css %}patterns_forms{% endblock %} -{% set is_paper = True %} + {% block content %} diff --git a/templates/docs/examples/base/paper/search-box-on-paper.html b/templates/docs/examples/base/paper/search-box-on-paper.html index 0e14c97557..89f4ca2114 100644 --- a/templates/docs/examples/base/paper/search-box-on-paper.html +++ b/templates/docs/examples/base/paper/search-box-on-paper.html @@ -2,7 +2,7 @@ {% block title %}Paper background / Search box{% endblock %} {% block standalone_css %}patterns_forms{% endblock %} -{% set is_paper = True %} + {% block content %}