home / skills / joncrangle / .dotfiles / kobalte

This skill helps you implement accessible, headless Kobalte components in SolidJS, ensuring proper structure and focus management with portals and roots.

npx playbooks add skill joncrangle/.dotfiles --skill kobalte

Review the files below or copy the command above to add this skill to your agents.

Files (3)
SKILL.md
2.5 KB
---
name: kobalte
description: Specialist in Kobalte, a headless, accessible UI component library for SolidJS. Focuses on accessibility (ARIA), composability, and styling unstyled primitives.
---
<skill_doc>
<trigger_keywords>
## Trigger Keywords

Activate this skill when the user mentions any of:

**Core**: Kobalte, Headless UI, Unstyled components, Accessible UI, A11y

**Components**: Select, Combobox, Dialog, Popover, Toast, Tabs, Accordion, Tooltip, Menubar, DropdownMenu

**Concepts**: Portal, Trigger, Content, Root, Polymorphism (as prop)

**Styling**: data-attributes, data-expanded, data-disabled, @kobalte/tailwindcss
</trigger_keywords>

## ⛔ Forbidden Patterns

1.  **NO Built-in Styles**: Do NOT expect components to look "good" out of the box. They are unstyled. You MUST apply CSS/Tailwind classes.
2.  **NO Missing Portals**: Always use `<Component.Portal>` for overlays (Dialog, Popover, Tooltip, Select) to avoid z-index/clipping issues.
3.  **NO Manual ARIA**: Do NOT manually add `role`, `aria-expanded`, etc. Kobalte manages this.
4.  **NO Direct Input in Select**: Use `<Select>` for button-triggered lists. Use `<Combobox>` if you need a text input.
5.  **NO Skipping `Root`**: All parts must be nested within the `Root` component (or passed via Context).

## 🤖 Agent Tool Strategy

1.  **Styling Strategy**: Check if Tailwind is used. If so, recommend `@kobalte/tailwindcss` plugin for `ui-selected:` modifiers.
2.  **Composition**: Always show the full structure: `Root` -> `Trigger` -> `Portal` -> `Content`.
3.  **Accessibility**: Emphasize that Kobalte handles focus management and keyboard nav automatically.
4.  **Integration**: Kobalte works perfectly with `@opentui/solid` (if using standard DOM renderer) or web projects.

## Quick Reference (30 seconds)

Kobalte Specialist - Accessible, Headless Primitives for SolidJS.

**Philosophy**:
- **Headless**: Logic only. You bring the UI/CSS.
- **Accessible**: WAI-ARIA APG compliant out of the box.
- **Composable**: Build complex UIs from granular parts.

**Styling via Data Attributes**:
- `[data-expanded]`: Component is open.
- `[data-selected]`: Item is active.
- `[data-disabled]`: Component is inactive.
- `[data-highlighted]`: Item is focused via keyboard.

**Anatomy**:
1.  **Root**: State container.
2.  **Trigger**: Toggle button.
3.  **Portal**: Renders overlay at body root.
4.  **Content**: The actual popup/panel.

---

## Resources

- **Examples**: See `examples/examples.md` for detailed code patterns.
- **References**: See `references/reference.md` for official documentation links.
</skill_doc>

Overview

This skill is a Kobalte specialist for SolidJS that guides building accessible, headless UI components. It explains correct component anatomy, accessibility guarantees, and styling strategies so you can compose unstyled primitives into production-ready UI. The guidance focuses on practical patterns, Tailwind integration, and common pitfalls to avoid.

How this skill works

I inspect your component usage and recommend a complete composition pattern: Root -> Trigger -> Portal -> Content (and nested parts like Item, Label, or Arrow). I check for accessibility mistakes you might introduce and point out where Kobalte already manages ARIA and keyboard behavior. I also detect styling approach (plain CSS vs Tailwind) and suggest the @kobalte/tailwindcss plugin when appropriate.

When to use it

  • When you need fully controllable, unstyled UI primitives for SolidJS
  • When accessibility, keyboard navigation, and ARIA compliance are required
  • When you want composable building blocks for complex widgets (selects, dialogs, menus)
  • When using overlays that must avoid z-index or clipping issues
  • When you prefer logic-first components and provide your own visual design

Best practices

  • Always nest parts inside the Root or provide context; don’t skip Root
  • Use Component.Portal for overlays (Dialog, Popover, Tooltip, Select) to avoid clipping and z-index issues
  • Do NOT add manual role/aria attributes; Kobalte manages ARIA and focus for you
  • Choose Select for button-triggered lists and Combobox for text-input-driven lists
  • If using Tailwind, install @kobalte/tailwindcss to access ui-selected and other data-attribute modifiers

Example use cases

  • Accessible dropdown menu using Root -> Trigger -> Portal -> Content with keyboard support
  • Custom-styled Select controlled by state and styled with Tailwind using data-selected and data-expanded attributes
  • Dialog with portal rendering at body root to avoid clipping in complex layouts
  • Combobox for typeahead search with keyboard highlight and managed ARIA
  • Tooltip or Popover implemented as Portal overlays with focus/escape handling provided automatically

FAQ

Do I need to add ARIA attributes manually?

No. Kobalte handles ARIA, roles, and keyboard interactions. Avoid adding manual aria-* or role attributes unless you have a specific advanced case.

When should I use Select vs Combobox?

Use Select when the trigger is a button and you don’t need free text input. Use Combobox when you need a text input for filtering or free typing.