# ⚡ Neon Design System
**Slint UI component library for Rust desktop apps.** 35+ components, dark/light theme runtime switch, neon accents, glass surfaces.
[](#-license)
[](https://slint.dev)
[](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+)
| **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
| `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)
| `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).