> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qomicex.top/llms.txt
> Use this file to discover all available pages before exploring further.

# UI component library (.p-* styles)

## UI component library (.p-\* styles)

The launcher ships a built-in set of `.p-*` style components for plugins (`plugin-css.ts`). They are injected automatically into plugin pages and Overlay windows (Overlay window)and follow the light/dark theme. Plugins can use them without importing any CSS file.

## Theme variables

All colors are defined through CSS variables that follow the launcher's light/dark theme automatically:

```css theme={null}
--background  --foreground  --card  --card-foreground
--popover  --popover-foreground  --primary  --primary-foreground
--secondary  --secondary-foreground  --muted  --muted-foreground
--accent  --accent-foreground  --destructive  --destructive-foreground
--border  --input  --ring
```

Reference them in your plugin styles:

```css theme={null}
.my-box { color: hsl(var(--foreground)); border: 1px solid hsl(var(--border)); }
```

### How theme following works

* Plugin pages and Overlay windows **follow the launcher's light/dark theme automatically**: the launcher injects the current theme's CSS variables into the plugin environment (synced via the `__qomicex_theme` postMessage), so light/dark switches take effect immediately.
* The plugin `body` background is **transparent**, exposing the launcher background (the plugin container needs no background of its own; just use the CSS variables).
* Theme variables are available both in plugin pages (inline/sandbox) and in Overlay windows (iframe).

## Component list

### Card

```html theme={null}
<div class="p-card">
  <div class="p-card-title">Heading</div>
  <div class="p-card-desc">Description text</div>
  <div>Content...</div>
</div>
```

### Button

```html theme={null}
<button class="p-btn p-btn--primary">Primary</button>
<button class="p-btn p-btn--default">Default</button>
<button class="p-btn p-btn--ghost">Ghost</button>
<button class="p-btn p-btn--danger">Danger</button>
<button class="p-btn p-btn--outline">Outline</button>
<button class="p-btn p-btn--sm">Small</button>
```

Variants: `--primary` `--default` `--ghost` `--danger` `--outline`; size: `--sm`

### Input / Textarea

```html theme={null}
<label class="p-label">API address</label>
<input class="p-input" placeholder="Enter a value">
<textarea class="p-textarea"></textarea>
```

### Badge

```html theme={null}
<span class="p-badge p-badge--green">Success</span>
<span class="p-badge p-badge--red">Failed</span>
<span class="p-badge p-badge--yellow">Warning</span>
<span class="p-badge p-badge--blue">Info</span>
<span class="p-badge p-badge--default">Default</span>
```

### Tabs

```html theme={null}
<div class="p-tabs">
  <button class="p-tab active" data-p-tab="a">Tab A</button>
  <button class="p-tab" data-p-tab="b">Tab B</button>
</div>
<div class="p-panel active" id="panel-a">Content of A</div>
<div class="p-panel" id="panel-b">Content of B</div>
```

* `data-p-tab` points to a panel with `id="panel-{name}"`.
* Click-to-switch is handled automatically by the injected script; you do not need to write any JS.
* Supported in Overlay windows as well.

### Switch

```html theme={null}
<label class="p-swiper">
  <input type="checkbox" checked>
  <span class="p-swiper-track"></span>
  Enable feature
</label>
```

* In an Overlay window, to use a Switch to show or hide a panel, add `data-p-switch="panelId"` to the input and the script toggles the matching `id` element automatically.

### Checkbox

```html theme={null}
<label class="p-check-field">
  <input type="checkbox">
  Remember choice
</label>
```

### Progress

```html theme={null}
<div class="p-progress"><div class="p-progress__bar" style="width:60%"></div></div>
 (indeterminate progress)
<div class="p-progress"><div class="p-progress__bar p-progress__bar--indeterminate"></div></div>
```

Modifiers: `--indeterminate` indeterminate, `--danger` danger, `--warn` warning

### Spinner

```html theme={null}
<div class="p-loader"></div>
```

### Empty state

```html theme={null}
<div class="p-empty">
  <div class="p-empty__icon">📭</div>
  <div class="p-empty__text">No data</div>
</div>
```

### Alert

```html theme={null}
<div class="p-alert p-alert--info">Info</div>
<div class="p-alert p-alert--success">Success</div>
<div class="p-alert p-alert--warn">Warning</div>
<div class="p-alert p-alert--error">Error</div>
```

