diff --git a/packages/envision-docs/gatsby-config.js b/packages/envision-docs/gatsby-config.js index 8e9fb60b0..d45aa63b2 100644 --- a/packages/envision-docs/gatsby-config.js +++ b/packages/envision-docs/gatsby-config.js @@ -16,6 +16,10 @@ module.exports = { title: 'Getting started', slug: 'getting-started', }, + { + title: 'Dashboard', + slug: 'dashboard', + }, { title: 'Branding', slug: 'ui', @@ -50,6 +54,13 @@ module.exports = { superscript_types: /(SuperType)/, }, }, + { + language: 'css-no-expand', + extend: 'css', + definition: { + superscript_types: /(SuperType)/, + }, + }, { language: 'js-no-expand', extend: 'javascript', @@ -79,6 +90,7 @@ module.exports = { list: 'doc-list', listItem: 'doc-list__item', image: 'doc-image', + table: 'doc-table', }, }, }, diff --git a/packages/envision-docs/src/components/Header/index.js b/packages/envision-docs/src/components/Header/index.js index 44b45b89d..a8283be45 100644 --- a/packages/envision-docs/src/components/Header/index.js +++ b/packages/envision-docs/src/components/Header/index.js @@ -4,10 +4,10 @@ import PropTypes from 'prop-types'; import Link from '../Link'; import ThemePicker from '../ThemePicker'; -const Header = ({ title, menuItems }) => { +const Header = ({ title, bodyClass, menuItems }) => { return ( <> - + { Header.propTypes = { title: PropTypes.string, + bodyClass: PropTypes.string, menuItems: PropTypes.array, }; diff --git a/packages/envision-docs/src/components/Theme/index.js b/packages/envision-docs/src/components/Theme/index.js index 862de14da..e0373d5ef 100644 --- a/packages/envision-docs/src/components/Theme/index.js +++ b/packages/envision-docs/src/components/Theme/index.js @@ -12,6 +12,9 @@ const ThemeProvider = ({ children }) => { }, []); React.useEffect(() => { + if (document.body.classList.contains('env-dashboard-theme')) { + return; + } let oldTheme = window.localStorage.getItem('env-theme'); document.body.classList.remove(oldTheme); if (theme) { diff --git a/packages/envision-docs/src/hooks/colorUtils.js b/packages/envision-docs/src/hooks/colorUtils.js new file mode 100644 index 000000000..0463cc164 --- /dev/null +++ b/packages/envision-docs/src/hooks/colorUtils.js @@ -0,0 +1,58 @@ +const WCAG_CONTRAST_RATIO = { + AA_LARGE: 1 / 3, + AA_NORMAL: 1 / 4.5, + AAA_LARGE: 1 / 4.5, + AAA_NORMAL: 1 / 7, +}; + +export const DASHBOARD_COLORS = [ + 'red', + 'pink', + 'purple', + 'deep-purple', + 'indigo', + 'blue', + 'light-blue', + 'cyan', + 'teal', + 'green', + 'light-green', + 'lime', + 'yellow', + 'orange', + 'brown', + 'gray', +]; +export const DASHBOARD_COLOR_VARIANTS = ['05', '20', '50', '90']; + +export const passesWCAG = (ratio, level) => { + level = level || WCAG_CONTRAST_RATIO.AA_NORMAL; + return 1 / ratio < level; +}; + +const hexToRgb = (hex) => { + const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; + const rgbRegex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i; + hex = hex.replace(shorthandRegex, function (m, r, g, b) { + return r + r + g + g + b + b; + }); + const result = rgbRegex.exec(hex); + const r = parseInt(result[1], 16); + const g = parseInt(result[2], 16); + const b = parseInt(result[3], 16); + return result ? [r, g, b] : null; +}; + +const luminance = (rgb) => { + const a = rgb.map(function (v) { + v /= 255; + return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4); + }); + return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722; +}; + +export const getContrastRatio = (hex1, hex2) => { + const lum1 = luminance(hexToRgb(hex1)); + const lum2 = luminance(hexToRgb(hex2)); + return (Math.max(lum1, lum2) + 0.05) / (Math.min(lum1, lum2) + 0.05); +}; diff --git a/packages/envision-docs/src/hooks/copyExample.js b/packages/envision-docs/src/hooks/copyExample.js index 862385d2a..5cbad88c9 100644 --- a/packages/envision-docs/src/hooks/copyExample.js +++ b/packages/envision-docs/src/hooks/copyExample.js @@ -292,6 +292,35 @@ export const useCopyExample = (content) => { }); }); + // Wrap Dashboard specific Envision styling + // so it doesn't leak into other doc pages. + const DASHBOARD_THEME = 'env-dashboard-theme'; + const wrapDashboardRule = (s) => { + const a = s.split(','); + a.forEach((s2, i) => { + a[i] = `.${DASHBOARD_THEME} ${s2}`.replace(/\s\s+/g, ' '); + }); + return a.join(', '); + }; + + for (let i = 0; i < document.styleSheets.length; i++) { + if (document.styleSheets[i].href.includes('dashboard')) { + const ruleList = document.styleSheets[i].cssRules; + for (let j = 0; j < ruleList.length; j++) { + if (ruleList[j].selectorText.includes('p.env-text')) { + if (!ruleList[j].selectorText.includes(DASHBOARD_THEME)) { + ruleList[j].selectorText = wrapDashboardRule( + ruleList[j].selectorText + ); + } + break; + } + } + + break; + } + } + // To initialize Image slider examples, // load method must be triggered again in gatsby. window.dispatchEvent(new Event('load')); diff --git a/packages/envision-docs/src/hooks/dashboardExample.js b/packages/envision-docs/src/hooks/dashboardExample.js new file mode 100644 index 000000000..864329425 --- /dev/null +++ b/packages/envision-docs/src/hooks/dashboardExample.js @@ -0,0 +1,85 @@ +import * as React from 'react'; +import { + DASHBOARD_COLOR_VARIANTS, + DASHBOARD_COLORS, + getContrastRatio, + passesWCAG, +} from './colorUtils'; +import { toTitleCase } from './demoUtils'; + +const TEXT_CONTRAST_ICON = + '' + + ''; + +const listItem = (options) => { + const o = Object.assign({}, options); + return `
  • +
    ${o.name} + ${o.hex} +
  • `; +}; + +export const useDashboardExample = (content) => { + React.useEffect(() => { + const colorList = document.getElementById('dashboard-color-list'); + if (colorList) { + const compStyleBody = getComputedStyle(document.body); + const bodyBgColor = compStyleBody.getPropertyValue( + `--env-dashboard-color-gray-05` + ); + const blackColor = compStyleBody.getPropertyValue( + `--env-dashboard-color-black` + ); + const whiteColor = compStyleBody.getPropertyValue( + `--env-dashboard-color-white` + ); + + DASHBOARD_COLORS.forEach((colorName) => { + const gridEl = document.createElement('div'); + gridEl.innerHTML = `

    ${toTitleCase( + colorName.replace('-', ' ') + )}

    `; + + const listEl = document.createElement('ul'); + listEl.classList.add('example-dashboard-color-list'); + + DASHBOARD_COLOR_VARIANTS.forEach((variantName) => { + let txtClassName = 'black'; + let variantText = variantName; + const bgClassName = `${colorName}-${variantName}`; + const bgColor = compStyleBody.getPropertyValue( + `--env-dashboard-color-${colorName}-${variantName}` + ); + + if (bgColor) { + const contrastBody = getContrastRatio(bgColor, bodyBgColor); + const contrastSection = getContrastRatio(bgColor, whiteColor); + const passesAAonWhite = passesWCAG(contrastSection); + const passesAAonBody = passesWCAG(contrastBody); + const canHaveBlackText = passesWCAG( + getContrastRatio(blackColor, bgColor) + ); + if (!canHaveBlackText) { + txtClassName = 'white'; + } + if (passesAAonWhite) { + variantText += TEXT_CONTRAST_ICON; + if (passesAAonBody) { + variantText += '*'; + } + } + } + + listEl.innerHTML += listItem({ + bgClassName: bgClassName, + txtClassName: txtClassName, + name: variantText, + hex: bgColor, + }); + }); + gridEl.appendChild(listEl); + colorList.appendChild(gridEl); + }); + } + }, [content]); +}; diff --git a/packages/envision-docs/src/hooks/demoUtils.js b/packages/envision-docs/src/hooks/demoUtils.js new file mode 100644 index 000000000..3f7e11057 --- /dev/null +++ b/packages/envision-docs/src/hooks/demoUtils.js @@ -0,0 +1,9 @@ +export const toTitleCase = (str) => { + return str + .toLowerCase() + .split(' ') + .map(function (word) { + return word.charAt(0).toUpperCase() + word.slice(1); + }) + .join(' '); +}; diff --git a/packages/envision-docs/src/pages/dashboard/index.md b/packages/envision-docs/src/pages/dashboard/index.md new file mode 100644 index 000000000..5fe646dd9 --- /dev/null +++ b/packages/envision-docs/src/pages/dashboard/index.md @@ -0,0 +1,468 @@ +--- +title: Envision for Dashboard Widgets +dashboard: true +--- + +## Introduction + +Envision for Dashboard Widgets is an extension to Envision that +should be used when creating Sitevision Dashboard Widgets. + +The Sitevision dashboard uses a supplied custom Envision theme as a base. + +Additional CSS variables, class names and components for building widgets are available as described in this page. + +## Designing a Dashboard Widget + +Use Envision components when possible. + +When using custom CSS for styling, all colors should use Envision and Dashboard variables. +Other colors and hard coded color values should be avoided. + +### Wrapper + +Most dashboard widgets should be placed inside a wrapper element with class `env-dashboard-widget`. +This will set the correct background, borders and more for the widget. The wrapper does not set a padding. + +
    +

    + Simple widget +

    + 96% +
    + +```html-no-example +
    + +
    +``` + +### Widget sizes + +There are four available sizes for a widget. The developer may decide which size or sizes a widget should support. +The selected available sizes will be available as a user setting when the widget is added to a dashboard. + +The widgets will be placed in a grid with four columns. Depending on the available screen size and the selected widget size, +a widget may use between one and four columns. + +A small widget will never use more than one column. An extra large widget will +use as many as available. A small widget will not vary much in size, but a large widget may use anything between +320 and 1440 pixels width. + +#### Widget size table + +| Widget | Columns | Sizes (px) | +| :---------- | :-----: | :--------: | +| Small | 1 | 250–342 | +| Medium | 1–2 | 320–708 | +| Large | 1–3 | 320–1074 | +| Extra Large | 1–4 | 320–1440 | + +## Responsive widgets + +Some widgets may need to use a responsive design to fit different widths. Media queries should **not** be used since the width +of the widget may not be relative to the viewport width. To make adaptions for different widget sizes, use [CSS container queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_container_queries). + +The grid column container where the app will be displayed is a [containment context](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_container_queries#using_container_queries) named `dashboard-widget`. + +### Responsive widget example + +
    +
    +

    + Responsive example widget +

    +

    96%

    +

    Resize this widget

    +
    +
    + +```html-no-example +
    +

    + Responsive example widget +

    +

    96%

    +
    +``` + +```css-no-expand + +@container dashboard-widget (max-width: 449px) { + .example-responsive-widget .env-ui-text-kpi-number { + font-size: var(--env-ui-text-kpi-number-font-size-small); + color: var(--env-dashboard-color-pink-50); + } +} + +@container dashboard-widget (min-width: 580px) { + .example-responsive-widget .env-ui-text-kpi-number { + font-size: var(--env-ui-text-kpi-number-font-size-large); + color: var(--env-dashboard-color-light-blue-90); + } +} +``` + +## Typography + +The widget theme uses [Inter](https://fonts.google.com/specimen/Inter) font family which has support for nine different weights +100-900. Other font familes should in most cases not be used. + +
    +

    + Thin 100 — The quick brown fox jumps … 123456789 +

    +

    + Extra Light 200 — The quick brown fox jumps … 123456789 +

    +

    + Light 300 — The quick brown fox jumps … 123456789 +

    +

    + Normal 400 — The quick brown fox jumps … 123456789 +

    +

    + Medium 500 — The quick brown fox jumps … 123456789 +

    +

    + Semi Bold 600 — The quick brown fox jumps … 123456789 +

    +

    + Bold 700 — The quick brown fox jumps … 123456789 +

    +

    + Extra Bold 800 — The quick brown fox jumps … 123456789 +

    +

    + Black 900 — The quick brown fox jumps … 123456789 +

    +
    + +```css +/* Available weights 100–900 */ +.example-fw-100 { + font-weight: 100; +} +``` + +### Headings + +Widgets should use [UI Text](/ui/#ui-text) for headings. + +```html +

    Overline

    +

    Heading

    +

    Section heading

    +

    Subheading

    +

    Caption / description

    +``` + +### Values and labels + +Additional styles only availble in widgets should be used for labels and values in charts and similar. + +```html +

    Axis label / Label

    +

    Axis value / Legend

    +``` + +### Key performance indicators + +For displaying key performance indicators you should use the `env-ui-text-kpi-number` class. +Set different sizes using CSS variables `--env-ui-text-kpi-number-font-size-{x}`. + +```html +96% +96% +96% +96% +``` + +```css +.example-kpi-small { + font-size: var(--env-ui-text-kpi-number-font-size-small); +} + +.example-kpi-large { + font-size: var(--env-ui-text-kpi-number-font-size-large); +} + +.example-kpi-x-large { + font-size: var(--env-ui-text-kpi-number-font-size-x-large); +} +``` + +## Badges + +If a value has changed for the better, the worse or is unchanged it may be displayed using one of the +widget specific badges availble. + +```html + + + + + Down 18% + + + + + + + No change + + + + + + + Up 18% + +``` + +## Colors + +Widgets should always use the widget color palette variables. In cases where using a variable is not possible, +for example in an image, the HEX values from the palette should be used. + +### Color palette + +Make sure color combinations are used that meets the WCAG 2 AA requirements. If unsure about a certain combination, +please use a [color contrast checker](https://webaim.org/resources/contrastchecker/) to validate. + +
    + +
    + +
    +
      +
    • +
      + Black + * + + #202330 +
      +
    • +
    • +
      + White + #ffffff +
      +
    • +
    +
    + +

    + + + = The color will pass WCAG 2 level AA contrast requirements as text on white (widget wrapper) background. +

    +

    + * = The color also passes contrast requirements if used as text on gray-05 (theme body) background. +

    + +### Color palette CSS variable names + +Color variables are named `--env-dashboard-color-white`, `--env-dashboard-color-black` and `--env-dashboard-color-{colorName}-{variant}`. + +Available color names: `red`, +`pink`,`purple`,`deep-purple`,`indigo`,`blue`,`light-blue`,`cyan`,`teal`,`green`,`light-green`,`lime`,`yellow`,`orange`,`brown`,`gray` + +Available variants: `05`, `20`, `50`, `90`, + +### Color palette utility classes + +Simple decoration of areas may be done using CSS classes. Each palette color has a background and a foreground classname. + +Available classnames are `env-dashboard-bg-color-{colorName}-{variant}` where `colorName` and `variant` follow the same +patterns as CSS variable names. + +```html +
    + This is a purple-20 area with default font color. +
    +
    + This is a purple-50 area with white font color. +
    +``` + +### Brand colors + +Brand colors are not available in the dashboard theme, please use the Color palette. + +## Widget example + +
    +

    + Chart widget example heading +

    +
    +

    + Legend line 1 + Legend line 2 +

    +
    +
    +

    + Y axis label +

    +
      +
    • 1,200
    • +
    • 1,000
    • +
    • 800
    • +
    • 600
    • +
    • 400
    • +
    + Example chart +

    + X axis label +

    +
      +
    • 25 nov
    • +
    • 26 nov
    • +
    • 27 nov
    • +
    • 28 nov
    • +
    • 29 nov
    • +
    •  
    • +
    +
    +
    + +### Simplified code example + +This example shows basic usage of CSS classes for headings, labels and more. + +```html-no-example + +
    +

    + Chart widget example heading +

    +

    + Legend line 1 + Legend line 2 +

    +

    + Y axis label +

    +
      +
    • 1,200
    • + ... +
    + +

    + X axis label +

    +
      +
    • 25 nov
    • + ... +
    +
    +``` + +## Available Additional CSS variables + +### Palette Colors + +- `--env-dashboard-color-black` +- `--env-dashboard-color-white` +- `--env-dashboard-color-red-05` +- `--env-dashboard-color-red-20` +- `--env-dashboard-color-red-50` +- `--env-dashboard-color-red-90` +- `--env-dashboard-color-pink-05` +- `--env-dashboard-color-pink-20` +- `--env-dashboard-color-pink-50` +- `--env-dashboard-color-pink-90` +- `--env-dashboard-color-purple-05` +- `--env-dashboard-color-purple-20` +- `--env-dashboard-color-purple-50` +- `--env-dashboard-color-purple-90` +- `--env-dashboard-color-deep-purple-05` +- `--env-dashboard-color-deep-purple-20` +- `--env-dashboard-color-deep-purple-50` +- `--env-dashboard-color-deep-purple-90` +- `--env-dashboard-color-indigo-05` +- `--env-dashboard-color-indigo-20` +- `--env-dashboard-color-indigo-50` +- `--env-dashboard-color-indigo-90` +- `--env-dashboard-color-blue-05` +- `--env-dashboard-color-blue-20` +- `--env-dashboard-color-blue-50` +- `--env-dashboard-color-blue-90` +- `--env-dashboard-color-light-blue-05` +- `--env-dashboard-color-light-blue-20` +- `--env-dashboard-color-light-blue-50` +- `--env-dashboard-color-light-blue-90` +- `--env-dashboard-color-cyan-05` +- `--env-dashboard-color-cyan-20` +- `--env-dashboard-color-cyan-50` +- `--env-dashboard-color-cyan-90` +- `--env-dashboard-color-teal-05` +- `--env-dashboard-color-teal-20` +- `--env-dashboard-color-teal-50` +- `--env-dashboard-color-teal-90` +- `--env-dashboard-color-green-05` +- `--env-dashboard-color-green-20` +- `--env-dashboard-color-green-50` +- `--env-dashboard-color-green-90` +- `--env-dashboard-color-light-green-05` +- `--env-dashboard-color-light-green-20` +- `--env-dashboard-color-light-green-50` +- `--env-dashboard-color-light-green-90` +- `--env-dashboard-color-lime-05` +- `--env-dashboard-color-lime-20` +- `--env-dashboard-color-lime-50` +- `--env-dashboard-color-lime-90` +- `--env-dashboard-color-yellow-05` +- `--env-dashboard-color-yellow-20` +- `--env-dashboard-color-yellow-50` +- `--env-dashboard-color-yellow-90` +- `--env-dashboard-color-orange-05` +- `--env-dashboard-color-orange-20` +- `--env-dashboard-color-orange-50` +- `--env-dashboard-color-orange-90` +- `--env-dashboard-color-brown-05` +- `--env-dashboard-color-brown-20` +- `--env-dashboard-color-brown-50` +- `--env-dashboard-color-brown-90` +- `--env-dashboard-color-gray-05` +- `--env-dashboard-color-gray-20` +- `--env-dashboard-color-gray-50` +- `--env-dashboard-color-gray-90` + +### Additional UI Texts + +- `--env-ui-text-label-font-family` +- `--env-ui-text-label-font-color` +- `--env-ui-text-label-font-size` +- `--env-ui-text-label-font-weight` +- `--env-ui-text-label-text-transform` +- `--env-ui-text-label-letter-spacing` +- `--env-ui-text-value-font-family` +- `--env-ui-text-value-font-color` +- `--env-ui-text-value-font-size` +- `--env-ui-text-value-font-weight` +- `--env-ui-text-value-text-transform` +- `--env-ui-text-value-letter-spacing` +- `--env-ui-text-kpi-number-font-family` +- `--env-ui-text-kpi-number-font-color` +- `--env-ui-text-kpi-number-font-size` +- `--env-ui-text-kpi-number-font-weight` +- `--env-ui-text-kpi-number-text-transform` +- `--env-ui-text-kpi-number-letter-spacing` +- `--env-ui-text-kpi-number-font-size-small` +- `--env-ui-text-kpi-number-font-size-large` +- `--env-ui-text-kpi-number-font-size-x-large` diff --git a/packages/envision-docs/src/pages/ui/index.md b/packages/envision-docs/src/pages/ui/index.md index f89c41934..be2ed1d09 100644 --- a/packages/envision-docs/src/pages/ui/index.md +++ b/packages/envision-docs/src/pages/ui/index.md @@ -12,6 +12,8 @@ A theme will have a brand color and a brand contrast color. [The default Envisio The brand color will be used to generate a palette of lighter and darker variants. Each color in the palette will get a matching contrast color for text verified against WCAG 2.0 AA. + + ## UI text UI Text will be used as the new default text styles for headings in all components. @@ -31,8 +33,6 @@ UI Text will be used as the new default text styles for headings in all componen Branding of components -## -
    diff --git a/packages/envision-docs/src/scss/demo.scss b/packages/envision-docs/src/scss/demo.scss index 963d2aa4a..70830c96c 100644 --- a/packages/envision-docs/src/scss/demo.scss +++ b/packages/envision-docs/src/scss/demo.scss @@ -537,6 +537,233 @@ $variableNames: 'neutral', 'active', 'attention', 'error'; } } +.example-dashboard-color-grid { + --env-cardholder-grid-column-width: 10em; +} + +.example-dashboard-color-list { + list-style-type: none; + margin: 0; + padding: 0; + + li { + font-size: 0.8em; + font-weight: 400; + + &:first-child { + flex: 1 1 100%; + } + + > div { + padding: 0 1em; + height: 3em; + display: flex; + justify-content: space-between; + align-items: center; + line-height: 1; + vertical-align: center; + + .example-dashboard-color-list-icon { + border: 1px solid rgba(255, 255, 255, 0.5); + margin: 0 0 0 0.5em; + } + + span { + display: inline-flex; + justify-content: flex-start; + align-items: center; + } + } + } +} + +.example-dashboard-color-list-icon { + border: 1px solid rgba(32, 35, 48, 0.5); + padding: 2px; + border-radius: 3px; +} + +.env-button--icon-before .example-dashboard-color-list-icon { + transform: translate(-3px, -3px); + border-color: currentColor !important; +} + +.env-button--icon-after .example-dashboard-color-list-icon { + transform: translate(3px, -3px); + border-color: currentColor !important; +} + +.example-dashboard-color-list-legend { + display: inline-flex; + justify-content: flex-start; + align-items: flex-start; + font-size: 0.8em; + + .example-dashboard-color-list-icon { + font-size: 1.4em; + margin: 0 0.5em 0 0; + } +} + +.example-responsive-widget { + min-width: 320px; + max-width: 708px; + width: fit-content; + + &__resizeable { + box-sizing: border-box; + width: 510px; + min-width: 318px; + max-width: 100%; + resize: horizontal; + overflow: hidden; + // Container queries to simulate Sitevision grid + container-type: inline-size; + container-name: dashboard-widget; + } +} + +.example-responsive-widget .env-ui-text-kpi-number { + transition: all 0.2s; +} + +@container dashboard-widget (max-width: 449px) { + .example-responsive-widget .env-ui-text-kpi-number { + font-size: var(--env-ui-text-kpi-number-font-size-small); + color: var(--env-dashboard-color-pink-50); + } +} + +@container dashboard-widget (min-width: 580px) { + .example-responsive-widget .env-ui-text-kpi-number { + font-size: var(--env-ui-text-kpi-number-font-size-large); + color: var(--env-dashboard-color-light-blue-90); + } +} + +.example-fw-100 { + font-weight: 100; +} + +.example-fw-200 { + font-weight: 200; +} + +.example-fw-300 { + font-weight: 300; +} + +.example-fw-400 { + font-weight: 400; +} + +.example-fw-500 { + font-weight: 500; +} + +.example-fw-600 { + font-weight: 600; +} + +.example-fw-700 { + font-weight: 700; +} + +.example-fw-800 { + font-weight: 800; +} + +.example-fw-900 { + font-weight: 900; +} + +.example-kpi-small { + font-size: var(--env-ui-text-kpi-number-font-size-small); +} + +.example-kpi-large { + font-size: var(--env-ui-text-kpi-number-font-size-large); +} + +.example-kpi-x-large { + font-size: var(--env-ui-text-kpi-number-font-size-x-large); +} + +canvas.example-canvas { + display: block; + max-width: 100%; + background-color: var(--env-section-background-color); +} + +#example-chart { + position: relative; + width: fit-content; + margin: 1.5em 0 3em 4em; +} + +.example-chart-axis { + list-style-type: none; + margin: 0; + padding: 0; +} + +.example-chart-axis--x { + display: flex; + position: absolute; + top: calc(100% + 0.125em); + right: 0; + left: 0; +} + +.example-chart-axis--x li { + width: 16.6667%; + max-width: 16.6667%; + white-space: nowrap; + text-align: center; + transform: translateX(50%); +} + +.example-chart-axis--y { + position: absolute; + top: 0; + right: calc(100% + 0.25em); + bottom: 0; + margin-top: -2px; +} + +.example-chart-axis--y li { + display: flex; + width: 3.25em; + height: 20%; + white-space: nowrap; + justify-content: flex-end; + flex: 1 0 20%; + align-items: center; + transform: translateY(-50%); +} + +.example-chart-axis-label-x, +.example-chart-axis-label-y { + position: absolute; +} + +.example-chart-axis-label-x { + top: calc(100% + 1.5em); + left: 0; + right: 0; + text-align: center; +} + +.example-chart-axis-label-y { + left: auto; + right: calc(100% + 2.5em); + top: 0; + bottom: 0; + rotate: -180deg; + text-align: center; + writing-mode: vertical-lr; +} + .example-section { &-brand { background-color: var(--env-ui-color-brand); diff --git a/packages/envision-docs/src/scss/docs.scss b/packages/envision-docs/src/scss/docs.scss index a8dd760a2..9b6c207c8 100644 --- a/packages/envision-docs/src/scss/docs.scss +++ b/packages/envision-docs/src/scss/docs.scss @@ -121,6 +121,16 @@ body[class*=' sv-theme-'] { } } +.env-dashboard-theme { + .code-example { + border: 4px solid var(--env-dashboard-color-brown-05); + } + + pre[class*='language-'] { + background-color: var(--env-dashboard-color-brown-05); + } +} + //----- SITEVISION THEME DEMO SITE ADJUSTMENTS END ----- //----- STYLE FOR MARKDOWN GENERATED MARKUP ELEMENTS START ----- @@ -205,6 +215,7 @@ body[class*=' sv-theme-'] { .doc-p { font-family: $roboto; + line-height: 1.5; margin: 0 0 1em; } @@ -234,6 +245,39 @@ blockquote.doc-blockquote { --env-button-font-family: #{$roboto}; } +.doc-table { + border-collapse: collapse; + + caption { + font-size: var(--env-font-size-large); + font-weight: 700; + text-align: left; + margin: 0 0 var(--env-spacing-x-small); + padding: 0 calc(#{var(--env-font-size-base)} / 1.25 * 0.5); + } + + thead th { + vertical-align: bottom; + } + + th { + text-align: left; + } + + th, + td { + font-size: var(--env-font-size-medium); + font-weight: 400; + border-top: 1px solid var(--env-border-color); + padding: var(--env-spacing-x-small); + vertical-align: top; + } + + th { + font-weight: 600; + } +} + //----- STYLE FOR MARKDOWN GENERATED MARKUP ELEMENTS END ----- :not(pre) > code[class*='language-'] { @@ -433,9 +477,12 @@ img { } .theme-picker { - //border-top: 1px solid var(--env-border-color); margin: 0 1em; + .env-dashboard-theme & { + display: none; + } + .env-form-element { margin: 0; padding: 0; diff --git a/packages/envision-docs/src/templates/BaseTemplate.js b/packages/envision-docs/src/templates/BaseTemplate.js index 78caf1272..3eafbd1a1 100644 --- a/packages/envision-docs/src/templates/BaseTemplate.js +++ b/packages/envision-docs/src/templates/BaseTemplate.js @@ -12,6 +12,7 @@ const filterMenuItems = (items) => { deprecated: node.frontmatter.deprecated, since: node.frontmatter.since, beta: node.frontmatter.beta, + dashboard: node.frontmatter.dashboard, slug: node.fields.slug, })) .reduce((accumulated, item) => { @@ -31,15 +32,22 @@ const BaseTemplate = ({ deprecated, since, beta, + dashboard, topMenuItems, menuCategories, menuItems, children, }) => { + const theme = + typeof window !== 'undefined' + ? window.localStorage.getItem('env-theme') + : ''; + + const bodyClass = dashboard ? 'env-dashboard-theme' : theme; return ( <> -
    -
    +
    +

    {title}

    {(since || beta || deprecated) && ( @@ -78,6 +86,7 @@ BaseTemplate.propTypes = { deprecated: PropTypes.bool, since: PropTypes.string, beta: PropTypes.bool, + dashboard: PropTypes.bool, topMenuItems: PropTypes.array, menuCategories: PropTypes.array, menuItems: PropTypes.array, diff --git a/packages/envision-docs/src/templates/docs.js b/packages/envision-docs/src/templates/docs.js index 3fa186501..7e40a13ec 100644 --- a/packages/envision-docs/src/templates/docs.js +++ b/packages/envision-docs/src/templates/docs.js @@ -2,6 +2,7 @@ import React, { useRef } from 'react'; import PropTypes from 'prop-types'; import { graphql } from 'gatsby'; import { useCopyExample } from '../hooks/copyExample'; +import { useDashboardExample } from '../hooks/dashboardExample'; import { useExpandCode } from '../hooks/expandCode'; import BaseTemplate from './BaseTemplate'; @@ -13,6 +14,7 @@ export default function Template({ const content = useRef(null); useCopyExample(content); useExpandCode(content); + useDashboardExample(content); return (