DEV Community

Discussion on: What happened to Components being just a visual thing?

redbar0n profile image
Magne Author

I agree with your attitude and advice, re: XState and statecharts.

Why change CSS at runtime at all?

To change the theme of the page. Dark mode, for instance.

CSS rules are designed to remain static for the lifetime of the page but they only become active when the specified conditions are met. You wanted "declarative" but now when you have it you want to imperatively change it at run time?

Perhaps what is needed is tooling that can weave together the required CSS style sheet at design time — prior to deployment.

Yes. is that tool. It allows a declarative way of writing CSS-in-JS at design time, while also weaving it together and changing it for you at run time.

Some of my pet peeves with Stimulus JS:

Thanks for sharing! It's very interesting to read your insights. I wouldn't have thought of that myself. Personally, my issue with Stimulus is just that I fear I'll incorrectly wire things up due to typos. Plus that with all the data-* prefixes, it's visually confusing (I feel that data-hello-target should have been a simple id). So I can't really quickly scan it to get the info I need. The latter is an issue I have with Ionic Framework too, with it's insistence on prefixing all their components with ion-* (when it ought to have been a suffix, imho).

the current astro/qwik/remix hype is giving me visions of this - making me wonder if they've gone a bridge too far.

I agree. I am overwhelmed by just trying to understand and differentiate all the different approaches...

I've suggested to Ryan Carniato that he - or someone equally knowledgeable - should make a standardised comparison diagram of the different approaches we have today:

Thread Thread
peerreynders profile image

To change the theme of the page. Dark mode, for instance.

Perhaps I'm naive but I would have thought that's a job for CSS custom properties i.e. an imperative swap of the design tokens that relate to light/dark.

I wouldn't have thought of that myself.

Don't get me wrong. Rails had a point to employ "convention over configuration" to counter the J2EE XML configuration madness at the time. But if you apply "convention over configuration" dogmatically you end up with an awful lot of convention that you have to keep in your head. It's always a question of balance; hard coding vs configuring vs convention and it's not easy to hit the optimum (which depends on the circumstances).

The biggest problem with the rendezvous example is that static.js — for a full page that would be a monster to work with. So you really would need tooling to map a more developer friendly representation to the machine friendly representation.

I fear I'll incorrectly wire things up due to typos. Plus that with all the data-* prefixes,

Look I completely empathize — I immediately thought: "I wish there was a tool that could verify that all the bindings are set up correctly".

Going back even further, when learning JavaScript I found myself craving the false sense of security that a C#/Java compiler gave me that I at least I got the syntax right. At the time I would have been very receptive to TypeScript (these days — poor ROI — how things change).

Now please indulge a digression here — I'll get to a point soon enough.

Oliver Steele: The IDE Divide

That article differentiates between the

  • Language-Maven
  • Tool-Maven

Given that presumed dichotomy in developer attitudes and my personal reading of the declarations of the vocal minority on social media I'm lead to the conclusion that the currently active generation of developers is immensely skewed towards the "I'll adopt it when the tooling is better" type.

That means that a "good idea" has to survive to the early/late majority stage of the innovation adoption lifecycle.

Innovation Adoption Lifecycle

That makes me wonder: How many "good ideas" die on the "innovators" and "early adopters" hill because the developer population is skewed so much towards the "Tool-Mavens" rather than the "Language-Mavens"?

So if you can make Stimulus JS work then by all means do it!

  • Now in your situation you'll be committed to formulating your templates twice and you'll have to keep them in sync — that's just how it is. However I'd consider adopting something like µhtml for client side templating for the larger partials and I would wrap each template in a (pure) function, passing it all the data it needs to instantiate.

  • Whenever possible use reactive bindings to update values inside the DOM rather than replacing nodes. This is the reason why I wish there was a non-UI core of Solid — for most purposes MobX seems a bit too heavy — I'd like something that is lighter than Redux. I guess one could always roll your own.

  • Keep those (Stimulus JS) controllers as skinny as possible. Their job is fairly narrow:

    • On connect/mount
      • Wire reactive subscriptions for value updates into the DOM and add event listeners for input.
      • If the nested content isn't already present use templates to create it client side (their controller(s) will take care of the rest).
    • On disconnect/unmount
      • Remove event listeners and unsubscribe the reactive bindings.
    • Whatever you do keep actual page application logic out of the (Stimulus JS) controllers.

Remember the aim (of rendezvous) is to have a JavaScript core application that can be effectively micro-tested without:

  • running it in a browser
  • having to spin up a fake DOM.

The templates, controller, event and reactive bindings are tested during integration testing with something like cypress or perhaps Puppeteer. The key is that by this point in time you already have full confidence in your decoupled, micro-tested page application logic.

when it ought to have been a suffix, imho

You have to keep in mind that while most browsers will handle non-standard attributes those attributes will actually invalidate the HTML (which is why those pesky alpine.js x-* attributes are another pet peeve of mine). If you are going to 'invent' attributes on standard HTML elements then they better be data-* attributes. At least Stimulus JS got that right.