CityOfDetroit / COD-Design-System

Design system for the City of Detroit.
https://cityofdetroit.github.io/COD-Design-System/
MIT License
1 stars 3 forks source link

Gracefully handle themes/color modes in design system #114

Closed maxatdetroit closed 7 months ago

maxatdetroit commented 1 year ago

Is your feature request related to a problem? Please describe.

When we want to nest our design system web components, the parent component colors (background, border, icons, etc.) do not take effect on child components. This forces the user of the design system to explicitly style the child component to match and contrast the parent component.

See CityOfDetroit/detroitmi#1167 as an example where a workaround is needed to make a button standout when nested within a card.

Describe the solution you'd like

Implement themes (i.e. color modes) for various styles of components. Themes / color modes override CSS variables (background, border, icons, etc.) to encapsulate colors that are consistent with one another. These variables bleed through the shadow DOM so they will also take effect on child components.

Work necessary to properly support themes / color modes in design system:

Describe alternatives you've considered

Alternatives considered:

  1. Allow the user of the design-system to explicitly set the borders in these scenarios. Cons: the user may forget, it takes more effort to use the components.
  2. Parent components communicate their background color to child components via Javascript, then child component styling is responsible for setting the sensible default colors (borders, background, text). Cons: implementation via Javascript is less desirable than implementation purely via stylesheets per Bootstrap approach.

Pseudocode example:

btnStyles = `
.btn.parent-bg-primary {
  --bs-btn-border-color: $light;
}
`;

class Button extends HTMLElement {
  constructor() {
    ...
    this.shadowDOM.appendChild(btnStyles);
  }

  connectedCallback() {...}

  setParentBackground(parentBackgroundClass) {
    this.btn.classList.add(parentBackgroundClass);
  }
}

class BoxWithButton extends HTMLElement {
  constructor() {...}

  connectedCallback() {
    const bgColor = this.getAttribute('data-bg');
    shadow.addEventListener('slotchange', () => {
      const tempElements = Array.from(this.children);
      tempElements.forEach((node) => {
        node.setParentBackground('parent-bg-' + bgColor);
        this.box.appendChild(node);
    }
  }

  setParentBackground(parentBackgroundClass) {
    this.btn.classList.add(parentBackgroundClass);
  }
}

Additional context Add any other context or screenshots about the feature request here.

maxatdetroit commented 7 months ago

This is replaced by #198