Live data from Hacker News

The Overcomplexity of the Shadcn Radio Button

paulmakeswebsites.com

301–310 of 351 posts

Re: The Overcomplexity of the Shadcn Radio Button

#301
post #23
post #13

Earlier quoted context omitted.

Exactly this. OP fails to understand that there are reasons why it was done this way, and that someone who spent thousand of hours working on this might know something that they don't.

Perhaps this is the original PR for the Radio/RadioGroup[1]. It does seem the complexity was a deliberate decision. [1] https://github.com/radix-ui/primitives/pull/121

Author here.

Thanks for sharing the PR. Frankly that raises more questions for me. Why do they want to wrap a label in a label? What is the actual goal here?

Re: The Overcomplexity of the Shadcn Radio Button

#302
post #270

Earlier quoted context omitted.

Can you provide more details about the issues?

Not really, because I no longer remember. I only remember bugs and frustration. But I looked at my code quickly and found this: ;; Let's render radio buttons ourselves. Because of bugs in React and Chrome, radio buttons mysteriously stop working. ;; https://stackoverflow.com/questions/48423061/radio-buttons-n... ;; https://github.com/facebook/react/issues/3446 followed by my own implementation of radio buttons, follo…

Reading through the threads that sounds like a React bug not a browser bug

Re: The Overcomplexity of the Shadcn Radio Button

#303

This is only "overcomplex" from a naive point of view. Radio buttons, as with all UI controls, have tremendous inherent complexity, which comes to light once requirements ask for something beyond the blessed happy path of the default browser button. Pixel perfect styling, animations, focus behaviors, interactions with external state, componentized branding to fit in with companies' ecosystems, etc. The baseline parad…

Author here. I've implemented all of these with the native radio button and CSS:

> Pixel perfect styling, animations, focus behaviors, interactions with external state, componentized branding to fit in with companies' ecosystems, etc.

Do you have a more specific example of something you've struggled with recently?

Re: The Overcomplexity of the Shadcn Radio Button

#305

> Why would you want to do this? Have you tried completely customising a radio button with CSS? Feel free to demonstrate a heavily customised radio button style where you don’t hide the native appearance.

Yes, several times. I've been specializing in front-end dev for over a decade.

I shared a simple example because Shadcn has a simple design.

You do often hide the native appearance if you need something complex, but doing that via CSS is still much simpler than a bunch of JS and a third party dependency.

If you have a specific design in mind I can show you how to do it.

Re: The Overcomplexity of the Shadcn Radio Button

#306

Earlier quoted context omitted.

Managing state and syncing it to the DOM manually is much harder than React (or any other big framework) for any non-trivial web app. Reactive, inherently asynchronous, event driven applications get complex easily.

Right. I encourage young devs to build a complex app using vanilla js. Feel the pain of two way state management. Then you’ll gain an appreciation for react. And you’ll learn browser APIs and know when react is overkill because it has its own pain

And, you'll know why this statement

> But for several years we've been able to style radio buttons however we want using a few CSS tools

proves how good the current state is, where a dev can think things will just be ok, for everyone, if you just ripped all that complexity and ship it (which should be the attitude for a good framework).

Re: The Overcomplexity of the Shadcn Radio Button

#307
post #295

Earlier quoted context omitted.

The point I wanted to emphasize is that even if you do overcomplicate your DOM, the component abstraction is what allows you to fix it in one place . Don't like what's in your component — add `return `, bam! It's fixed across the entire app now.

And how is the surrounding JS code, like the event handlers, and the CSS of the component supposed to still work now? A radio input will need at the very least additional CSS to remove the native appearance. Unlikely that was set already --> it's not that easy.

The idea is that the component's API is not the DOM. Usually this means your data should flow in a certain way: top-down.

Application code is not supposed to use the DOM as the source of truth for some boolean state that the checkbox is an input for.

You don't usually read a component's state from outside (here: the "checked" property).

Instead you define an API where data only flows top-down.

When your checkbox component follows this paradigm, it is "controlled", and if it contains a standard HTML input, that input's "checked" DOM object property is bound to the data passed into the component ("props"). Clicking it won't check it anymore until you add an "onClick" callback and pass a function into this callback that will make the "checked" prop change.

