No I'm not going to go digging in a repo without so much as a top-level overview of the approach
No I'm not going to go digging in a repo without so much as a top-level overview of the approach
namespace App {
export class SegmentedButtonComponent {
readonly head
constructor(...segments: ((element: HTMLElement) => Raw.Param)[]) {
this.head = raw.div(
raw.css(
"> *", {
display: "inline-block",
padding: "1em",
borderRadius: "5px",
userSelect: "none",
webkitUserSelect: "none",
cursor: "default",
},
"> .active", {
backgroundColor: "hsl(215, 100%, 50%)",
color: "white",
},
),
() => {
const buttons: HTMLElement[] = []
for (const fn of segments) {
const button = raw.div()
raw.get(button)(
raw.on("click", () => this.select(button)),
fn(button),
)
buttons.push(button)
}
return buttons
},
)
}
select(childElement: HTMLElement) {
toggleClass(childElement, "active")
}
}
function toggleClass(child: Element, cls: string) {
Array.from(child.parentElement!.children).map(e => e.classList.toggle(cls, e === child))
}
}<div style="display:inline-block...." [style]="{ 'backgroundColor: hsl(215, 100%, 50%)' : active }" (click)="active = !active">
Like, I know you want to create an element and blah blah...but if it takes your dev 4x longer to write it, why are you doing it? Ultimately, in the real world, all of this is devs trying to make bragging rights for reasons with no real commercial viability intended. As much as we like the idea of less JS frameworks and all that, there is a reason why every major company uses them - they allow people to make business-impacting changes and features faster.
What is really funny to me though is that it is even an awful example - you should never use a div as a button, it is an accessibility nightmare. That is telling.
Eh, that's easily fixable with role="button" and tabindex="0". Oh, and adding a keyup handler so space and enter both click it. After that though, you have a perfectly good button. Well, minus any visual feedback that it's being clicked, but presumably you're doing some custom effect to go with the custom element...
So never say "never", but yeah, use a damn <button> whenever you have the choice. The roles are there to give you an escape hatch when you don't. And sometimes buttons are actually just button-shaped links, in which case you _really_ want to use an <a> tag, because those are heinous to imitate properly.
I have to say this is a bit disingenuous. You pulled the segmented button component which in a real-world environment would just be a part of a library. You should show the part where it gets used. From my experience, how this ends up playing out in a real-world environment is that these things end up getting boxed into higher-level UI libraries that turn all this stuff into quick function calls.
The vast majority of devs aren't (and shouldn't be) writing their own custom components.
Component frameworks are for doing exactly that, and they generally make it pretty easy, with no manual DOM manipulation required when state changes.
Rather than continue with my salty commentary, I suggest to anyone still reading to look at any other file in the example project and draw their own conclusions: https://github.com/squaresapp/rawjs-sample
The live sample of that is not very impressive. And even worse:
> These are the limitations you need to accept with this project structure:
> You have to be disciplined to only use dependencies that are published on jsdelivr (npm install programmers need to clean up their act)
That with a package.json which has dependencies @squaresapp/rawjs and rawter, both of which have no info on npmjs. Talk about "do as I say, not as I do". The idea that you might be able to handle things like i18n and a18y without dependencies screams "not invented here" syndrome.
that said, I do agree that pointing to a highly opinionated example project is a bit confusing
https://rawjssample.pages.dev/
I immediately see that it ~hijacks my back button~ fills my back-stack such that I can't use the back button normally. Doesn't look promising.
Maybe it's just a poor demo, are there better examples?
I absolutely hate when pages hijack the back button, but this ain’t it.
It’s still a bad experience, though.
I guess rendering the UI as a function of state still has its merits.