From 4c48b15e45b5254197f8b4ec884d54a5ce5608bf Mon Sep 17 00:00:00 2001 From: oliverschuerch Date: Fri, 1 Mar 2024 15:52:55 +0100 Subject: [PATCH] fix(components): implement :host-context fallback for firefox and safari --- .../post-card-control.module.scss | 5 ++ .../post-card-control/post-card-control.scss | 67 +++++++++++++++++++ .../post-card-control/post-card-control.tsx | 40 +++++++++-- 3 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 packages/components/src/components/post-card-control/post-card-control.module.scss 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 new file mode 100644 index 0000000000..f843459b36 --- /dev/null +++ b/packages/components/src/components/post-card-control/post-card-control.module.scss @@ -0,0 +1,5 @@ +@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 ca2e5b0786..e2ba443d2a 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 @@ -177,3 +177,70 @@ } } } + +// 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'] { + margin-bottom: post.$size-regular; + } +} + +@each $bg in post.$dark-backgrounds { + .card-control[data-host-context*='#{$bg}'] { + --post-card-control-border-color: #{post.$white}; + --post-card-control-bg: transparent; + --post-card-control-color: #{post.$white}; + --post-card-control-input-border-color: #{post.$white}; + --post-card-control-input-bg: transparent; + + &:not(.is-disabled) { + // order matters! + // because we only overwrite the props, which need to be different from one selector to the other. + + &.is-checked { + --post-card-control-border-color: #{post.$yellow}; + --post-card-control-bg: #{post.$yellow}; + --post-card-control-color: #{post.$gray-80}; + --post-card-control-input-border-color: #{post.$gray-80}; + --post-card-control-input-bg: #{post.$white}; + + &.is-invalid { + --post-card-control-bg: #{post.$yellow}; + } + } + + &.is-invalid { + --post-card-control-border-color: #{post.$danger}; + --post-card-control-bg: #{post.$error-background}; + --post-card-control-color: #{post.$danger}; + --post-card-control-input-border-color: #{post.$danger}; + --post-card-control-input-bg: #{post.$white}; + } + + &:hover { + --post-card-control-border-color: #{post.$black}; + --post-card-control-bg: #{post.$gray-20}; + --post-card-control-color: #{post.$black}; + --post-card-control-input-border-color: #{post.$black}; + --post-card-control-input-bg: #{post.$white}; + } + } + + // show focus even if is-disabled, because aria-disabled allows focus at any moment + &.is-focused { + &:where(:has(.card-control--input:focus-visible)) { + outline-color: post.$white; + } + } + + // TODO: update white alpha colors with design-system alpha colors, once they are defined + &.is-disabled { + --post-card-control-border-color: #{#{rgba(post.$white, 0.8)}}; + --post-card-control-bg: transparent; + --post-card-control-color: #{#{rgba(post.$white, 0.8)}}; + --post-card-control-input-border-color: #{#{rgba(post.$white, 0.8)}}; + --post-card-control-input-bg: transparent; + } + } +} 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 9ba3527e96..e0faba6fec 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,6 +14,13 @@ import { import { checkNonEmpty, checkOneOf } from '../../utils'; import { version } from '../../../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'; + +const SCSS_VARIABLES = parse(scss); + let cardControlIds = 0; /** @@ -49,10 +56,10 @@ export class PostCardControl { private control: HTMLInputElement; private controlId = `PostCardControl_${cardControlIds++}`; + private initialChecked: boolean; @Element() host: HTMLPostCardControlElement; - @State() initialChecked: boolean; @State() focused = false; @AttachInternals() private internals: ElementInternals; @@ -296,11 +303,34 @@ export class PostCardControl { this.groupCollectMembers(); } - connectedCallback() { - this.initialChecked = this.checked; + // remove as soon as all browser support :host-context() + private readonly HOST_CONTEXT_FILTERS = ['fieldset', ...SCSS_VARIABLES['dark-bg-selectors']]; + private hostContext: string[]; + + private setHostContext() { + this.hostContext = []; + let element = this.host as HTMLElement; + + while (element) { + const localName = element.localName; + const id = element.id ? `#${element.id}` : ''; + const classes = + element.classList.length > 0 ? `.${Array.from(element.classList).join('.')}` : ''; + + this.hostContext.push(`${localName}${id}${classes}`); + element = element.parentElement; + } + + this.hostContext = this.hostContext.filter(ctx => + this.HOST_CONTEXT_FILTERS.find(f => ctx.includes(f)), + ); } - componentWillLoad() { + connectedCallback() { + // remove as soon as all browser support :host-context() + this.setHostContext(); + + this.initialChecked = this.checked; this.validateControlLabel(); this.validateControlType(); } @@ -317,6 +347,8 @@ 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 as HTMLInputElement)}