# ⚡ Neon Design System

**Slint UI component library for Rust desktop apps.** 35+ components, dark/light theme runtime switch, neon accents, glass surfaces.

[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue)](#-license)
[![Slint](https://img.shields.io/badge/Slint-1.9%2B-purple)](https://slint.dev)
[![Rust](https://img.shields.io/badge/rust-1.75%2B-orange)](https://www.rust-lang.org/)

Built for infrastructure / monitoring / data dashboards. Pure Slint widgets — no GPUI, no nightly Rust, no native fork. Drops into any Slint 1.9+ project.

---

## Quick start (consumer app)

### 1. Add the dependency in **both** `[dependencies]` and `[build-dependencies]`

```toml
[dependencies]
slint = "1.9"
slint-ui-system = { git = "https://github.com/wilmercampagna/slint-ui-system" }

[build-dependencies]
slint-build = "1.9"
slint-ui-system = { git = "https://github.com/wilmercampagna/slint-ui-system" }
```

The build script needs the lib at build-time to read `SLINT_LIBRARY_PATH`; the runtime side gets the Rust helpers.

### 2. Wire `build.rs`

```rust
use slint_build::CompilerConfiguration;

fn main() {
    let neon = format!("{}/index.slint",
                       slint_ui_system::SLINT_LIBRARY_PATH);
    let cfg = CompilerConfiguration::new()
        .with_library_paths(
            [("neon".to_string(), neon.into())]
                .into_iter().collect()
        );
    slint_build::compile_with_config("ui/app.slint", cfg).unwrap();
}
```

### 3. Import components in your `.slint`

```slint
import {
    Theme,
    NeonButton, PrimaryNeonButton,
    NeonCard, NeonH2, NeonBody,
    NeonHStack, NeonVStack, NeonToggle,
} from "@neon";

// Re-export Theme so the Rust side can flip dark/light at runtime.
export { Theme } from "@neon";

export component AppWindow inherits Window {
    title: "My app";
    background: Theme.bg-base;

    NeonVStack {
        NeonH2 { text: "⚡ Hello Neon"; color: Theme.neon-cyan; }
        NeonCard {
            title: "Welcome";
            NeonBody { text: "35+ components, dark/light runtime switch."; }
        }
        PrimaryNeonButton {
            text: "Click me";
            clicked => { /* … */ }
        }
    }
}
```

### 4. Wire Rust

```rust
use slint::ComponentHandle;
slint::include_modules!();

// One-liner that hooks Theme into Neon's runtime helpers.
slint_ui_system::impl_theme_access!(AppWindow, Theme);

fn main() -> Result<(), slint::PlatformError> {
    let win = AppWindow::new()?;
    slint_ui_system::theme::set_dark_mode(&win, true);
    win.run()
}
```

That's the entire integration. Full working code in [`examples/simple/`](examples/simple/) — clone + `cargo run -p neon-example-simple`.

---

## Components (35+)

| Category | Components | File |
|----------|-----------|------|
| **Buttons** | Outline, Primary, Ghost, Danger, Icon | [`button.slint`](ui/components/button.slint) |
| **Inputs** | Text, Search, TextArea | [`input.slint`](ui/components/input.slint) |
| **Cards** | Card, Section, InfoCard | [`card.slint`](ui/components/card.slint) |
| **Modals** | Modal, Drawer, ConfirmDialog | [`modal.slint`](ui/components/modal.slint) |
| **Floating Panel** ⭐ | FloatingPanel (drag + resize + persist) | [`floating_panel.slint`](ui/components/floating_panel.slint) |
| **Context Menu** ⭐ | ContextMenu, ContextMenuItem | [`context_menu.slint`](ui/components/context_menu.slint) |
| **Navigation** | Sidebar, TopBar, Tabs | [`nav.slint`](ui/components/nav.slint) |
| **Toggles** | Toggle, Checkbox, RadioGroup | [`toggle.slint`](ui/components/toggle.slint) |
| **Sliders** | Slider, ProgressBar, Spinner | [`slider.slint`](ui/components/slider.slint) |
| **Badges** | Badge, Tag, CountBadge, StatusDot | [`badge.slint`](ui/components/badge.slint) |
| **Lists & Tables** | ListItem, ListGroup, DataTable | [`list.slint`](ui/components/list.slint) |
| **Virtual Table** ⭐ | VirtualTable (ListView-based) | [`virtual_table.slint`](ui/components/virtual_table.slint) |
| **Charts** | BarChart, LineChart | [`chart.slint`](ui/components/chart.slint) |
| **Charts Extra** ⭐ | Sparkline, AreaChart, ScatterChart, PieChart, StackedBar | [`charts_extra.slint`](ui/components/charts_extra.slint) |
| **Form** | Select, DatePicker | [`form.slint`](ui/components/form.slint) |
| **Combobox** ⭐ | Combobox (filterable Select) | [`combobox.slint`](ui/components/combobox.slint) |
| **Date Range** ⭐ | DateRangePicker | [`date_range_picker.slint`](ui/components/date_range_picker.slint) |
| **Form Validation** ⭐ | FormField, FormGroup, FormSummary, FormSubmit | [`form_validation.slint`](ui/components/form_validation.slint) |
| **Tree** | TreeView (hierarchical) | [`tree.slint`](ui/components/tree.slint) |
| **Color Picker** | HSV picker (RGB/hex outputs) | [`color-picker.slint`](ui/components/color-picker.slint) |
| **Skeleton** ⭐ | Skeleton (shimmer + variants), SkeletonText, SkeletonGate | [`skeleton.slint`](ui/components/skeleton.slint) |
| **Utility** | Tooltip, Dropdown, Pagination, Breadcrumbs, SplitView, Splitter handles, Notification, ToastQueue | various |
| **Advanced** | Accordion, Steps, Tabs (standalone), EmptyState, ProgressCircular | [`advanced.slint`](ui/components/advanced.slint) |
| **Icons** | 57 SVG icons with `colorize` support | [`icons.slint`](ui/components/icons.slint) |

⭐ = nuevo en v0.4.0. See [`docs/CHANGELOG.md`](docs/CHANGELOG.md).

---

## Theme

- **Dark** (default): deep navy base (`#0a0e17`) with cyan / magenta / green neon accents.
- **Light**: cool pearl (`#f2f5fa`) with darkened neons for readability.
- Runtime switch — every token reads `dark-mode ? X : ThemeLight.X` so flipping `Theme.dark-mode` re-tints the entire UI instantly.
- Tokens: 9 surfaces, 4 borders, 4 text levels, 6 accents (+ 4 glow), 10 spacings (4 px grid), 5 radii, 7 font sizes, 10+ animation durations.
- Full reference: [`docs/theme-tokens.md`](docs/theme-tokens.md).

---

## Project layout

```
slintUiSystem/
├── src/
│   ├── lib.rs            # Public Rust API (re-exports + SLINT_LIBRARY_PATH)
│   ├── main.rs           # Demo binary (consumes its own lib)
│   ├── theme.rs          # set_dark_mode / is_dark_mode / toggle helpers + impl_theme_access! macro
│   ├── bridge.rs         # neon_ui_setup! macro + integration docs
│   └── color.rs          # parse_hex / format_rgb(a) / to_slint_color
├── ui/                   # The Slint library — consumers import from here via @neon
│   ├── index.slint       # Re-export hub. The `@neon` library entry point.
│   ├── theme.slint       # Dark + Light theme tokens (single global, runtime switch)
│   ├── theme_light.slint # Light constants
│   ├── demo.slint        # Demo's own UI
│   ├── components/       # 30+ component .slint files
│   ├── layouts/          # App shell + stack helpers
│   └── icons/            # 57 SVG icons (currentColor)
├── examples/
│   └── simple/           # Minimal consumer template — copy this for new projects
└── docs/
    ├── index.html        # Interactive documentation
    ├── component-api.md  # Property tables for every component
    ├── theme-tokens.md   # Token reference
    └── CHANGELOG.md
```

---

## Rust API

| Symbol | Kind | Description |
|---|---|---|
| `slint_ui_system::SLINT_LIBRARY_PATH` | `const &str` | Absolute path to `ui/` for `build.rs` setup. |
| `slint_ui_system::theme::set_dark_mode(&win, bool)` | fn | Apply dark/light at runtime. |
| `slint_ui_system::theme::is_dark_mode(&win) -> bool` | fn | Read current flag. |
| `slint_ui_system::theme::toggle(&win)` | fn | Flip current. |
| `slint_ui_system::impl_theme_access!(Window, Theme)` | macro | Wire your generated window + Theme types into the helpers above. |
| `slint_ui_system::neon_ui_setup!(Window, Theme, dark = true)` | macro | One-shot: `Window::new()` + initial dark flag. |
| `slint_ui_system::color::parse_hex("#ff0080")` | fn | `Result<(u8,u8,u8,u8), HexError>`. |
| `slint_ui_system::color::format_rgb(r, g, b)` | fn | `String` → `"#rrggbb"`. |
| `slint_ui_system::color::to_slint_color(r, g, b, a)` | fn | `(u8,u8,u8,u8)` → `slint::Color`. |

Detailed docs: `cargo doc --open` or [docs.rs/slint-ui-system](https://docs.rs/slint-ui-system).

---

## Run the demo

```bash
git clone https://github.com/wilmercampagna/slint-ui-system.git
cd slint-ui-system
cargo run                           # interactive component browser
cargo run -p neon-example-simple    # minimal consumer template
```

The demo is itself a consumer of the lib — `src/main.rs` is a great reference for the canonical wiring.

---

## Documentation

- Interactive HTML docs: open `docs/index.html` in a browser.
- Component API tables: [`docs/component-api.md`](docs/component-api.md).
- Theme tokens: [`docs/theme-tokens.md`](docs/theme-tokens.md).
- Changelog: [`docs/CHANGELOG.md`](docs/CHANGELOG.md).
- Contributing: [`CONTRIBUTING.md`](CONTRIBUTING.md).

---

## Keyboard shortcuts (in the demo)

| Key | Action |
|-----|--------|
| `Esc` | Close modals / drawers / toasts |
| `←` / `→` | Previous / next tab |

---

## Build & test

```bash
cargo build           # Build lib + demo bin
cargo test            # Run unit tests (color parsing, library path, …)
cargo run             # Open the demo
cargo run -p neon-example-simple   # Open the simple consumer example
cargo doc --open      # Render the Rust API docs
```

---

## License

Dual-licensed under either of:

- [MIT License](LICENSE-MIT)
- [Apache License, Version 2.0](LICENSE-APACHE)

at your option.

Contributions are accepted under the same dual license — see [`CONTRIBUTING.md`](CONTRIBUTING.md).
