diff --git a/packages/components/docs/sass.md b/packages/components/docs/sass.md index 88111c2b1c06..4900b81535c9 100644 --- a/packages/components/docs/sass.md +++ b/packages/components/docs/sass.md @@ -3642,7 +3642,7 @@ Define theme variables from a map of tokens Source code ```scss -@mixin carbon--theme($theme: $carbon--theme) { +@mixin carbon--theme($theme: $carbon--theme, $emit-custom-properties: false) { $interactive-01: map-get($theme, 'interactive-01') !global; $interactive-02: map-get($theme, 'interactive-02') !global; $interactive-03: map-get($theme, 'interactive-03') !global; @@ -3702,6 +3702,67 @@ Define theme variables from a map of tokens $active-01: map-get($theme, 'active-01') !global; $hover-field: map-get($theme, 'hover-field') !global; + @if $emit-custom-properties == true { + --interactive-01: #{map-get($theme, 'interactive-01')}; + --interactive-02: #{map-get($theme, 'interactive-02')}; + --interactive-03: #{map-get($theme, 'interactive-03')}; + --interactive-04: #{map-get($theme, 'interactive-04')}; + --ui-background: #{map-get($theme, 'ui-background')}; + --ui-01: #{map-get($theme, 'ui-01')}; + --ui-02: #{map-get($theme, 'ui-02')}; + --ui-03: #{map-get($theme, 'ui-03')}; + --ui-04: #{map-get($theme, 'ui-04')}; + --ui-05: #{map-get($theme, 'ui-05')}; + --text-01: #{map-get($theme, 'text-01')}; + --text-02: #{map-get($theme, 'text-02')}; + --text-03: #{map-get($theme, 'text-03')}; + --text-04: #{map-get($theme, 'text-04')}; + --icon-01: #{map-get($theme, 'icon-01')}; + --icon-02: #{map-get($theme, 'icon-02')}; + --icon-03: #{map-get($theme, 'icon-03')}; + --link-01: #{map-get($theme, 'link-01')}; + --field-01: #{map-get($theme, 'field-01')}; + --field-02: #{map-get($theme, 'field-02')}; + --inverse-01: #{map-get($theme, 'inverse-01')}; + --inverse-02: #{map-get($theme, 'inverse-02')}; + --support-01: #{map-get($theme, 'support-01')}; + --support-02: #{map-get($theme, 'support-02')}; + --support-03: #{map-get($theme, 'support-03')}; + --support-04: #{map-get($theme, 'support-04')}; + --inverse-support-01: #{map-get($theme, 'inverse-support-01')}; + --inverse-support-02: #{map-get($theme, 'inverse-support-02')}; + --inverse-support-03: #{map-get($theme, 'inverse-support-03')}; + --inverse-support-04: #{map-get($theme, 'inverse-support-04')}; + --overlay-01: #{map-get($theme, 'overlay-01')}; + --focus: #{map-get($theme, 'focus')}; + --hover-primary: #{map-get($theme, 'hover-primary')}; + --active-primary: #{map-get($theme, 'active-primary')}; + --hover-primary-text: #{map-get($theme, 'hover-primary-text')}; + --hover-secondary: #{map-get($theme, 'hover-secondary')}; + --active-secondary: #{map-get($theme, 'active-secondary')}; + --hover-tertiary: #{map-get($theme, 'hover-tertiary')}; + --active-tertiary: #{map-get($theme, 'active-tertiary')}; + --hover-ui: #{map-get($theme, 'hover-ui')}; + --active-ui: #{map-get($theme, 'active-ui')}; + --selected-ui: #{map-get($theme, 'selected-ui')}; + --hover-selected-ui: #{map-get($theme, 'hover-selected-ui')}; + --hover-danger: #{map-get($theme, 'hover-danger')}; + --active-danger: #{map-get($theme, 'active-danger')}; + --hover-row: #{map-get($theme, 'hover-row')}; + --visited-link: #{map-get($theme, 'visited-link')}; + --disabled-01: #{map-get($theme, 'disabled-01')}; + --disabled-02: #{map-get($theme, 'disabled-02')}; + --disabled-03: #{map-get($theme, 'disabled-03')}; + --highlight: #{map-get($theme, 'highlight')}; + --skeleton-01: #{map-get($theme, 'skeleton-01')}; + --skeleton-02: #{map-get($theme, 'skeleton-02')}; + --brand-01: #{map-get($theme, 'brand-01')}; + --brand-02: #{map-get($theme, 'brand-02')}; + --brand-03: #{map-get($theme, 'brand-03')}; + --active-01: #{map-get($theme, 'active-01')}; + --hover-field: #{map-get($theme, 'hover-field')}; + } + @content; // Reset to default theme after apply in content @if $theme != $carbon--theme { @@ -3714,9 +3775,10 @@ Define theme variables from a map of tokens - **Parameters**: -| Name | Description | Type | Default value | -| -------- | ------------------- | ----- | ---------------- | -| `$theme` | Map of theme tokens | `Map` | `$carbon--theme` | +| Name | Description | Type | Default value | +| ------------------------- | --------------------------------------------- | ------ | ---------------- | +| `$theme` | Map of theme tokens | `Map` | `$carbon--theme` | +| `$emit-custom-properties` | Output CSS Custom Properties for theme tokens | `Bool` | `false` | **Example**: diff --git a/packages/components/src/globals/scss/vendor/@carbon/elements/scss/themes/_mixins.scss b/packages/components/src/globals/scss/vendor/@carbon/elements/scss/themes/_mixins.scss index 572640299360..2f38345a1f9c 100644 --- a/packages/components/src/globals/scss/vendor/@carbon/elements/scss/themes/_mixins.scss +++ b/packages/components/src/globals/scss/vendor/@carbon/elements/scss/themes/_mixins.scss @@ -9,6 +9,7 @@ /// Define theme variables from a map of tokens /// @access public /// @param {Map} $theme [$carbon--theme] - Map of theme tokens +/// @param {Bool} $emit-custom-properties [false] - Output CSS Custom Properties for theme tokens /// @content Pass in your custom declaration blocks to be used after the token maps set theming variables. /// /// @example scss @@ -28,7 +29,7 @@ /// } /// /// @group @carbon/themes -@mixin carbon--theme($theme: $carbon--theme) { +@mixin carbon--theme($theme: $carbon--theme, $emit-custom-properties: false) { $interactive-01: map-get($theme, 'interactive-01') !global; $interactive-02: map-get($theme, 'interactive-02') !global; $interactive-03: map-get($theme, 'interactive-03') !global; @@ -88,6 +89,67 @@ $active-01: map-get($theme, 'active-01') !global; $hover-field: map-get($theme, 'hover-field') !global; + @if $emit-custom-properties == true { + --interactive-01: #{map-get($theme, 'interactive-01')}; + --interactive-02: #{map-get($theme, 'interactive-02')}; + --interactive-03: #{map-get($theme, 'interactive-03')}; + --interactive-04: #{map-get($theme, 'interactive-04')}; + --ui-background: #{map-get($theme, 'ui-background')}; + --ui-01: #{map-get($theme, 'ui-01')}; + --ui-02: #{map-get($theme, 'ui-02')}; + --ui-03: #{map-get($theme, 'ui-03')}; + --ui-04: #{map-get($theme, 'ui-04')}; + --ui-05: #{map-get($theme, 'ui-05')}; + --text-01: #{map-get($theme, 'text-01')}; + --text-02: #{map-get($theme, 'text-02')}; + --text-03: #{map-get($theme, 'text-03')}; + --text-04: #{map-get($theme, 'text-04')}; + --icon-01: #{map-get($theme, 'icon-01')}; + --icon-02: #{map-get($theme, 'icon-02')}; + --icon-03: #{map-get($theme, 'icon-03')}; + --link-01: #{map-get($theme, 'link-01')}; + --field-01: #{map-get($theme, 'field-01')}; + --field-02: #{map-get($theme, 'field-02')}; + --inverse-01: #{map-get($theme, 'inverse-01')}; + --inverse-02: #{map-get($theme, 'inverse-02')}; + --support-01: #{map-get($theme, 'support-01')}; + --support-02: #{map-get($theme, 'support-02')}; + --support-03: #{map-get($theme, 'support-03')}; + --support-04: #{map-get($theme, 'support-04')}; + --inverse-support-01: #{map-get($theme, 'inverse-support-01')}; + --inverse-support-02: #{map-get($theme, 'inverse-support-02')}; + --inverse-support-03: #{map-get($theme, 'inverse-support-03')}; + --inverse-support-04: #{map-get($theme, 'inverse-support-04')}; + --overlay-01: #{map-get($theme, 'overlay-01')}; + --focus: #{map-get($theme, 'focus')}; + --hover-primary: #{map-get($theme, 'hover-primary')}; + --active-primary: #{map-get($theme, 'active-primary')}; + --hover-primary-text: #{map-get($theme, 'hover-primary-text')}; + --hover-secondary: #{map-get($theme, 'hover-secondary')}; + --active-secondary: #{map-get($theme, 'active-secondary')}; + --hover-tertiary: #{map-get($theme, 'hover-tertiary')}; + --active-tertiary: #{map-get($theme, 'active-tertiary')}; + --hover-ui: #{map-get($theme, 'hover-ui')}; + --active-ui: #{map-get($theme, 'active-ui')}; + --selected-ui: #{map-get($theme, 'selected-ui')}; + --hover-selected-ui: #{map-get($theme, 'hover-selected-ui')}; + --hover-danger: #{map-get($theme, 'hover-danger')}; + --active-danger: #{map-get($theme, 'active-danger')}; + --hover-row: #{map-get($theme, 'hover-row')}; + --visited-link: #{map-get($theme, 'visited-link')}; + --disabled-01: #{map-get($theme, 'disabled-01')}; + --disabled-02: #{map-get($theme, 'disabled-02')}; + --disabled-03: #{map-get($theme, 'disabled-03')}; + --highlight: #{map-get($theme, 'highlight')}; + --skeleton-01: #{map-get($theme, 'skeleton-01')}; + --skeleton-02: #{map-get($theme, 'skeleton-02')}; + --brand-01: #{map-get($theme, 'brand-01')}; + --brand-02: #{map-get($theme, 'brand-02')}; + --brand-03: #{map-get($theme, 'brand-03')}; + --active-01: #{map-get($theme, 'active-01')}; + --hover-field: #{map-get($theme, 'hover-field')}; + } + @content; // Reset to default theme after apply in content @if $theme != $carbon--theme { diff --git a/packages/components/src/globals/scss/vendor/@carbon/themes/scss/_mixins.scss b/packages/components/src/globals/scss/vendor/@carbon/themes/scss/_mixins.scss index 572640299360..2f38345a1f9c 100644 --- a/packages/components/src/globals/scss/vendor/@carbon/themes/scss/_mixins.scss +++ b/packages/components/src/globals/scss/vendor/@carbon/themes/scss/_mixins.scss @@ -9,6 +9,7 @@ /// Define theme variables from a map of tokens /// @access public /// @param {Map} $theme [$carbon--theme] - Map of theme tokens +/// @param {Bool} $emit-custom-properties [false] - Output CSS Custom Properties for theme tokens /// @content Pass in your custom declaration blocks to be used after the token maps set theming variables. /// /// @example scss @@ -28,7 +29,7 @@ /// } /// /// @group @carbon/themes -@mixin carbon--theme($theme: $carbon--theme) { +@mixin carbon--theme($theme: $carbon--theme, $emit-custom-properties: false) { $interactive-01: map-get($theme, 'interactive-01') !global; $interactive-02: map-get($theme, 'interactive-02') !global; $interactive-03: map-get($theme, 'interactive-03') !global; @@ -88,6 +89,67 @@ $active-01: map-get($theme, 'active-01') !global; $hover-field: map-get($theme, 'hover-field') !global; + @if $emit-custom-properties == true { + --interactive-01: #{map-get($theme, 'interactive-01')}; + --interactive-02: #{map-get($theme, 'interactive-02')}; + --interactive-03: #{map-get($theme, 'interactive-03')}; + --interactive-04: #{map-get($theme, 'interactive-04')}; + --ui-background: #{map-get($theme, 'ui-background')}; + --ui-01: #{map-get($theme, 'ui-01')}; + --ui-02: #{map-get($theme, 'ui-02')}; + --ui-03: #{map-get($theme, 'ui-03')}; + --ui-04: #{map-get($theme, 'ui-04')}; + --ui-05: #{map-get($theme, 'ui-05')}; + --text-01: #{map-get($theme, 'text-01')}; + --text-02: #{map-get($theme, 'text-02')}; + --text-03: #{map-get($theme, 'text-03')}; + --text-04: #{map-get($theme, 'text-04')}; + --icon-01: #{map-get($theme, 'icon-01')}; + --icon-02: #{map-get($theme, 'icon-02')}; + --icon-03: #{map-get($theme, 'icon-03')}; + --link-01: #{map-get($theme, 'link-01')}; + --field-01: #{map-get($theme, 'field-01')}; + --field-02: #{map-get($theme, 'field-02')}; + --inverse-01: #{map-get($theme, 'inverse-01')}; + --inverse-02: #{map-get($theme, 'inverse-02')}; + --support-01: #{map-get($theme, 'support-01')}; + --support-02: #{map-get($theme, 'support-02')}; + --support-03: #{map-get($theme, 'support-03')}; + --support-04: #{map-get($theme, 'support-04')}; + --inverse-support-01: #{map-get($theme, 'inverse-support-01')}; + --inverse-support-02: #{map-get($theme, 'inverse-support-02')}; + --inverse-support-03: #{map-get($theme, 'inverse-support-03')}; + --inverse-support-04: #{map-get($theme, 'inverse-support-04')}; + --overlay-01: #{map-get($theme, 'overlay-01')}; + --focus: #{map-get($theme, 'focus')}; + --hover-primary: #{map-get($theme, 'hover-primary')}; + --active-primary: #{map-get($theme, 'active-primary')}; + --hover-primary-text: #{map-get($theme, 'hover-primary-text')}; + --hover-secondary: #{map-get($theme, 'hover-secondary')}; + --active-secondary: #{map-get($theme, 'active-secondary')}; + --hover-tertiary: #{map-get($theme, 'hover-tertiary')}; + --active-tertiary: #{map-get($theme, 'active-tertiary')}; + --hover-ui: #{map-get($theme, 'hover-ui')}; + --active-ui: #{map-get($theme, 'active-ui')}; + --selected-ui: #{map-get($theme, 'selected-ui')}; + --hover-selected-ui: #{map-get($theme, 'hover-selected-ui')}; + --hover-danger: #{map-get($theme, 'hover-danger')}; + --active-danger: #{map-get($theme, 'active-danger')}; + --hover-row: #{map-get($theme, 'hover-row')}; + --visited-link: #{map-get($theme, 'visited-link')}; + --disabled-01: #{map-get($theme, 'disabled-01')}; + --disabled-02: #{map-get($theme, 'disabled-02')}; + --disabled-03: #{map-get($theme, 'disabled-03')}; + --highlight: #{map-get($theme, 'highlight')}; + --skeleton-01: #{map-get($theme, 'skeleton-01')}; + --skeleton-02: #{map-get($theme, 'skeleton-02')}; + --brand-01: #{map-get($theme, 'brand-01')}; + --brand-02: #{map-get($theme, 'brand-02')}; + --brand-03: #{map-get($theme, 'brand-03')}; + --active-01: #{map-get($theme, 'active-01')}; + --hover-field: #{map-get($theme, 'hover-field')}; + } + @content; // Reset to default theme after apply in content @if $theme != $carbon--theme { diff --git a/packages/elements/docs/sass.md b/packages/elements/docs/sass.md index 77de23fb2a8d..6638848c9f53 100644 --- a/packages/elements/docs/sass.md +++ b/packages/elements/docs/sass.md @@ -3291,7 +3291,7 @@ Define theme variables from a map of tokens Source code ```scss -@mixin carbon--theme($theme: $carbon--theme) { +@mixin carbon--theme($theme: $carbon--theme, $emit-custom-properties: false) { $interactive-01: map-get($theme, 'interactive-01') !global; $interactive-02: map-get($theme, 'interactive-02') !global; $interactive-03: map-get($theme, 'interactive-03') !global; @@ -3351,6 +3351,67 @@ Define theme variables from a map of tokens $active-01: map-get($theme, 'active-01') !global; $hover-field: map-get($theme, 'hover-field') !global; + @if $emit-custom-properties == true { + --interactive-01: #{map-get($theme, 'interactive-01')}; + --interactive-02: #{map-get($theme, 'interactive-02')}; + --interactive-03: #{map-get($theme, 'interactive-03')}; + --interactive-04: #{map-get($theme, 'interactive-04')}; + --ui-background: #{map-get($theme, 'ui-background')}; + --ui-01: #{map-get($theme, 'ui-01')}; + --ui-02: #{map-get($theme, 'ui-02')}; + --ui-03: #{map-get($theme, 'ui-03')}; + --ui-04: #{map-get($theme, 'ui-04')}; + --ui-05: #{map-get($theme, 'ui-05')}; + --text-01: #{map-get($theme, 'text-01')}; + --text-02: #{map-get($theme, 'text-02')}; + --text-03: #{map-get($theme, 'text-03')}; + --text-04: #{map-get($theme, 'text-04')}; + --icon-01: #{map-get($theme, 'icon-01')}; + --icon-02: #{map-get($theme, 'icon-02')}; + --icon-03: #{map-get($theme, 'icon-03')}; + --link-01: #{map-get($theme, 'link-01')}; + --field-01: #{map-get($theme, 'field-01')}; + --field-02: #{map-get($theme, 'field-02')}; + --inverse-01: #{map-get($theme, 'inverse-01')}; + --inverse-02: #{map-get($theme, 'inverse-02')}; + --support-01: #{map-get($theme, 'support-01')}; + --support-02: #{map-get($theme, 'support-02')}; + --support-03: #{map-get($theme, 'support-03')}; + --support-04: #{map-get($theme, 'support-04')}; + --inverse-support-01: #{map-get($theme, 'inverse-support-01')}; + --inverse-support-02: #{map-get($theme, 'inverse-support-02')}; + --inverse-support-03: #{map-get($theme, 'inverse-support-03')}; + --inverse-support-04: #{map-get($theme, 'inverse-support-04')}; + --overlay-01: #{map-get($theme, 'overlay-01')}; + --focus: #{map-get($theme, 'focus')}; + --hover-primary: #{map-get($theme, 'hover-primary')}; + --active-primary: #{map-get($theme, 'active-primary')}; + --hover-primary-text: #{map-get($theme, 'hover-primary-text')}; + --hover-secondary: #{map-get($theme, 'hover-secondary')}; + --active-secondary: #{map-get($theme, 'active-secondary')}; + --hover-tertiary: #{map-get($theme, 'hover-tertiary')}; + --active-tertiary: #{map-get($theme, 'active-tertiary')}; + --hover-ui: #{map-get($theme, 'hover-ui')}; + --active-ui: #{map-get($theme, 'active-ui')}; + --selected-ui: #{map-get($theme, 'selected-ui')}; + --hover-selected-ui: #{map-get($theme, 'hover-selected-ui')}; + --hover-danger: #{map-get($theme, 'hover-danger')}; + --active-danger: #{map-get($theme, 'active-danger')}; + --hover-row: #{map-get($theme, 'hover-row')}; + --visited-link: #{map-get($theme, 'visited-link')}; + --disabled-01: #{map-get($theme, 'disabled-01')}; + --disabled-02: #{map-get($theme, 'disabled-02')}; + --disabled-03: #{map-get($theme, 'disabled-03')}; + --highlight: #{map-get($theme, 'highlight')}; + --skeleton-01: #{map-get($theme, 'skeleton-01')}; + --skeleton-02: #{map-get($theme, 'skeleton-02')}; + --brand-01: #{map-get($theme, 'brand-01')}; + --brand-02: #{map-get($theme, 'brand-02')}; + --brand-03: #{map-get($theme, 'brand-03')}; + --active-01: #{map-get($theme, 'active-01')}; + --hover-field: #{map-get($theme, 'hover-field')}; + } + @content; // Reset to default theme after apply in content @if $theme != $carbon--theme { @@ -3363,9 +3424,10 @@ Define theme variables from a map of tokens - **Parameters**: -| Name | Description | Type | Default value | -| -------- | ------------------- | ----- | ---------------- | -| `$theme` | Map of theme tokens | `Map` | `$carbon--theme` | +| Name | Description | Type | Default value | +| ------------------------- | --------------------------------------------- | ------ | ---------------- | +| `$theme` | Map of theme tokens | `Map` | `$carbon--theme` | +| `$emit-custom-properties` | Output CSS Custom Properties for theme tokens | `Bool` | `false` | **Example**: diff --git a/packages/scss-generator/src/types/definitions.js b/packages/scss-generator/src/types/definitions.js index 2f7f19bf5782..43decfd23d29 100644 --- a/packages/scss-generator/src/types/definitions.js +++ b/packages/scss-generator/src/types/definitions.js @@ -372,14 +372,19 @@ const Declaration = defineType('Declaration', { validate: assertValueType('string'), }, value: { - validate: assertValueType('string'), + validate: () => + assertOneOf([assertValueType('string'), assertType(CallExpression)]), }, }, generate(printer, node) { printer.token(node.property); printer.token(':'); printer.space(); - printer.token(node.value); + if (typeof node.value === 'string') { + printer.token(node.value); + } else { + printer.print(node.value); + } printer.token(';'); }, }); diff --git a/packages/themes/docs/sass.md b/packages/themes/docs/sass.md index 9038285fcb34..d8e90349d326 100644 --- a/packages/themes/docs/sass.md +++ b/packages/themes/docs/sass.md @@ -86,7 +86,7 @@ Define theme variables from a map of tokens Source code ```scss -@mixin carbon--theme($theme: $carbon--theme) { +@mixin carbon--theme($theme: $carbon--theme, $emit-custom-properties: false) { $interactive-01: map-get($theme, 'interactive-01') !global; $interactive-02: map-get($theme, 'interactive-02') !global; $interactive-03: map-get($theme, 'interactive-03') !global; @@ -146,6 +146,67 @@ Define theme variables from a map of tokens $active-01: map-get($theme, 'active-01') !global; $hover-field: map-get($theme, 'hover-field') !global; + @if $emit-custom-properties == true { + --interactive-01: #{map-get($theme, 'interactive-01')}; + --interactive-02: #{map-get($theme, 'interactive-02')}; + --interactive-03: #{map-get($theme, 'interactive-03')}; + --interactive-04: #{map-get($theme, 'interactive-04')}; + --ui-background: #{map-get($theme, 'ui-background')}; + --ui-01: #{map-get($theme, 'ui-01')}; + --ui-02: #{map-get($theme, 'ui-02')}; + --ui-03: #{map-get($theme, 'ui-03')}; + --ui-04: #{map-get($theme, 'ui-04')}; + --ui-05: #{map-get($theme, 'ui-05')}; + --text-01: #{map-get($theme, 'text-01')}; + --text-02: #{map-get($theme, 'text-02')}; + --text-03: #{map-get($theme, 'text-03')}; + --text-04: #{map-get($theme, 'text-04')}; + --icon-01: #{map-get($theme, 'icon-01')}; + --icon-02: #{map-get($theme, 'icon-02')}; + --icon-03: #{map-get($theme, 'icon-03')}; + --link-01: #{map-get($theme, 'link-01')}; + --field-01: #{map-get($theme, 'field-01')}; + --field-02: #{map-get($theme, 'field-02')}; + --inverse-01: #{map-get($theme, 'inverse-01')}; + --inverse-02: #{map-get($theme, 'inverse-02')}; + --support-01: #{map-get($theme, 'support-01')}; + --support-02: #{map-get($theme, 'support-02')}; + --support-03: #{map-get($theme, 'support-03')}; + --support-04: #{map-get($theme, 'support-04')}; + --inverse-support-01: #{map-get($theme, 'inverse-support-01')}; + --inverse-support-02: #{map-get($theme, 'inverse-support-02')}; + --inverse-support-03: #{map-get($theme, 'inverse-support-03')}; + --inverse-support-04: #{map-get($theme, 'inverse-support-04')}; + --overlay-01: #{map-get($theme, 'overlay-01')}; + --focus: #{map-get($theme, 'focus')}; + --hover-primary: #{map-get($theme, 'hover-primary')}; + --active-primary: #{map-get($theme, 'active-primary')}; + --hover-primary-text: #{map-get($theme, 'hover-primary-text')}; + --hover-secondary: #{map-get($theme, 'hover-secondary')}; + --active-secondary: #{map-get($theme, 'active-secondary')}; + --hover-tertiary: #{map-get($theme, 'hover-tertiary')}; + --active-tertiary: #{map-get($theme, 'active-tertiary')}; + --hover-ui: #{map-get($theme, 'hover-ui')}; + --active-ui: #{map-get($theme, 'active-ui')}; + --selected-ui: #{map-get($theme, 'selected-ui')}; + --hover-selected-ui: #{map-get($theme, 'hover-selected-ui')}; + --hover-danger: #{map-get($theme, 'hover-danger')}; + --active-danger: #{map-get($theme, 'active-danger')}; + --hover-row: #{map-get($theme, 'hover-row')}; + --visited-link: #{map-get($theme, 'visited-link')}; + --disabled-01: #{map-get($theme, 'disabled-01')}; + --disabled-02: #{map-get($theme, 'disabled-02')}; + --disabled-03: #{map-get($theme, 'disabled-03')}; + --highlight: #{map-get($theme, 'highlight')}; + --skeleton-01: #{map-get($theme, 'skeleton-01')}; + --skeleton-02: #{map-get($theme, 'skeleton-02')}; + --brand-01: #{map-get($theme, 'brand-01')}; + --brand-02: #{map-get($theme, 'brand-02')}; + --brand-03: #{map-get($theme, 'brand-03')}; + --active-01: #{map-get($theme, 'active-01')}; + --hover-field: #{map-get($theme, 'hover-field')}; + } + @content; // Reset to default theme after apply in content @if $theme != $carbon--theme { @@ -158,9 +219,10 @@ Define theme variables from a map of tokens - **Parameters**: -| Name | Description | Type | Default value | -| -------- | ------------------- | ----- | ---------------- | -| `$theme` | Map of theme tokens | `Map` | `$carbon--theme` | +| Name | Description | Type | Default value | +| ------------------------- | --------------------------------------------- | ------ | ---------------- | +| `$theme` | Map of theme tokens | `Map` | `$carbon--theme` | +| `$emit-custom-properties` | Output CSS Custom Properties for theme tokens | `Bool` | `false` | **Example**: diff --git a/packages/themes/examples/preview/index.js b/packages/themes/examples/preview/index.js index b614c64f019b..cfd01beaf4db 100644 --- a/packages/themes/examples/preview/index.js +++ b/packages/themes/examples/preview/index.js @@ -5,7 +5,8 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import cx from 'classnames'; +import React, { useState } from 'react'; import ReactDOM from 'react-dom'; import * as colors from '@carbon/colors'; import { themes, formatTokenName } from '@carbon/themes'; @@ -44,6 +45,9 @@ function App() {
  • Theming
  • +
  • + Custom Properties +
  • @@ -229,8 +233,54 @@ $custom-theme: map-merge( +
    + +
    ); } +function ThemeSwitcher() { + const [theme, setTheme] = useState('white'); + const className = cx({ + 'theme--white': theme === 'white', + 'theme--g10': theme === 'g10', + 'theme--g90': theme === 'g90', + 'theme--g100': theme === 'g100', + }); + + return ( +
    +
    +
    +

    Custom Properties

    +
    +
    +
    +
    +

    Current theme: {theme}

    +
    +

    Change theme

    + + + + +
    +
    +

    Tokens

    + {['field-01', 'field-02', 'inverse-01', 'inverse-02'].map(token => ( +
    + {token} +
    + ))} +
    +
    +
    +
    + ); +} + + render(); diff --git a/packages/themes/examples/preview/package.json b/packages/themes/examples/preview/package.json index af14f6a220e1..0ebe49a38190 100644 --- a/packages/themes/examples/preview/package.json +++ b/packages/themes/examples/preview/package.json @@ -8,6 +8,7 @@ "develop": "parcel index.html --no-cache" }, "dependencies": { + "classnames": "^2.2.6", "parcel-bundler": "^1.12.2", "react": "^16.8.4", "react-dom": "^16.8.4" diff --git a/packages/themes/examples/preview/styles.scss b/packages/themes/examples/preview/styles.scss index dda5759b8c71..12302cb295a6 100644 --- a/packages/themes/examples/preview/styles.scss +++ b/packages/themes/examples/preview/styles.scss @@ -107,3 +107,16 @@ $custom-theme: map-merge( @include my-custom-token-component(); } } + +.theme--white { + @include carbon--theme($carbon--theme--white, true); +} +.theme--g10 { + @include carbon--theme($carbon--theme--g10, true); +} +.theme--g90 { + @include carbon--theme($carbon--theme--g90, true); +} +.theme--g100 { + @include carbon--theme($carbon--theme--g100, true); +} diff --git a/packages/themes/examples/preview/yarn.lock b/packages/themes/examples/preview/yarn.lock index b3d79cf36e19..c50c5118188a 100644 --- a/packages/themes/examples/preview/yarn.lock +++ b/packages/themes/examples/preview/yarn.lock @@ -1236,6 +1236,11 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +classnames@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== + cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" diff --git a/packages/themes/scss/_mixins.scss b/packages/themes/scss/_mixins.scss index 572640299360..2f38345a1f9c 100644 --- a/packages/themes/scss/_mixins.scss +++ b/packages/themes/scss/_mixins.scss @@ -9,6 +9,7 @@ /// Define theme variables from a map of tokens /// @access public /// @param {Map} $theme [$carbon--theme] - Map of theme tokens +/// @param {Bool} $emit-custom-properties [false] - Output CSS Custom Properties for theme tokens /// @content Pass in your custom declaration blocks to be used after the token maps set theming variables. /// /// @example scss @@ -28,7 +29,7 @@ /// } /// /// @group @carbon/themes -@mixin carbon--theme($theme: $carbon--theme) { +@mixin carbon--theme($theme: $carbon--theme, $emit-custom-properties: false) { $interactive-01: map-get($theme, 'interactive-01') !global; $interactive-02: map-get($theme, 'interactive-02') !global; $interactive-03: map-get($theme, 'interactive-03') !global; @@ -88,6 +89,67 @@ $active-01: map-get($theme, 'active-01') !global; $hover-field: map-get($theme, 'hover-field') !global; + @if $emit-custom-properties == true { + --interactive-01: #{map-get($theme, 'interactive-01')}; + --interactive-02: #{map-get($theme, 'interactive-02')}; + --interactive-03: #{map-get($theme, 'interactive-03')}; + --interactive-04: #{map-get($theme, 'interactive-04')}; + --ui-background: #{map-get($theme, 'ui-background')}; + --ui-01: #{map-get($theme, 'ui-01')}; + --ui-02: #{map-get($theme, 'ui-02')}; + --ui-03: #{map-get($theme, 'ui-03')}; + --ui-04: #{map-get($theme, 'ui-04')}; + --ui-05: #{map-get($theme, 'ui-05')}; + --text-01: #{map-get($theme, 'text-01')}; + --text-02: #{map-get($theme, 'text-02')}; + --text-03: #{map-get($theme, 'text-03')}; + --text-04: #{map-get($theme, 'text-04')}; + --icon-01: #{map-get($theme, 'icon-01')}; + --icon-02: #{map-get($theme, 'icon-02')}; + --icon-03: #{map-get($theme, 'icon-03')}; + --link-01: #{map-get($theme, 'link-01')}; + --field-01: #{map-get($theme, 'field-01')}; + --field-02: #{map-get($theme, 'field-02')}; + --inverse-01: #{map-get($theme, 'inverse-01')}; + --inverse-02: #{map-get($theme, 'inverse-02')}; + --support-01: #{map-get($theme, 'support-01')}; + --support-02: #{map-get($theme, 'support-02')}; + --support-03: #{map-get($theme, 'support-03')}; + --support-04: #{map-get($theme, 'support-04')}; + --inverse-support-01: #{map-get($theme, 'inverse-support-01')}; + --inverse-support-02: #{map-get($theme, 'inverse-support-02')}; + --inverse-support-03: #{map-get($theme, 'inverse-support-03')}; + --inverse-support-04: #{map-get($theme, 'inverse-support-04')}; + --overlay-01: #{map-get($theme, 'overlay-01')}; + --focus: #{map-get($theme, 'focus')}; + --hover-primary: #{map-get($theme, 'hover-primary')}; + --active-primary: #{map-get($theme, 'active-primary')}; + --hover-primary-text: #{map-get($theme, 'hover-primary-text')}; + --hover-secondary: #{map-get($theme, 'hover-secondary')}; + --active-secondary: #{map-get($theme, 'active-secondary')}; + --hover-tertiary: #{map-get($theme, 'hover-tertiary')}; + --active-tertiary: #{map-get($theme, 'active-tertiary')}; + --hover-ui: #{map-get($theme, 'hover-ui')}; + --active-ui: #{map-get($theme, 'active-ui')}; + --selected-ui: #{map-get($theme, 'selected-ui')}; + --hover-selected-ui: #{map-get($theme, 'hover-selected-ui')}; + --hover-danger: #{map-get($theme, 'hover-danger')}; + --active-danger: #{map-get($theme, 'active-danger')}; + --hover-row: #{map-get($theme, 'hover-row')}; + --visited-link: #{map-get($theme, 'visited-link')}; + --disabled-01: #{map-get($theme, 'disabled-01')}; + --disabled-02: #{map-get($theme, 'disabled-02')}; + --disabled-03: #{map-get($theme, 'disabled-03')}; + --highlight: #{map-get($theme, 'highlight')}; + --skeleton-01: #{map-get($theme, 'skeleton-01')}; + --skeleton-02: #{map-get($theme, 'skeleton-02')}; + --brand-01: #{map-get($theme, 'brand-01')}; + --brand-02: #{map-get($theme, 'brand-02')}; + --brand-03: #{map-get($theme, 'brand-03')}; + --active-01: #{map-get($theme, 'active-01')}; + --hover-field: #{map-get($theme, 'hover-field')}; + } + @content; // Reset to default theme after apply in content @if $theme != $carbon--theme { diff --git a/packages/themes/tasks/build.js b/packages/themes/tasks/build.js index 4937f9be2738..fbba066fcfa1 100644 --- a/packages/themes/tasks/build.js +++ b/packages/themes/tasks/build.js @@ -74,6 +74,7 @@ async function build() { t.Comment(`/ Define theme variables from a map of tokens / @access public / @param {Map} $theme [$${defaultThemeMapName}] - Map of theme tokens +/ @param {Bool} $emit-custom-properties [false] - Output CSS Custom Properties for theme tokens / @content Pass in your custom declaration blocks to be used after the token maps set theming variables. / / @example scss @@ -100,6 +101,10 @@ async function build() { left: t.Identifier('theme'), right: t.Identifier(defaultThemeMapName), }), + t.AssignmentPattern({ + left: t.Identifier('emit-custom-properties'), + right: t.SassBoolean(false), + }), ], body: t.BlockStatement({ body: [ @@ -115,6 +120,22 @@ async function build() { global: true, }); }), + t.IfStatement({ + test: t.LogicalExpression({ + left: t.Identifier('emit-custom-properties'), + operator: '==', + right: t.SassBoolean(true), + }), + consequent: t.BlockStatement( + tokenColors.map(token => { + const name = formatTokenName(token); + return t.Declaration({ + property: `--${name}`, + value: `#{map-get($theme, '${name}')}`, + }); + }) + ), + }), t.AtContent(), t.Comment(' Reset to default theme after apply in content'), t.IfStatement({