GithubHelp home page GithubHelp logo

Support global CSS about destiny HOT 7 OPEN

0kku avatar 0kku commented on August 23, 2024
Support global CSS

from destiny.

Comments (7)

0kku avatar 0kku commented on August 23, 2024 1

Importing CSS from URLs is not yet supported directly by the static styles property. There are ways you could convert a URL to a style sheet object, but none of the ways are particularly ergonomic. Import assertions may in the future help with statically importing CSS files, but I agree that there's going to have to be some stop-gap solution while we wait for the aforementioned feature to stabilize.

That being said, the code style I originally wanted to encourage was a pattern where you write components that come with styles and import them where they're being used. That way, styles are not decoupled from the structure of the component, and the component is always accompanied by the intended styles. So, for example, if you wanted to have a special button that's styled in a particular way, you'd create a StyledButton and import where it's being used:

export class StyledButton extends Component {
  static captureProps = true;
  forwardProps = new Ref;

  static styles = css`
    button {
      background: green;
    }
  `;
  
  template = html`
    <button destiny:ref=${this.forwardProps}>
      <slot/>
    </button>
  `
}

and then use it like this:

import { StyledButton } from "./StyledButton.js";

html`
  <!-- Other content -->
  <${StyledButton}>Click me</${StyledButton}>
`;

However, there are a couple of problems with this:

  1. This isn't very ergonomic to do. I could work on making it more ergonomic if this is the pattern we want to ultimately encourage. Perhaps something similar to styled-components?
  2. This doesn't work well for form elements because form-associated custom elements are not yet supported by browsers (planned with P3 in Firefox, implemented in Chromium, planned with P2 in Webkit). Until the feature is supported in all major browsers, there needs to be some other workaround for this use-case.

from destiny.

0kku avatar 0kku commented on August 23, 2024

While this would technically be somewhat trivial to implement, after some deliberation, I'm not convinced it's necessarily a good idea. Encouraging globally declared rules is a little orthogonal to the design of the rest of the library, and kind of defeats the whole point of styles being scoped by the components.

Since this issue was first raised, support for static styles has been added, which allow you to reuse styles:

class Foo extends Component {
  static styles = [
    myReusedStyles,
    css`
      /* styles specific to the component */
    `,
  ];
}

It may be less convenient to have to explicitly opt into using the styles you intend to be global in every component, but explicitness tends to make debugging things easier and tends to be less bug prone.

from destiny.

ebebbington avatar ebebbington commented on August 23, 2024

Whilst I didn't know we could do something like [reusableStyles, css...]

Here's my initial thoughts:

Why would people want to use global styles?

  1. They have a global.css stylesheet, that may give a common style to all input element, buttons etc. This isn't really achievable with scoped css because you'd have to rewrite the same CSS (stay with me here)

  2. Pulling in libraries, eg <link rel="/public/css/boostrap.min.css"> or pulling it through a CDN

I personally think these are very valid usecases. As of now, they cannot be done. (stay with me...). Which leads me on to...

How can we address those?

  1. We can address the first point by using the example @0kku has shown in the description of this issue. this could be along the lines of:
// ./public/components/styles.ts
// Instead of your view linking to the css file, that css file is instead converted to a JS exported variabled
import { html } from ...
export const globalStyles = css`
   input { color: red }
`

// ./public/components/Chat.ts
import { globalStyles } from ...
class Chat extends Component {
  static styles = [
     globalStyles,
     css`
       .some-scoped-elem { ... }
     `
  ]
}

Now I guess this bring a slight problem: every component will have to add this same line. Now is that a bad thing? Maybe it's subjective. So maybe it's down to @0kku as to whether they implement some logic to apply 'global styles' to components, which from what I understand, is considered bad practice: the whole idea of the shadow dom is only scoped css applies.

  1. I don't believe we can address this already. I believe the only way this would be supported is extra work done by @0kku. I would not know what that work would be,, but the idea would be that global available styles would apply to components. Maybe this can be strict: global available styles imported from a url are only supported? eg bootstrap

from destiny.

ebebbington avatar ebebbington commented on August 23, 2024

I'm guessing there must some some projects (company software, pet projects etc) that use a shadow dom and have a common UI/styling, where styles are shared across components. I'm just curious how they handle it?

from destiny.

0kku avatar 0kku commented on August 23, 2024

I'm guessing there must some some projects (company software, pet projects etc) that use a shadow dom and have a common UI/styling, where styles are shared across components. I'm just curious how they handle it?

I have to admit that I'm not sure what the generally agreed-on way to do this is, but I would guess that the most common pattern is to include a <link rel="stylesheet" href="global-styles.css" /> tag in the component's template. This approach will work with Destiny as well, should you want to use it.

from destiny.

ebebbington avatar ebebbington commented on August 23, 2024

@0kku Wow that is something i've done in other porjects, but completely overlooked regarding this topic for Destiny...

I retract my original opinions and would 100% agree with you, on the fact that buttons, lists etc (any common element) should be a component and used as a 'sub component'.

To be honest, i'd argue it can be ergonomic - after all be it react or destiny, we use components right? You have a 'custom slider component'? or a button? or a form? Thats a component that can accept props (if needed).

Example:

GET /user/new will display a UsersNew component. That component will use FormComponent as a 'child'. You pass in a click ahndler for the submit button. That form component will consist of using input components too

I have to admit that I'm not sure what the generally agreed-on way to do this is, but I would guess that the most common pattern is to include a tag in the component's template. This approach will work with Destiny as well, should you want to use it.

I guess that is a way, but it doesn't feel right, you know? Seems like it does go against the premise of scoped components?

Regarding general styles eg on the body, or helper classes eg .flex or .text-align-c, they could be a reusableStyles variable

The only thing i'm left thinking about is 'external' styles, again going back to bootstrap (just an example, could be tailwind, literally anything), whether it's in a lib dir, or you're using a cdn to serve it. And from what you've said, that seems near impossible or not a very ergonomic approach

Maybe this is just a matter discussing how an application would go about using external/third party stylesheets?

from destiny.

ebebbington avatar ebebbington commented on August 23, 2024

After a long convesation with @0kku, re've discovered that using global stylesheets is possible:

abstract class BaseComponent extends Component {
    protected html (input: TemplateResult) {
        return xml`
          <link rel="stylesheet" href="styles.css" />
          ${input}
        `
    }
}
class CustomButton extends BaseComponent {
    override template = this.html(xml`<button>hello:)</button><p>hi as well</p>`)
}
class AppRoot extends BaseComponent {
    override template = this.html(xml`<p>hello</p><${CustomButton} />`)
}
register(AppRoot)

I suggest the above and the notes from #15 (comment) (eg styles = [css'${globalStyles}, css'${thisComponentStyles}'])

@0kku I'm happy to write work on a write up for this and you could add it to the wiki? afaik outsider contributors can't edit the wiki

from destiny.

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.