The checkbox is now "controlled" and it's state was "lifted up" (meaning that it is determined not by the checkbox component itself).

"controlled" means you tell React to always force the "checked" DOM property to be the same as the "checked" prop you pass into the component. You do this by assigning to the reflected "checked" HTML attribute in JSX.

When your components only use this "top-down" data flow, they're "pure" in React lingo. Because they look like pure functions: props => DOM fragment. The machinery behind the scenes means they're not actually that (something has to coordinate the rendering).

But if you don't use internal state (e.g. useState hook) or global stores, these "impure" parts are React internals only, and you can have a mental model that views the component like a pure function.

This makes it easier to connect it with other components in a tree.

For example:

HTMLInputElement.checked can be true without a "checked" attribute being in the markup.

If you want to have some text next to it that says "checked / not checked" you have to wire stuff, and this stuff depends on your markup.

If you have a "controlled" checkbox, you have a tree, not only for the markup, but also for the data: the boolean "checked" state can now be declared one level above both the info text and the checkbox. Then the info text doesn't care at all about events anymore.

And the checkbox component only uses a callback that is also independent from the exact markup structure (e.g. a selector for the HTML input element).

You don't need to read from the checkbox to update the text. You feed both with a boolean and both can be "pure" components. The checkbox gets a "onClick" callback and it's checked state is no longer internal, it's "controlled".

The wiring you have to do instead of the regular DOM events (which would read the input's state) is now to use your "onClick" callback to toggle your boolean.

Internally, in the component, you do whatever you need to read and write to the DOM. But usually that just means "what markup do I return".

Input elements and reflected attributes such as "checked" are already a relatively complex case.

And, you can escape the recommended top-down data flow by many means (refs, context, accessing centralized "stores" from within the component...), but that's often where it gets ugly. But you need to do it often when your app gets bigger (centralized data stores), or when you implement things like UI libraries (refs).

Re: The Overcomplexity of the Shadcn Radio Button

#308

Earlier quoted context omitted.

Based on profits of many webapps, there is no line. What eng here forget is that they are oft not the targeted consumer. The hypothetically perfect website doesnt sell as well as a colorful fat choncker does. It is like fast food, not every cares about farm to table.

> It is like fast food, not every cares about farm to table I mean, a "colorful fat choncker" website is literally the opposite of fast food - its slower to arrive, and focuses way too much on appearances . In this analogy, the website using these ridiculous abstractions is more like Salt Bae or whatever idiotic trend has replaced him. All glitz, zero substance, slower, and for no apparent reason. The fast food equiv…

Everyone always says slower and bloat and bad etc etc but it is all relative. Not everyone is an eng who scoffs at waiting another 100ms.

I do like your analogy tho. It is better. Most people want that trendy experience or fast food. Still, both exist because the market demands it be so despite how much it tilts a subset.

Re: The Overcomplexity of the Shadcn Radio Button

#309

Earlier quoted context omitted.

Based on profits of many webapps, there is no line. What eng here forget is that they are oft not the targeted consumer. The hypothetically perfect website doesnt sell as well as a colorful fat choncker does. It is like fast food, not every cares about farm to table.

Except the correct way can be just as colorful, and it takes more effort to implement the bad way.

This is objectively not true, if it were the path of least resistance would mean everyone uses the option that is fastest and best.

It takes far less effort to implement the bad way. I think people take their own skill for granted. Maybe you can but most others cannot. Maybe they will learn or maybe they are happy to put food on the table and go home at 5.

Re: The Overcomplexity of the Shadcn Radio Button

#310

Earlier quoted context omitted.

Protip: the space between the UI control and the label should be done using padding (or achieved via label nesting) so that the entire area is clickable. [ x ] some long label ꜛꜛꜛ padding here, not margins or gaps (clicking between the control and the label does nothing now)

Calling this a "Protip" is generous. That the combined element has any surface area that doesn't toggle the radio setting is a straight-up bug. It is laughable for a component this heavily refined to have such a basic usability flaw.

I'm thinking protip was sarcasm :)
Post reply on HN