Есть ли способ получить доступ к атрибуту тега HTML в CSS в Shadow-DOM? - PullRequest
0 голосов
/ 28 марта 2019

Я создаю пользовательский компонент с помощью StencilJS, и мне нужно внести некоторые изменения в схему, когда пользователь использует клавиатуру или мышь для навигации по компоненту.

Мой компонент использует ShadowDOM, и я хочу получить доступ к атрибуту тега HTML из CSS.

Атрибуты тега генерируются с помощью what-input (https://github.com/ten1seven/what-input) для обнаружения событий клавиатуры и мыши.

Я пытался использовать CSS-селекторы, такие как [data-whatintent=keyboard] и html[data-whatintent=keyboard], но это не сработало.

Это мой тег HTML, из которого я хочу получить доступ к атрибуту data-whatintent:

<html dir="ltr" lang="en" data-whatinput="keyboard" data-whatintent="mouse">

  <my-custom-component></my-custom-component>

</html>

А это мой CSS:

[data-whatintent=keyboard] *:focus {
  outline: solid 2px #1A79C6;
}

Я хочу, чтобы мой CSS в ShadowDOM мог использовать значение атрибута data-whatintent, чтобы установить стили для моего компонента, чтобы контур был таким, как я хочу.

Ответы [ 2 ]

2 голосов
/ 28 марта 2019

Ответ Supersharp верен, однако это не код StencilJS, а также поддержка контекста хоста - flakey (не работает в Firefox и, вероятно, IE11).

Вы можете «перенести» атрибут в элемент hostи затем используйте селектор изнутри стиля компонента хоста:

TSX:

private intent: String;

componentWillLoad() {
    this.intent = document.querySelector('html').getAttribute('data-whatintent');
}

hostData() {
    return {
        'data-whatintent': this.intent
    };
}

SCSS:

:host([data-whatintent="keyboard"]) *:focus {
    outline: solid 2px #1A79C6;
}

Если атрибут data-whatintent изменяется динамически,сделайте это свойством компонента, и функция слушателя обновит ваш компонент.При желании вы можете использовать это свойство для добавления / удаления классов на хост для стилизации, хотя вы также можете продолжать использовать селектор атрибутов.

TSX:

@Prop({ mutable: true, reflectToAtrr: true }) dataWhatintent: String;

componentWillLoad() {
    this.dataWhatintent = document.querySelector('html').getAttribute('data-whatintent');
}

hostData() {
    return {
        class: { 
            'data-intent-keyboard': this.dataWhatintent === 'keyboard' 
        }
    };
}

SCSS:

:host(.data-intent-keyboard) *:focus {
    outline: solid 2px #1A79C6;
}

Обработчик событий клавиатуры и мыши в документе:

function intentHandler(event: Event) {
    const intent = event instanceof KeyboardEvent ? 'keyboard' : 'mouse';
    document.querySelectorAll('my-custom-component').forEach(
        el => el.setAttribute('data-whatintent', intent)
    );
}
2 голосов
/ 28 марта 2019

Вы можете использовать : host-context () , чтобы применить стиль CSS в Shadow DOM в зависимости от контекста, в котором используется пользовательский элемент.

customElements.define( 'my-custom-component', class extends HTMLElement {
    constructor() {
        super()
        this.attachShadow( { mode: 'open' } )
            .innerHTML = `
              <style>
                :host-context( [data-whatinput=keyboard] ) *:focus {
                   outline: solid 2px #1A79C6;
                }
              </style>
              <input value="Hello">`
    }
} )         
           
<html dir="ltr" lang="en" data-whatinput="keyboard" data-whatintent="mouse">

  <my-custom-component></my-custom-component>

</html>
...