# UI Dev

MUST be used whenever the task involves UI development, renderer code changes, adding...

- Repository: https://github.com/elirantutia/vibeyard (1393 stars)
- Category: Design
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add elirantutia/vibeyard --skill ui-dev -g -a claude-code -y`
Codex: `npx skills add elirantutia/vibeyard --skill ui-dev -g -a codex -y`
Cursor: `npx skills add elirantutia/vibeyard --skill ui-dev -g -a cursor -y`
Gemini CLI: `npx skills add elirantutia/vibeyard --skill ui-dev -g -a gemini-cli -y`

## Description

This skill MUST be used whenever the task involves UI development, renderer code changes, adding or modifying components, creating modals or dialogs, working with CSS styles, building new UI features, or touching any file in src/renderer/. Use this skill when the user asks to "add a button", "create a modal", "add a dropdown", "update the sidebar", "style a component", "add a new UI feature", or any renderer/frontend work.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# UI Development Guide

This project uses **vanilla TypeScript DOM manipulation**, no framework. All UI lives in `src/renderer/`. Follow the patterns and reuse the components documented below.

## Custom Dropdown / Select

**Never use native `<select>`.** Always use the custom select component:

```typescript
import { createCustomSelect } from './components/custom-select';

const select = createCustomSelect('my-select', [
  { value: 'a', label: 'Option A' },
  { value: 'b', label: 'Option B' },
  { value: 'c', label: 'Disabled', disabled: true },
], 'a'); // default value

// select.getValue(), get current value
// select.destroy(), cleanup
```

- **File**: `src/renderer/components/custom-select.ts`
- **CSS classes**: `.custom-select`, `.custom-select-trigger`, `.custom-select-dropdown`, `.custom-select-item`
- Supports keyboard navigation (Arrow keys, Enter, Escape, Tab)

## Modals

Use `showModal()` for generic modals with form fields:

```typescript
import { showModal, closeModal, setModalError } from './components/modal';

showModal('My Title', [
  { id: 'name', label: 'Name', type: 'text', placeholder: 'Enter name' },
  { id: 'option', label: 'Option', type: 'select', options: [...] },
  { id: 'enabled', label: 'Enable feature', type: 'checkbox' },
], (values) => {
  // values is Record<string, string>
  if (!values.name) {
    setModalError('name', 'Name is required');
    return;
  }
  // ... handle confirm
  closeModal();
});
```

- **File**: `src/renderer/components/modal.ts`
- Exports: `showModal()`, `closeModal()`, `setModalError()`
- Supports field types: `text`, `checkbox`, `select` (uses custom select internally)
- Supports field buttons (e.g., a "Browse" button next to a text input)
- Keyboard: Enter to confirm, Escape to cancel

For specialized modals (complex layout, multi-pane, unique behavior), create a dedicated file in `src/renderer/components/` following the existing pattern (e.g., `preferences-modal.ts`, `usage-modal.ts`).

The rest: https://github.com/elirantutia/vibeyard/blob/HEAD/.claude/skills/ui-dev/SKILL.md