### Table

```html theme={null}
<table class="p-table">
  <tr><th>Name</th><th>Value</th></tr>
  <tr><td>Example</td><td>123</td></tr>
</table>
```

### Select

```html theme={null}
<div class="p-select">
  <select>
    <option>Option A</option>
    <option>Option B</option>
  </select>
</div>
```

### Menu

```html theme={null}
<div class="p-menu">
  <div class="p-menu-item">Normal item</div>
  <div class="p-menu-item p-menu-item--danger">Dangerous item</div>
</div>
```

### Tooltip

```html theme={null}
<span class="p-tooltip" data-tip="Tooltip text">Hover me</span>
```

### Color picker

```html theme={null}
<div class="p-color-picker"><span class="p-color-picker__swatch" style="background:#f00"></span> Color</div>
```

## Icons (React components)

Icons ship with the component library: **synchronous, zero IPC, tree-shakeable**. In React
plugins do not hand-roll SVGs, and do not wrap the `getIconSvg` bridge yourself.

### `<Glyph>` — per-icon static import (recommended)

```tsx theme={null}
import { Glyph } from '@qomicex/plugin-ui'
import { ServerIcon } from '@qomicex/plugin-ui/icons/server'
import { FolderOpenIcon } from '@qomicex/plugin-ui/icons/folder-open'

<Glyph icon={ServerIcon} className="h-4 w-4" />
```

* The subpath is the class name without the `fa-solid fa-` prefix; brand icons add `brand-`
  (`fa-brands fa-github` → `@qomicex/plugin-ui/icons/brand-github`)
* The export name is PascalCase + `Icon`
* The bundler keeps only the icons you import, and a wrong icon name **fails at build time**
  instead of reaching the runtime
* Filled with `currentColor`, so it follows the theme automatically; pass `label` for an
  accessible name

### `<Icon>` — when the icon name comes from runtime data

```tsx theme={null}
import { Icon } from '@qomicex/plugin-ui'

<Icon name={iconNameFromSettings} className="h-4 w-4" />
```

`name` is a runtime string the bundler cannot analyse, so the **entire icon table (\~160KB) is
lazily loaded as a separate chunk** — only downloaded when an `<Icon>` actually renders. Prefer
`<Glyph>` whenever the name is known at compile time.

Unknown names render `null` (no empty gap) and `console.warn` in dev builds.

### Discovering icons

```tsx theme={null}
import { ICON_NAMES, hasIcon } from '@qomicex/plugin-ui'

ICON_NAMES.includes('fa-solid fa-server')   // true
hasIcon('fa-solid fa-skull')                 // false
```

At runtime (including theme and plugin-private icons): `await __PLUGIN_API__.call('listIcons')`.
**Do not hardcode an icon list** — the built-in table evolves with the launcher, so
`listIcons()` / `ICON_NAMES` are the authoritative sources.

### Layout and utilities

```html theme={null}
<div class="p-row"><span>Horizontal row</span></div>
<div class="p-row p-row--between">Space between</div>
<div class="p-col">Vertical column</div>
```

* `.p-row` `--wrap` `--between`, `.p-col`
* `.p-icon` `--lg`, `.p-divider` `.p-hr` `.p-separator`, `.p-status-dot --up/--down/--warn`, `.p-pre`
* Spacing: `.p-mt-1/2/3` `.p-mb-1/2/3` `.p-gap-1/2/3`
* Text: `.p-text-center` `.p-text-muted` `.p-text-sm/xs/lg` `.p-font-mono`
* Other: `.p-ml-auto` `.p-truncate` `.p-rounded`

## Example

```html theme={null}
<div class="p-card">
  <div class="p-card-title">Download status</div>
  <div class="p-row p-row--between">
    <span>Installing</span>
    <span class="p-badge p-badge--blue">In progress</span>
  </div>
  <div class="p-progress"><div class="p-progress__bar" style="width:45%"></div></div>
  <div class="p-tabs" style="margin-top:12px">
    <button class="p-tab active" data-p-tab="log">Log</button>
    <button class="p-tab" data-p-tab="info">Details</button>
  </div>
  <div class="p-panel active" id="panel-log"><pre class="p-pre">Downloading...</pre></div>
  <div class="p-panel" id="panel-info">Version 1.2.0</div>
</div>
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.