Skip to content

Latest commit

 

History

History
135 lines (94 loc) · 5.99 KB

observe.md

File metadata and controls

135 lines (94 loc) · 5.99 KB

twind/observe

Allows to copy-paste tailwind examples. This feature can be used together with your favorite framework without any additional setup.

The twind/observe modules allows to use the class attribute for tailwind rules. If such a rule is detected the corresponding CSS rule is created and injected into the stylesheet. No need for tw but it can be used on the same elements as well.

This is meant for advanced use cases. Most of the time you may want to use twind/shim.

Table Of Contents (Click To Expand)

Usage

import { observe } from 'twind/observe'

observe(document.body)

document.body.innerHTML = `
  <main class="h-screen bg-purple-400 flex items-center justify-center">
    <h1 class="font-bold text(center 5xl white sm:gray-800 md:pink-700)">
      This is Twind!
    </h1>
  </main>
`

live and interactive shim demo

All twind syntax features like grouping are supported.

If you want to simplify the instantiation and automatically observe take look at twind/shim.

Customization

twind/observe uses the default/global tw instance if not configured otherwise. You can provide a custom instance in several ways:

import { create } from 'twind'
import { observe, createObserver } from 'twind/observe'

// Create a custom instance
const instance = create(/* ... */)

// 1. As second parameter
observe(document.body, instance)

// 2. As this context
observe.call(document.body)
observe.bind(instance)(document.body)

// 3. Use the factory
createObserver(instance).observe(document.body)

API

import { createObserver, observe } from 'twind/observe'

const observer = createObserver(/* custom instance */)
// Or to start observing an element right away
// const observer = observe(document.body)

// Start observing a node
observer.observe(node)

// Stop observing
observer.disconnect(node)

Example

This example shows how a custom observer instance can be used to shim a web component.

This example is using Constructable Stylesheet Objects and DocumentOrShadowRoot.adoptedStyleSheets which have limited browser support at the moment (December 2020).

import { LitElement, html } from 'lit-element'
import { create, cssomSheet } from 'twind'
import { createObserver } from 'twind/observe'

// 1. Create separate CSSStyleSheet
const sheet = cssomSheet({ target: new CSSStyleSheet() })

// 2. Use that to create an own twind instance
const instance = create({ sheet })

class TwindElement extends LitElement {
  // 3. Apply the same style to each instance of this component
  static styles = [sheet.target]

  // 4. Start observing class attributes changes
  connectedCallback() {
    super.connectedCallback()
    this._observer = createObserver(instance).observe(this.renderRoot)
  }

  // 5. Stop observing class attributes changes
  disconnectedCallback() {
    super.disconnectedCallback()
    this._observer.disconnect()
  }

  render() {
    // 5. Use tailwind rules in class attributes
    return html`
      <main class="h-screen bg-purple-400 flex items-center justify-center">
        <h1 class="font-bold text(center 5xl white sm:gray-800 md:pink-700)">This is Twind!</h1>
      </main>
    `
  }
}

customElements.define('twind-element', TwindElement)

document.body.innerHTML = '<twind-element></twind-element>'

live and interactive demo

Implementation Details

This uses a MutationObserver to detect changed class attributes or added DOM nodes. On detection the class attribute is parsed and translated by twind to inject the required classes into the stylesheet and the class attribute is updated to reflect the added CSS class names that may have been hashed.