From be80b6838ab163af405d9bfec0302fd42a7e6ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= <33580481+alizedebray@users.noreply.github.com> Date: Tue, 13 Aug 2024 15:22:10 +0200 Subject: [PATCH 1/3] fix(components): remove scss module import (#3358) --- .changeset/fair-suns-agree.md | 5 ++ packages/components/src/components.d.ts | 16 +++--- .../post-card-control.module.scss | 5 -- .../post-card-control/post-card-control.scss | 22 ++++++-- .../post-card-control/post-card-control.tsx | 55 ++++++++----------- .../components/post-card-control/readme.md | 8 +-- packages/components/stencil.config.ts | 1 - packages/styles/src/variables/_color.scss | 38 ++++++++----- 8 files changed, 82 insertions(+), 68 deletions(-) create mode 100644 .changeset/fair-suns-agree.md delete mode 100644 packages/components/src/components/post-card-control/post-card-control.module.scss diff --git a/.changeset/fair-suns-agree.md b/.changeset/fair-suns-agree.md new file mode 100644 index 0000000000..3362bdc0fd --- /dev/null +++ b/.changeset/fair-suns-agree.md @@ -0,0 +1,5 @@ +--- +'@swisspost/design-system-components': patch +--- + +Fixed the `post-card-control` component to use the correct color scheme when placed on nested colored backgrounds. diff --git a/packages/components/src/components.d.ts b/packages/components/src/components.d.ts index 11a2b05f4e..a01163268d 100644 --- a/packages/components/src/components.d.ts +++ b/packages/components/src/components.d.ts @@ -80,7 +80,7 @@ export namespace Components { */ interface PostCardControl { /** - * Defines the `checked` attribute of the control. If `true`, the control is selected at its value will be included in the forms data. + * Defines the `checked` attribute of the control. If `true`, the control is selected at its value will be included in the forms' data. */ "checked": boolean; /** @@ -88,7 +88,7 @@ export namespace Components { */ "description": string; /** - * Defines the `disabled` attribute of the control. If `true`, the user can not interact with the control and the controls value will not be included in the forms data. + * Defines the `disabled` attribute of the control. If `true`, the user can not interact with the control and the controls value will not be included in the forms' data. */ "disabled": boolean; /** @@ -96,7 +96,7 @@ export namespace Components { */ "groupReset": () => Promise; /** - * Defines the icon `name` inside of the card. If not set the icon will not show up. + * Defines the icon `name` inside the card. If not set the icon will not show up. */ "icon": string; /** @@ -116,7 +116,7 @@ export namespace Components { */ "type": 'checkbox' | 'radio'; /** - * Defines the validation `validity` of the control. To reset validity to an undefiend state, simply remove the attribute from the control. + * Defines the validation `validity` of the control. To reset validity to an undefined state, simply remove the attribute from the control. */ "validity": null | 'true' | 'false'; /** @@ -588,7 +588,7 @@ declare namespace LocalJSX { */ interface PostCardControl { /** - * Defines the `checked` attribute of the control. If `true`, the control is selected at its value will be included in the forms data. + * Defines the `checked` attribute of the control. If `true`, the control is selected at its value will be included in the forms' data. */ "checked"?: boolean; /** @@ -596,11 +596,11 @@ declare namespace LocalJSX { */ "description"?: string; /** - * Defines the `disabled` attribute of the control. If `true`, the user can not interact with the control and the controls value will not be included in the forms data. + * Defines the `disabled` attribute of the control. If `true`, the user can not interact with the control and the controls value will not be included in the forms' data. */ "disabled"?: boolean; /** - * Defines the icon `name` inside of the card. If not set the icon will not show up. + * Defines the icon `name` inside the card. If not set the icon will not show up. */ "icon"?: string; /** @@ -624,7 +624,7 @@ declare namespace LocalJSX { */ "type": 'checkbox' | 'radio'; /** - * Defines the validation `validity` of the control. To reset validity to an undefiend state, simply remove the attribute from the control. + * Defines the validation `validity` of the control. To reset validity to an undefined state, simply remove the attribute from the control. */ "validity"?: null | 'true' | 'false'; /** diff --git a/packages/components/src/components/post-card-control/post-card-control.module.scss b/packages/components/src/components/post-card-control/post-card-control.module.scss deleted file mode 100644 index f843459b36..0000000000 --- a/packages/components/src/components/post-card-control/post-card-control.module.scss +++ /dev/null @@ -1,5 +0,0 @@ -@use '@swisspost/design-system-styles/core' as post; - -:export { - dark-bg-selectors: [post.$dark-backgrounds]; -} diff --git a/packages/components/src/components/post-card-control/post-card-control.scss b/packages/components/src/components/post-card-control/post-card-control.scss index df6630f9ff..9633f47f09 100644 --- a/packages/components/src/components/post-card-control/post-card-control.scss +++ b/packages/components/src/components/post-card-control/post-card-control.scss @@ -1,13 +1,19 @@ +@use 'sass:list'; @use 'sass:math'; @use '@swisspost/design-system-styles/core' as post; @use '@swisspost/design-system-styles/components/form-check'; /* -* There are a whole bunch of !important statments in this file. +* There are a whole bunch of !important statements in this file. * They are necessary and should not be removed, because we need to override the .form-check styles here. */ :host { + + // remove as soon as all browser support :host-context() + // https://caniuse.com/?search=%3Ahost-context() + --post-card-control-bg-context: #{post.$backgrounds}; + display: flex; width: 100%; } @@ -416,14 +422,22 @@ // remove as soon as all browser support :host-context() // https://caniuse.com/?search=%3Ahost-context() -:host(:not(:last-child)) { - .card-control[data-host-context*='fieldset'] { +:host(:not([data-context])) { + display: none; +} + +:host([data-context*='fieldset']:not(:last-child)) { + .card-control { margin-bottom: post.$size-regular; } } +$dark-bg-context: (); @each $bg in post.$dark-backgrounds { - .card-control[data-host-context*='#{$bg}'] { + $dark-bg-context: list.append($dark-bg-context, "[data-context*='#{$bg}']", $separator: comma); +} +:host(:is(#{$dark-bg-context})) { + .card-control { --post-card-control-border-color: #{post.$white}; --post-card-control-bg: transparent; --post-card-control-color: #{post.$white}; diff --git a/packages/components/src/components/post-card-control/post-card-control.tsx b/packages/components/src/components/post-card-control/post-card-control.tsx index 1f42eb8397..a6d237eb42 100644 --- a/packages/components/src/components/post-card-control/post-card-control.tsx +++ b/packages/components/src/components/post-card-control/post-card-control.tsx @@ -14,14 +14,6 @@ import { import { checkNonEmpty, checkOneOf } from '@/utils'; import { version } from '@root/package.json'; -// remove as soon as all browser support :host-context() -// https://caniuse.com/?search=%3Ahost-context() -import scss from './post-card-control.module.scss'; -import { parse } from '@/utils/sass-export'; - -/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ -const SCSS_VARIABLES: any = parse(scss); - let cardControlIds = 0; /** @@ -98,23 +90,23 @@ export class PostCardControl { @Prop() readonly value: string = null; /** - * Defines the `checked` attribute of the control. If `true`, the control is selected at its value will be included in the forms data. + * Defines the `checked` attribute of the control. If `true`, the control is selected at its value will be included in the forms' data. */ @Prop({ mutable: true }) checked = false; /** - * Defines the `disabled` attribute of the control. If `true`, the user can not interact with the control and the controls value will not be included in the forms data. + * Defines the `disabled` attribute of the control. If `true`, the user can not interact with the control and the controls value will not be included in the forms' data. */ @Prop({ mutable: true }) disabled = false; /** * Defines the validation `validity` of the control. - * To reset validity to an undefiend state, simply remove the attribute from the control. + * To reset validity to an undefined state, simply remove the attribute from the control. */ @Prop({ mutable: true }) validity: null | 'true' | 'false' = null; /** - * Defines the icon `name` inside of the card. + * Defines the icon `name` inside the card. * If not set the icon will not show up. */ @Prop() readonly icon: string = null; @@ -174,7 +166,7 @@ export class PostCardControl { } @Watch('disabled') - updateControlDisbled() { + updateControlDisabled() { this.controlSetChecked(this.checked); } @@ -322,33 +314,31 @@ export class PostCardControl { } } - // remove as soon as all browser support the :host-context() selector - private readonly HOST_CONTEXT_FILTERS = ['fieldset', ...SCSS_VARIABLES['dark-bg-selectors']]; - private hostContext: string[]; - + // remove as soon as all browser support :host-context() + // https://caniuse.com/?search=%3Ahost-context() private setHostContext() { - this.hostContext = []; - let element = this.host as HTMLElement; + let bgContext: string; + const possibleBgContexts = window + .getComputedStyle(this.host) + .getPropertyValue('--post-card-control-bg-context') + .split(', '); + + let formContext: string; + const possibleFromContexts = ['fieldset']; - while (element) { - const localName = element.localName; - const id = element.id ? `#${element.id}` : ''; - const classes = - element.classList.length > 0 ? `.${Array.from(element.classList).join('.')}` : ''; + let element = this.host as HTMLElement; + while (element && (!bgContext || !formContext)) { + bgContext = bgContext ?? possibleBgContexts.find(selector => element.matches(selector)); + formContext = formContext ?? possibleFromContexts.find(selector => element.matches(selector)); - this.hostContext.push(`${localName}${id}${classes}`); element = element.parentElement; } - this.hostContext = this.hostContext.filter(ctx => - this.HOST_CONTEXT_FILTERS.find(f => ctx.includes(f)), - ); + const hostContext = [bgContext, formContext].filter(context => !!context).join(' '); + this.host.setAttribute('data-context', hostContext); } connectedCallback() { - // remove as soon as all browser support :host-context() - this.setHostContext(); - this.initialChecked = this.checked; } @@ -368,8 +358,6 @@ export class PostCardControl { 'is-valid': this.validity !== null && this.validity !== 'false', 'is-invalid': this.validity === 'false', }} - // remove as soon as all browser support :host-context() - data-host-context={this.hostContext.join(' ')} > (this.control = el)} @@ -416,6 +404,7 @@ export class PostCardControl { } componentDidRender() { + this.setHostContext(); this.groupCollectMembers(); } diff --git a/packages/components/src/components/post-card-control/readme.md b/packages/components/src/components/post-card-control/readme.md index 41f7a9e5b3..9d340000d5 100644 --- a/packages/components/src/components/post-card-control/readme.md +++ b/packages/components/src/components/post-card-control/readme.md @@ -9,14 +9,14 @@ | Property | Attribute | Description | Type | Default | | -------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | ----------- | -| `checked` | `checked` | Defines the `checked` attribute of the control. If `true`, the control is selected at its value will be included in the forms data. | `boolean` | `false` | +| `checked` | `checked` | Defines the `checked` attribute of the control. If `true`, the control is selected at its value will be included in the forms' data. | `boolean` | `false` | | `description` | `description` | Defines the description in the control-label. | `string` | `null` | -| `disabled` | `disabled` | Defines the `disabled` attribute of the control. If `true`, the user can not interact with the control and the controls value will not be included in the forms data. | `boolean` | `false` | -| `icon` | `icon` | Defines the icon `name` inside of the card. If not set the icon will not show up. | `string` | `null` | +| `disabled` | `disabled` | Defines the `disabled` attribute of the control. If `true`, the user can not interact with the control and the controls value will not be included in the forms' data. | `boolean` | `false` | +| `icon` | `icon` | Defines the icon `name` inside the card. If not set the icon will not show up. | `string` | `null` | | `label` _(required)_ | `label` | Defines the text in the control-label. | `string` | `undefined` | | `name` | `name` | Defines the `name` attribute of the control. This is a required property, when the control should participate in a native `form`. If not specified, a native `form` will never contain this controls value. This is a required property, when the control is used with type `radio`. | `string` | `null` | | `type` _(required)_ | `type` | Defines the `type` attribute of the control. | `"checkbox" \| "radio"` | `undefined` | -| `validity` | `validity` | Defines the validation `validity` of the control. To reset validity to an undefiend state, simply remove the attribute from the control. | `"false" \| "true"` | `null` | +| `validity` | `validity` | Defines the validation `validity` of the control. To reset validity to an undefined state, simply remove the attribute from the control. | `"false" \| "true"` | `null` | | `value` | `value` | Defines the `value` attribute of the control. This is a required property, when the control is used with type `radio`. | `string` | `null` | diff --git a/packages/components/stencil.config.ts b/packages/components/stencil.config.ts index bf43556a40..8c83d4839b 100644 --- a/packages/components/stencil.config.ts +++ b/packages/components/stencil.config.ts @@ -61,7 +61,6 @@ export const config: Config = { rollupPlugins: { before: [ postcss({ - modules: true, use: { sass: { includePaths: ['node_modules'], diff --git a/packages/styles/src/variables/_color.scss b/packages/styles/src/variables/_color.scss index 56ee1197e6..b06b201078 100644 --- a/packages/styles/src/variables/_color.scss +++ b/packages/styles/src/variables/_color.scss @@ -184,20 +184,32 @@ $background-colors: map.merge($background-colors, $signal-colors); $background-colors: map.merge($background-colors, $signal-background-colors); $background-colors: map.merge($background-colors, $accent-colors); -// Compile a list of dark backgrounds, used in the :is selector mixin at mixins/color -$dark-backgrounds: () !default; +// Compile a list of light and dark backgrounds, used in the :is selector mixin at mixins/color +$_backgrounds: ( + light: (), + dark: (), +) !default; + @each $color-name, $color in $background-colors { - @if (contrast-fn.light-or-dark($color) == 'dark') { - $dark-backgrounds: list.append($dark-backgrounds, '.bg-#{$color-name}', $separator: comma); - } + $key: contrast-fn.light-or-dark($color); + $values: list.append(map.get($_backgrounds, $key), '.bg-#{$color-name}', $separator: comma); + $_backgrounds: map.set($_backgrounds, $key, $values); } + @each $color-name, $color in $notification-colors { - @if (contrast-fn.light-or-dark($color) == 'dark') { - $dark-backgrounds: list.append($dark-backgrounds, '.alert-#{$color-name}', $separator: comma); - $dark-backgrounds: list.append( - $dark-backgrounds, - 'post-alert[type=#{$color-name}]', - $separator: comma - ); - } + $key: contrast-fn.light-or-dark($color); + $values: list.join( + map.get($_backgrounds, $key), + '.alert-#{$color-name}' 'post-alert[type=#{$color-name}]', + $separator: comma + ); + $_backgrounds: map.set($_backgrounds, $key, $values); } + +$backgrounds: list.join( + map.get($_backgrounds, light), + map.get($_backgrounds, dark), + $separator: comma +); +$dark-backgrounds: map.get($_backgrounds, dark) !default; +$light-backgrounds: map.get($_backgrounds, light) !default; From 14b44cb31528d4df3e24cdb1c11e1f6ac3b7bd35 Mon Sep 17 00:00:00 2001 From: Philipp Gfeller <1659006+gfellerph@users.noreply.github.com> Date: Wed, 14 Aug 2024 08:32:03 +0200 Subject: [PATCH 2/3] fix(tag): set max-length to 100% (#3388) --- .changeset/some-people-say.md | 5 +++++ packages/styles/src/variables/components/_tag.scss | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/some-people-say.md diff --git a/.changeset/some-people-say.md b/.changeset/some-people-say.md new file mode 100644 index 0000000000..b329ef0b8d --- /dev/null +++ b/.changeset/some-people-say.md @@ -0,0 +1,5 @@ +--- +'@swisspost/design-system-styles': patch +--- + +Set the `max-width` constraint of the tag component to 100% for improved accessibility. Try to keep tag text as short as possible though. diff --git a/packages/styles/src/variables/components/_tag.scss b/packages/styles/src/variables/components/_tag.scss index 54cb240407..a54518da39 100644 --- a/packages/styles/src/variables/components/_tag.scss +++ b/packages/styles/src/variables/components/_tag.scss @@ -6,7 +6,7 @@ $tag-gap: spacing.$size-micro; $tag-padding-y: 0; $tag-padding-x: spacing.$size-mini; -$tag-max-width: sizing.px-to-rem(296); +$tag-max-width: 100%; $tag-border-width: spacing.$size-hair; $tag-border-radius: spacing.$size-micro; $tag-font-size: type.$font-size-16; From e8460d8383c747f52fe3f0012aebabaf2aadfeec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= <33580481+alizedebray@users.noreply.github.com> Date: Wed, 14 Aug 2024 13:26:11 +0200 Subject: [PATCH 3/3] fix(styles): fix watch gulp task (#3405) --- packages/styles/gulpfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/styles/gulpfile.js b/packages/styles/gulpfile.js index 3268e80cfd..df7e5df4fa 100644 --- a/packages/styles/gulpfile.js +++ b/packages/styles/gulpfile.js @@ -180,7 +180,7 @@ gulp.task('sass:tests', () => { gulp.task( 'watch', gulp.series('temporarily-copy-token-files', () => { - return gulp.watch('./src/**/*.scss', 'copy'); + return gulp.watch('./src/**/*.scss', gulp.series('copy')); }), );