diff --git a/packages/foundations/scss/colors/_variables.scss b/packages/foundations/scss/colors/_variables.scss index 1f6d60d402b..92f1d8b73ab 100644 --- a/packages/foundations/scss/colors/_variables.scss +++ b/packages/foundations/scss/colors/_variables.scss @@ -3,6 +3,11 @@ $variants: "neutral", "brand", "critical", "successful", "warning", $variant-colors: "neutral", "critical", "successful", "warning", "informational"; +$on-background-colors: "default", "weak", "contrast", "contrast-weak", "border"; + +$background-colors: "lvl-1", "lvl-2", "lvl-3", "transparent-full", + "transparent-semi"; + // current - for adaptive colors $db-current-icon-color: var(--db-current-icon-color, inherit); diff --git a/packages/foundations/scss/colors/classes/_get-class.scss b/packages/foundations/scss/colors/classes/_get-class.scss index 569affa6a96..e747183dcb2 100644 --- a/packages/foundations/scss/colors/classes/_get-class.scss +++ b/packages/foundations/scss/colors/classes/_get-class.scss @@ -32,3 +32,40 @@ } } } + +@mixin init-container-colors($variant) { + [data-container-color="#{$variant}"], + .db-container-color-#{$variant} { + @extend %db-#{$variant}-variables; + color: var(--db-current-color-on-bg-enabled); + background-color: var(--db-current-color-bg-lvl-1-enabled); + } +} + +@mixin init-on-background-colors($color) { + [data-on-bg-color="#{$color}"], + .db-on-bg-color-#{$color} { + @if $color == "default" { + color: var(--db-current-color-on-bg-enabled); + } @else if $color == "weak" { + color: var(--db-current-color-on-bg-weak-enabled); + } @else if $color == "contrast" { + color: var(--db-current-color-contrast-high-enabled); + } @else if $color == "contrast-weak" { + color: var(--db-current-color-contrast-low-enabled); + } @else if $color == "border" { + color: var(--db-current-color-border); + } @else { + @error "Unknown color #{$color}."; + } + } +} + +@mixin init-background-colors($background-color) { + [data-bg-color="#{$background-color}"], + .db-bg-color-#{$background-color} { + background-color: var( + --db-current-color-bg-#{$background-color}-enabled + ); + } +} diff --git a/packages/foundations/scss/colors/classes/all.scss b/packages/foundations/scss/colors/classes/all.scss index c0b48133828..b913d7a26e2 100644 --- a/packages/foundations/scss/colors/classes/all.scss +++ b/packages/foundations/scss/colors/classes/all.scss @@ -3,8 +3,18 @@ @each $variant in index.$variants { @include get-class.init($variant); + @include get-class.init-container-colors($variant); } -@each $variant in index.$additional-variants { - @include get-class.init($variant); +@each $additional-variant in index.$additional-variants { + @include get-class.init($additional-variant); + @include get-class.init-container-colors($additional-variant); +} + +@each $background-color in index.$background-colors { + @include get-class.init-background-colors($background-color); +} + +@each $on-background-color in index.$on-background-colors { + @include get-class.init-on-background-colors($on-background-color); } diff --git a/packages/foundations/scss/colors/classes/blue.scss b/packages/foundations/scss/colors/classes/blue.scss index 58006472034..3a0f950f6d7 100644 --- a/packages/foundations/scss/colors/classes/blue.scss +++ b/packages/foundations/scss/colors/classes/blue.scss @@ -4,3 +4,4 @@ $variant: "blue"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/brand.scss b/packages/foundations/scss/colors/classes/brand.scss index 6720bf24e04..aea2912554f 100644 --- a/packages/foundations/scss/colors/classes/brand.scss +++ b/packages/foundations/scss/colors/classes/brand.scss @@ -4,3 +4,4 @@ $variant: "brand"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/critical.scss b/packages/foundations/scss/colors/classes/critical.scss index df42b07ab88..c9314365bf3 100644 --- a/packages/foundations/scss/colors/classes/critical.scss +++ b/packages/foundations/scss/colors/classes/critical.scss @@ -4,3 +4,4 @@ $variant: "critical"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/cyan.scss b/packages/foundations/scss/colors/classes/cyan.scss index ec899c20ede..e2a248e6431 100644 --- a/packages/foundations/scss/colors/classes/cyan.scss +++ b/packages/foundations/scss/colors/classes/cyan.scss @@ -4,3 +4,4 @@ $variant: "cyan"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/green.scss b/packages/foundations/scss/colors/classes/green.scss index 945ad15238c..6925c042ace 100644 --- a/packages/foundations/scss/colors/classes/green.scss +++ b/packages/foundations/scss/colors/classes/green.scss @@ -4,3 +4,4 @@ $variant: "green"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/informational.scss b/packages/foundations/scss/colors/classes/informational.scss index d84586b4d95..48327921702 100644 --- a/packages/foundations/scss/colors/classes/informational.scss +++ b/packages/foundations/scss/colors/classes/informational.scss @@ -4,3 +4,4 @@ $variant: "informational"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/neutral.scss b/packages/foundations/scss/colors/classes/neutral.scss index 1c1f7966e6a..c0468093226 100644 --- a/packages/foundations/scss/colors/classes/neutral.scss +++ b/packages/foundations/scss/colors/classes/neutral.scss @@ -4,3 +4,4 @@ $variant: "neutral"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/orange.scss b/packages/foundations/scss/colors/classes/orange.scss index d1d7a01fc8a..90574af39f8 100644 --- a/packages/foundations/scss/colors/classes/orange.scss +++ b/packages/foundations/scss/colors/classes/orange.scss @@ -4,3 +4,4 @@ $variant: "orange"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/pink.scss b/packages/foundations/scss/colors/classes/pink.scss index 248cac046f5..49f1ae5e0bc 100644 --- a/packages/foundations/scss/colors/classes/pink.scss +++ b/packages/foundations/scss/colors/classes/pink.scss @@ -4,3 +4,4 @@ $variant: "pink"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/red.scss b/packages/foundations/scss/colors/classes/red.scss index 714bf7de277..cdd924a56d1 100644 --- a/packages/foundations/scss/colors/classes/red.scss +++ b/packages/foundations/scss/colors/classes/red.scss @@ -4,3 +4,4 @@ $variant: "red"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/successful.scss b/packages/foundations/scss/colors/classes/successful.scss index 5339ccb3ee4..5e2e7311d78 100644 --- a/packages/foundations/scss/colors/classes/successful.scss +++ b/packages/foundations/scss/colors/classes/successful.scss @@ -4,3 +4,4 @@ $variant: "successful"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/turquoise.scss b/packages/foundations/scss/colors/classes/turquoise.scss index 6a96e2e9c77..a4376dab792 100644 --- a/packages/foundations/scss/colors/classes/turquoise.scss +++ b/packages/foundations/scss/colors/classes/turquoise.scss @@ -4,3 +4,4 @@ $variant: "turquoise"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/violet.scss b/packages/foundations/scss/colors/classes/violet.scss index a98eebf8f3c..3e04f12950c 100644 --- a/packages/foundations/scss/colors/classes/violet.scss +++ b/packages/foundations/scss/colors/classes/violet.scss @@ -4,3 +4,4 @@ $variant: "violet"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/warning.scss b/packages/foundations/scss/colors/classes/warning.scss index 0237b8e5561..1cfe6e51a65 100644 --- a/packages/foundations/scss/colors/classes/warning.scss +++ b/packages/foundations/scss/colors/classes/warning.scss @@ -4,3 +4,4 @@ $variant: "warning"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/packages/foundations/scss/colors/classes/yellow.scss b/packages/foundations/scss/colors/classes/yellow.scss index f210532d61b..6471d78cbcd 100644 --- a/packages/foundations/scss/colors/classes/yellow.scss +++ b/packages/foundations/scss/colors/classes/yellow.scss @@ -4,3 +4,4 @@ $variant: "yellow"; @include get-class.init($variant); +@include get-class.init-container-colors($variant); diff --git a/showcases/patternhub/components/copy-clipboard-button/index.tsx b/showcases/patternhub/components/copy-clipboard-button/index.tsx new file mode 100644 index 00000000000..d0cc9a7d0e1 --- /dev/null +++ b/showcases/patternhub/components/copy-clipboard-button/index.tsx @@ -0,0 +1,59 @@ +import { type MouseEvent, type ReactNode, useEffect, useState } from 'react'; +import { DBButton, DBTooltip } from '../../../../output/react/src/index'; + +export type CopyClipboardButtonProps = { + name: string; + children?: ReactNode; + copyText: string; +}; + +const CopyClipboardButton = ({ + name, + children, + copyText +}: CopyClipboardButtonProps) => { + const [justCopied, setJustCopied] = useState(false); + + const onCopyButtonClick = async (event: MouseEvent) => { + event.stopPropagation(); + + if (typeof navigator !== 'undefined') { + setJustCopied(true); + await navigator.clipboard.writeText(copyText); + } + }; + + useEffect(() => { + let timeout: ReturnType | undefined; + + if (justCopied) { + timeout = setTimeout(() => { + setJustCopied(false); + }, 1500); + } + + return () => { + clearTimeout(timeout); + }; + }, [justCopied]); + + return ( + + + {children} + + + ); +}; + +export default CopyClipboardButton; diff --git a/showcases/patternhub/components/foundations/colors/colors-grid/index.tsx b/showcases/patternhub/components/foundations/colors/colors-grid/index.tsx new file mode 100644 index 00000000000..04179a57e24 --- /dev/null +++ b/showcases/patternhub/components/foundations/colors/colors-grid/index.tsx @@ -0,0 +1,63 @@ +import checkerboard from '../../../../public/assets/images/checkerboard.png'; +import CopyClipboardButton from '../../../copy-clipboard-button'; +import { type ColorValue } from '../data'; + +const ColorsGrid = ({ + values, + prefixClass, + dataAttributeName, + showCheckerboard, + enableDarkMode, + variant +}: { + values: ColorValue[]; + prefixClass: string; + dataAttributeName: string; + showCheckerboard: boolean; + enableDarkMode: boolean; + variant: 'class' | 'dataAttribute'; +}) => { + const getText = (value: string) => + variant === 'class' + ? `${prefixClass}${value}` + : `${dataAttributeName}="${value}"`; + + const getAttributes = (value: string) => + variant === 'class' + ? { className: `${prefixClass}${value}` } + : { [dataAttributeName]: value }; + + return ( +
+ {' '} + {values.map((value, index) => { + const v = typeof value === 'string' ? value : value.value; + const appendix = + typeof value === 'string' ? undefined : value.appendix; + return ( +
+ + {getText(v)} + {appendix} + + + Copied to clipboard + +
+ ); + })} +
+ ); +}; + +export default ColorsGrid; diff --git a/showcases/patternhub/components/foundations/colors/colors-overview-tabs/index.tsx b/showcases/patternhub/components/foundations/colors/colors-overview-tabs/index.tsx new file mode 100644 index 00000000000..a08b3cd474b --- /dev/null +++ b/showcases/patternhub/components/foundations/colors/colors-overview-tabs/index.tsx @@ -0,0 +1,72 @@ +import { useState } from 'react'; +import { + DBSwitch, + DBTabItem, + DBTabList, + DBTabPanel, + DBTabs +} from '../../../../../../output/react/src'; +import ColorsGrid from '../colors-grid'; +import { type ColorValue } from '../data'; + +const ColorsOverviewTabs = ({ + values, + prefixClass, + dataAttributeName +}: { + values: ColorValue[]; + prefixClass: string; + dataAttributeName: string; +}) => { + const [showCheckerboard, setShowCheckerboard] = useState(false); + const [enableDarkMode, setEnableDarkMode] = useState(false); + + return ( + <> +
+ { + setShowCheckerboard(event.target.checked); + }}> + Show checkerboard + + { + setEnableDarkMode(event.target.checked); + }}> + Preview dark mode + +
+ + + Classes + Data Attributes + + + + + + + + + + ); +}; + +export default ColorsOverviewTabs; diff --git a/showcases/patternhub/components/foundations/colors/data.ts b/showcases/patternhub/components/foundations/colors/data.ts new file mode 100644 index 00000000000..bf2b8b43958 --- /dev/null +++ b/showcases/patternhub/components/foundations/colors/data.ts @@ -0,0 +1,38 @@ +export const semanticColors = [ + 'neutral', + 'brand', + 'critical', + 'successful', + 'warning', + 'informational' +]; + +export const additionalColors = [ + 'yellow', + 'orange', + 'red', + 'pink', + 'violet', + 'blue', + 'cyan', + 'turquoise', + 'green' +]; + +export const backgroundColors = [ + 'lvl-1', + 'lvl-2', + 'lvl-3', + 'transparent-full', + 'transparent-semi' +]; + +export const onBackgroundColors = [ + { value: 'default' }, + { value: 'weak' }, + { value: 'contrast' }, + { value: 'contrast-weak', appendix: ' *' }, + { value: 'border', appendix: ' *' } +]; + +export type ColorValue = string | { value: string; appendix?: string }; diff --git a/showcases/patternhub/pages/foundations/colors/overview.tsx b/showcases/patternhub/pages/foundations/colors/overview.tsx index 862efe43a5c..6fe8a41c144 100644 --- a/showcases/patternhub/pages/foundations/colors/overview.tsx +++ b/showcases/patternhub/pages/foundations/colors/overview.tsx @@ -1,59 +1,132 @@ -import { useState } from 'react'; import DefaultPage from '../../../components/default-page'; -import { COLORS } from '../../../../../packages/components/src/shared/constants'; -import { DBInput } from '../../../../../output/react/src'; - -const additionalColors = [ - 'yellow', - 'orange', - 'red', - 'pink', - 'violet', - 'blue', - 'cyan', - 'turquoise', - 'green' -]; -const getAdditionalColors = () => { - const colors: string[] = []; - - for (const color of additionalColors) { - colors.push( - `${color}-bg-lvl-1`, - `${color}-bg-lvl-2`, - `${color}-bg-lvl-3`, - `${color}-bg-transparent-semi`, - `${color}-bg-transparent-full` - ); - } - - return colors; -}; +import { DBInfotext } from '../../../../../output/react/src'; +import ColorsOverviewTabs from '../../../components/foundations/colors/colors-overview-tabs'; +import { + additionalColors, + backgroundColors, + onBackgroundColors, + semanticColors +} from '../../../components/foundations/colors/data'; const ColorOverview = () => { - const additionalColors = getAdditionalColors(); - const [search, setSearch] = useState(''); - return ( -

Color Overview

- - { - setSearch(event.target.value); - }} +
+

Color classes

+

+ These classes (or data-attributes) can be + used to apply a{' '} + monochromatic adaptive color scheme or a{' '} + color modifier (background color, + on-background color) to containers and elements. +

+

+ + These classes are not intended for individual + styling of your own components. The corresponding CSS + Custom Properties should be used for this. + +

+ How to use: +
+
+ + Note: All three methods are optional: they can be used + individually or in any combination on an element. + +
    +
  1. + Should an entire container be given an{' '} + adaptive color scheme? Then use a{' '} + db-container-color-[ color ] class. +
  2. +
  3. + The background color, in particular the{' '} + elevation level, can be modified with a{' '} + db-bg-color-[ color ] class. +
  4. +
  5. + The contrast of the text and{' '} + icon color can be changed with the{' '} + on-background classes:{' '} + db-on-bg-color-[ color ] +
  6. +
+

1. Container color

+

+ These classes define the{' '} + monochromatic adaptive color scheme for a + container. Texts, icons and backgrounds in it then + automatically adapt to the color set. +

+

+ Each container color class functions as a shorthand and + applies the following by default: +

+
    +
  • + A bunch of CSS Custom Properties to apply the{' '} + monochromatic adaptive color scheme +
  • +
  • + Background color modifier{' '} + db-bg-color-lvl-1 (Level 1 background + by default) +
  • +
  • + On background color modifier{' '} + db-on-bg-color-default (highest text + contrast by default) +
  • +
+

Semantic container color

+

+ These semantic colors are used to give a container a + corresponding meaning. Neutral stands for + the regular color scheme, which is usually applied to root. +

+ +

Additional container color

+ +

2. Background color modifier

+

+ These classes define the type of background color for a + container. The exact color tone then results from the + current semantics (in root neutral by + default). This means that each of these background types + exists for each semantic color. +

+ +

3. On background color modifier

+

+ This class is used to define the contrast for{' '} + texts and icons. As with + the background colors, these are displayed according to the + current color scheme. +

+

+ + * These colors do not have sufficient contrast. They are + therefore not permitted as text colors. + +

+ - -

Overview

-
- {[...COLORS, ...additionalColors] - .filter((color) => color.includes(search)) - .map((color) => ( -
{color}
- ))}
); diff --git a/showcases/patternhub/public/assets/images/checkerboard.png b/showcases/patternhub/public/assets/images/checkerboard.png new file mode 100644 index 00000000000..a4bc71ddc0e Binary files /dev/null and b/showcases/patternhub/public/assets/images/checkerboard.png differ diff --git a/showcases/patternhub/styles/globals.scss b/showcases/patternhub/styles/globals.scss index cb83aa81b5c..000282679d2 100644 --- a/showcases/patternhub/styles/globals.scss +++ b/showcases/patternhub/styles/globals.scss @@ -169,18 +169,50 @@ div[class^="ch-"] { } // colors overview - .color-overview-container { @extend %grid-container; - padding: variables.$db-spacing-fixed-md; + position: relative; + padding: variables.$db-spacing-fixed-md 0; + + @include screen-sizes.screen() { + --columns: 2; + } + + @include screen-sizes.screen("md") { + --columns: 3; + } + + > span { + position: absolute; + block-size: 100%; + inline-size: 100%; + } + + &[data-color-scheme="dark"] > span { + filter: invert(1) brightness(1.2); + } > div { + position: relative; display: flex; justify-content: center; align-items: center; - border: 1px solid black; + border: 1px solid colors.$db-current-color-border; padding: variables.$db-spacing-fixed-md; } + + button { + position: absolute; + inset-inline-end: var(--db-spacing-fixed-md); + inset-block-start: 50%; + transform: translateY(-50%); + } +} + +.color-overview-switches { + display: flex; + gap: variables.$db-spacing-fixed-lg; + margin-block-end: variables.$db-spacing-fixed-md; } // density examples