Giter Site home page Giter Site logo

Adopted stylesheets support about twind HOT 11 CLOSED

tw-in-js avatar tw-in-js commented on August 22, 2024
Adopted stylesheets support

from twind.

Comments (11)

43081j avatar 43081j commented on August 22, 2024 1

I guess it means in your example, a stylesheet would exist per component. Whereas if we reused the same one across modules, we could have one monolithic TW stylesheet many components can adopt.

Not sure if either way is better than the other. This way we keep each component contained at least, so each one has its own tw stylesheet. Which can mean some duplication but less risk of side effects etc

Guess I'm saying i like your way better 😂

from twind.

sastan avatar sastan commented on August 22, 2024 1

Thanks. That means a lot. Closing it now.

Feel free to reopen if you something is not working as expected.

from twind.

43081j avatar 43081j commented on August 22, 2024

Could in fact also have a lit-element sheet which can append the stylesheet to the static styles property of the component.

Which raises another question: how would consumers choose which sheet implementation to use? is that doable via setup()?

edit:

this works for lit-element:

import {LitElement, html} from 'lit-element';
import {setup, tw, cssomSheet} from 'twind';

const myElementStyles = new CSSStyleSheet();

setup({
  sheet: cssomSheet({target: myElementStyles})
});

export class MyElement extends LitElement {
  public static styles = [myElementStyles];

  render() {
    return html`
      <h1 class=${tw`bg-black`}>Foo</h1>
      <p class=${tw`bg-purple-400`}>This is a test</p>
    `;
  }
}

customElements.define('my-element', MyElement);

edit number 2:

after trying this and playing around with it for some time, i don't think its necessarily missing functionality. rather its documentation that could be added.

examples of how to use constructed stylesheets just like i have done above, as these can then be passed straight into vanilla components and lit-element.

from twind.

sastan avatar sastan commented on August 22, 2024

Thanks for the great write up. That helped a lot.

You are right. Docs where missing. I took your examples and adopted (😄 ) them:

I hope these help... Let us know what we can improve! Cheers...

For future reference:

Web Components

This example shows how Custom Element can have its styles separated without having the side effect of polluting the root document's styles.

live and interactive demo

import { create, cssomSheet } from twind'

// 1. Create seperate CSSStyleSheet
const componentStyles = new CSSStyleSheet()

// 2. Use that to create an own twind instance
const { tw } = create({
  sheet: cssomSheet({ target: componentStyles })
});

class TwindElement extends HTMLElement {
  constructor() {
    super()

    const shadow = this.attachShadow({ mode: 'open' })

    // 3. Apply the same style to each instance of this component
    shadow.adoptedStyleSheets = [componentStyles]

    // 4. Use "own" tw function
    shadow.innerHTML = `
      <main class="${tw`h-screen bg-purple-400 flex items-center justify-center`}">
        <h1 class="${tw`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>'

LitElement

live and interactive demo

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

// 1. Create seperate CSSStyleSheet
const componentStyles = new CSSStyleSheet()

// 2. Use that to create an own twind instance
const { tw } = create({
  sheet: cssomSheet({ target: componentStyles })
});

class TwindElement extends LitElement {
  createRenderRoot() {
    const shadow = super.createRenderRoot()

    // 3. Apply the same style to each instance of this component
    shadow.adoptedStyleSheets = [componentStyles]
    
    return shadow
  }

  render() {
    // 4. Use "own" tw function
    return html`
      <main class="${tw`h-screen bg-purple-400 flex items-center justify-center`}">
        <h1 class="${tw`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>'

from twind.

43081j avatar 43081j commented on August 22, 2024

For the lit example you can use the static styles property:

class Foo extends LitElement {
  static styles = [componentStyles];
}

So you don't need to mess with custom render roots.

Also am I understanding correctly in that this means:

  • one stylesheet instance
  • multiple tw instances (probably one per component)

Would this be any less performant than one tw instance we pass around?

from twind.

sastan avatar sastan commented on August 22, 2024

For the lit example you can use the static styles property:

class Foo extends LitElement {
  static styles = [componentStyles];
}

I'll update the docs. Could not use that in esm.codes

Also am I understanding correctly in that this means:

  • one stylesheet instance

Jep.

  • multiple tw instances (probably one per component)

Just one as well. A sheet should always be associated with exactly one tw instance. The tw is defined in the module scope and used by all component instances.

Would this be any less performant than one tw instance we pass around?

Performance should be fine. Memory may be an issue because of the caching if you have a lot of tw instance. I have no idea what a lot means here. We'll need to investigate memory usage a little more.

from twind.

sastan avatar sastan commented on August 22, 2024

We added a target prop to the sheet which makes the code more readable i hope:

docs - Lit Element

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

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

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

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

What do you think?

from twind.

43081j avatar 43081j commented on August 22, 2024

I like it, maybe you could default to newing one up too if the consumer hasn't passed one.

Meanwhile I'll have a look at the browser compatibility when I get chance. For the lit usage, to support browsers without constructed stylesheets. It'll need a bit more work I think but will figure it out

from twind.

sastan avatar sastan commented on August 22, 2024

I like it, maybe you could default to newing one up too if the consumer hasn't passed one.

In that case we use cssom with a stylesheet id=__twind (the existing one or a new one) in the browser and in node we fallback to a no-op sheet:

https://github.com/tw-in-js/twind/blob/main/src/twind/configure.ts#L125

from twind.

43081j avatar 43081j commented on August 22, 2024

Ah fair enough I completely forgot it's used for the other cases too!

Looks fine to me how it is then :D

Nice work again on this stuff in general. It's a good interesting project

from twind.

sastan avatar sastan commented on August 22, 2024

@43081j I have opened an PR #19 which would allow to use separate twind/shim instances. Could you share your insight if this makes sense and take a look at https://github.com/tw-in-js/twind/blob/twind-observe/docs/observe.md#example if that example is valid and useful.

from twind.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.