Использование материального веб-компонента внутри litElement

Я пытаюсь создать небольшое приложение, используя PWA Starter Kit из Polymer проект.

Можно ли использовать веб-компонент из https://material.io/develop/web/components/input-controls/text-field/ внутри моего LitElement? Я хочу использовать текстовую область.

Что я пробовал:

import {html, customElement, LitElement} from "lit-element";
//
import {MDCTextField} from '@material/textfield';

@customElement('text-editor')
export class TextEditor extends LitElement {

    protected render() {
        return html`<div class="mdc-text-field mdc-text-field--textarea">
  <textarea id="textarea" class="mdc-text-field__input" rows="8" cols="40"></textarea>
  <div class="mdc-notched-outline">
    <div class="mdc-notched-outline__leading"></div>
    <div class="mdc-notched-outline__notch">
      <label for="textarea" class="mdc-floating-label">Textarea Label</label>
    </div>
    <div class="mdc-notched-outline__trailing"></div>
  </div>
</div>`
    }

}

Однако, поскольку я нигде не использую «MDCTextField», компилятор TypeScript жалуется, что «MDCTextField объявлен, но его значение никогда не читается».

Я получаю текстовую область, отображаемую в HTML, но ни один из стилей не применяется.

Как я могу повторно использовать веб-компонент MDCTextField в LitElement?


person zelite    schedule 17.06.2019    source источник


Ответы (1)


Да, вам необходимо использовать статические стили LitElement, в которых используются конструируемые стили вместе с резервным вариантом для не поддерживающих браузеров:

import { html, customElement, LitElement, unsafeCSS } from 'lit-element';

import { MDCTextField } from '@material/textfield';

// IMPORTANT: USE WEBPACK RAW-LOADER OR EQUIVALENT
import style from 'raw-loader!@material/textfield/dist/mdc.textfield.css';

@customElement('text-editor')
export class TextEditor extends LitElement {

  static styles = [unsafeCSS(style)];

  private textField?: MDCTextField;

  connectedCallback() {

    super.connectedCallback();

    const elm = this.shadowRoot!.querySelector('.mdc-text-field')! as HTMLElement;

    if (elm && !this.textField) {
      // Element is re-attached to the DOM
      this.makeTextField();
    }
  }

  disconnectedCallback() {
    if (this.textField) {
      this.textField.destroy();
      this.textField = undefined;
    }
  }

  render() {
    return html`
      <div class='mdc-text-field mdc-text-field--textarea'>
        <textarea id='textarea' class='mdc-text-field__input' rows='8' cols='40'></textarea>
        <div class='mdc-notched-outline'>
          <div class='mdc-notched-outline__leading'></div>
          <div class='mdc-notched-outline__notch'>
            <label for='textarea' class='mdc-floating-label'>Textarea Label</label>
          </div>
          <div class='mdc-notched-outline__trailing'></div>
        </div>
    </div>`;
  }

  firstUpdated() {
    // Executed just once
    this.makeTextField();
  }

  private makeTextField() {
    const elm = this.shadowRoot!.querySelector('.mdc-text-field')! as HTMLElement;

    this.textField = new MDCTextField(elm);
  }

}

Вот что вам нужно сделать:

  1. Используйте пакет, например Webpack или rollup, для чтения файла CSS в виде строки. В приведенном выше примере я использовал Sebpack с raw-loader.
  2. Инициализируйте MDCTextField, когда компонент визуализируется впервые, используя firstUpdated событие жизненного цикла.
  3. Впоследствии компонент может быть удален и повторно вставлен в DOM, и поэтому вы захотите уничтожить, очистить и повторно инициализировать экземпляр MDCTextField.
person Harshal Patil    schedule 18.06.2019
comment
Когда я использую ваш пример кода, на веб-странице ничего не отображается. Однако, если я закомментирую connectedCallback, он будет отображен: / - person zelite; 20.06.2019
comment
Вот что я имею в виду: stackblitz.com/edit/lhprwb (без css, потому что я не мог получить он работает внутри stackblitzt). Если я раскомментирую функцию connectedCallback, то на странице ничего не будет отображаться. - person zelite; 20.06.2019
comment
@zelite, извини! Я забыл добавить super.connectedCallback(); в connectedCallback метод. LitElement выполняет однократную инициализацию в своем суперклассе, поэтому она необходима. Я обновил фрагмент. - person Harshal Patil; 20.06.2019
comment
У вас есть пример использования свертки и без машинописного текста, показывающий компоненты материала в litelement? - person aver; 01.08.2019
comment
@aver, у меня нет примера Non-TypeScript. Но это должно помочь: github.com/webf-zone/sprinkles - person Harshal Patil; 02.08.2019