From a692c33c992424de7d0630899a1f885b2ba2eb4c Mon Sep 17 00:00:00 2001 From: Barrett Grubbs Date: Wed, 3 Jul 2024 10:23:34 -0400 Subject: [PATCH 1/2] Application Header dark mode --- .../cbp-app-header/cbp-app-header.scss | 125 ++++++++++++++++-- .../cbp-app-header/cbp-app-header.stories.tsx | 7 +- 2 files changed, 118 insertions(+), 14 deletions(-) diff --git a/packages/web-components/src/components/cbp-app-header/cbp-app-header.scss b/packages/web-components/src/components/cbp-app-header/cbp-app-header.scss index cd3b5aa9..717bc2c9 100644 --- a/packages/web-components/src/components/cbp-app-header/cbp-app-header.scss +++ b/packages/web-components/src/components/cbp-app-header/cbp-app-header.scss @@ -1,3 +1,100 @@ +/** + /*** Base variables *** + * @Prop --cbp-app-header-color-background: var(--cbp-color-white) + * @Prop --cbp-app-header-color-background-dark: var(--cbp-color-base-neutral-dark); + + /*** Child variables *** + * @Prop --cbp-app-header-child-color: var(--cbp-color-interactive-secondary-darker); + * @Prop --cbp-app-header-child-color-dark: var(--cbp-color-interactive-secondary-lighter); + * @Prop --cbp-app-header-child-color-background: transparent; + * @Prop --cbp-app-header-child-color-background-dark: transparent; + * @Prop --cbp-app-header-child-color-border: transparent; + * @Prop --cbp-app-header-child-color-border-dark: transparent; + * @Prop --cbp-app-header-child-color-outline: var(--cbp-color-white); + * @Prop --cbp-app-header-child-color-outline-dark: transparent; + + /*** Hover variables *** + * @Prop --cbp-app-header-child-color-text-hover: var(--cbp-color-interactive-secondary-darker); + * @Prop --cbp-app-header-child-color-text-hover-dark: var(--cbp-color-interactive-secondary-lighter); + * @Prop --cbp-app-header-child-color-background-hover: var(--cbp-color-interactive-secondary-lighter); + * @Prop --cbp-app-header-child-color-background-hover-dark: var(--cbp-color-interactive-secondary-darker); + * @Prop --cbp-app-header-child-color-border-hover: var(--cbp-color-interactive-secondary-darker); + * @Prop --cbp-app-header-child-color-border-hover-dark: var(--cbp-color-interactive-secondary-lighter); + + /*** Focus variables *** + * @Prop --cbp-app-header-child-color-text-focus: var(--cbp-color-text-lightest); + * @Prop --cbp-app-header-child-color-text-focus-dark: var(--cbp-color-text-darkest); + * @Prop --cbp-app-header-child-color-background-focus: var(--cbp-color-interactive-focus-dark); + * @Prop --cbp-app-header-child-color-background-focus-dark: var(--cbp-color-interactive-focus-light); + * @Prop --cbp-app-header-child-color-border-focus: var(--cbp-color-interactive-focus-dark); + * @Prop --cbp-app-header-child-color-border-focus-dark: transparent; + * @Prop --cbp-app-header-child-color-outline-focus: var(--cbp-color-white); + * @Prop --cbp-app-header-child-color-outline-focus-dark: var(--cbp-color-black); + + /*** Active variables *** + * @Prop --cbp-app-header-child-color-background-active: var(--cbp-color-interactive-active-dark); + * @Prop --cbp-app-header-child-color-background-active-dark: var(--cbp-color-interactive-focus-light); + * @Prop --cbp-app-header-child-color-border-active: var(--cbp-color-interactive-active-dark); + * @Prop --cbp-app-header-child-color-border-active-dark: var(--cbp-color-text-darkest); + * */ + +:root { + --cbp-app-header-color-background: var(--cbp-color-white); + --cbp-app-header-color-background-dark: var(--cbp-color-base-neutral-dark); + + --cbp-app-header-child-color: var(--cbp-color-interactive-secondary-darker); + --cbp-app-header-child-color-dark: var(--cbp-color-interactive-secondary-lighter); + --cbp-app-header-child-color-background: transparent; + --cbp-app-header-child-color-background-dark: transparent; + --cbp-app-header-child-color-border: transparent; + --cbp-app-header-child-color-border-dark: transparent; + --cbp-app-header-child-color-outline: var(--cbp-color-white); + --cbp-app-header-child-color-outline-dark: transparent; + + --cbp-app-header-child-color-text-hover: var(--cbp-color-interactive-secondary-darker); + --cbp-app-header-child-color-text-hover-dark: var(--cbp-color-interactive-secondary-lighter); + --cbp-app-header-child-color-background-hover: var(--cbp-color-interactive-secondary-lighter); + --cbp-app-header-child-color-background-hover-dark: var(--cbp-color-interactive-secondary-darker); + --cbp-app-header-child-color-border-hover: var(--cbp-color-interactive-secondary-darker); + --cbp-app-header-child-color-border-hover-dark: var(--cbp-color-interactive-secondary-lighter); + + --cbp-app-header-child-color-text-focus: var(--cbp-color-text-lightest); + --cbp-app-header-child-color-text-focus-dark: var(--cbp-color-text-darkest); + --cbp-app-header-child-color-background-focus: var(--cbp-color-interactive-focus-dark); + --cbp-app-header-child-color-background-focus-dark: var(--cbp-color-interactive-focus-light); + --cbp-app-header-child-color-border-focus: var(--cbp-color-interactive-focus-dark); + --cbp-app-header-child-color-border-focus-dark: transparent; + --cbp-app-header-child-color-outline-focus: var(--cbp-color-white); + --cbp-app-header-child-color-outline-focus-dark: var(--cbp-color-black); + + --cbp-app-header-child-color-background-active: var(--cbp-color-interactive-active-dark); + --cbp-app-header-child-color-background-active-dark: var(--cbp-color-interactive-focus-light); + --cbp-app-header-child-color-border-active: var(--cbp-color-interactive-active-dark); + --cbp-app-header-child-color-border-active-dark: var(--cbp-color-text-darkest); +} + +[data-cbp-theme=light] cbp-app-header[context*=dark]:not([context=light-always]), +[data-cbp-theme=dark] cbp-app-header:not([context=dark-inverts]):not([context=light-always]) { + --cbp-app-header-color-background: var(--cbp-app-header-color-background-dark); + + --cbp-app-header-child-color: var(--cbp-app-header-child-color-dark); + --cbp-app-header-child-color-background: var(--cbp-app-header-child-color-background-dark); + --cbp-app-header-child-color-border: var(--cbp-app-header-child-color-border-dark); + --cbp-app-header-child-color-outline: var(--cbp-app-header-child-color-outline-dark); + + --cbp-app-header-child-color-text-hover: var(--cbp-app-header-child-color-text-hover-dark); + --cbp-app-header-child-color-background-hover: var(--cbp-app-header-child-color-background-hover-dark); + --cbp-app-header-child-color-border-hover: var(--cbp-app-header-child-color-border-hover-dark); + + --cbp-app-header-child-color-text-focus: var(--cbp-app-header-child-color-text-focus-dark); + --cbp-app-header-child-color-background-focus: var(--cbp-app-header-child-color-background-focus-dark); + --cbp-app-header-child-color-border-focus: var(--cbp-app-header-child-color-border-focus-dark); + --cbp-app-header-child-color-outline-focus: var(--cbp-app-header-child-color-outline-focus-dark); + + --cbp-app-header-child-color-background-active: var(--cbp-app-header-child-color-background-active-dark); + --cbp-app-header-child-color-border-active: var(--cbp-app-header-child-color-border-active-dark); +} + cbp-app-header { display: flex; align-items: center; @@ -7,7 +104,7 @@ cbp-app-header { width: 100%; min-height: var(--cbp-space-14x); padding: 0 var(--cbp-responsive-spacing-outer); - background-color: var(--cbp-color-white); + background-color: var(--cbp-app-header-color-background); box-shadow: var(--cbp-shadow-level-3-down); z-index: var(--cbp-z-index-level-1); @@ -23,37 +120,39 @@ cbp-app-header { height: 100%; min-height: var(--cbp-space-14x); padding: 0 var(--cbp-space-3x); - color: var(--cbp-color-interactive-secondary-darker); - background-color: transparent; + color: var(--cbp-app-header-child-color); + background-color: var(--cbp-app-header-child-color-background); font-size: var(--cbp-font-size-heading-xs); font-weight: var(--cbp-font-weight-medium); text-decoration: none; white-space: nowrap; - border-color: transparent; + border-color: var(--cbp-app-header-child-color-border); border-style: solid; border-width: 0 0 var(--cbp-border-size-xl) 0; - outline-color: var(--cbp-color-white); + outline-color: var(--cbp-app-header-child-color-outline); outline-style: solid; outline-width: 0; outline-offset: calc(-1 * var(--cbp-space-1x)); cursor: pointer; &:hover { - color: var(--cbp-color-interactive-secondary-darker); - background-color: var(--cbp-color-interactive-secondary-lighter); - border-color: var(--cbp-color-interactive-secondary-darker); + color: var(--cbp-app-header-child-color-text-hover); + background-color: var(--cbp-app-header-child-color-background-hover); + border-color: var(--cbp-app-header-child-color-border-hover); } &:focus { - color: var(--cbp-color-text-lightest); - background-color: var(--cbp-color-interactive-focus-dark); - border-color: var(--cbp-color-interactive-focus-dark); + color: var(--cbp-app-header-child-color-text-focus); + background-color: var(--cbp-app-header-child-color-background-focus); + border-color: var(--cbp-app-header-child-color-border-focus); outline-width: var(--cbp-border-size-md); + outline-color: var(--cbp-app-header-child-color-outline-focus); + } &:active { - background-color: var(--cbp-color-interactive-active-dark); - border-color: var(--cbp-color-interactive-active-dark); + background-color: var(--cbp-app-header-child-color-background-active); + border: var(--cbp-app-header-child-color-border-active); } } diff --git a/packages/web-components/src/components/cbp-app-header/cbp-app-header.stories.tsx b/packages/web-components/src/components/cbp-app-header/cbp-app-header.stories.tsx index cba43cb3..35a40fa6 100644 --- a/packages/web-components/src/components/cbp-app-header/cbp-app-header.stories.tsx +++ b/packages/web-components/src/components/cbp-app-header/cbp-app-header.stories.tsx @@ -5,6 +5,10 @@ export default { layout: 'fullscreen', }, argTypes: { + context : { + control: 'select', + options: [ "light-inverts", "light-always", "dark-inverts", "dark-always"] + }, sx: { description: 'Supports adding inline styles as an object of key-value pairs comprised of CSS properties and values. Values should reference design tokens when possible.', control: 'object', @@ -12,9 +16,10 @@ export default { }, }; -const Template = ({ sx }) => { +const Template = ({ context, sx }) => { return ` Application Name From 581336a4ab00a2b04543868b779550a7dbc4a98c Mon Sep 17 00:00:00 2001 From: Barrett Grubbs Date: Wed, 3 Jul 2024 13:52:37 -0400 Subject: [PATCH 2/2] add context to the component file --- .../src/components/cbp-app-header/cbp-app-header.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/web-components/src/components/cbp-app-header/cbp-app-header.tsx b/packages/web-components/src/components/cbp-app-header/cbp-app-header.tsx index c65e39a2..7b56918e 100644 --- a/packages/web-components/src/components/cbp-app-header/cbp-app-header.tsx +++ b/packages/web-components/src/components/cbp-app-header/cbp-app-header.tsx @@ -1,4 +1,4 @@ -import { Component, Host, h } from '@stencil/core'; +import { Component, Host, h, Prop } from '@stencil/core'; @Component({ tag: 'cbp-app-header', @@ -6,6 +6,10 @@ import { Component, Host, h } from '@stencil/core'; }) export class CbpAppHeader { + + /** Specifies the context of the component as it applies to the visual design and whether it inverts when light/dark mode is toggled. Default behavior is "light-inverts" and does not have to be specified. */ + @Prop({ reflect: true }) context: "light-inverts" | "light-always" | "dark-inverts" | "dark-always"; + render() { return (