Some checks are pending
Documentation Lint & Validation / Markdown Linting (push) Waiting to run
Documentation Lint & Validation / Validate mdBook Configuration (push) Waiting to run
Documentation Lint & Validation / Content & Structure Validation (push) Waiting to run
Documentation Lint & Validation / Lint & Validation Summary (push) Blocked by required conditions
mdBook Build & Deploy / Build mdBook (push) Waiting to run
mdBook Build & Deploy / Documentation Quality Check (push) Blocked by required conditions
mdBook Build & Deploy / Deploy to GitHub Pages (push) Blocked by required conditions
mdBook Build & Deploy / Notification (push) Blocked by required conditions
Rust CI / Security Audit (push) Waiting to run
Rust CI / Check + Test + Lint (nightly) (push) Waiting to run
Rust CI / Check + Test + Lint (stable) (push) Waiting to run
281 lines
8.2 KiB
Markdown
281 lines
8.2 KiB
Markdown
# vapora-leptos-ui
|
|
|
|
Glassmorphism UI component library for Leptos 0.8.15+
|
|
|
|
**Status**: Functional with core components implemented. Suitable for internal use and projects willing to contribute.
|
|
|
|
## Features
|
|
|
|
- 🎨 **Glassmorphism design** - Cyan/purple/pink gradients with backdrop blur
|
|
- 🔄 **CSR/SSR agnostic** - Components work in both client-side and server-side rendering contexts
|
|
- ♿ **Accessible** - ARIA labels, keyboard navigation (Modal), focus management (Modal)
|
|
- 📱 **Mobile responsive** - Tailwind-based responsive utilities
|
|
- 🎯 **UnoCSS compatible** - Works with build-time CSS generation
|
|
- 🧩 **Reusable** - Can be used in any Leptos 0.8+ project
|
|
|
|
## Installation
|
|
|
|
```toml
|
|
[dependencies]
|
|
vapora-leptos-ui = { path = "../vapora-leptos-ui" }
|
|
leptos = "0.8.15"
|
|
```
|
|
|
|
**Note**: Not yet published to crates.io. Use as a path dependency or git dependency.
|
|
|
|
## Quick Start
|
|
|
|
```rust
|
|
use leptos::prelude::*;
|
|
use vapora_leptos_ui::{Button, Input, Spinner, Variant, Size};
|
|
|
|
#[component]
|
|
fn App() -> impl IntoView {
|
|
view! {
|
|
<div class="p-6 space-y-4">
|
|
<Button variant=Variant::Primary size=Size::Large>
|
|
"Create Project"
|
|
</Button>
|
|
|
|
<Input
|
|
input_type="text"
|
|
placeholder="Enter your name..."
|
|
on_input=Callback::new(|_ev| {
|
|
// Handle input
|
|
})
|
|
/>
|
|
|
|
<Spinner size=Size::Medium />
|
|
</div>
|
|
}
|
|
}
|
|
```
|
|
|
|
## Available Components
|
|
|
|
### ✅ Primitives (Fully Functional)
|
|
|
|
| Component | Description | Variants | Status |
|
|
|-----------|-------------|----------|--------|
|
|
| **Button** | Glassmorphism button | Primary, Secondary, Danger, Ghost | ✅ Complete |
|
|
| **Input** | Text input field | N/A | ✅ Complete |
|
|
| **Badge** | Status badge | Custom classes | ✅ Complete |
|
|
| **Spinner** | Loading animation | Small, Medium, Large | ✅ Complete |
|
|
|
|
### ✅ Layout (Fully Functional)
|
|
|
|
| Component | Description | Features | Status |
|
|
|-----------|-------------|----------|--------|
|
|
| **Card** | Container card | Glassmorphism, hoverable, glow colors | ✅ Complete |
|
|
| **Modal** | Dialog overlay | Portal, keyboard (Escape), focus trap, backdrop click | ✅ Complete |
|
|
|
|
### ✅ Data (Fully Functional)
|
|
|
|
| Component | Description | Features | Status |
|
|
|-----------|-------------|----------|--------|
|
|
| **Table** | Data table | Internal sorting, sortable columns | ✅ Complete |
|
|
| **Pagination** | Page controls | Current page, total pages, callbacks | ✅ Complete |
|
|
| **StatCard** | Metric display | Label, value, optional trend | ✅ Complete |
|
|
|
|
### ✅ Forms (Fully Functional)
|
|
|
|
| Component | Description | Features | Status |
|
|
|-----------|-------------|----------|--------|
|
|
| **FormField** | Form wrapper | Label, error display, help text, required indicator | ✅ Complete |
|
|
| **Validation** | Helper functions | `validate_required`, `validate_email`, `validate_min_length`, `validate_max_length` | ✅ Complete |
|
|
|
|
### ✅ Feedback (Fully Functional)
|
|
|
|
| Component | Description | Features | Status |
|
|
|-----------|-------------|----------|--------|
|
|
| **ToastProvider** | Toast context | Global notifications, auto-dismiss (3s) | ✅ Complete |
|
|
| **use_toast()** | Toast hook | Show success/error/info toasts | ✅ Complete |
|
|
|
|
### ✅ Navigation (Fully Functional)
|
|
|
|
| Component | Description | Features | Status |
|
|
|-----------|-------------|----------|--------|
|
|
| **SpaLink** | Client-side link | No page reload, external link detection | ✅ Complete |
|
|
|
|
### 🔧 Utilities
|
|
|
|
| Component | Description | Status |
|
|
|-----------|-------------|--------|
|
|
| **Portal** | DOM portal | ✅ Complete (used by Modal) |
|
|
|
|
## Theme System
|
|
|
|
```rust
|
|
use vapora_leptos_ui::{Variant, Size, BlurLevel, GlowColor};
|
|
|
|
// Visual variants
|
|
Variant::Primary // Cyan-purple gradient
|
|
Variant::Secondary // Transparent with border
|
|
Variant::Danger // Red gradient
|
|
Variant::Ghost // Subtle hover
|
|
|
|
// Size variants
|
|
Size::Small // px-3 py-1.5 text-sm
|
|
Size::Medium // px-4 py-2 text-base (default)
|
|
Size::Large // px-6 py-3 text-lg
|
|
|
|
// Backdrop blur levels
|
|
BlurLevel::None, Sm, Md, Lg, Xl
|
|
|
|
// Glow colors (for Card)
|
|
GlowColor::None, Cyan, Purple, Pink, Blue
|
|
```
|
|
|
|
## Examples
|
|
|
|
See [cookbook.md](./cookbook.md) for comprehensive examples of each component.
|
|
|
|
### Modal with Form
|
|
|
|
```rust
|
|
use vapora_leptos_ui::{Modal, FormField, Input, Button};
|
|
|
|
#[component]
|
|
fn CreateProject() -> impl IntoView {
|
|
let (show_modal, set_show_modal) = signal(false);
|
|
let (title, set_title) = signal(String::new());
|
|
|
|
view! {
|
|
<Button on_click=Callback::new(move |_| set_show_modal.set(true))>
|
|
"New Project"
|
|
</Button>
|
|
|
|
<Show when=move || show_modal.get()>
|
|
<Modal on_close=Callback::new(move |_| set_show_modal.set(false))>
|
|
<h2 class="text-2xl font-bold text-white mb-4">"Create Project"</h2>
|
|
<FormField label="Title".to_string() required=true>
|
|
<Input
|
|
placeholder="Project name"
|
|
on_input=Callback::new(move |ev| {
|
|
// Extract value from event
|
|
set_title.set(event_target_value(&ev));
|
|
})
|
|
/>
|
|
</FormField>
|
|
</Modal>
|
|
</Show>
|
|
}
|
|
}
|
|
```
|
|
|
|
### Table with Pagination
|
|
|
|
```rust
|
|
use vapora_leptos_ui::{Table, TableColumn, Pagination};
|
|
|
|
#[component]
|
|
fn DataTable() -> impl IntoView {
|
|
let (current_page, set_current_page) = signal(1usize);
|
|
let items_per_page = 10;
|
|
|
|
let columns = vec![
|
|
TableColumn::new("Name", "name").sortable(),
|
|
TableColumn::new("Status", "status").sortable(),
|
|
TableColumn::new("Date", "date"),
|
|
];
|
|
|
|
// Paginate data
|
|
let total_pages = data.len().div_ceil(items_per_page);
|
|
let paginated_data = /* slice data for current page */;
|
|
|
|
view! {
|
|
<Table columns=columns rows=paginated_data />
|
|
|
|
{move || if total_pages > 1 {
|
|
view! {
|
|
<Pagination
|
|
current_page=current_page.get()
|
|
total_pages=total_pages
|
|
on_page_change=Callback::new(move |page| {
|
|
set_current_page.set(page);
|
|
})
|
|
/>
|
|
}
|
|
} else {
|
|
view! { <div /> }
|
|
}}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Architecture
|
|
|
|
This library follows the **Rustelo pattern** for CSR/SSR agnostic components:
|
|
|
|
```
|
|
component/
|
|
├── mod.rs # Module exports
|
|
├── unified.rs # Public API (delegates to client/ssr)
|
|
├── client.rs # WASM/interactive implementation
|
|
└── ssr.rs # Server-side static implementation
|
|
```
|
|
|
|
Components automatically select the correct implementation:
|
|
|
|
- **WASM target (`wasm32-unknown-unknown`)**: Uses `client.rs` with full interactivity
|
|
- **Non-WASM target**: Uses `ssr.rs` for static server-side rendering
|
|
|
|
## Known Limitations
|
|
|
|
See [limitations.md](./limitations.md) for detailed list of known issues and missing features.
|
|
|
|
**Summary:**
|
|
|
|
- No i18n support yet
|
|
- Table sorting is client-side only (no server-side sorting)
|
|
- Toast auto-dismiss timing is fixed (3 seconds)
|
|
- Input is uncontrolled (no `value` prop)
|
|
- No Select, Textarea, Checkbox, Radio components yet
|
|
- No Dialog, ConfirmDialog components yet
|
|
|
|
## Development
|
|
|
|
```bash
|
|
# Build component library (WASM target)
|
|
cargo build -p vapora-leptos-ui --target wasm32-unknown-unknown
|
|
|
|
# Run clippy (strict mode)
|
|
cargo clippy -p vapora-leptos-ui --target wasm32-unknown-unknown -- -D warnings
|
|
|
|
# Format code
|
|
cargo fmt -p vapora-leptos-ui
|
|
```
|
|
|
|
## Contributing
|
|
|
|
This library is under active development. Contributions welcome:
|
|
|
|
1. Check [limitations.md](./limitations.md) for missing features
|
|
2. Follow existing component patterns (unified/client/ssr)
|
|
3. Ensure clippy passes with `-D warnings`
|
|
4. Add examples to [cookbook.md](./cookbook.md)
|
|
|
|
## License
|
|
|
|
Licensed under either of:
|
|
|
|
- Apache License, Version 2.0
|
|
- MIT License
|
|
|
|
at your option.
|
|
|
|
## Version
|
|
|
|
Current version: 1.2.0
|
|
|
|
Compatible with:
|
|
|
|
- Leptos 0.8.15
|
|
- Rust 1.75+
|
|
- UnoCSS 0.63+
|
|
|
|
**Changelog:**
|
|
|
|
- **1.2.0** (2026-02-08): Core components complete (Button, Input, Table, Modal, Pagination, FormField, Toast, Card, Badge, Spinner, SpaLink, Portal)
|
|
- **1.0.0** (2026-01-11): Initial release
|