DEV Community

Chris Garrett
Chris Garrett

Posted on

Using Hyperkit to supercharge UI Development without writing JS

I’ve been working on Hyperkit over the past couple of weeks, and I’m excited to share the first release. Hyperkit is now live on npm. It’s a collection of headless custom elements/web components designed to simplify building rich UIs with server-side frameworks like Rails or Revel.

Why Hyperkit?

The pull of React, for me, has always been the clarity and DX that comes with colocating a component’s behaviour with its markup and styling. It makes building complex front-ends much more intuitive and easier to reason about. The counterpart in Rails is Stimulus, which often feels disconnected - relying on magic incantations of data attributes to apply behaviour, making it difficult to trace and debug.

For simpler UI components like a stylable select, or a click-to-copy button, I didn’t want to always rely on React. That’s where Hyperkit comes in. It’s a set of headless custom elements that help bridge that gap by bringing custom behaviour to plain HTML without the need for JavaScript-heavy frameworks.

What’s in Hyperkit?

Hyperkit covers a range of UX patterns, such as sortable lists, repeating fieldsets, and even calendars. Because Hyperkit uses custom elements, you write them as simple HTML tags, and the behaviour is encapsulated directly within the tag.

Here’s an example of a styled sortable list using Hyperkit:

<hyperkit-sortable class="bg-white rounded shadow-md w-64 overflow-hidden">
  <hyperkit-sortable-item class="flex items-center justify-between pr-4 pl-3 py-2 border-b border-b-zinc-200 data-[before]:border-t-2 data-[before]:border-t-blue-400 data-[after]:border-b-2 data-[after]:border-b-blue-400 text-zinc-800">
    <hyperkit-sortable-handle>
      <button class="cursor-move mr-2 text-zinc-400 select-none font-black px-1">&#8942;</button>
    </hyperkit-sortable-handle>
    <span class="text-xs font-medium flex-grow">Item 1</span>
  </hyperkit-sortable-item>
  <hyperkit-sortable-item class="flex items-center justify-between pr-4 pl-3 py-2 border-b border-b-zinc-200 data-[before]:border-t-2 data-[before]:border-t-blue-400 data-[after]:border-b-2 data-[after]:border-b-blue-400 text-zinc-800">
    <hyperkit-sortable-handle>
      <button class="cursor-move mr-2 text-zinc-400 select-none font-black px-1">&#8942;</button>
    </hyperkit-sortable-handle>
    <span class="text-xs font-medium flex-grow">Item 2</span>
  </hyperkit-sortable-item>
</hyperkit-sortable>
Enter fullscreen mode Exit fullscreen mode

And here’s a styled calendar built with Hyperkit:

<hyperkit-calendar class="w-64 bg-white rounded-lg shadow-lg p-4 block">
  <div class="flex justify-between items-center mb-4">
    <hyperkit-previous-month>
      <button class="text-zinc-600 hover:text-zinc-800 text-xl">&lt;</button>
    </hyperkit-previous-month>
    <hyperkit-current-month class="text-xl font-bold text-zinc-800"></hyperkit-current-month>
    <hyperkit-next-month>
      <button class="text-zinc-600 hover:text-zinc-800 text-xl">&gt;</button>
    </hyperkit-next-month>
  </div>
  <div class="grid grid-cols-7 gap-1 mb-2">
    <div class="text-center text-xs font-semibold text-zinc-600">M</div>
    <div class="text-center text-xs font-semibold text-zinc-600">T</div>
    <div class="text-center text-xs font-semibold text-zinc-600">W</div>
    <div class="text-center text-xs font-semibold text-zinc-600">T</div>
    <div class="text-center text-xs font-semibold text-zinc-600">F</div>
    <div class="text-center text-xs font-semibold text-zinc-600">S</div>
    <div class="text-center text-xs font-semibold text-zinc-600">S</div>
  </div>
  <hyperkit-days-list class="grid grid-cols-7 gap-1"></hyperkit-days-list>
  <template slot="day-number">
    <hyperkit-day-number>
      <button class="w-8 h-8 flex items-center justify-center rounded-full cursor-pointer text-xs hover:bg-zinc-100 focus:ring-1 focus:ring-lime-500 focus:bg-lime-200 transition-colors duration-200 data-[today]:bg-lime-600 text-zinc-800 data-[today]:text-white data-[selected]:bg-lime-200 data-[other-month]:text-zinc-400 disabled:text-zinc-400"></button>
    </hyperkit-day-number>
  </template>
</hyperkit-calendar>
Enter fullscreen mode Exit fullscreen mode

Top comments (0)