# XUI

A tiny UI helpers library for userscripts / browser extensions. The first
function shipped is `XUI.notify` — a Shadow-DOM-isolated, dependency-free
toast for "task complete / failed" style messages.

> Other UI helpers (modal / popover / drawer / loading) will be added in
> subsequent changes. This document covers only `notify`.

## Features

- One global function, sync return, no setup: `XUI.notify(text, options?)`.
- Four semantic types: `info`, `success`, `warning`, `error`.
- Custom duration; `0` means sticky (auto-dismiss off).
- Multi-notification stacking — newer ones appear above older ones.
- Manual close via the returned `{ close() }` handle or the inline × button.
- Style isolation through Shadow DOM — host page CSS can't reach in,
  XUI's CSS can't leak out.
- Zero dependencies, no `@grant` needed, no build step.

## Install

```html
<!-- As a regular <script> tag in a userscript demo / extension page -->
<script src="./XUI.js"></script>
```

```js
// @require https://raw.githubusercontent.com/<user>/scriptcats/main/libs/XUI/XUI.js
// In a userscript that shares the same origin / CDN as this repo.
```

## API

### `XUI.notify(message, options?)`

Shows a notification in the top-right corner of the page.

| Option     | Type                                                   | Default   | Description                            |
| ---------- | ------------------------------------------------------ | --------- | -------------------------------------- |
| `type`     | `"info"` \| `"success"` \| `"warning"` \| `"error"`    | `"info"`  | Semantic type, controls accent color.  |
| `duration` | `number` (ms)                                          | `3000`    | Auto-dismiss delay; `0` keeps it sticky. |
| `closable` | `boolean`                                              | `true`    | Whether to render the × close button.   |

- Returns `{ close(): void }` — call to dismiss immediately.
- Unknown `type` values fall back to `"info"` (no throw).

## Example

```js
// Quick neutral hint
XUI.notify("Saved");

// Explicit success
XUI.notify("Upload complete", { type: "success" });

// Sticky, dismiss when the async work resolves
const h = XUI.notify("Uploading…", { duration: 0 });
uploadFile()
  .then(() => XUI.notify("Done", { type: "success" }))
  .finally(h.close);
```

## Demo

Open [`demo.html`](./demo.html) in any modern browser. It loads
`XUI.js` via a relative `<script>` and lets you fire all variants
without any userscript manager.

## Compatibility

Tested against Chrome + Tampermonkey, Firefox + Tampermonkey and ScriptCat
desktop. Requires `Element.prototype.attachShadow`, which is available in
all evergreen browsers (no fallback shipped).
