agentleFS
vekzz-devvekzz-dev/opencode-skills/skills/ui-components/SKILL.md

ui-components

Skill4 starsChanged 40 days agoMITView on GitHub

Pre-built UI component libraries for server-rendered HTML: Preline UI, HyperUI, Flowbite. Modals, tables, forms, navbars, dropdowns — no React, no build step. Trigger: UI components, component library, Preline, HyperUI, Flowbite, Tailwind CSS components, pre-built UI.

  • Installs packages

5 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

2 rules. 0 are common, 2 are distinctive, and 0 are very specific to this project.

  • 0

    Common

    Most of the 5 edited versions we read keep these.

  • 2

    Distinctive

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Recommendation: Start with Preline UI — best component coverage and zero friction with HTMX + Alpine.

    line 28
  2. Distinctive:

    After an HTMX swap, you must reinitialize:

    line 160

“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

When to Use

  • Building a web UI and need pre-made components (modals, tables, navbars, forms)
  • Want a decent-looking UI without writing CSS from scratch
  • Using Thymeleaf + HTMX + Alpine.js and need components that don't fight that stack

Instructions

Stack Fit

LibraryComponentsJSHTMXAlpineLicense
Preline UI640+ (modals, datatables, forms, nav, datepicker)Headless (replaceable)✅ Perfect✅ Drop-inMIT
HyperUI + HyperUX~200 + 9 Alpine patternsNone / Alpine-native✅ Perfect✅ Built with AlpineMIT
Flowbite56+ categories, charts, datatablesflowbite.js required⚠️ Needs reinit after swap⚠️ AdaptableMIT

Recommendation: Start with Preline UI — best component coverage and zero friction with HTMX + Alpine.

Preline UI — Integration

Setup:

<!-- In your Thymeleaf layout -->
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
  <!-- Preline JS (headless — optional, replace with Alpine) -->
  <script src="https://cdn.jsdelivr.net/npm/preline/dist/preline.js" defer></script>
  <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3/dist/cdn.min.js"></script>
</head>

Or with npm in a Spring Boot static resources setup:

npm install preline

Then in your Tailwind config:

module.exports = {
  content: [
    './src/main/resources/templates/**/*.html',
    './node_modules/preline/dist/*.js',
  ],
  plugins: [require('preline/plugin')],
}

Example — Modal with Alpine instead of Preline JS:

<!-- Preline HTML structure + Alpine for interactivity -->
<div x-data="{ open: false }">
  <button @click="open = true" type="button"
          class="py-2 px-4 bg-blue-600 text-white rounded-lg">
    Open Modal
  </button>
  <div x-show="open" x-cloak
       class="fixed inset-0 z-50 flex items-center justify-center">
    <div class="absolute inset-0 bg-black/50" @click="open = false"></div>
    <div class="relative bg-white rounded-xl shadow-lg p-6 max-w-md w-full">
      <h3 class="text-lg font-semibold">Modal Title</h3>
      <p class="mt-2 text-gray-600">Modal content here</p>
      <button @click="open = false" class="mt-4 px-4 py-2 bg-gray-200 rounded">Close</button>
    </div>
  </div>
</div>

Example — Table with HTMX:

<!-- Thymeleaf template -->
<div class="overflow-x-auto rounded-xl border">
  <table class="min-w-full divide-y divide-gray-200">
    <thead class="bg-gray-50">
      <tr>
        <th class="px-6 py-3 text-left text-sm font-medium text-gray-500">Name</th>
        <th class="px-6 py-3 text-left text-sm font-medium text-gray-500">Role</th>
        <th class="px-6 py-3 text-right text-sm font-medium text-gray-500">Actions</th>
      </tr>
    </thead>
    <tbody class="divide-y divide-gray-200" id="user-table">
      <tr th:each="user : ${users}"
          class="hover:bg-gray-50 transition"
          th:include="fragments/user-row :: row">
      </tr>
    </tbody>
  </table>
</div>

<!-- Delete button in fragment -->
<button hx-delete="@{/users/{id}(id=${user.id})}"
        hx-target="#user-table"
        hx-swap="outerHTML"
        hx-confirm="Delete this user?"
        class="text-red-600 hover:text-red-800 text-sm font-medium">
  Delete
</button>

HyperUI + HyperUX — Zero Friction

HyperUI is pure HTML + Tailwind — zero JavaScript. Copy and paste.

<!-- Alert from HyperUI (no JS) -->
<div class="rounded-xl border border-gray-100 bg-white p-4">
  <div class="flex items-start gap-4">
    <span class="text-green-600">
      <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
      </svg>
    </span>
    <div class="flex-1">
      <strong class="block font-medium text-gray-900"> Changes saved </strong>
      <p class="mt-1 text-sm text-gray-700">Your profile has been updated.</p>
    </div>
  </div>
</div>

HyperUX is its companion — built with Alpine.js for interactive components:

<!-- Dropdown from HyperUX -->
<div x-data="{ open: false }" class="relative">
  <button @click="open = !open"
          class="flex items-center gap-2 px-4 py-2 bg-white border rounded-lg">
    Options
    <svg x-bind:class="open && '-rotate-180'" class="w-4 h-4 transition">...</svg>
  </button>
  <div x-show="open" @click.outside="open = false"
       class="absolute right-0 mt-2 w-48 bg-white border rounded-lg shadow-lg py-1">
    <a href="#" class="block px-4 py-2 text-sm hover:bg-gray-50">Profile</a>
    <a href="#" class="block px-4 py-2 text-sm hover:bg-gray-50">Settings</a>
    <hr class="my-1">
    <a href="#" class="block px-4 py-2 text-sm text-red-600 hover:bg-red-50">Logout</a>
  </div>
</div>

Flowbite — If You Already Use It

Flowbite's JS hooks into data-modal-target, data-dropdown-toggle, etc. After an HTMX swap, you must reinitialize:

<script>
  document.addEventListener('htmx:afterSwap', function() {
    initFlowbite();  // reattach event listeners after HTMX updates the DOM
  });
</script>

Or skip flowbite.js entirely and use Alpine for the same components:

<!-- Flowbite card (no JS needed) -->
<div class="max-w-sm bg-white border border-gray-200 rounded-xl shadow-sm">
  <img class="rounded-t-xl" src="/img/photo.jpg" alt="">
  <div class="p-5">
    <h5 class="text-xl font-bold tracking-tight text-gray-900">Card title</h5>
    <p class="mt-2 text-gray-600">Card description here.</p>
    <a href="#" class="inline-flex mt-3 px-4 py-2 text-sm font-medium text-white bg-blue-700 rounded-lg hover:bg-blue-800">
      Read more
    </a>
  </div>
</div>

Decision Table

NeedLibrary
Maximum component varietyPreline UI
Zero JS dependency, pure HTMLHyperUI
Alpine-native interactive componentsHyperUX
Charts, datatables, datepickerPreline UI
Quick dashboard layoutFlowbite (templates) or Preline (blocks)

Anti-Patterns

  • Loading multiple component libraries — pick ONE; mixing Preline + Flowbite breaks class naming conventions
  • Adding jQuery for interactions you can do with Alpine — 80KB for something Alpine does in 8KB
  • Using a React component library (shadcn, MUI, Chakra) — they don't work with server-rendered HTML
  • Fighting the CDN — use npm + Tailwind config for proper purging in production

Commands

# Preline with npm (Spring Boot static resources)
npm install preline

# Tailwind config for Preline
npx tailwindcss init -p

Resources

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.