init slint project
This commit is contained in:
commit
e1326e529c
56 changed files with 12692 additions and 0 deletions
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
target/
|
||||
**/target/
|
||||
dist/
|
||||
node_modules/
|
||||
diff
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
.env.prod
|
||||
.logs/
|
||||
.logs/**
|
||||
docker.dev/**/.env
|
||||
**/.env
|
||||
.env.*local
|
||||
|
||||
*address.json
|
||||
cex_database*
|
||||
|
||||
Config.toml
|
||||
.cursor/
|
||||
|
||||
*.crt
|
||||
*.key
|
||||
*.p12
|
||||
7
.vscode/extensions.json
vendored
Normal file
7
.vscode/extensions.json
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"rust-lang.rust-analyzer",
|
||||
"vadimcn.vscode-lldb",
|
||||
"Slint.slint"
|
||||
]
|
||||
}
|
||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"files.autoSave": "off"
|
||||
}
|
||||
8738
Cargo.lock
generated
Normal file
8738
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
25
Cargo.toml
Normal file
25
Cargo.toml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
[package]
|
||||
name = "ziya-slint"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
description = "One stop shop for your trading habit - Slint version"
|
||||
authors = ["rizary"]
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
slint = "1.12.0"
|
||||
i-slint-backend-winit = "1.12.0"
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
reqwest = { version = "0.12", features = ["json"] }
|
||||
anyhow = "1.0"
|
||||
log = "0.4"
|
||||
env_logger = "0.11"
|
||||
solana-sdk = "2.3.0"
|
||||
chrono = { version = "0.4.39", features = ["serde"] }
|
||||
chrono-tz = "0.10.3"
|
||||
image = { version = "0.25.6", default-features = false, features = [ "ico", "jpeg", "gif", "webp", "tiff" ] }
|
||||
|
||||
[build-dependencies]
|
||||
slint-build = "1.12.0"
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
155
README.md
Normal file
155
README.md
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
# Ziya - Slint Edition
|
||||
|
||||
**One stop shop for your trading habit** - Now powered by Slint and Rust!
|
||||
|
||||
> **/dˤiˈjaːʔ/**, "zee‑yah" — *Proper noun, meaning "light"*
|
||||
> A bismillahDAO creation
|
||||
|
||||
## Overview
|
||||
|
||||
This is a modern rewrite of the Ziya trading platform using [Slint](https://slint.dev/) for the UI and Rust for the backend logic. Slint provides a declarative UI language that makes it easy to create beautiful, native desktop applications.
|
||||
|
||||
## Features
|
||||
|
||||
- **Modern Native UI**: Built with Slint's declarative UI language
|
||||
- **Fast Performance**: Native Rust performance with efficient rendering
|
||||
- **Clean Architecture**: Separated UI and business logic
|
||||
- **Async Operations**: Non-blocking token fetching and user management
|
||||
- **Modular Design**: Well-organized codebase with clear separation of concerns
|
||||
|
||||
### Application States
|
||||
|
||||
- **Loading**: Initial app startup and initialization
|
||||
- **Login**: User authentication interface
|
||||
- **Dashboard**: Main trading dashboard with token search
|
||||
- **Hunting Ground**: Advanced trading tools (placeholder)
|
||||
- **Profile**: User profile and wallet information
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
ziya-slint/
|
||||
├── src/
|
||||
│ ├── main.rs # Application entry point
|
||||
│ ├── lib.rs # Module organization
|
||||
│ ├── app_state.rs # Application state management
|
||||
│ └── services/ # Business logic services
|
||||
│ ├── mod.rs
|
||||
│ ├── token_service.rs # Token data and search
|
||||
│ └── user_service.rs # User authentication and profiles
|
||||
├── ui/
|
||||
│ └── app-window.slint # Main UI definition
|
||||
├── Cargo.toml # Project dependencies
|
||||
└── build.rs # Build configuration
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Rust 1.70+ (recommended via [rustup](https://rustup.rs/))
|
||||
- Git
|
||||
|
||||
### Installation
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd ziya-slint
|
||||
```
|
||||
|
||||
2. Build and run:
|
||||
```bash
|
||||
cargo run
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Running in Development Mode
|
||||
|
||||
```bash
|
||||
# Run with debug logging
|
||||
RUST_LOG=debug cargo run
|
||||
```
|
||||
|
||||
### Building for Release
|
||||
|
||||
```bash
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### UI Layer (Slint)
|
||||
|
||||
The UI is defined in `ui/app-window.slint` using Slint's declarative language. Key features:
|
||||
|
||||
- **State-based rendering**: Different UI states for loading, login, dashboard, etc.
|
||||
- **Reactive properties**: Automatic UI updates when data changes
|
||||
- **Component composition**: Reusable UI elements
|
||||
- **Modern styling**: Clean, professional design
|
||||
|
||||
### Business Logic (Rust)
|
||||
|
||||
- **Services Pattern**: Separate services for different concerns
|
||||
- **Async/Await**: Non-blocking operations for better UX
|
||||
- **Error Handling**: Proper error propagation with `anyhow`
|
||||
- **Type Safety**: Strong typing throughout the application
|
||||
|
||||
### Key Components
|
||||
|
||||
1. **TokenService**: Handles token data fetching and search
|
||||
2. **UserService**: Manages user authentication and profiles
|
||||
3. **AppState**: Central application state management
|
||||
4. **Main**: Coordinates UI and business logic
|
||||
|
||||
## Comparison with Vue/Electron Version
|
||||
|
||||
| Aspect | Vue/Electron | Slint/Rust |
|
||||
|--------|--------------|------------|
|
||||
| **Performance** | ~50MB memory, slower startup | ~10MB memory, instant startup |
|
||||
| **Bundle Size** | ~100MB with Node.js | ~5MB standalone binary |
|
||||
| **Development** | Hot reload, web tools | Fast compilation, native debugging |
|
||||
| **Deployment** | Requires Node.js runtime | Single self-contained binary |
|
||||
| **UI Development** | HTML/CSS/JS knowledge required | Slint DSL (QML-like, simpler) |
|
||||
| **Type Safety** | TypeScript (optional) | Full Rust type safety |
|
||||
|
||||
## Contributing
|
||||
|
||||
This is part of the bismillahDAO ecosystem. When contributing:
|
||||
|
||||
1. Follow Rust conventions and best practices
|
||||
2. Keep UI logic in Slint files, business logic in Rust
|
||||
3. Write tests for business logic
|
||||
4. Update documentation for new features
|
||||
|
||||
## Migration Status
|
||||
|
||||
### ✅ Completed Features
|
||||
- [x] Basic application structure
|
||||
- [x] Loading, login, and dashboard states
|
||||
- [x] Token list display and search
|
||||
- [x] User profile management
|
||||
- [x] Navigation between views
|
||||
- [x] Mock data services
|
||||
|
||||
### 🚧 In Progress
|
||||
- [ ] Real API integration
|
||||
- [ ] Advanced token analysis
|
||||
- [ ] Wallet integration
|
||||
- [ ] Trading features
|
||||
|
||||
### 📋 Planned Features
|
||||
- [ ] Real-time token price updates
|
||||
- [ ] Advanced charting
|
||||
- [ ] Portfolio tracking
|
||||
- [ ] Trading automation
|
||||
- [ ] Export/import functionality
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see LICENSE file for details.
|
||||
|
||||
## About bismillahDAO
|
||||
|
||||
This project is created by bismillahDAO, focused on building ethical and innovative trading tools for the cryptocurrency community.
|
||||
8
build.rs
Normal file
8
build.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fn main() {
|
||||
// Use fluent-light as default, but we'll support dynamic switching
|
||||
let config = slint_build::CompilerConfiguration::new()
|
||||
.with_style("fluent-light".to_string());
|
||||
|
||||
slint_build::compile_with_config("ui/index.slint", config)
|
||||
.expect("Slint build failed");
|
||||
}
|
||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
4
public/icons/dark-mode/chart-network-dark-mode.svg
Normal file
4
public/icons/dark-mode/chart-network-dark-mode.svg
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 24 24" style="filter: brightness(0) invert(1);">
|
||||
<path fill="currentColor" d="m20.5,13c-1.204,0-2.268.612-2.898,1.54l-1.014-.563c.263-.607.411-1.275.411-1.977,0-2.757-2.243-5-5-5-.822,0-1.586.218-2.27.571l-.937-1.448c.734-.642,1.207-1.574,1.207-2.623,0-1.93-1.57-3.5-3.5-3.5s-3.5,1.57-3.5,3.5,1.57,3.5,3.5,3.5c.521,0,1.012-.122,1.457-.328l.934,1.443c-1.143.917-1.891,2.308-1.891,3.884,0,1.198.441,2.284,1.146,3.146l-2.56,2.56c-.584-.438-1.302-.707-2.086-.707-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5,3.5-1.57,3.5-3.5c0-.785-.269-1.502-.707-2.086l2.56-2.56c.862.705,1.948,1.146,3.146,1.146,1.697,0,3.195-.854,4.099-2.151l1.08.6c-.106.334-.179.682-.179,1.051,0,1.93,1.57,3.5,3.5,3.5s3.5-1.57,3.5-3.5-1.57-3.5-3.5-3.5ZM4,3.5c0-1.378,1.121-2.5,2.5-2.5s2.5,1.122,2.5,2.5-1.121,2.5-2.5,2.5-2.5-1.122-2.5-2.5Zm-.5,19.5c-1.379,0-2.5-1.122-2.5-2.5s1.121-2.5,2.5-2.5,2.5,1.122,2.5,2.5-1.121,2.5-2.5,2.5Zm8.5-7c-2.206,0-4-1.794-4-4s1.794-4,4-4,4,1.794,4,4-1.794,4-4,4Zm8.5,3c-1.379,0-2.5-1.122-2.5-2.5s1.121-2.5,2.5-2.5,2.5,1.122,2.5,2.5-1.121,2.5-2.5,2.5Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
2
public/icons/light-mode/chart-network-light-mode.svg
Normal file
2
public/icons/light-mode/chart-network-light-mode.svg
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 24 24" width="512" height="512"><path d="M20,12a3.994,3.994,0,0,0-3.172,1.566l-.07-.03a5,5,0,0,0-6.009-6.377l-.091-.172A3.995,3.995,0,1,0,8.879,7.9l.073.137a4.992,4.992,0,0,0-1.134,6.7L5.933,16.5a4,4,0,1,0,1.455,1.377l1.838-1.718a4.993,4.993,0,0,0,6.539-.871l.279.119A4,4,0,1,0,20,12ZM6,4A2,2,0,1,1,8,6,2,2,0,0,1,6,4ZM4,22a2,2,0,1,1,2-2A2,2,0,0,1,4,22Zm8-7a3,3,0,0,1-1.6-5.534l.407-.217A3,3,0,1,1,12,15Zm8,3a2,2,0,1,1,2-2A2,2,0,0,1,20,18Z"/></svg>
|
||||
|
After Width: | Height: | Size: 573 B |
2
src/lib.rs
Normal file
2
src/lib.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// This lib.rs is currently not used since we're building a binary application
|
||||
// If needed in the future, add modules here
|
||||
119
src/main.rs
Normal file
119
src/main.rs
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
// Prevent console window in addition to Slint window in Windows release builds when, e.g., starting the app via file manager. Ignored on other platforms.
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
use slint::*;
|
||||
use i_slint_backend_winit::WinitWindowAccessor;
|
||||
|
||||
// Import the main window from our FSD-structured UI
|
||||
slint::include_modules!();
|
||||
|
||||
fn main() -> Result<(), slint::PlatformError> {
|
||||
// Create the main window
|
||||
let ui = MainWindow::new()?;
|
||||
|
||||
// Clone handle for callbacks
|
||||
let ui_handle = ui.as_weak();
|
||||
|
||||
// Handle navigation changes
|
||||
ui.on_navigation_changed({
|
||||
let ui_handle = ui_handle.clone();
|
||||
move |page| {
|
||||
println!("Navigation changed to: {}", page);
|
||||
if let Some(ui) = ui_handle.upgrade() {
|
||||
// Update current page state
|
||||
ui.set_current_page(page.into());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle theme toggle - using direct function call as per Slint discussion #5860
|
||||
ui.on_theme_toggle_clicked({
|
||||
let ui_handle = ui_handle.clone();
|
||||
move || {
|
||||
println!("Theme toggle callback received from UI");
|
||||
if let Some(ui) = ui_handle.upgrade() {
|
||||
// Call the public theme toggle function directly
|
||||
ui.invoke_toggle_theme();
|
||||
println!("Theme toggle function invoked successfully");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle logout
|
||||
ui.on_logout_clicked({
|
||||
let _ui_handle = ui_handle.clone();
|
||||
move || {
|
||||
println!("Logout clicked");
|
||||
// Implement logout logic here
|
||||
}
|
||||
});
|
||||
|
||||
// Handle buy action
|
||||
ui.on_buy_clicked({
|
||||
let _ui_handle = ui_handle.clone();
|
||||
move || {
|
||||
println!("Buy clicked");
|
||||
// Implement buy logic here
|
||||
}
|
||||
});
|
||||
|
||||
// Handle sell action
|
||||
ui.on_sell_clicked({
|
||||
let _ui_handle = ui_handle.clone();
|
||||
move || {
|
||||
println!("Sell clicked");
|
||||
// Implement sell logic here
|
||||
}
|
||||
});
|
||||
|
||||
// Window control handlers - simplified drag handling
|
||||
ui.on_start_drag_window({
|
||||
let ui_handle = ui_handle.clone();
|
||||
move || {
|
||||
if let Some(ui) = ui_handle.upgrade() {
|
||||
let window = ui.window();
|
||||
window.with_winit_window(|winit_window| {
|
||||
if !window.is_maximized() {
|
||||
let _ = winit_window.drag_window();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ui.on_minimize_window({
|
||||
let ui_handle = ui_handle.clone();
|
||||
move || {
|
||||
if let Some(ui) = ui_handle.upgrade() {
|
||||
let _ = ui.window().set_minimized(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ui.on_maximize_window({
|
||||
let ui_handle = ui_handle.clone();
|
||||
move || {
|
||||
if let Some(ui) = ui_handle.upgrade() {
|
||||
let window = ui.window();
|
||||
let _ = window.set_maximized(!window.is_maximized());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ui.on_close_window({
|
||||
let ui_handle = ui_handle.clone();
|
||||
move || {
|
||||
if let Some(ui) = ui_handle.upgrade() {
|
||||
let _ = ui.window().hide();
|
||||
let _ = slint::quit_event_loop();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Set initial state
|
||||
ui.set_current_page("Dashboard".into());
|
||||
ui.set_user_initials("JD".into());
|
||||
|
||||
// Run the application
|
||||
ui.run()
|
||||
}
|
||||
325
ui/app/index.slint
Normal file
325
ui/app/index.slint
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
// App Layer - Main Application Entry Point
|
||||
// This is the root of the application following Feature-Sliced Design
|
||||
|
||||
// No std-widgets needed since we're using Layout components
|
||||
|
||||
// Import from shared layer (design system, UI kit)
|
||||
import { Theme } from "../shared/design-system/tokens/theme.slint";
|
||||
|
||||
// Import widgets (standalone UI blocks)
|
||||
import { NavigationWidget } from "../widgets/navigation/index.slint";
|
||||
|
||||
// Import pages
|
||||
import { Dashboard } from "../pages/dashboard/index.slint";
|
||||
|
||||
export component App {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
// Application state
|
||||
in-out property <string> current-page: "Dashboard";
|
||||
in-out property <string> user-initials: "JD";
|
||||
|
||||
// Callbacks
|
||||
callback navigation-changed(string);
|
||||
callback theme-toggle-clicked();
|
||||
callback logout-clicked();
|
||||
callback buy-clicked();
|
||||
callback sell-clicked();
|
||||
callback start-drag-window();
|
||||
callback minimize-window();
|
||||
callback maximize-window();
|
||||
callback close-window();
|
||||
|
||||
// Global drag area - covers entire window but sits behind interactive elements
|
||||
TouchArea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z: -1;
|
||||
|
||||
moved => {
|
||||
if (self.pressed) {
|
||||
root.start-drag-window();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VerticalLayout {
|
||||
spacing: 0px;
|
||||
|
||||
// Title Bar - fixed height
|
||||
Rectangle {
|
||||
height: 32px;
|
||||
background: Theme.surface;
|
||||
|
||||
HorizontalLayout {
|
||||
padding: 4px;
|
||||
spacing: 8px;
|
||||
|
||||
// Draggable area (left side) - takes most of the space
|
||||
Rectangle {
|
||||
horizontal-stretch: 1;
|
||||
|
||||
Text {
|
||||
text: "Ziya Trading Platform";
|
||||
color: Theme.text-primary;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
vertical-alignment: center;
|
||||
x: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
// Theme Toggle Button - fixed size
|
||||
Rectangle {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
border-radius: 10px;
|
||||
background: Theme.is-dark-mode ? Theme.primary : Theme.border;
|
||||
|
||||
Rectangle {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 8px;
|
||||
background: white;
|
||||
x: Theme.is-dark-mode ? 22px : 2px;
|
||||
y: 2px;
|
||||
|
||||
animate x { duration: 200ms; easing: ease-in-out; }
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => {
|
||||
theme-toggle-clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Window Controls - fixed size
|
||||
HorizontalLayout {
|
||||
spacing: 2px;
|
||||
|
||||
// Minimize Button
|
||||
Rectangle {
|
||||
width: 28px;
|
||||
height: 24px;
|
||||
border-radius: 2px;
|
||||
background: minimize-area.pressed ? #30404040 : minimize-area.has-hover ? #20404040 : transparent;
|
||||
|
||||
Text {
|
||||
text: "−";
|
||||
color: Theme.text-primary;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
minimize-area := TouchArea {
|
||||
clicked => { minimize-window(); }
|
||||
}
|
||||
}
|
||||
|
||||
// Maximize Button
|
||||
Rectangle {
|
||||
width: 28px;
|
||||
height: 24px;
|
||||
border-radius: 2px;
|
||||
background: maximize-area.pressed ? #30404040 : maximize-area.has-hover ? #20404040 : transparent;
|
||||
|
||||
Text {
|
||||
text: "□";
|
||||
color: Theme.text-primary;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
maximize-area := TouchArea {
|
||||
clicked => { maximize-window(); }
|
||||
}
|
||||
}
|
||||
|
||||
// Close Button
|
||||
Rectangle {
|
||||
width: 28px;
|
||||
height: 24px;
|
||||
border-radius: 2px;
|
||||
background: close-area.pressed ? #E53E3E : close-area.has-hover ? #C53030 : transparent;
|
||||
|
||||
Text {
|
||||
text: "×";
|
||||
color: close-area.has-hover ? white : Theme.text-primary;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
close-area := TouchArea {
|
||||
clicked => { close-window(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main content area - stretches to fill remaining vertical space
|
||||
HorizontalLayout {
|
||||
spacing: 0px;
|
||||
|
||||
// Navigation Widget (Sidebar) - fixed width
|
||||
NavigationWidget {
|
||||
width: 280px;
|
||||
current-page: root.current-page;
|
||||
user-initials: root.user-initials;
|
||||
|
||||
navigation-changed(page) => {
|
||||
root.current-page = page;
|
||||
root.navigation-changed(page);
|
||||
}
|
||||
|
||||
logout-clicked => { root.logout-clicked(); }
|
||||
}
|
||||
|
||||
// Main content area - stretches to fill remaining horizontal space
|
||||
Rectangle {
|
||||
background: Theme.background;
|
||||
|
||||
// Page routing based on current-page
|
||||
if current-page == "Dashboard": Dashboard {
|
||||
user-initials: root.user-initials;
|
||||
logout => { root.logout-clicked(); }
|
||||
trade-buy(asset, amount) => { root.buy-clicked(); }
|
||||
trade-sell(asset, amount) => { root.sell-clicked(); }
|
||||
}
|
||||
|
||||
if current-page == "Trading": Rectangle {
|
||||
background: Theme.background;
|
||||
|
||||
VerticalLayout {
|
||||
padding: 24px;
|
||||
spacing: 16px;
|
||||
alignment: center;
|
||||
|
||||
Text {
|
||||
text: "🎯 Trading Interface";
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: Theme.text-primary;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Advanced trading features coming soon...";
|
||||
font-size: 18px;
|
||||
color: Theme.text-secondary;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if current-page == "Portfolio": Rectangle {
|
||||
background: Theme.background;
|
||||
|
||||
VerticalLayout {
|
||||
padding: 24px;
|
||||
spacing: 16px;
|
||||
alignment: center;
|
||||
|
||||
Text {
|
||||
text: "💼 Portfolio Management";
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: Theme.text-primary;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Portfolio tracking and management features coming soon...";
|
||||
font-size: 18px;
|
||||
color: Theme.text-secondary;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if current-page == "Markets": Rectangle {
|
||||
background: Theme.background;
|
||||
|
||||
VerticalLayout {
|
||||
padding: 24px;
|
||||
spacing: 16px;
|
||||
alignment: center;
|
||||
|
||||
Text {
|
||||
text: "📈 Market Data";
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: Theme.text-primary;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Real-time market data and analysis coming soon...";
|
||||
font-size: 18px;
|
||||
color: Theme.text-secondary;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if current-page == "HuntingGround": Rectangle {
|
||||
background: Theme.background;
|
||||
|
||||
VerticalLayout {
|
||||
padding: 24px;
|
||||
spacing: 16px;
|
||||
alignment: center;
|
||||
|
||||
Text {
|
||||
text: "🎯 Token Hunting Ground";
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: Theme.text-primary;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Discover and track new tokens coming soon...";
|
||||
font-size: 18px;
|
||||
color: Theme.text-secondary;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if current-page == "Profile": Rectangle {
|
||||
background: Theme.background;
|
||||
|
||||
VerticalLayout {
|
||||
padding: 24px;
|
||||
spacing: 16px;
|
||||
alignment: center;
|
||||
|
||||
Text {
|
||||
text: "👤 User Profile";
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: Theme.text-primary;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Profile management and settings coming soon...";
|
||||
font-size: 18px;
|
||||
color: Theme.text-secondary;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/entities/token/index.slint
Normal file
2
ui/entities/token/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Token Entity Public API
|
||||
export { TokenListView } from "ui/token-list.slint";
|
||||
181
ui/entities/token/ui/token-list.slint
Normal file
181
ui/entities/token/ui/token-list.slint
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
import { Button, VerticalBox, HorizontalBox, LineEdit, ScrollView } from "std-widgets.slint";
|
||||
|
||||
// Token data structure
|
||||
export struct TokenData {
|
||||
name: string,
|
||||
symbol: string,
|
||||
price: string,
|
||||
market-cap: string,
|
||||
volume: string,
|
||||
}
|
||||
|
||||
// Token list component
|
||||
export component TokenListView {
|
||||
in-out property <color> primary-color: #2563eb;
|
||||
in-out property <color> background-color: #f8fafc;
|
||||
in-out property <color> card-background: #ffffff;
|
||||
in-out property <color> text-color: #1e293b;
|
||||
in-out property <color> border-color: #e2e8f0;
|
||||
in-out property <string> search-query: "";
|
||||
in-out property <[TokenData]> tokens: [];
|
||||
|
||||
// Callbacks
|
||||
callback search-changed(string);
|
||||
callback token-selected(TokenData);
|
||||
|
||||
Rectangle {
|
||||
background: background-color;
|
||||
|
||||
VerticalBox {
|
||||
spacing: 20px;
|
||||
padding: 20px;
|
||||
|
||||
// Header section
|
||||
VerticalBox {
|
||||
spacing: 15px;
|
||||
|
||||
Text {
|
||||
text: "Token Explorer";
|
||||
font-size: 24px;
|
||||
color: text-color;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
// Search bar
|
||||
LineEdit {
|
||||
placeholder-text: "Search tokens...";
|
||||
text <=> search-query;
|
||||
height: 45px;
|
||||
edited => {
|
||||
search-changed(search-query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Token list
|
||||
ScrollView {
|
||||
viewport-height: 400px;
|
||||
|
||||
VerticalBox {
|
||||
spacing: 10px;
|
||||
|
||||
for token in tokens: Rectangle {
|
||||
height: 80px;
|
||||
background: card-background;
|
||||
border-radius: 12px;
|
||||
border-width: 1px;
|
||||
border-color: border-color;
|
||||
drop-shadow-blur: 5px;
|
||||
drop-shadow-color: #00000008;
|
||||
|
||||
HorizontalBox {
|
||||
alignment: stretch;
|
||||
spacing: 15px;
|
||||
padding: 15px;
|
||||
|
||||
// Token icon placeholder
|
||||
Rectangle {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 25px;
|
||||
background: primary-color.with-alpha(0.1);
|
||||
|
||||
Text {
|
||||
text: token.symbol.to-uppercase();
|
||||
color: primary-color;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
// Token info
|
||||
VerticalBox {
|
||||
alignment: start;
|
||||
spacing: 5px;
|
||||
|
||||
Text {
|
||||
text: token.name;
|
||||
font-size: 16px;
|
||||
color: text-color;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: token.symbol.to-uppercase();
|
||||
font-size: 12px;
|
||||
color: text-color;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
// Price info
|
||||
VerticalBox {
|
||||
alignment: end;
|
||||
spacing: 5px;
|
||||
|
||||
Text {
|
||||
text: "$" + token.price;
|
||||
font-size: 16px;
|
||||
color: text-color;
|
||||
font-weight: 600;
|
||||
horizontal-alignment: right;
|
||||
}
|
||||
|
||||
HorizontalBox {
|
||||
alignment: end;
|
||||
spacing: 10px;
|
||||
|
||||
Text {
|
||||
text: "MC: $" + token.market-cap;
|
||||
font-size: 10px;
|
||||
color: text-color;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Vol: $" + token.volume;
|
||||
font-size: 10px;
|
||||
color: text-color;
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => {
|
||||
token-selected(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loading state or empty state
|
||||
if tokens.length == 0: Rectangle {
|
||||
height: 200px;
|
||||
background: card-background;
|
||||
border-radius: 12px;
|
||||
border-width: 1px;
|
||||
border-color: border-color;
|
||||
|
||||
VerticalBox {
|
||||
alignment: center;
|
||||
spacing: 10px;
|
||||
|
||||
Text {
|
||||
text: search-query == "" ? "🔍" : "😔";
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: search-query == "" ? "Loading tokens..." : "No tokens found";
|
||||
color: text-color;
|
||||
opacity: 0.7;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
75
ui/index.slint
Normal file
75
ui/index.slint
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// Main Entry Point - Following Feature-Sliced Design
|
||||
// This is the root file that main.rs imports
|
||||
// Following the pattern from moonlogs: index -> app -> pages/widgets/entities/shared
|
||||
|
||||
import { App } from "app/index.slint";
|
||||
import { Theme } from "shared/design-system/index.slint";
|
||||
|
||||
export component MainWindow inherits Window {
|
||||
// Window properties
|
||||
preferred-width: 1280px;
|
||||
preferred-height: 1024px;
|
||||
min-width: 1080px;
|
||||
min-height: 800px;
|
||||
no-frame: true;
|
||||
background: Theme.background;
|
||||
|
||||
// Properties
|
||||
in-out property <string> current-page: "Dashboard";
|
||||
in-out property <string> user-initials: "JD";
|
||||
|
||||
// Callbacks that will be handled by main.rs
|
||||
callback navigation-changed(string);
|
||||
callback theme-toggle-clicked();
|
||||
callback logout-clicked();
|
||||
callback buy-clicked();
|
||||
callback sell-clicked();
|
||||
callback start-drag-window();
|
||||
callback minimize-window();
|
||||
callback maximize-window();
|
||||
callback close-window();
|
||||
|
||||
// Public function that can be called from Rust to toggle theme
|
||||
public function toggle_theme() {
|
||||
Theme.is-dark-mode = !Theme.is-dark-mode;
|
||||
debug("Theme toggled from Rust. New state: " + (Theme.is-dark-mode ? "dark" : "light"));
|
||||
}
|
||||
|
||||
// App component handles all the UI following FSD layers
|
||||
App {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
current-page: root.current-page;
|
||||
user-initials: root.user-initials;
|
||||
|
||||
// Forward all callbacks to main.rs
|
||||
navigation-changed(page) => {
|
||||
root.current-page = page;
|
||||
root.navigation-changed(page);
|
||||
}
|
||||
theme-toggle-clicked => {
|
||||
root.theme-toggle-clicked();
|
||||
}
|
||||
logout-clicked => {
|
||||
root.logout-clicked();
|
||||
}
|
||||
buy-clicked => {
|
||||
root.buy-clicked();
|
||||
}
|
||||
sell-clicked => {
|
||||
root.sell-clicked();
|
||||
}
|
||||
start-drag-window => {
|
||||
root.start-drag-window();
|
||||
}
|
||||
minimize-window => {
|
||||
root.minimize-window();
|
||||
}
|
||||
maximize-window => {
|
||||
root.maximize-window();
|
||||
}
|
||||
close-window => {
|
||||
root.close-window();
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/pages/auth/index.slint
Normal file
2
ui/pages/auth/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Auth Page Public API
|
||||
export { LoginView } from "ui/login-page.slint";
|
||||
155
ui/pages/auth/ui/login-page.slint
Normal file
155
ui/pages/auth/ui/login-page.slint
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
import { Button, VerticalBox, HorizontalBox, LineEdit } from "std-widgets.slint";
|
||||
|
||||
// Login component with branded interface
|
||||
export component LoginView {
|
||||
in-out property <color> primary-color: #2563eb;
|
||||
in-out property <color> background-color: #f8fafc;
|
||||
in-out property <color> text-color: #1e293b;
|
||||
in-out property <string> app-version: "0.2.0";
|
||||
|
||||
// Login form state
|
||||
in-out property <string> email: "";
|
||||
in-out property <string> password: "";
|
||||
|
||||
// Callbacks
|
||||
callback login-clicked(string, string);
|
||||
callback navigate-to-dashboard();
|
||||
|
||||
Rectangle {
|
||||
background: background-color;
|
||||
|
||||
VerticalBox {
|
||||
alignment: center;
|
||||
spacing: 30px;
|
||||
padding: 40px;
|
||||
|
||||
// Logo and branding section
|
||||
VerticalBox {
|
||||
alignment: center;
|
||||
spacing: 10px;
|
||||
|
||||
Rectangle {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 40px;
|
||||
background: primary-color.with-alpha(0.1);
|
||||
|
||||
// Logo placeholder
|
||||
Rectangle {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: primary-color;
|
||||
border-radius: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Ziya";
|
||||
font-size: 48px;
|
||||
color: text-color;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "/dˤiˈjaːʔ/, \"zee‑yah\" — Proper noun, meaning \"light\"";
|
||||
font-size: 14px;
|
||||
color: text-color;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "One stop shop trading solution";
|
||||
font-size: 20px;
|
||||
color: text-color;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "A bismillahDAO creation";
|
||||
font-size: 12px;
|
||||
color: primary-color;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
// Login form section
|
||||
VerticalBox {
|
||||
alignment: center;
|
||||
spacing: 20px;
|
||||
width: 400px;
|
||||
|
||||
// Email field
|
||||
VerticalBox {
|
||||
spacing: 8px;
|
||||
|
||||
Text {
|
||||
text: "Email";
|
||||
color: text-color;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
LineEdit {
|
||||
placeholder-text: "Enter your email";
|
||||
text <=> email;
|
||||
height: 45px;
|
||||
}
|
||||
}
|
||||
|
||||
// Password field
|
||||
VerticalBox {
|
||||
spacing: 8px;
|
||||
|
||||
Text {
|
||||
text: "Password";
|
||||
color: text-color;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
LineEdit {
|
||||
placeholder-text: "Enter your password";
|
||||
text <=> password;
|
||||
height: 45px;
|
||||
}
|
||||
}
|
||||
|
||||
// Login button
|
||||
Button {
|
||||
text: "Sign In";
|
||||
primary: true;
|
||||
height: 50px;
|
||||
clicked => {
|
||||
login-clicked(email, password);
|
||||
}
|
||||
}
|
||||
|
||||
// Quick access button
|
||||
HorizontalBox {
|
||||
spacing: 10px;
|
||||
alignment: center;
|
||||
|
||||
Text {
|
||||
text: "Quick access:";
|
||||
color: text-color;
|
||||
opacity: 0.7;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "Demo Mode";
|
||||
height: 35px;
|
||||
clicked => {
|
||||
navigate-to-dashboard();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Version " + app-version;
|
||||
font-size: 10px;
|
||||
color: text-color;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/pages/dashboard/index.slint
Normal file
2
ui/pages/dashboard/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Dashboard Page Public API
|
||||
export { Dashboard } from "ui/dashboard-page.slint";
|
||||
443
ui/pages/dashboard/ui/dashboard-page.slint
Normal file
443
ui/pages/dashboard/ui/dashboard-page.slint
Normal file
|
|
@ -0,0 +1,443 @@
|
|||
import { ScrollView, Button, LineEdit, ComboBox } from "std-widgets.slint";
|
||||
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
|
||||
|
||||
// Professional dashboard component with global theme support
|
||||
export component Dashboard {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
in-out property <string> user-initials: "JD";
|
||||
|
||||
callback logout();
|
||||
callback trade-buy(string, string);
|
||||
callback trade-sell(string, string);
|
||||
|
||||
// Let the parent layout handle sizing
|
||||
|
||||
VerticalLayout {
|
||||
spacing: 0px;
|
||||
|
||||
// Top navbar using HorizontalLayout for proper layout
|
||||
Rectangle {
|
||||
height: 64px;
|
||||
background: Theme.surface;
|
||||
border-width: 1px;
|
||||
border-color: Theme.border;
|
||||
|
||||
HorizontalLayout {
|
||||
padding: 16px;
|
||||
alignment: stretch;
|
||||
|
||||
Text {
|
||||
text: "Ziya Dashboard";
|
||||
color: Theme.text-primary;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
// Spacer to push user profile to the right
|
||||
Rectangle {
|
||||
horizontal-stretch: 1;
|
||||
}
|
||||
|
||||
// User profile button
|
||||
Rectangle {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: Theme.primary;
|
||||
border-radius: 20px;
|
||||
|
||||
Text {
|
||||
text: user-initials;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => { logout(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dashboard content - no scrollbar, just layout
|
||||
VerticalLayout {
|
||||
vertical-stretch: 1;
|
||||
padding: 24px;
|
||||
spacing: 24px;
|
||||
|
||||
// Stats cards row using HorizontalLayout with proper stretch
|
||||
HorizontalLayout {
|
||||
spacing: 24px;
|
||||
alignment: stretch;
|
||||
|
||||
// Total Balance
|
||||
Rectangle {
|
||||
horizontal-stretch: 1;
|
||||
background: Theme.card-background;
|
||||
border-radius: 12px;
|
||||
border-width: 1px;
|
||||
border-color: Theme.card-border;
|
||||
drop-shadow-blur: 8px;
|
||||
drop-shadow-color: Theme.is-dark-mode ? #00000020 : #00000008;
|
||||
|
||||
VerticalLayout {
|
||||
padding: 20px;
|
||||
spacing: 8px;
|
||||
|
||||
Text {
|
||||
text: "Total Balance";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "$25,600";
|
||||
color: Theme.primary;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "↗︎ 12% (30d)";
|
||||
color: Theme.success;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Active Positions
|
||||
Rectangle {
|
||||
horizontal-stretch: 1;
|
||||
background: Theme.card-background;
|
||||
border-radius: 12px;
|
||||
border-width: 1px;
|
||||
border-color: Theme.card-border;
|
||||
drop-shadow-blur: 8px;
|
||||
drop-shadow-color: Theme.is-dark-mode ? #00000020 : #00000008;
|
||||
|
||||
VerticalLayout {
|
||||
padding: 20px;
|
||||
spacing: 8px;
|
||||
|
||||
Text {
|
||||
text: "Active Positions";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "8";
|
||||
color: Theme.warning;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "↗︎ 2 new today";
|
||||
color: Theme.success;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// P&L Today
|
||||
Rectangle {
|
||||
horizontal-stretch: 1;
|
||||
background: Theme.card-background;
|
||||
border-radius: 12px;
|
||||
border-width: 1px;
|
||||
border-color: Theme.card-border;
|
||||
drop-shadow-blur: 8px;
|
||||
drop-shadow-color: Theme.is-dark-mode ? #00000020 : #00000008;
|
||||
|
||||
VerticalLayout {
|
||||
padding: 20px;
|
||||
spacing: 8px;
|
||||
|
||||
Text {
|
||||
text: "P&L Today";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "+$450";
|
||||
color: Theme.success;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "↗︎ +2.1%";
|
||||
color: Theme.success;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Trading interface row using HorizontalLayout
|
||||
HorizontalLayout {
|
||||
spacing: 24px;
|
||||
alignment: stretch;
|
||||
|
||||
// Quick Trade card
|
||||
Rectangle {
|
||||
horizontal-stretch: 2;
|
||||
background: Theme.card-background;
|
||||
border-radius: 16px;
|
||||
border-width: 1px;
|
||||
border-color: Theme.card-border;
|
||||
drop-shadow-blur: 16px;
|
||||
drop-shadow-color: Theme.is-dark-mode ? #00000020 : #00000008;
|
||||
|
||||
VerticalLayout {
|
||||
padding: 24px;
|
||||
spacing: 20px;
|
||||
|
||||
Text {
|
||||
text: "Quick Trade";
|
||||
color: Theme.text-primary;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
|
||||
// Token selector using HorizontalLayout
|
||||
HorizontalLayout {
|
||||
spacing: 12px;
|
||||
alignment: start;
|
||||
|
||||
Text {
|
||||
text: "Token:";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 14px;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
model: ["SOL", "BTC", "ETH", "USDC"];
|
||||
current-value: "SOL";
|
||||
}
|
||||
}
|
||||
|
||||
// Amount input using HorizontalLayout
|
||||
HorizontalLayout {
|
||||
spacing: 12px;
|
||||
alignment: start;
|
||||
|
||||
Text {
|
||||
text: "Amount:";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 14px;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
LineEdit {
|
||||
placeholder-text: "0.00";
|
||||
horizontal-stretch: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Trade buttons using HorizontalLayout
|
||||
HorizontalLayout {
|
||||
spacing: 12px;
|
||||
alignment: stretch;
|
||||
|
||||
Button {
|
||||
text: "Buy";
|
||||
primary: true;
|
||||
horizontal-stretch: 1;
|
||||
clicked => {
|
||||
trade-buy("SOL", "100");
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "Sell";
|
||||
horizontal-stretch: 1;
|
||||
clicked => {
|
||||
trade-sell("SOL", "50");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recent Activity card
|
||||
Rectangle {
|
||||
horizontal-stretch: 1;
|
||||
background: Theme.card-background;
|
||||
border-radius: 16px;
|
||||
border-width: 1px;
|
||||
border-color: Theme.card-border;
|
||||
drop-shadow-blur: 16px;
|
||||
drop-shadow-color: Theme.is-dark-mode ? #00000020 : #00000008;
|
||||
|
||||
VerticalLayout {
|
||||
padding: 24px;
|
||||
spacing: 16px;
|
||||
|
||||
Text {
|
||||
text: "Recent Activity";
|
||||
color: Theme.text-primary;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
|
||||
// Activity items using VerticalLayout
|
||||
VerticalLayout {
|
||||
spacing: 12px;
|
||||
|
||||
// Activity item 1
|
||||
HorizontalLayout {
|
||||
spacing: 12px;
|
||||
alignment: stretch;
|
||||
|
||||
Rectangle {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
background: Theme.success;
|
||||
}
|
||||
|
||||
VerticalLayout {
|
||||
spacing: 2px;
|
||||
horizontal-stretch: 1;
|
||||
|
||||
Text {
|
||||
text: "Bought 2.5 SOL";
|
||||
color: Theme.text-primary;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "2 minutes ago";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Activity item 2
|
||||
HorizontalLayout {
|
||||
spacing: 12px;
|
||||
alignment: stretch;
|
||||
|
||||
Rectangle {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
background: Theme.error;
|
||||
}
|
||||
|
||||
VerticalLayout {
|
||||
spacing: 2px;
|
||||
horizontal-stretch: 1;
|
||||
|
||||
Text {
|
||||
text: "Sold 1.0 ETH";
|
||||
color: Theme.text-primary;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "1 hour ago";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Activity item 3
|
||||
HorizontalLayout {
|
||||
spacing: 12px;
|
||||
alignment: stretch;
|
||||
|
||||
Rectangle {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
background: Theme.warning;
|
||||
}
|
||||
|
||||
VerticalLayout {
|
||||
spacing: 2px;
|
||||
horizontal-stretch: 1;
|
||||
|
||||
Text {
|
||||
text: "Staked 100 USDC";
|
||||
color: Theme.text-primary;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "3 hours ago";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Theme demonstration section
|
||||
Rectangle {
|
||||
background: Theme.surface;
|
||||
border-radius: 12px;
|
||||
border-width: 1px;
|
||||
border-color: Theme.border;
|
||||
|
||||
VerticalLayout {
|
||||
padding: 20px;
|
||||
spacing: 12px;
|
||||
|
||||
Text {
|
||||
text: "Theme Status";
|
||||
color: Theme.text-primary;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Current theme: " + (Theme.is-dark-mode ? "Dark Mode 🌙" : "Light Mode ☀️");
|
||||
color: Theme.text-secondary;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "All components are now using the global theme system for consistent theming across the application.";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/pages/hunting-ground/index.slint
Normal file
2
ui/pages/hunting-ground/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Hunting Ground Page Public API
|
||||
export { HuntingGroundPage } from "ui/hunting-ground-page.slint";
|
||||
30
ui/pages/hunting-ground/ui/hunting-ground-page.slint
Normal file
30
ui/pages/hunting-ground/ui/hunting-ground-page.slint
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { VerticalBox } from "std-widgets.slint";
|
||||
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
|
||||
|
||||
// Hunting Ground Page Component
|
||||
export component HuntingGroundPage {
|
||||
Rectangle {
|
||||
background: Theme.background;
|
||||
|
||||
VerticalBox {
|
||||
padding: 32px;
|
||||
spacing: 24px;
|
||||
alignment: center;
|
||||
|
||||
Text {
|
||||
text: "🎯 Hunting Ground";
|
||||
color: Theme.text-primary;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Advanced token hunting and discovery features";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 16px;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/pages/markets/index.slint
Normal file
2
ui/pages/markets/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Markets Page Public API
|
||||
export { MarketsPage } from "ui/markets-page.slint";
|
||||
30
ui/pages/markets/ui/markets-page.slint
Normal file
30
ui/pages/markets/ui/markets-page.slint
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { VerticalBox } from "std-widgets.slint";
|
||||
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
|
||||
|
||||
// Markets Page Component
|
||||
export component MarketsPage {
|
||||
Rectangle {
|
||||
background: Theme.background;
|
||||
|
||||
VerticalBox {
|
||||
padding: 32px;
|
||||
spacing: 24px;
|
||||
alignment: center;
|
||||
|
||||
Text {
|
||||
text: "Markets";
|
||||
color: Theme.text-primary;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Market data and analysis will be displayed here";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 16px;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/pages/portfolio/index.slint
Normal file
2
ui/pages/portfolio/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Portfolio Page Public API
|
||||
export { PortfolioPage } from "ui/portfolio-page.slint";
|
||||
30
ui/pages/portfolio/ui/portfolio-page.slint
Normal file
30
ui/pages/portfolio/ui/portfolio-page.slint
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { VerticalBox } from "std-widgets.slint";
|
||||
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
|
||||
|
||||
// Portfolio Page Component
|
||||
export component PortfolioPage {
|
||||
Rectangle {
|
||||
background: Theme.background;
|
||||
|
||||
VerticalBox {
|
||||
padding: 32px;
|
||||
spacing: 24px;
|
||||
alignment: center;
|
||||
|
||||
Text {
|
||||
text: "Portfolio";
|
||||
color: Theme.text-primary;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Your investment portfolio will be displayed here";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 16px;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/pages/trading/index.slint
Normal file
2
ui/pages/trading/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Trading Page Public API
|
||||
export { TradingPage } from "ui/trading-page.slint";
|
||||
78
ui/pages/trading/ui/trading-page.slint
Normal file
78
ui/pages/trading/ui/trading-page.slint
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import { VerticalBox, HorizontalBox } from "std-widgets.slint";
|
||||
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
|
||||
|
||||
// Trading Page Component
|
||||
export component TradingPage {
|
||||
callback buy-clicked();
|
||||
callback sell-clicked();
|
||||
|
||||
Rectangle {
|
||||
background: Theme.background;
|
||||
|
||||
VerticalBox {
|
||||
padding: 32px;
|
||||
spacing: 24px;
|
||||
alignment: center;
|
||||
|
||||
Text {
|
||||
text: "Trading Page";
|
||||
color: Theme.text-primary;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Advanced trading features coming soon...";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 16px;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
HorizontalBox {
|
||||
spacing: 16px;
|
||||
alignment: center;
|
||||
|
||||
Rectangle {
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
background: #10b981;
|
||||
border-radius: 8px;
|
||||
|
||||
Text {
|
||||
text: "Buy";
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => { buy-clicked(); }
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
background: #ef4444;
|
||||
border-radius: 8px;
|
||||
|
||||
Text {
|
||||
text: "Sell";
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => { sell-clicked(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
5
ui/shared/config/index.slint
Normal file
5
ui/shared/config/index.slint
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// Shared Configuration Public API
|
||||
// Export application configuration
|
||||
|
||||
// Currently no config defined
|
||||
// export * from "app-config.slint";
|
||||
971
ui/shared/design-system/components/design-system.slint
Normal file
971
ui/shared/design-system/components/design-system.slint
Normal file
|
|
@ -0,0 +1,971 @@
|
|||
// Fluent 2 Design System for Ziya Trading Platform
|
||||
// Based on Microsoft Fluent 2 Design Language
|
||||
// https://fluent2.microsoft.design/
|
||||
|
||||
// Complete Fluent UI Color System - All Themes Support
|
||||
// Theme mode enumeration
|
||||
export enum ColorMode { light, dark, team-light, team-dark }
|
||||
|
||||
export global FluentColors {
|
||||
// Current theme mode
|
||||
in-out property <ColorMode> current-mode: ColorMode.light;
|
||||
|
||||
// Theme switching callback
|
||||
callback switch-theme(ColorMode);
|
||||
|
||||
// ===== LIGHT THEME COLORS =====
|
||||
|
||||
// Neutral Colors - Light
|
||||
out property <color> neutral-foreground-1-light: #242424;
|
||||
out property <color> neutral-foreground-2-light: #424242;
|
||||
out property <color> neutral-foreground-3-light: #616161;
|
||||
out property <color> neutral-foreground-4-light: #757575;
|
||||
out property <color> neutral-foreground-disabled-light: #bdbdbd;
|
||||
out property <color> neutral-foreground-inverted-light: #ffffff;
|
||||
out property <color> neutral-foreground-inverted-2-light: #f5f5f5;
|
||||
out property <color> neutral-foreground-on-brand-light: #ffffff;
|
||||
out property <color> neutral-foreground-static-inverted-light: #ffffff;
|
||||
out property <color> neutral-foreground-inverted-disabled-light: #ffffff;
|
||||
|
||||
// Interactive states - Light theme
|
||||
out property <color> neutral-foreground-1-hover-light: #424242;
|
||||
out property <color> neutral-foreground-1-pressed-light: #242424;
|
||||
out property <color> neutral-foreground-2-hover-light: #616161;
|
||||
out property <color> neutral-foreground-2-pressed-light: #424242;
|
||||
out property <color> neutral-foreground-2-brand-hover-light: #0078d4;
|
||||
out property <color> neutral-foreground-2-brand-pressed-light: #005a9e;
|
||||
out property <color> neutral-foreground-2-brand-selected-light: #0078d4;
|
||||
|
||||
// Link colors - Light theme
|
||||
out property <color> neutral-foreground-link-light: #0078d4;
|
||||
out property <color> neutral-foreground-link-hover-light: #106ebe;
|
||||
out property <color> neutral-foreground-link-pressed-light: #005a9e;
|
||||
out property <color> neutral-foreground-link-selected-light: #0078d4;
|
||||
|
||||
out property <color> neutral-background-1-light: #ffffff;
|
||||
out property <color> neutral-background-2-light: #fafafa;
|
||||
out property <color> neutral-background-3-light: #f5f5f5;
|
||||
out property <color> neutral-background-4-light: #f0f0f0;
|
||||
out property <color> neutral-background-5-light: #ebebeb;
|
||||
out property <color> neutral-background-6-light: #e1e1e1;
|
||||
out property <color> neutral-background-inverted-light: #292929;
|
||||
out property <color> neutral-background-static-light: #f0f0f0;
|
||||
out property <color> neutral-background-alpha-light: #ffffff;
|
||||
out property <color> neutral-background-alpha-2-light: #ffffff;
|
||||
|
||||
// Background interactive states - Light theme
|
||||
out property <color> neutral-background-1-hover-light: #f5f5f5;
|
||||
out property <color> neutral-background-1-pressed-light: #f0f0f0;
|
||||
out property <color> neutral-background-1-selected-light: #ebebeb;
|
||||
out property <color> neutral-background-2-hover-light: #f0f0f0;
|
||||
out property <color> neutral-background-2-pressed-light: #ebebeb;
|
||||
out property <color> neutral-background-2-selected-light: #e1e1e1;
|
||||
out property <color> neutral-background-3-hover-light: #ebebeb;
|
||||
out property <color> neutral-background-3-pressed-light: #e1e1e1;
|
||||
out property <color> neutral-background-3-selected-light: #c7c7c7;
|
||||
|
||||
out property <color> neutral-stroke-1-light: #e1e1e1;
|
||||
out property <color> neutral-stroke-2-light: #c7c7c7;
|
||||
out property <color> neutral-stroke-3-light: #b3b3b3;
|
||||
out property <color> neutral-stroke-accessible-light: #616161;
|
||||
out property <color> neutral-stroke-focus-1-light: #ffffff;
|
||||
out property <color> neutral-stroke-focus-2-light: #000000;
|
||||
out property <color> neutral-stroke-disabled-light: #e1e1e1;
|
||||
|
||||
// Stroke interactive states - Light theme
|
||||
out property <color> neutral-stroke-1-hover-light: #c7c7c7;
|
||||
out property <color> neutral-stroke-1-pressed-light: #b3b3b3;
|
||||
out property <color> neutral-stroke-1-selected-light: #b3b3b3;
|
||||
out property <color> neutral-stroke-2-hover-light: #b3b3b3;
|
||||
out property <color> neutral-stroke-2-pressed-light: #9e9e9e;
|
||||
|
||||
// ===== DARK THEME COLORS =====
|
||||
|
||||
// Neutral Colors - Dark
|
||||
out property <color> neutral-foreground-1-dark: #ffffff;
|
||||
out property <color> neutral-foreground-2-dark: #f5f5f5;
|
||||
out property <color> neutral-foreground-3-dark: #ebebeb;
|
||||
out property <color> neutral-foreground-4-dark: #cccccc;
|
||||
out property <color> neutral-foreground-disabled-dark: #858585;
|
||||
out property <color> neutral-foreground-inverted-dark: #242424;
|
||||
out property <color> neutral-foreground-inverted-2-dark: #292929;
|
||||
out property <color> neutral-foreground-on-brand-dark: #ffffff;
|
||||
out property <color> neutral-foreground-static-inverted-dark: #ffffff;
|
||||
out property <color> neutral-foreground-inverted-disabled-dark: #858585;
|
||||
|
||||
// Interactive states - Dark theme
|
||||
out property <color> neutral-foreground-1-hover-dark: #f5f5f5;
|
||||
out property <color> neutral-foreground-1-pressed-dark: #ffffff;
|
||||
out property <color> neutral-foreground-2-hover-dark: #ebebeb;
|
||||
out property <color> neutral-foreground-2-pressed-dark: #f5f5f5;
|
||||
out property <color> neutral-foreground-2-brand-hover-dark: #62abf5;
|
||||
out property <color> neutral-foreground-2-brand-pressed-dark: #77b7f7;
|
||||
out property <color> neutral-foreground-2-brand-selected-dark: #479ef5;
|
||||
|
||||
// Link colors - Dark theme
|
||||
out property <color> neutral-foreground-link-dark: #479ef5;
|
||||
out property <color> neutral-foreground-link-hover-dark: #62abf5;
|
||||
out property <color> neutral-foreground-link-pressed-dark: #77b7f7;
|
||||
out property <color> neutral-foreground-link-selected-dark: #479ef5;
|
||||
|
||||
out property <color> neutral-background-1-dark: #1c1c1c;
|
||||
out property <color> neutral-background-2-dark: #242424;
|
||||
out property <color> neutral-background-3-dark: #292929;
|
||||
out property <color> neutral-background-4-dark: #333333;
|
||||
out property <color> neutral-background-5-dark: #3d3d3d;
|
||||
out property <color> neutral-background-6-dark: #474747;
|
||||
out property <color> neutral-background-inverted-dark: #ffffff;
|
||||
out property <color> neutral-background-static-dark: #333333;
|
||||
out property <color> neutral-background-alpha-dark: #1c1c1c;
|
||||
out property <color> neutral-background-alpha-2-dark: #1c1c1c;
|
||||
|
||||
// Background interactive states - Dark theme
|
||||
out property <color> neutral-background-1-hover-dark: #242424;
|
||||
out property <color> neutral-background-1-pressed-dark: #292929;
|
||||
out property <color> neutral-background-1-selected-dark: #333333;
|
||||
out property <color> neutral-background-2-hover-dark: #292929;
|
||||
out property <color> neutral-background-2-pressed-dark: #333333;
|
||||
out property <color> neutral-background-2-selected-dark: #3d3d3d;
|
||||
out property <color> neutral-background-3-hover-dark: #333333;
|
||||
out property <color> neutral-background-3-pressed-dark: #3d3d3d;
|
||||
out property <color> neutral-background-3-selected-dark: #474747;
|
||||
|
||||
out property <color> neutral-stroke-1-dark: #3d3d3d;
|
||||
out property <color> neutral-stroke-2-dark: #525252;
|
||||
out property <color> neutral-stroke-3-dark: #666666;
|
||||
out property <color> neutral-stroke-accessible-dark: #cccccc;
|
||||
out property <color> neutral-stroke-focus-1-dark: #ffffff;
|
||||
out property <color> neutral-stroke-focus-2-dark: #000000;
|
||||
out property <color> neutral-stroke-disabled-dark: #3d3d3d;
|
||||
|
||||
// Stroke interactive states - Dark theme
|
||||
out property <color> neutral-stroke-1-hover-dark: #525252;
|
||||
out property <color> neutral-stroke-1-pressed-dark: #666666;
|
||||
out property <color> neutral-stroke-1-selected-dark: #666666;
|
||||
out property <color> neutral-stroke-2-hover-dark: #666666;
|
||||
out property <color> neutral-stroke-2-pressed-dark: #757575;
|
||||
|
||||
// ===== TEAM LIGHT THEME COLORS =====
|
||||
|
||||
// Neutral Colors - Team Light
|
||||
out property <color> neutral-foreground-1-team-light: #242424;
|
||||
out property <color> neutral-foreground-2-team-light: #424242;
|
||||
out property <color> neutral-foreground-3-team-light: #616161;
|
||||
out property <color> neutral-foreground-4-team-light: #757575;
|
||||
out property <color> neutral-foreground-disabled-team-light: #bdbdbd;
|
||||
out property <color> neutral-foreground-inverted-team-light: #ffffff;
|
||||
out property <color> neutral-foreground-inverted-2-team-light: #f5f5f5;
|
||||
out property <color> neutral-foreground-on-brand-team-light: #ffffff;
|
||||
out property <color> neutral-foreground-static-inverted-team-light: #ffffff;
|
||||
out property <color> neutral-foreground-inverted-disabled-team-light: #ffffff;
|
||||
|
||||
// Interactive states - Team Light theme
|
||||
out property <color> neutral-foreground-1-hover-team-light: #424242;
|
||||
out property <color> neutral-foreground-1-pressed-team-light: #242424;
|
||||
out property <color> neutral-foreground-2-hover-team-light: #616161;
|
||||
out property <color> neutral-foreground-2-pressed-team-light: #424242;
|
||||
out property <color> neutral-foreground-2-brand-hover-team-light: #585a96;
|
||||
out property <color> neutral-foreground-2-brand-pressed-team-light: #4c4e85;
|
||||
out property <color> neutral-foreground-2-brand-selected-team-light: #6264a7;
|
||||
|
||||
// Link colors - Team Light theme
|
||||
out property <color> neutral-foreground-link-team-light: #6264a7;
|
||||
out property <color> neutral-foreground-link-hover-team-light: #585a96;
|
||||
out property <color> neutral-foreground-link-pressed-team-light: #4c4e85;
|
||||
out property <color> neutral-foreground-link-selected-team-light: #6264a7;
|
||||
|
||||
out property <color> neutral-background-1-team-light: #ffffff;
|
||||
out property <color> neutral-background-2-team-light: #f8f8f8;
|
||||
out property <color> neutral-background-3-team-light: #f3f2f1;
|
||||
out property <color> neutral-background-4-team-light: #edebe9;
|
||||
out property <color> neutral-background-5-team-light: #e1dfdd;
|
||||
out property <color> neutral-background-6-team-light: #d2d0ce;
|
||||
out property <color> neutral-background-inverted-team-light: #292929;
|
||||
out property <color> neutral-background-static-team-light: #edebe9;
|
||||
out property <color> neutral-background-alpha-team-light: #ffffff;
|
||||
out property <color> neutral-background-alpha-2-team-light: #ffffff;
|
||||
|
||||
// Background interactive states - Team Light theme
|
||||
out property <color> neutral-background-1-hover-team-light: #f8f8f8;
|
||||
out property <color> neutral-background-1-pressed-team-light: #f3f2f1;
|
||||
out property <color> neutral-background-1-selected-team-light: #edebe9;
|
||||
out property <color> neutral-background-2-hover-team-light: #f3f2f1;
|
||||
out property <color> neutral-background-2-pressed-team-light: #edebe9;
|
||||
out property <color> neutral-background-2-selected-team-light: #e1dfdd;
|
||||
out property <color> neutral-background-3-hover-team-light: #edebe9;
|
||||
out property <color> neutral-background-3-pressed-team-light: #e1dfdd;
|
||||
out property <color> neutral-background-3-selected-team-light: #d2d0ce;
|
||||
|
||||
out property <color> neutral-stroke-1-team-light: #d2d0ce;
|
||||
out property <color> neutral-stroke-2-team-light: #c8c6c4;
|
||||
out property <color> neutral-stroke-3-team-light: #b3b0ad;
|
||||
out property <color> neutral-stroke-accessible-team-light: #605e5c;
|
||||
out property <color> neutral-stroke-focus-1-team-light: #ffffff;
|
||||
out property <color> neutral-stroke-focus-2-team-light: #000000;
|
||||
out property <color> neutral-stroke-disabled-team-light: #d2d0ce;
|
||||
|
||||
// Stroke interactive states - Team Light theme
|
||||
out property <color> neutral-stroke-1-hover-team-light: #c8c6c4;
|
||||
out property <color> neutral-stroke-1-pressed-team-light: #b3b0ad;
|
||||
out property <color> neutral-stroke-1-selected-team-light: #b3b0ad;
|
||||
out property <color> neutral-stroke-2-hover-team-light: #b3b0ad;
|
||||
out property <color> neutral-stroke-2-pressed-team-light: #a19f9d;
|
||||
|
||||
// ===== TEAM DARK THEME COLORS =====
|
||||
|
||||
// Neutral Colors - Team Dark
|
||||
out property <color> neutral-foreground-1-team-dark: #ffffff;
|
||||
out property <color> neutral-foreground-2-team-dark: #f3f2f1;
|
||||
out property <color> neutral-foreground-3-team-dark: #edebe9;
|
||||
out property <color> neutral-foreground-4-team-dark: #d2d0ce;
|
||||
out property <color> neutral-foreground-disabled-team-dark: #8a8886;
|
||||
out property <color> neutral-foreground-inverted-team-dark: #242424;
|
||||
out property <color> neutral-foreground-inverted-2-team-dark: #292929;
|
||||
out property <color> neutral-foreground-on-brand-team-dark: #ffffff;
|
||||
out property <color> neutral-foreground-static-inverted-team-dark: #ffffff;
|
||||
out property <color> neutral-foreground-inverted-disabled-team-dark: #8a8886;
|
||||
|
||||
// Interactive states - Team Dark theme
|
||||
out property <color> neutral-foreground-1-hover-team-dark: #f3f2f1;
|
||||
out property <color> neutral-foreground-1-pressed-team-dark: #ffffff;
|
||||
out property <color> neutral-foreground-2-hover-team-dark: #edebe9;
|
||||
out property <color> neutral-foreground-2-pressed-team-dark: #f3f2f1;
|
||||
out property <color> neutral-foreground-2-brand-hover-team-dark: #9a9bd2;
|
||||
out property <color> neutral-foreground-2-brand-pressed-team-dark: #a8a9db;
|
||||
out property <color> neutral-foreground-2-brand-selected-team-dark: #8b8cc8;
|
||||
|
||||
// Link colors - Team Dark theme
|
||||
out property <color> neutral-foreground-link-team-dark: #8b8cc8;
|
||||
out property <color> neutral-foreground-link-hover-team-dark: #9a9bd2;
|
||||
out property <color> neutral-foreground-link-pressed-team-dark: #a8a9db;
|
||||
out property <color> neutral-foreground-link-selected-team-dark: #8b8cc8;
|
||||
|
||||
out property <color> neutral-background-1-team-dark: #252423;
|
||||
out property <color> neutral-background-2-team-dark: #2d2c2b;
|
||||
out property <color> neutral-background-3-team-dark: #323130;
|
||||
out property <color> neutral-background-4-team-dark: #3b3a39;
|
||||
out property <color> neutral-background-5-team-dark: #484644;
|
||||
out property <color> neutral-background-6-team-dark: #605e5c;
|
||||
out property <color> neutral-background-inverted-team-dark: #ffffff;
|
||||
out property <color> neutral-background-static-team-dark: #3b3a39;
|
||||
out property <color> neutral-background-alpha-team-dark: #252423;
|
||||
out property <color> neutral-background-alpha-2-team-dark: #252423;
|
||||
|
||||
// Background interactive states - Team Dark theme
|
||||
out property <color> neutral-background-1-hover-team-dark: #2d2c2b;
|
||||
out property <color> neutral-background-1-pressed-team-dark: #323130;
|
||||
out property <color> neutral-background-1-selected-team-dark: #3b3a39;
|
||||
out property <color> neutral-background-2-hover-team-dark: #323130;
|
||||
out property <color> neutral-background-2-pressed-team-dark: #3b3a39;
|
||||
out property <color> neutral-background-2-selected-team-dark: #484644;
|
||||
out property <color> neutral-background-3-hover-team-dark: #3b3a39;
|
||||
out property <color> neutral-background-3-pressed-team-dark: #484644;
|
||||
out property <color> neutral-background-3-selected-team-dark: #605e5c;
|
||||
|
||||
out property <color> neutral-stroke-1-team-dark: #484644;
|
||||
out property <color> neutral-stroke-2-team-dark: #605e5c;
|
||||
out property <color> neutral-stroke-3-team-dark: #797775;
|
||||
out property <color> neutral-stroke-accessible-team-dark: #d2d0ce;
|
||||
out property <color> neutral-stroke-focus-1-team-dark: #ffffff;
|
||||
out property <color> neutral-stroke-focus-2-team-dark: #000000;
|
||||
out property <color> neutral-stroke-disabled-team-dark: #484644;
|
||||
|
||||
// Stroke interactive states - Team Dark theme
|
||||
out property <color> neutral-stroke-1-hover-team-dark: #605e5c;
|
||||
out property <color> neutral-stroke-1-pressed-team-dark: #797775;
|
||||
out property <color> neutral-stroke-1-selected-team-dark: #797775;
|
||||
out property <color> neutral-stroke-2-hover-team-dark: #797775;
|
||||
out property <color> neutral-stroke-2-pressed-team-dark: #8a8886;
|
||||
|
||||
// ===== BRAND COLORS (All Themes) =====
|
||||
|
||||
// Brand Colors - Light
|
||||
out property <color> brand-background-1-light: #0078d4;
|
||||
out property <color> brand-background-2-light: #106ebe;
|
||||
out property <color> brand-background-3-light: #005a9e;
|
||||
out property <color> brand-foreground-1-light: #ffffff;
|
||||
out property <color> brand-foreground-2-light: #f3f2f1;
|
||||
out property <color> brand-stroke-1-light: #0078d4;
|
||||
out property <color> brand-stroke-2-light: #106ebe;
|
||||
|
||||
// Brand interactive states - Light theme
|
||||
out property <color> brand-background-1-hover-light: #106ebe;
|
||||
out property <color> brand-background-1-pressed-light: #005a9e;
|
||||
out property <color> brand-background-1-selected-light: #0078d4;
|
||||
out property <color> brand-background-2-hover-light: #005a9e;
|
||||
out property <color> brand-background-2-pressed-light: #004578;
|
||||
out property <color> brand-stroke-1-hover-light: #106ebe;
|
||||
out property <color> brand-stroke-1-pressed-light: #005a9e;
|
||||
|
||||
// Brand Colors - Dark
|
||||
out property <color> brand-background-1-dark: #479ef5;
|
||||
out property <color> brand-background-2-dark: #62abf5;
|
||||
out property <color> brand-background-3-dark: #77b7f7;
|
||||
out property <color> brand-foreground-1-dark: #ffffff;
|
||||
out property <color> brand-foreground-2-dark: #f3f2f1;
|
||||
out property <color> brand-stroke-1-dark: #479ef5;
|
||||
out property <color> brand-stroke-2-dark: #62abf5;
|
||||
|
||||
// Brand interactive states - Dark theme
|
||||
out property <color> brand-background-1-hover-dark: #62abf5;
|
||||
out property <color> brand-background-1-pressed-dark: #77b7f7;
|
||||
out property <color> brand-background-1-selected-dark: #479ef5;
|
||||
out property <color> brand-background-2-hover-dark: #77b7f7;
|
||||
out property <color> brand-background-2-pressed-dark: #8cc8f8;
|
||||
out property <color> brand-stroke-1-hover-dark: #62abf5;
|
||||
out property <color> brand-stroke-1-pressed-dark: #77b7f7;
|
||||
|
||||
// Brand Colors - Team Light
|
||||
out property <color> brand-background-1-team-light: #6264a7;
|
||||
out property <color> brand-background-2-team-light: #585a96;
|
||||
out property <color> brand-background-3-team-light: #4c4e85;
|
||||
out property <color> brand-foreground-1-team-light: #ffffff;
|
||||
out property <color> brand-foreground-2-team-light: #f3f2f1;
|
||||
out property <color> brand-stroke-1-team-light: #6264a7;
|
||||
out property <color> brand-stroke-2-team-light: #585a96;
|
||||
|
||||
// Brand interactive states - Team Light theme
|
||||
out property <color> brand-background-1-hover-team-light: #585a96;
|
||||
out property <color> brand-background-1-pressed-team-light: #4c4e85;
|
||||
out property <color> brand-background-1-selected-team-light: #6264a7;
|
||||
out property <color> brand-background-2-hover-team-light: #4c4e85;
|
||||
out property <color> brand-background-2-pressed-team-light: #414374;
|
||||
out property <color> brand-stroke-1-hover-team-light: #585a96;
|
||||
out property <color> brand-stroke-1-pressed-team-light: #4c4e85;
|
||||
|
||||
// Brand Colors - Team Dark
|
||||
out property <color> brand-background-1-team-dark: #8b8cc8;
|
||||
out property <color> brand-background-2-team-dark: #9a9bd2;
|
||||
out property <color> brand-background-3-team-dark: #a8a9db;
|
||||
out property <color> brand-foreground-1-team-dark: #ffffff;
|
||||
out property <color> brand-foreground-2-team-dark: #f3f2f1;
|
||||
out property <color> brand-stroke-1-team-dark: #8b8cc8;
|
||||
out property <color> brand-stroke-2-team-dark: #9a9bd2;
|
||||
|
||||
// Brand interactive states - Team Dark theme
|
||||
out property <color> brand-background-1-hover-team-dark: #9a9bd2;
|
||||
out property <color> brand-background-1-pressed-team-dark: #a8a9db;
|
||||
out property <color> brand-background-1-selected-team-dark: #8b8cc8;
|
||||
out property <color> brand-background-2-hover-team-dark: #a8a9db;
|
||||
out property <color> brand-background-2-pressed-team-dark: #b6b7e4;
|
||||
out property <color> brand-stroke-1-hover-team-dark: #9a9bd2;
|
||||
out property <color> brand-stroke-1-pressed-team-dark: #a8a9db;
|
||||
|
||||
// ===== SEMANTIC COLORS (All Themes) =====
|
||||
|
||||
// Success Colors - All Themes
|
||||
out property <color> success-background-1-light: #107c10;
|
||||
out property <color> success-background-2-light: #0e6e0e;
|
||||
out property <color> success-foreground-1-light: #ffffff;
|
||||
out property <color> success-stroke-1-light: #107c10;
|
||||
|
||||
out property <color> success-background-1-dark: #54b054;
|
||||
out property <color> success-background-2-dark: #6bb26b;
|
||||
out property <color> success-foreground-1-dark: #ffffff;
|
||||
out property <color> success-stroke-1-dark: #54b054;
|
||||
|
||||
out property <color> success-background-1-team-light: #237b4b;
|
||||
out property <color> success-background-2-team-light: #1e6f42;
|
||||
out property <color> success-foreground-1-team-light: #ffffff;
|
||||
out property <color> success-stroke-1-team-light: #237b4b;
|
||||
|
||||
out property <color> success-background-1-team-dark: #5bb85b;
|
||||
out property <color> success-background-2-team-dark: #6fc46f;
|
||||
out property <color> success-foreground-1-team-dark: #ffffff;
|
||||
out property <color> success-stroke-1-team-dark: #5bb85b;
|
||||
|
||||
// Warning Colors - All Themes
|
||||
out property <color> warning-background-1-light: #fde047;
|
||||
out property <color> warning-background-2-light: #facc15;
|
||||
out property <color> warning-foreground-1-light: #323130;
|
||||
out property <color> warning-stroke-1-light: #f7c52d;
|
||||
|
||||
out property <color> warning-background-1-dark: #ffb900;
|
||||
out property <color> warning-background-2-dark: #ffc328;
|
||||
out property <color> warning-foreground-1-dark: #323130;
|
||||
out property <color> warning-stroke-1-dark: #ffb900;
|
||||
|
||||
out property <color> warning-background-1-team-light: #c19c00;
|
||||
out property <color> warning-background-2-team-light: #a18600;
|
||||
out property <color> warning-foreground-1-team-light: #ffffff;
|
||||
out property <color> warning-stroke-1-team-light: #c19c00;
|
||||
|
||||
out property <color> warning-background-1-team-dark: #ffd43a;
|
||||
out property <color> warning-background-2-team-dark: #ffda56;
|
||||
out property <color> warning-foreground-1-team-dark: #323130;
|
||||
out property <color> warning-stroke-1-team-dark: #ffd43a;
|
||||
|
||||
// Critical/Error Colors - All Themes
|
||||
out property <color> critical-background-1-light: #d13438;
|
||||
out property <color> critical-background-2-light: #b91c1c;
|
||||
out property <color> critical-foreground-1-light: #ffffff;
|
||||
out property <color> critical-stroke-1-light: #d13438;
|
||||
|
||||
out property <color> critical-background-1-dark: #ff6b6b;
|
||||
out property <color> critical-background-2-dark: #ff8080;
|
||||
out property <color> critical-foreground-1-dark: #ffffff;
|
||||
out property <color> critical-stroke-1-dark: #ff6b6b;
|
||||
|
||||
out property <color> critical-background-1-team-light: #c50e1f;
|
||||
out property <color> critical-background-2-team-light: #a80e1b;
|
||||
out property <color> critical-foreground-1-team-light: #ffffff;
|
||||
out property <color> critical-stroke-1-team-light: #c50e1f;
|
||||
|
||||
out property <color> critical-background-1-team-dark: #ff8080;
|
||||
out property <color> critical-background-2-team-dark: #ff9494;
|
||||
out property <color> critical-foreground-1-team-dark: #ffffff;
|
||||
out property <color> critical-stroke-1-team-dark: #ff8080;
|
||||
|
||||
// ===== CURRENT THEME ACCESSORS =====
|
||||
// These automatically switch based on current-mode
|
||||
|
||||
// Current Neutral Colors
|
||||
out property <color> neutral-foreground-1: current-mode == ColorMode.light ? neutral-foreground-1-light :
|
||||
current-mode == ColorMode.dark ? neutral-foreground-1-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-foreground-1-team-light : neutral-foreground-1-team-dark;
|
||||
|
||||
out property <color> neutral-foreground-2: current-mode == ColorMode.light ? neutral-foreground-2-light :
|
||||
current-mode == ColorMode.dark ? neutral-foreground-2-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-foreground-2-team-light : neutral-foreground-2-team-dark;
|
||||
|
||||
out property <color> neutral-foreground-3: current-mode == ColorMode.light ? neutral-foreground-3-light :
|
||||
current-mode == ColorMode.dark ? neutral-foreground-3-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-foreground-3-team-light : neutral-foreground-3-team-dark;
|
||||
|
||||
out property <color> neutral-foreground-disabled: current-mode == ColorMode.light ? neutral-foreground-disabled-light :
|
||||
current-mode == ColorMode.dark ? neutral-foreground-disabled-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-foreground-disabled-team-light : neutral-foreground-disabled-team-dark;
|
||||
|
||||
out property <color> neutral-background-1: current-mode == ColorMode.light ? neutral-background-1-light :
|
||||
current-mode == ColorMode.dark ? neutral-background-1-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-background-1-team-light : neutral-background-1-team-dark;
|
||||
|
||||
out property <color> neutral-background-2: current-mode == ColorMode.light ? neutral-background-2-light :
|
||||
current-mode == ColorMode.dark ? neutral-background-2-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-background-2-team-light : neutral-background-2-team-dark;
|
||||
|
||||
out property <color> neutral-background-3: current-mode == ColorMode.light ? neutral-background-3-light :
|
||||
current-mode == ColorMode.dark ? neutral-background-3-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-background-3-team-light : neutral-background-3-team-dark;
|
||||
|
||||
out property <color> neutral-background-4: current-mode == ColorMode.light ? neutral-background-4-light :
|
||||
current-mode == ColorMode.dark ? neutral-background-4-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-background-4-team-light : neutral-background-4-team-dark;
|
||||
|
||||
out property <color> neutral-stroke-1: current-mode == ColorMode.light ? neutral-stroke-1-light :
|
||||
current-mode == ColorMode.dark ? neutral-stroke-1-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-stroke-1-team-light : neutral-stroke-1-team-dark;
|
||||
|
||||
out property <color> neutral-stroke-2: current-mode == ColorMode.light ? neutral-stroke-2-light :
|
||||
current-mode == ColorMode.dark ? neutral-stroke-2-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-stroke-2-team-light : neutral-stroke-2-team-dark;
|
||||
|
||||
out property <color> neutral-stroke-accessible: current-mode == ColorMode.light ? neutral-stroke-accessible-light :
|
||||
current-mode == ColorMode.dark ? neutral-stroke-accessible-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-stroke-accessible-team-light : neutral-stroke-accessible-team-dark;
|
||||
|
||||
// Current Interactive States
|
||||
out property <color> neutral-foreground-1-hover: current-mode == ColorMode.light ? neutral-foreground-1-hover-light :
|
||||
current-mode == ColorMode.dark ? neutral-foreground-1-hover-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-foreground-1-hover-team-light : neutral-foreground-1-hover-team-dark;
|
||||
|
||||
out property <color> neutral-foreground-2-brand-hover: current-mode == ColorMode.light ? neutral-foreground-2-brand-hover-light :
|
||||
current-mode == ColorMode.dark ? neutral-foreground-2-brand-hover-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-foreground-2-brand-hover-team-light : neutral-foreground-2-brand-hover-team-dark;
|
||||
|
||||
// Current Link Colors
|
||||
out property <color> neutral-foreground-link: current-mode == ColorMode.light ? neutral-foreground-link-light :
|
||||
current-mode == ColorMode.dark ? neutral-foreground-link-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-foreground-link-team-light : neutral-foreground-link-team-dark;
|
||||
|
||||
out property <color> neutral-foreground-link-hover: current-mode == ColorMode.light ? neutral-foreground-link-hover-light :
|
||||
current-mode == ColorMode.dark ? neutral-foreground-link-hover-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-foreground-link-hover-team-light : neutral-foreground-link-hover-team-dark;
|
||||
|
||||
out property <color> neutral-foreground-link-pressed: current-mode == ColorMode.light ? neutral-foreground-link-pressed-light :
|
||||
current-mode == ColorMode.dark ? neutral-foreground-link-pressed-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-foreground-link-pressed-team-light : neutral-foreground-link-pressed-team-dark;
|
||||
|
||||
// Current Background Interactive States
|
||||
out property <color> neutral-background-1-hover: current-mode == ColorMode.light ? neutral-background-1-hover-light :
|
||||
current-mode == ColorMode.dark ? neutral-background-1-hover-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-background-1-hover-team-light : neutral-background-1-hover-team-dark;
|
||||
|
||||
out property <color> neutral-background-1-pressed: current-mode == ColorMode.light ? neutral-background-1-pressed-light :
|
||||
current-mode == ColorMode.dark ? neutral-background-1-pressed-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-background-1-pressed-team-light : neutral-background-1-pressed-team-dark;
|
||||
|
||||
// Current Stroke Interactive States
|
||||
out property <color> neutral-stroke-1-hover: current-mode == ColorMode.light ? neutral-stroke-1-hover-light :
|
||||
current-mode == ColorMode.dark ? neutral-stroke-1-hover-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-stroke-1-hover-team-light : neutral-stroke-1-hover-team-dark;
|
||||
|
||||
out property <color> neutral-stroke-1-pressed: current-mode == ColorMode.light ? neutral-stroke-1-pressed-light :
|
||||
current-mode == ColorMode.dark ? neutral-stroke-1-pressed-dark :
|
||||
current-mode == ColorMode.team-light ? neutral-stroke-1-pressed-team-light : neutral-stroke-1-pressed-team-dark;
|
||||
|
||||
// Current Brand Colors
|
||||
out property <color> brand-background-1: current-mode == ColorMode.light ? brand-background-1-light :
|
||||
current-mode == ColorMode.dark ? brand-background-1-dark :
|
||||
current-mode == ColorMode.team-light ? brand-background-1-team-light : brand-background-1-team-dark;
|
||||
|
||||
out property <color> brand-background-2: current-mode == ColorMode.light ? brand-background-2-light :
|
||||
current-mode == ColorMode.dark ? brand-background-2-dark :
|
||||
current-mode == ColorMode.team-light ? brand-background-2-team-light : brand-background-2-team-dark;
|
||||
|
||||
out property <color> brand-foreground-1: current-mode == ColorMode.light ? brand-foreground-1-light :
|
||||
current-mode == ColorMode.dark ? brand-foreground-1-dark :
|
||||
current-mode == ColorMode.team-light ? brand-foreground-1-team-light : brand-foreground-1-team-dark;
|
||||
|
||||
// Current Brand Interactive States
|
||||
out property <color> brand-background-1-hover: current-mode == ColorMode.light ? brand-background-1-hover-light :
|
||||
current-mode == ColorMode.dark ? brand-background-1-hover-dark :
|
||||
current-mode == ColorMode.team-light ? brand-background-1-hover-team-light : brand-background-1-hover-team-dark;
|
||||
|
||||
out property <color> brand-background-1-pressed: current-mode == ColorMode.light ? brand-background-1-pressed-light :
|
||||
current-mode == ColorMode.dark ? brand-background-1-pressed-dark :
|
||||
current-mode == ColorMode.team-light ? brand-background-1-pressed-team-light : brand-background-1-pressed-team-dark;
|
||||
|
||||
// Current Semantic Colors
|
||||
out property <color> success-background-1: current-mode == ColorMode.light ? success-background-1-light :
|
||||
current-mode == ColorMode.dark ? success-background-1-dark :
|
||||
current-mode == ColorMode.team-light ? success-background-1-team-light : success-background-1-team-dark;
|
||||
|
||||
out property <color> warning-background-1: current-mode == ColorMode.light ? warning-background-1-light :
|
||||
current-mode == ColorMode.dark ? warning-background-1-dark :
|
||||
current-mode == ColorMode.team-light ? warning-background-1-team-light : warning-background-1-team-dark;
|
||||
|
||||
out property <color> critical-background-1: current-mode == ColorMode.light ? critical-background-1-light :
|
||||
current-mode == ColorMode.dark ? critical-background-1-dark :
|
||||
current-mode == ColorMode.team-light ? critical-background-1-team-light : critical-background-1-team-dark;
|
||||
|
||||
// Legacy compatibility and Trading-specific colors
|
||||
out property <color> neutral-foreground-rest: neutral-foreground-1;
|
||||
out property <color> profit-green: success-background-1;
|
||||
out property <color> loss-red: critical-background-1;
|
||||
out property <color> neutral-gray: neutral-foreground-3;
|
||||
|
||||
// Accent colors for trading UI
|
||||
out property <color> accent-purple: #f000b8;
|
||||
out property <color> accent-teal: #37cdbe;
|
||||
out property <color> accent-blue: brand-background-1;
|
||||
}
|
||||
|
||||
// Typography System - Official Fluent 2 Typography Tokens
|
||||
// Based on: https://fluent2.microsoft.design/typography
|
||||
export global FluentTypography {
|
||||
// ===== FLUENT FONT STACKS =====
|
||||
// Segoe - unmistakably Microsoft (Primary Web/Windows font stack)
|
||||
out property <string> font-family-base: "Segoe UI Variable, Segoe UI, system-ui, sans-serif";
|
||||
out property <string> font-family-web: "Segoe UI Variable, Segoe UI, system-ui, sans-serif";
|
||||
out property <string> font-family-windows: "Segoe UI Variable, Segoe UI, system-ui, sans-serif";
|
||||
|
||||
// Platform-specific native font stacks for cross-platform consistency
|
||||
out property <string> font-family-macos: "SF Pro Display, SF Pro Text, system-ui, sans-serif";
|
||||
out property <string> font-family-ios: "SF Pro Display, SF Pro Text, system-ui, sans-serif";
|
||||
out property <string> font-family-android: "Roboto, system-ui, sans-serif";
|
||||
|
||||
// Specialized font families
|
||||
out property <string> font-family-monospace: "Cascadia Code, Cascadia Mono, Consolas, Courier New, monospace";
|
||||
out property <string> font-family-numeric: "Bahnschrift, Segoe UI Variable, Segoe UI, system-ui, sans-serif";
|
||||
|
||||
// ===== FONT WEIGHTS - Fluent 2 Weight Scale =====
|
||||
out property <int> font-weight-regular: 400; // Regular
|
||||
out property <int> font-weight-medium: 500; // Medium (Android)
|
||||
out property <int> font-weight-semibold: 600; // Semibold
|
||||
out property <int> font-weight-bold: 700; // Bold
|
||||
|
||||
// ===== WEB TYPE RAMP - Official Fluent 2 Web Typography =====
|
||||
// Caption styles
|
||||
out property <length> font-size-caption-2: 10px; // Caption 2
|
||||
out property <length> line-height-caption-2: 14px;
|
||||
out property <int> font-weight-caption-2: font-weight-regular;
|
||||
out property <int> font-weight-caption-2-strong: font-weight-semibold;
|
||||
|
||||
out property <length> font-size-caption-1: 12px; // Caption 1
|
||||
out property <length> line-height-caption-1: 16px;
|
||||
out property <int> font-weight-caption-1: font-weight-regular;
|
||||
out property <int> font-weight-caption-1-strong: font-weight-semibold;
|
||||
out property <int> font-weight-caption-1-stronger: font-weight-bold;
|
||||
|
||||
// Body styles
|
||||
out property <length> font-size-body-1: 14px; // Body 1 (Default)
|
||||
out property <length> line-height-body-1: 20px;
|
||||
out property <int> font-weight-body-1: font-weight-regular;
|
||||
out property <int> font-weight-body-1-strong: font-weight-semibold;
|
||||
out property <int> font-weight-body-1-stronger: font-weight-bold;
|
||||
|
||||
// Subtitle styles
|
||||
out property <length> font-size-subtitle-2: 16px; // Subtitle 2
|
||||
out property <length> line-height-subtitle-2: 22px;
|
||||
out property <int> font-weight-subtitle-2: font-weight-semibold;
|
||||
out property <int> font-weight-subtitle-2-stronger: font-weight-bold;
|
||||
|
||||
out property <length> font-size-subtitle-1: 20px; // Subtitle 1
|
||||
out property <length> line-height-subtitle-1: 26px;
|
||||
out property <int> font-weight-subtitle-1: font-weight-semibold;
|
||||
|
||||
// Title styles
|
||||
out property <length> font-size-title-3: 24px; // Title 3
|
||||
out property <length> line-height-title-3: 32px;
|
||||
out property <int> font-weight-title-3: font-weight-semibold;
|
||||
|
||||
out property <length> font-size-title-2: 28px; // Title 2
|
||||
out property <length> line-height-title-2: 36px;
|
||||
out property <int> font-weight-title-2: font-weight-semibold;
|
||||
|
||||
out property <length> font-size-title-1: 32px; // Title 1
|
||||
out property <length> line-height-title-1: 40px;
|
||||
out property <int> font-weight-title-1: font-weight-semibold;
|
||||
|
||||
// Large title and display
|
||||
out property <length> font-size-large-title: 40px; // Large Title
|
||||
out property <length> line-height-large-title: 52px;
|
||||
out property <int> font-weight-large-title: font-weight-semibold;
|
||||
|
||||
out property <length> font-size-display: 68px; // Display
|
||||
out property <length> line-height-display: 92px;
|
||||
out property <int> font-weight-display: font-weight-semibold;
|
||||
|
||||
// ===== WINDOWS TYPE RAMP - Official Fluent 2 Windows Typography =====
|
||||
// Windows-specific variants using Segoe UI Variable
|
||||
out property <length> font-size-windows-caption: 12px; // Caption
|
||||
out property <length> line-height-windows-caption: 16px;
|
||||
out property <int> font-weight-windows-caption: font-weight-regular;
|
||||
|
||||
out property <length> font-size-windows-body: 14px; // Body
|
||||
out property <length> line-height-windows-body: 20px;
|
||||
out property <int> font-weight-windows-body: font-weight-regular;
|
||||
out property <int> font-weight-windows-body-strong: font-weight-semibold;
|
||||
|
||||
out property <length> font-size-windows-body-large: 18px; // Body Large
|
||||
out property <length> line-height-windows-body-large: 24px;
|
||||
out property <int> font-weight-windows-body-large: font-weight-regular;
|
||||
|
||||
out property <length> font-size-windows-subtitle: 20px; // Subtitle
|
||||
out property <length> line-height-windows-subtitle: 28px;
|
||||
out property <int> font-weight-windows-subtitle: font-weight-semibold;
|
||||
|
||||
out property <length> font-size-windows-title: 28px; // Title
|
||||
out property <length> line-height-windows-title: 36px;
|
||||
out property <int> font-weight-windows-title: font-weight-semibold;
|
||||
|
||||
out property <length> font-size-windows-large-title: 40px; // Large Title
|
||||
out property <length> line-height-windows-large-title: 52px;
|
||||
out property <int> font-weight-windows-large-title: font-weight-semibold;
|
||||
|
||||
out property <length> font-size-windows-display: 68px; // Display
|
||||
out property <length> line-height-windows-display: 92px;
|
||||
out property <int> font-weight-windows-display: font-weight-semibold;
|
||||
|
||||
// ===== LEGACY NUMERIC TOKENS - For backward compatibility =====
|
||||
out property <length> font-size-100: font-size-caption-2; // 10px
|
||||
out property <length> font-size-200: font-size-caption-1; // 12px
|
||||
out property <length> font-size-300: font-size-body-1; // 14px
|
||||
out property <length> font-size-400: font-size-subtitle-2; // 16px
|
||||
out property <length> font-size-500: 18px; // Custom
|
||||
out property <length> font-size-600: font-size-subtitle-1; // 20px
|
||||
out property <length> font-size-700: font-size-title-3; // 24px
|
||||
out property <length> font-size-800: font-size-title-2; // 28px
|
||||
out property <length> font-size-900: font-size-title-1; // 32px
|
||||
out property <length> font-size-1000: font-size-large-title; // 40px
|
||||
out property <length> font-size-1100: 48px; // Custom Large
|
||||
out property <length> font-size-1200: font-size-display; // 68px
|
||||
|
||||
out property <length> line-height-100: line-height-caption-2; // 14px
|
||||
out property <length> line-height-200: line-height-caption-1; // 16px
|
||||
out property <length> line-height-300: line-height-body-1; // 20px
|
||||
out property <length> line-height-400: line-height-subtitle-2; // 22px
|
||||
out property <length> line-height-500: 24px; // Custom
|
||||
out property <length> line-height-600: line-height-subtitle-1; // 26px
|
||||
out property <length> line-height-700: line-height-title-3; // 32px
|
||||
out property <length> line-height-800: line-height-title-2; // 36px
|
||||
out property <length> line-height-900: line-height-title-1; // 40px
|
||||
out property <length> line-height-1000: line-height-large-title; // 52px
|
||||
out property <length> line-height-1100: 60px; // Custom
|
||||
out property <length> line-height-1200: line-height-display; // 92px
|
||||
|
||||
// ===== TEXT STYLING UTILITIES =====
|
||||
// Letter spacing for fine typography control
|
||||
out property <length> letter-spacing-tight: -0.16px; // For large text
|
||||
out property <length> letter-spacing-normal: 0px; // Standard
|
||||
out property <length> letter-spacing-wide: 0.32px; // For small text
|
||||
|
||||
// Text decoration
|
||||
out property <string> text-decoration-none: "none";
|
||||
out property <string> text-decoration-underline: "underline";
|
||||
out property <string> text-decoration-line-through: "line-through";
|
||||
|
||||
// Text transform (following Fluent guidance for sentence case)
|
||||
out property <string> text-transform-none: "none";
|
||||
out property <string> text-transform-uppercase: "uppercase";
|
||||
out property <string> text-transform-lowercase: "lowercase";
|
||||
out property <string> text-transform-capitalize: "capitalize";
|
||||
|
||||
// ===== USAGE EXAMPLES =====
|
||||
// Caption 2: font-size: FluentTypography.font-size-caption-2; line-height: FluentTypography.line-height-caption-2; font-weight: FluentTypography.font-weight-caption-2;
|
||||
// Body 1: font-size: FluentTypography.font-size-body-1; line-height: FluentTypography.line-height-body-1; font-weight: FluentTypography.font-weight-body-1;
|
||||
// Title 1: font-size: FluentTypography.font-size-title-1; line-height: FluentTypography.line-height-title-1; font-weight: FluentTypography.font-weight-title-1;
|
||||
// Display: font-size: FluentTypography.font-size-display; line-height: FluentTypography.line-height-display; font-weight: FluentTypography.font-weight-display;
|
||||
}
|
||||
|
||||
// Spacing System - Fluent 2 Spacing Scale
|
||||
export global FluentSpacing {
|
||||
out property <length> space-2: 2px;
|
||||
out property <length> space-4: 4px;
|
||||
out property <length> space-6: 6px;
|
||||
out property <length> space-8: 8px;
|
||||
out property <length> space-10: 10px;
|
||||
out property <length> space-12: 12px;
|
||||
out property <length> space-16: 16px;
|
||||
out property <length> space-20: 20px;
|
||||
out property <length> space-24: 24px;
|
||||
out property <length> space-28: 28px;
|
||||
out property <length> space-32: 32px;
|
||||
out property <length> space-36: 36px;
|
||||
out property <length> space-40: 40px;
|
||||
out property <length> space-48: 48px;
|
||||
out property <length> space-64: 64px;
|
||||
out property <length> space-80: 80px;
|
||||
out property <length> space-96: 96px;
|
||||
out property <length> space-120: 120px;
|
||||
}
|
||||
|
||||
// Border Radius - Complete Fluent UI Border Radius System
|
||||
export global FluentRadius {
|
||||
// Corner Radius Scale
|
||||
out property <length> border-radius-none: 0px;
|
||||
out property <length> border-radius-small: 2px;
|
||||
out property <length> border-radius-medium: 4px;
|
||||
out property <length> border-radius-large: 6px;
|
||||
out property <length> border-radius-x-large: 8px;
|
||||
out property <length> border-radius-circular: 10000px;
|
||||
|
||||
// Legacy support
|
||||
out property <length> radius-none: 0px;
|
||||
out property <length> radius-small: 2px;
|
||||
out property <length> radius-medium: 4px;
|
||||
out property <length> radius-large: 6px;
|
||||
out property <length> radius-xlarge: 8px;
|
||||
out property <length> radius-circular: 10000px;
|
||||
}
|
||||
|
||||
// Shadows - Complete Fluent UI Shadow System
|
||||
// Based on: https://react.fluentui.dev/?path=/docs/theme-shadows--docs
|
||||
export global FluentShadows {
|
||||
// ===== SHADOW BRAND TOKENS =====
|
||||
// These are the primary shadow tokens used throughout Fluent UI
|
||||
|
||||
// Shadow 2 - Subtle elevation (tooltips, dropdowns)
|
||||
out property <length> shadow-2-x: 0px;
|
||||
out property <length> shadow-2-y: 1px;
|
||||
out property <length> shadow-2-blur: 2px;
|
||||
out property <length> shadow-2-spread: 0px;
|
||||
out property <color> shadow-2-color: #00000014; // 8% opacity black
|
||||
|
||||
// Shadow 4 - Low elevation (cards, buttons)
|
||||
out property <length> shadow-4-x: 0px;
|
||||
out property <length> shadow-4-y: 2px;
|
||||
out property <length> shadow-4-blur: 4px;
|
||||
out property <length> shadow-4-spread: 0px;
|
||||
out property <color> shadow-4-color: #0000001f; // 12% opacity black
|
||||
|
||||
// Shadow 8 - Medium elevation (dialogs, menus)
|
||||
out property <length> shadow-8-x: 0px;
|
||||
out property <length> shadow-8-y: 4px;
|
||||
out property <length> shadow-8-blur: 8px;
|
||||
out property <length> shadow-8-spread: 0px;
|
||||
out property <color> shadow-8-color: #0000001f; // 12% opacity black
|
||||
|
||||
// Shadow 16 - High elevation (modals, flyouts)
|
||||
out property <length> shadow-16-x: 0px;
|
||||
out property <length> shadow-16-y: 8px;
|
||||
out property <length> shadow-16-blur: 16px;
|
||||
out property <length> shadow-16-spread: 0px;
|
||||
out property <color> shadow-16-color: #00000024; // 14% opacity black
|
||||
|
||||
// Shadow 28 - Very high elevation (teaching callouts)
|
||||
out property <length> shadow-28-x: 0px;
|
||||
out property <length> shadow-28-y: 14px;
|
||||
out property <length> shadow-28-blur: 28px;
|
||||
out property <length> shadow-28-spread: 0px;
|
||||
out property <color> shadow-28-color: #00000024; // 14% opacity black
|
||||
|
||||
// Shadow 64 - Maximum elevation (panels, navigation)
|
||||
out property <length> shadow-64-x: 0px;
|
||||
out property <length> shadow-64-y: 32px;
|
||||
out property <length> shadow-64-blur: 64px;
|
||||
out property <length> shadow-64-spread: 0px;
|
||||
out property <color> shadow-64-color: #00000033; // 20% opacity black
|
||||
|
||||
// ===== THEME-AWARE SHADOW COLORS =====
|
||||
// Light theme shadow colors
|
||||
out property <color> shadow-light-ambient: #0000000f; // 6% opacity black
|
||||
out property <color> shadow-light-key: #00000014; // 8% opacity black
|
||||
out property <color> shadow-light-ambient-darker: #00000014; // 8% opacity black
|
||||
out property <color> shadow-light-key-darker: #0000001f; // 12% opacity black
|
||||
out property <color> shadow-light-ambient-darkest: #0000001f; // 12% opacity black
|
||||
out property <color> shadow-light-key-darkest: #00000024; // 14% opacity black
|
||||
|
||||
// Dark theme shadow colors
|
||||
out property <color> shadow-dark-ambient: #0000001f; // 12% opacity black
|
||||
out property <color> shadow-dark-key: #00000024; // 14% opacity black
|
||||
out property <color> shadow-dark-ambient-darker: #00000024; // 14% opacity black
|
||||
out property <color> shadow-dark-key-darker: #00000033; // 20% opacity black
|
||||
out property <color> shadow-dark-ambient-darkest: #00000033; // 20% opacity black
|
||||
out property <color> shadow-dark-key-darkest: #00000047; // 28% opacity black
|
||||
|
||||
// ===== SPECIALIZED SHADOW TOKENS =====
|
||||
// Brand shadow (with brand color tint)
|
||||
out property <length> shadow-brand-x: 0px;
|
||||
out property <length> shadow-brand-y: 2px;
|
||||
out property <length> shadow-brand-blur: 8px;
|
||||
out property <length> shadow-brand-spread: 0px;
|
||||
out property <color> shadow-brand-color: #0078d414; // Brand blue with 8% opacity
|
||||
|
||||
// Inset shadow (for pressed states)
|
||||
out property <length> shadow-inset-x: 0px;
|
||||
out property <length> shadow-inset-y: 1px;
|
||||
out property <length> shadow-inset-blur: 2px;
|
||||
out property <length> shadow-inset-spread: 0px;
|
||||
out property <color> shadow-inset-color: #0000001f; // 12% opacity black
|
||||
|
||||
// Focus shadow (for accessibility)
|
||||
out property <length> shadow-focus-x: 0px;
|
||||
out property <length> shadow-focus-y: 0px;
|
||||
out property <length> shadow-focus-blur: 0px;
|
||||
out property <length> shadow-focus-spread: 2px;
|
||||
out property <color> shadow-focus-color: #0078d4; // Brand blue
|
||||
|
||||
// ===== COMPONENT-SPECIFIC SHADOW TOKENS =====
|
||||
// Button shadows
|
||||
out property <color> shadow-button-rest: shadow-2-color;
|
||||
out property <color> shadow-button-hover: shadow-4-color;
|
||||
out property <color> shadow-button-pressed: shadow-inset-color;
|
||||
|
||||
// Card shadows
|
||||
out property <color> shadow-card-rest: shadow-4-color;
|
||||
out property <color> shadow-card-hover: shadow-8-color;
|
||||
|
||||
// Dialog shadows
|
||||
out property <color> shadow-dialog: shadow-64-color;
|
||||
|
||||
// Flyout shadows
|
||||
out property <color> shadow-flyout: shadow-16-color;
|
||||
|
||||
// Tooltip shadows
|
||||
out property <color> shadow-tooltip: shadow-8-color;
|
||||
|
||||
// ===== LEGACY SHADOW SUPPORT =====
|
||||
// Note: shadow-*-blur properties are already defined above in the main shadow tokens
|
||||
// They can be used directly for backward compatibility
|
||||
|
||||
// ===== SHADOW UTILITY FUNCTIONS =====
|
||||
// Helper properties for common shadow combinations
|
||||
|
||||
// Subtle shadow (for subtle elevation)
|
||||
out property <length> subtle-shadow-x: shadow-2-x;
|
||||
out property <length> subtle-shadow-y: shadow-2-y;
|
||||
out property <length> subtle-shadow-blur: shadow-2-blur;
|
||||
out property <color> subtle-shadow-color: shadow-2-color;
|
||||
|
||||
// Default shadow (for standard elevation)
|
||||
out property <length> default-shadow-x: shadow-4-x;
|
||||
out property <length> default-shadow-y: shadow-4-y;
|
||||
out property <length> default-shadow-blur: shadow-4-blur;
|
||||
out property <color> default-shadow-color: shadow-4-color;
|
||||
|
||||
// Deep shadow (for high elevation)
|
||||
out property <length> deep-shadow-x: shadow-16-x;
|
||||
out property <length> deep-shadow-y: shadow-16-y;
|
||||
out property <length> deep-shadow-blur: shadow-16-blur;
|
||||
out property <color> deep-shadow-color: shadow-16-color;
|
||||
|
||||
// ===== USAGE NOTES =====
|
||||
// To apply shadows in components, use the individual tokens:
|
||||
// Example: Rectangle { drop-shadow-offset-x: FluentShadows.shadow-4-x; drop-shadow-offset-y: FluentShadows.shadow-4-y; drop-shadow-blur: FluentShadows.shadow-4-blur; drop-shadow-color: FluentShadows.shadow-4-color; }
|
||||
// For focus states: Rectangle { border-width: FluentShadows.shadow-focus-spread; border-color: FluentShadows.shadow-focus-color; }
|
||||
}
|
||||
|
||||
// Component Tokens - Fluent 2 Component Specifications
|
||||
export global FluentComponents {
|
||||
// Button
|
||||
out property <length> button-height-small: 24px;
|
||||
out property <length> button-height-medium: 32px;
|
||||
out property <length> button-height-large: 40px;
|
||||
out property <length> button-padding-horizontal: 16px;
|
||||
out property <length> button-border-radius: FluentRadius.border-radius-medium;
|
||||
|
||||
// Input
|
||||
out property <length> input-height: 32px;
|
||||
out property <length> input-padding-horizontal: 12px;
|
||||
out property <length> input-border-radius: FluentRadius.border-radius-medium;
|
||||
out property <length> input-border-width: 1px;
|
||||
|
||||
// Card
|
||||
out property <length> card-padding: FluentSpacing.space-16;
|
||||
out property <length> card-border-radius: FluentRadius.border-radius-large;
|
||||
out property <length> card-border-width: 1px;
|
||||
|
||||
// Navigation
|
||||
out property <length> nav-item-height: 40px;
|
||||
out property <length> nav-item-padding: FluentSpacing.space-12;
|
||||
out property <length> nav-item-border-radius: FluentRadius.border-radius-medium;
|
||||
|
||||
// Title Bar
|
||||
out property <length> titlebar-height: 32px;
|
||||
out property <length> titlebar-button-width: 46px;
|
||||
|
||||
// Sidebar
|
||||
out property <length> sidebar-width: 280px;
|
||||
out property <length> sidebar-collapsed-width: 48px;
|
||||
}
|
||||
|
||||
// Animation & Motion - Fluent 2 Motion System
|
||||
export global FluentMotion {
|
||||
out property <duration> duration-ultra-fast: 50ms;
|
||||
out property <duration> duration-faster: 100ms;
|
||||
out property <duration> duration-fast: 150ms;
|
||||
out property <duration> duration-normal: 200ms;
|
||||
out property <duration> duration-slow: 300ms;
|
||||
out property <duration> duration-slower: 400ms;
|
||||
out property <duration> duration-ultra-slow: 500ms;
|
||||
|
||||
// Easing curves (represented as animation properties)
|
||||
out property <easing> ease-accelerate: ease-in;
|
||||
out property <easing> ease-decelerate: ease-out;
|
||||
out property <easing> ease-standard: ease-in-out;
|
||||
out property <easing> ease-max: ease;
|
||||
}
|
||||
|
||||
// Layout Grid - Fluent 2 Layout System
|
||||
export global FluentLayout {
|
||||
// Breakpoints
|
||||
out property <length> breakpoint-small: 480px;
|
||||
out property <length> breakpoint-medium: 768px;
|
||||
out property <length> breakpoint-large: 1024px;
|
||||
out property <length> breakpoint-xlarge: 1440px;
|
||||
|
||||
// Container max widths
|
||||
out property <length> container-small: 640px;
|
||||
out property <length> container-medium: 768px;
|
||||
out property <length> container-large: 1024px;
|
||||
out property <length> container-xlarge: 1280px;
|
||||
|
||||
// Grid
|
||||
out property <length> grid-gutter: FluentSpacing.space-24;
|
||||
out property <int> grid-columns: 12;
|
||||
}
|
||||
|
||||
// Z-Index Scale
|
||||
export global FluentLayers {
|
||||
out property <int> layer-base: 0;
|
||||
out property <int> layer-dropdown: 1000;
|
||||
out property <int> layer-sticky: 1020;
|
||||
out property <int> layer-banner: 1030;
|
||||
out property <int> layer-overlay: 1040;
|
||||
out property <int> layer-modal: 1050;
|
||||
out property <int> layer-popover: 1060;
|
||||
out property <int> layer-tooltip: 1070;
|
||||
out property <int> layer-toast: 1080;
|
||||
}
|
||||
8
ui/shared/design-system/index.slint
Normal file
8
ui/shared/design-system/index.slint
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// Design System Public API
|
||||
// This file exports all design tokens and components from the design system
|
||||
|
||||
// Export design tokens
|
||||
export { Theme } from "tokens/theme.slint";
|
||||
|
||||
// Export design system components
|
||||
export * from "components/design-system.slint";
|
||||
29
ui/shared/design-system/tokens/theme.slint
Normal file
29
ui/shared/design-system/tokens/theme.slint
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// Global theme management system
|
||||
export global Theme {
|
||||
in-out property <bool> is-dark-mode: false;
|
||||
|
||||
// Color scheme properties that automatically update based on theme
|
||||
out property <color> background: is-dark-mode ? #1a1a1a : #ffffff;
|
||||
out property <color> surface: is-dark-mode ? #2a2a2a : #f5f5f5;
|
||||
out property <color> primary: #3b82f6;
|
||||
out property <color> primary-variant: is-dark-mode ? #60a5fa : #2563eb;
|
||||
out property <color> secondary: is-dark-mode ? #64748b : #475569;
|
||||
out property <color> text-primary: is-dark-mode ? #ffffff : #1f2937;
|
||||
out property <color> text-secondary: is-dark-mode ? #d1d5db : #6b7280;
|
||||
out property <color> border: is-dark-mode ? #374151 : #e5e7eb;
|
||||
out property <color> accent: is-dark-mode ? #22c55e : #16a34a;
|
||||
out property <color> error: #ef4444;
|
||||
out property <color> warning: #f59e0b;
|
||||
out property <color> success: #10b981;
|
||||
|
||||
// Card and container colors
|
||||
out property <color> card-background: is-dark-mode ? #2a2a2a : #ffffff;
|
||||
out property <color> card-border: is-dark-mode ? #404040 : #e5e7eb;
|
||||
|
||||
// Navigation colors
|
||||
out property <color> nav-background: is-dark-mode ? #1f1f1f : #f8fafc;
|
||||
out property <color> nav-active: primary;
|
||||
out property <color> nav-hover: is-dark-mode ? #374151 : #f1f5f9;
|
||||
|
||||
// Theme state is directly modified by components and Rust code
|
||||
}
|
||||
12
ui/shared/index.slint
Normal file
12
ui/shared/index.slint
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// Shared Layer Public API
|
||||
// This file exports all shared utilities, components, and design system
|
||||
|
||||
// Export design system
|
||||
export { Theme, FluentColors, FluentTypography, FluentSpacing, FluentRadius, FluentShadows, FluentComponents, FluentMotion, FluentLayout, FluentLayers, ColorMode } from "design-system/index.slint";
|
||||
|
||||
// Export UI components
|
||||
export { Button, Card, Input, LoadingView, Container, Grid } from "ui/index.slint";
|
||||
|
||||
// Export utilities and config - currently commented out in their index files
|
||||
// export * from "lib/index.slint";
|
||||
// export * from "config/index.slint";
|
||||
5
ui/shared/lib/index.slint
Normal file
5
ui/shared/lib/index.slint
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// Shared Library Public API
|
||||
// Export utility functions and helpers
|
||||
|
||||
// Currently no utilities defined
|
||||
// export * from "utils/common-utils.slint";
|
||||
50
ui/shared/ui/button/button.slint
Normal file
50
ui/shared/ui/button/button.slint
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import { VerticalBox, HorizontalBox } from "std-widgets.slint";
|
||||
|
||||
// Basic Button Component
|
||||
export component Button {
|
||||
in property <string> text;
|
||||
in property <bool> enabled: true;
|
||||
in property <color> background-color: #2563eb;
|
||||
in property <color> text-color: white;
|
||||
in property <color> hover-color: #1d4ed8;
|
||||
in property <color> disabled-color: #94a3b8;
|
||||
in property <length> border-radius: 6px;
|
||||
in property <length> padding-horizontal: 16px;
|
||||
in property <length> padding-vertical: 8px;
|
||||
|
||||
callback clicked();
|
||||
|
||||
min-width: 80px;
|
||||
min-height: 36px;
|
||||
|
||||
Rectangle {
|
||||
background: enabled ? (touch-area.has-hover ? hover-color : background-color) : disabled-color;
|
||||
border-radius: border-radius;
|
||||
|
||||
HorizontalBox {
|
||||
padding-left: padding-horizontal;
|
||||
padding-right: padding-horizontal;
|
||||
padding-top: padding-vertical;
|
||||
padding-bottom: padding-vertical;
|
||||
alignment: center;
|
||||
|
||||
Text {
|
||||
text: root.text;
|
||||
color: text-color;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
touch-area := TouchArea {
|
||||
enabled: root.enabled;
|
||||
clicked => {
|
||||
if (root.enabled) {
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/shared/ui/button/index.slint
Normal file
2
ui/shared/ui/button/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Button Component Public API
|
||||
export { Button } from "button.slint";
|
||||
27
ui/shared/ui/card/card.slint
Normal file
27
ui/shared/ui/card/card.slint
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { VerticalBox } from "std-widgets.slint";
|
||||
|
||||
// Basic Card Component
|
||||
export component Card {
|
||||
in property <color> background-color: white;
|
||||
in property <color> border-color: #e2e8f0;
|
||||
in property <length> border-radius: 8px;
|
||||
in property <length> border-width: 1px;
|
||||
in property <length> card-padding: 16px;
|
||||
in property <length> shadow-blur: 4px;
|
||||
in property <color> shadow-color: #00000010;
|
||||
|
||||
Rectangle {
|
||||
background: background-color;
|
||||
border-radius: border-radius;
|
||||
border-width: border-width;
|
||||
border-color: border-color;
|
||||
drop-shadow-blur: shadow-blur;
|
||||
drop-shadow-color: shadow-color;
|
||||
drop-shadow-offset-y: 2px;
|
||||
|
||||
VerticalBox {
|
||||
padding: root.card-padding;
|
||||
@children
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/shared/ui/card/index.slint
Normal file
2
ui/shared/ui/card/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Card Component Public API
|
||||
export { Card } from "card.slint";
|
||||
9
ui/shared/ui/index.slint
Normal file
9
ui/shared/ui/index.slint
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// UI Kit Public API
|
||||
// This file exports all shared UI components
|
||||
|
||||
// Export basic components
|
||||
export { Button } from "button/index.slint";
|
||||
export { Card } from "card/index.slint";
|
||||
export { Input } from "input/index.slint";
|
||||
export { LoadingView } from "loading/index.slint";
|
||||
export { Container, Grid } from "layout/index.slint";
|
||||
2
ui/shared/ui/input/index.slint
Normal file
2
ui/shared/ui/input/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Input Component Public API
|
||||
export { Input } from "input.slint";
|
||||
20
ui/shared/ui/input/input.slint
Normal file
20
ui/shared/ui/input/input.slint
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { LineEdit } from "std-widgets.slint";
|
||||
|
||||
// Basic Input Component
|
||||
export component Input {
|
||||
in-out property <string> text;
|
||||
in property <string> placeholder;
|
||||
in property <bool> enabled: true;
|
||||
|
||||
callback edited(string);
|
||||
|
||||
LineEdit {
|
||||
text: root.text;
|
||||
placeholder-text: root.placeholder;
|
||||
enabled: root.enabled;
|
||||
edited(t) => {
|
||||
root.text = t;
|
||||
root.edited(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/shared/ui/layout/index.slint
Normal file
2
ui/shared/ui/layout/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Layout Components Public API
|
||||
export { Container, Grid } from "layout.slint";
|
||||
32
ui/shared/ui/layout/layout.slint
Normal file
32
ui/shared/ui/layout/layout.slint
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import { VerticalBox, HorizontalBox } from "std-widgets.slint";
|
||||
|
||||
// Container Component
|
||||
export component Container {
|
||||
in property <length> container-max-width: 1200px;
|
||||
in property <length> container-padding: 16px;
|
||||
|
||||
HorizontalBox {
|
||||
alignment: center;
|
||||
|
||||
Rectangle {
|
||||
max-width: root.container-max-width;
|
||||
|
||||
VerticalBox {
|
||||
padding: root.container-padding;
|
||||
@children
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Grid Component
|
||||
export component Grid {
|
||||
in property <length> gap: 16px;
|
||||
in property <int> columns: 2;
|
||||
|
||||
// Basic grid implementation - can be enhanced
|
||||
VerticalBox {
|
||||
spacing: root.gap;
|
||||
@children
|
||||
}
|
||||
}
|
||||
2
ui/shared/ui/loading/index.slint
Normal file
2
ui/shared/ui/loading/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Loading Component Public API
|
||||
export { LoadingView } from "loading.slint";
|
||||
54
ui/shared/ui/loading/loading.slint
Normal file
54
ui/shared/ui/loading/loading.slint
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import { VerticalBox } from "std-widgets.slint";
|
||||
|
||||
// Loading component for app initialization
|
||||
export component LoadingView {
|
||||
in-out property <color> primary-color: #2563eb;
|
||||
in-out property <color> background-color: #f8fafc;
|
||||
in-out property <color> text-color: #1e293b;
|
||||
in-out property <string> app-version: "0.2.0";
|
||||
|
||||
Rectangle {
|
||||
background: background-color;
|
||||
|
||||
VerticalBox {
|
||||
alignment: center;
|
||||
spacing: 20px;
|
||||
|
||||
// Loading spinner
|
||||
Rectangle {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 30px;
|
||||
background: primary-color;
|
||||
|
||||
// Pulsing animation effect
|
||||
animate background {
|
||||
duration: 1s;
|
||||
iteration-count: -1;
|
||||
easing: ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Loading Ziya";
|
||||
font-size: 24px;
|
||||
color: text-color;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Initializing your trading environment...";
|
||||
font-size: 14px;
|
||||
color: text-color;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Version " + app-version;
|
||||
font-size: 10px;
|
||||
color: text-color;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/widgets/navigation/index.slint
Normal file
2
ui/widgets/navigation/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Navigation Widget Public API
|
||||
export { NavigationWidget } from "ui/navigation-widget.slint";
|
||||
291
ui/widgets/navigation/ui/navigation-widget.slint
Normal file
291
ui/widgets/navigation/ui/navigation-widget.slint
Normal file
|
|
@ -0,0 +1,291 @@
|
|||
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
|
||||
|
||||
// Navigation Widget (Sidebar)
|
||||
export component NavigationWidget {
|
||||
in-out property <string> current-page: "Dashboard";
|
||||
in property <string> user-initials: "JD";
|
||||
|
||||
callback navigation-changed(string);
|
||||
callback logout-clicked();
|
||||
|
||||
Rectangle {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: Theme.nav-background;
|
||||
|
||||
VerticalLayout {
|
||||
padding: 16px;
|
||||
spacing: 20px;
|
||||
alignment: space-between;
|
||||
|
||||
// Top section with logo and navigation
|
||||
VerticalLayout {
|
||||
spacing: 20px;
|
||||
|
||||
// Logo Section
|
||||
HorizontalLayout {
|
||||
spacing: 12px;
|
||||
alignment: start;
|
||||
padding-top: 16px;
|
||||
|
||||
Rectangle {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 20px;
|
||||
background: Theme.primary;
|
||||
|
||||
Text {
|
||||
text: "Z";
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
VerticalLayout {
|
||||
spacing: 2px;
|
||||
|
||||
Text {
|
||||
text: "Ziya";
|
||||
color: Theme.text-primary;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
}
|
||||
Text {
|
||||
text: "Trading Platform";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation Menu
|
||||
VerticalLayout {
|
||||
spacing: 4px;
|
||||
|
||||
// Dashboard
|
||||
Rectangle {
|
||||
height: 44px;
|
||||
border-radius: 8px;
|
||||
background: current-page == "Dashboard" ? Theme.nav-active : transparent;
|
||||
|
||||
HorizontalLayout {
|
||||
padding: 12px;
|
||||
spacing: 12px;
|
||||
alignment: start;
|
||||
|
||||
Text {
|
||||
text: "📊";
|
||||
font-size: 16px;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Dashboard";
|
||||
color: current-page == "Dashboard" ? white : Theme.text-primary;
|
||||
font-size: 14px;
|
||||
font-weight: current-page == "Dashboard" ? 600 : 400;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => {
|
||||
root.current-page = "Dashboard";
|
||||
root.navigation-changed("Dashboard");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Trading
|
||||
Rectangle {
|
||||
height: 44px;
|
||||
border-radius: 8px;
|
||||
background: current-page == "Trading" ? Theme.nav-active : transparent;
|
||||
|
||||
HorizontalLayout {
|
||||
padding: 12px;
|
||||
spacing: 12px;
|
||||
alignment: start;
|
||||
|
||||
Text {
|
||||
text: "💹";
|
||||
font-size: 16px;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Trading";
|
||||
color: current-page == "Trading" ? white : Theme.text-primary;
|
||||
font-size: 14px;
|
||||
font-weight: current-page == "Trading" ? 600 : 400;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => {
|
||||
root.current-page = "Trading";
|
||||
root.navigation-changed("Trading");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Portfolio
|
||||
Rectangle {
|
||||
height: 44px;
|
||||
border-radius: 8px;
|
||||
background: current-page == "Portfolio" ? Theme.nav-active : transparent;
|
||||
|
||||
HorizontalLayout {
|
||||
padding: 12px;
|
||||
spacing: 12px;
|
||||
alignment: start;
|
||||
|
||||
Text {
|
||||
text: "💼";
|
||||
font-size: 16px;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Portfolio";
|
||||
color: current-page == "Portfolio" ? white : Theme.text-primary;
|
||||
font-size: 14px;
|
||||
font-weight: current-page == "Portfolio" ? 600 : 400;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => {
|
||||
root.current-page = "Portfolio";
|
||||
root.navigation-changed("Portfolio");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Markets
|
||||
Rectangle {
|
||||
height: 44px;
|
||||
border-radius: 8px;
|
||||
background: current-page == "Markets" ? Theme.nav-active : transparent;
|
||||
|
||||
HorizontalLayout {
|
||||
padding: 12px;
|
||||
spacing: 12px;
|
||||
alignment: start;
|
||||
|
||||
Text {
|
||||
text: "📈";
|
||||
font-size: 16px;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Markets";
|
||||
color: current-page == "Markets" ? white : Theme.text-primary;
|
||||
font-size: 14px;
|
||||
font-weight: current-page == "Markets" ? 600 : 400;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => {
|
||||
root.current-page = "Markets";
|
||||
root.navigation-changed("Markets");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hunting Ground
|
||||
Rectangle {
|
||||
height: 44px;
|
||||
border-radius: 8px;
|
||||
background: current-page == "HuntingGround" ? Theme.nav-active : transparent;
|
||||
|
||||
HorizontalLayout {
|
||||
padding: 12px;
|
||||
spacing: 12px;
|
||||
alignment: start;
|
||||
|
||||
Text {
|
||||
text: "🎯";
|
||||
font-size: 16px;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Hunting Ground";
|
||||
color: current-page == "HuntingGround" ? white : Theme.text-primary;
|
||||
font-size: 14px;
|
||||
font-weight: current-page == "HuntingGround" ? 600 : 400;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => {
|
||||
root.current-page = "HuntingGround";
|
||||
root.navigation-changed("HuntingGround");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// User Profile Section (bottom)
|
||||
Rectangle {
|
||||
height: 60px;
|
||||
border-radius: 8px;
|
||||
background: Theme.surface;
|
||||
|
||||
HorizontalLayout {
|
||||
padding: 12px;
|
||||
spacing: 12px;
|
||||
alignment: start;
|
||||
|
||||
Rectangle {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 18px;
|
||||
background: Theme.primary;
|
||||
|
||||
Text {
|
||||
text: user-initials;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
VerticalLayout {
|
||||
spacing: 2px;
|
||||
|
||||
Text {
|
||||
text: "User";
|
||||
color: Theme.text-primary;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Logout";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => { root.logout-clicked(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
178
ui/widgets/navigation/ui/sidebar.slint
Normal file
178
ui/widgets/navigation/ui/sidebar.slint
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
import { VerticalBox, HorizontalBox, ScrollView } from "std-widgets.slint";
|
||||
|
||||
// Navigation menu item data structure
|
||||
export struct MenuItem {
|
||||
name: string,
|
||||
icon: string,
|
||||
active: bool,
|
||||
}
|
||||
|
||||
// Professional sidebar navigation with direct styling
|
||||
export component Sidebar {
|
||||
in property <[MenuItem]> menu-items: [
|
||||
{ name: "Dashboard", icon: "📊", active: true },
|
||||
{ name: "Profile", icon: "👤", active: false },
|
||||
{ name: "Trading", icon: "💹", active: false },
|
||||
{ name: "Portfolio", icon: "💼", active: false },
|
||||
{ name: "Markets", icon: "📈", active: false },
|
||||
{ name: "Hunting Ground", icon: "🎯", active: false },
|
||||
{ name: "Analytics", icon: "📊", active: false },
|
||||
];
|
||||
|
||||
callback menu-item-clicked(string);
|
||||
|
||||
width: 256px;
|
||||
|
||||
Rectangle {
|
||||
background: #f2f2f2;
|
||||
border-width: 0px;
|
||||
border-color: #e5e6e6;
|
||||
|
||||
ScrollView {
|
||||
viewport-height: root.height;
|
||||
|
||||
VerticalBox {
|
||||
padding: 16px;
|
||||
spacing: 8px;
|
||||
|
||||
// Sidebar Header
|
||||
Rectangle {
|
||||
height: 60px;
|
||||
|
||||
VerticalBox {
|
||||
alignment: center;
|
||||
spacing: 8px;
|
||||
|
||||
// Logo area
|
||||
Rectangle {
|
||||
height: 32px;
|
||||
|
||||
HorizontalBox {
|
||||
alignment: center;
|
||||
spacing: 8px;
|
||||
|
||||
// App icon
|
||||
Rectangle {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background: #570df8;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Ziya";
|
||||
color: #1f2937;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Divider
|
||||
Rectangle {
|
||||
height: 1px;
|
||||
background: #e5e6e6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Menu Items
|
||||
for item[index] in menu-items: Rectangle {
|
||||
height: 44px;
|
||||
border-radius: 8px;
|
||||
|
||||
// Active/hover state styling
|
||||
background: item.active ? #570df8 : transparent;
|
||||
|
||||
states [
|
||||
active when item.active: {
|
||||
background: #570df8;
|
||||
}
|
||||
hover when menu-area.has-hover && !item.active: {
|
||||
background: #e5e6e6;
|
||||
}
|
||||
]
|
||||
|
||||
animate background { duration: 150ms; }
|
||||
|
||||
HorizontalBox {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
alignment: start;
|
||||
spacing: 12px;
|
||||
|
||||
// Icon
|
||||
Text {
|
||||
text: item.icon;
|
||||
font-size: 16px;
|
||||
vertical-alignment: center;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
// Menu item text
|
||||
Text {
|
||||
text: item.name;
|
||||
color: item.active ? #ffffff : #1f2937;
|
||||
font-size: 14px;
|
||||
font-weight: item.active ? 600 : 500;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
// Active indicator
|
||||
if item.active: Rectangle {
|
||||
width: 4px;
|
||||
height: 20px;
|
||||
background: #ffffff;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
menu-area := TouchArea {
|
||||
clicked => { menu-item-clicked(item.name); }
|
||||
}
|
||||
}
|
||||
|
||||
// Spacer to push footer to bottom
|
||||
Rectangle {
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
// Sidebar Footer
|
||||
Rectangle {
|
||||
height: 60px;
|
||||
|
||||
VerticalBox {
|
||||
alignment: center;
|
||||
spacing: 8px;
|
||||
|
||||
// Divider
|
||||
Rectangle {
|
||||
height: 1px;
|
||||
background: #e5e6e6;
|
||||
}
|
||||
|
||||
// Status section
|
||||
HorizontalBox {
|
||||
alignment: center;
|
||||
spacing: 8px;
|
||||
|
||||
// Status indicator
|
||||
Rectangle {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: #36d399;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Connected";
|
||||
color: #6b7280;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/widgets/trading-stats/index.slint
Normal file
2
ui/widgets/trading-stats/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Trading Stats Widget Public API
|
||||
export { StatsCard } from "ui/stats-card.slint";
|
||||
55
ui/widgets/trading-stats/ui/stats-card.slint
Normal file
55
ui/widgets/trading-stats/ui/stats-card.slint
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import { VerticalBox } from "std-widgets.slint";
|
||||
|
||||
// Professional stats card component with direct styling
|
||||
export component StatsCard {
|
||||
in property <string> title: "Stat Title";
|
||||
in property <string> value: "$0.00";
|
||||
in property <string> change: "0%";
|
||||
in property <bool> positive: true;
|
||||
in property <color> accent-color: #570df8;
|
||||
|
||||
min-width: 200px;
|
||||
height: 120px;
|
||||
|
||||
Rectangle {
|
||||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
border-width: 1px;
|
||||
border-color: #e5e6e6;
|
||||
drop-shadow-blur: 8px;
|
||||
drop-shadow-color: #00000008;
|
||||
|
||||
VerticalBox {
|
||||
padding: 20px;
|
||||
spacing: 8px;
|
||||
alignment: start;
|
||||
|
||||
// Title
|
||||
Text {
|
||||
text: title;
|
||||
color: #64748b;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
|
||||
// Main value
|
||||
Text {
|
||||
text: value;
|
||||
color: accent-color;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
|
||||
// Change indicator
|
||||
Text {
|
||||
text: change;
|
||||
color: positive ? #36d399 : #f87272;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
horizontal-alignment: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/widgets/user-profile/index.slint
Normal file
2
ui/widgets/user-profile/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// User Profile Widget Public API
|
||||
export { ProfileView } from "ui/profile.slint";
|
||||
251
ui/widgets/user-profile/ui/profile.slint
Normal file
251
ui/widgets/user-profile/ui/profile.slint
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
import { Button, VerticalBox, HorizontalBox } from "std-widgets.slint";
|
||||
|
||||
// User profile structure
|
||||
export struct UserProfile {
|
||||
name: string,
|
||||
email: string,
|
||||
wallet-address: string,
|
||||
}
|
||||
|
||||
// Profile component
|
||||
export component ProfileView {
|
||||
in-out property <color> primary-color: #2563eb;
|
||||
in-out property <color> background-color: #f8fafc;
|
||||
in-out property <color> card-background: #ffffff;
|
||||
in-out property <color> text-color: #1e293b;
|
||||
in-out property <color> border-color: #e2e8f0;
|
||||
in-out property <UserProfile> user-profile;
|
||||
|
||||
// Callbacks
|
||||
callback edit-profile();
|
||||
callback view-wallet();
|
||||
callback export-data();
|
||||
|
||||
Rectangle {
|
||||
background: background-color;
|
||||
|
||||
VerticalBox {
|
||||
spacing: 30px;
|
||||
padding: 30px;
|
||||
|
||||
// Header
|
||||
Text {
|
||||
text: "Profile";
|
||||
font-size: 28px;
|
||||
color: text-color;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
// Profile card
|
||||
Rectangle {
|
||||
background: card-background;
|
||||
border-radius: 16px;
|
||||
border-width: 1px;
|
||||
border-color: border-color;
|
||||
drop-shadow-blur: 10px;
|
||||
drop-shadow-color: #00000010;
|
||||
|
||||
VerticalBox {
|
||||
spacing: 25px;
|
||||
padding: 30px;
|
||||
|
||||
// Avatar section
|
||||
HorizontalBox {
|
||||
alignment: start;
|
||||
spacing: 20px;
|
||||
|
||||
Rectangle {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 40px;
|
||||
background: primary-color.with-alpha(0.1);
|
||||
|
||||
Text {
|
||||
text: user-profile.name != "" ? user-profile.name.to-uppercase() : "U";
|
||||
color: primary-color;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
VerticalBox {
|
||||
alignment: start;
|
||||
spacing: 8px;
|
||||
|
||||
Text {
|
||||
text: user-profile.name != "" ? user-profile.name : "Demo User";
|
||||
font-size: 24px;
|
||||
color: text-color;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: user-profile.email != "" ? user-profile.email : "demo@ziya.app";
|
||||
font-size: 14px;
|
||||
color: text-color;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wallet section
|
||||
VerticalBox {
|
||||
spacing: 15px;
|
||||
|
||||
Text {
|
||||
text: "Wallet Information";
|
||||
font-size: 18px;
|
||||
color: text-color;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
background: #f1f5f9;
|
||||
border-radius: 8px;
|
||||
|
||||
VerticalBox {
|
||||
spacing: 10px;
|
||||
padding: 15px;
|
||||
|
||||
Text {
|
||||
text: "Wallet Address";
|
||||
font-size: 12px;
|
||||
color: text-color;
|
||||
opacity: 0.7;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: user-profile.wallet-address != "" ?
|
||||
user-profile.wallet-address :
|
||||
"Demo123...Wallet456";
|
||||
font-size: 14px;
|
||||
color: text-color;
|
||||
font-family: "monospace";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Actions section
|
||||
VerticalBox {
|
||||
spacing: 15px;
|
||||
|
||||
Text {
|
||||
text: "Profile Actions";
|
||||
font-size: 18px;
|
||||
color: text-color;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
VerticalBox {
|
||||
spacing: 10px;
|
||||
|
||||
Button {
|
||||
text: "✏️ Edit Profile";
|
||||
height: 45px;
|
||||
clicked => { edit-profile(); }
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "👛 View Wallet Details";
|
||||
height: 45px;
|
||||
clicked => { view-wallet(); }
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "📥 Export Data";
|
||||
height: 45px;
|
||||
clicked => { export-data(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stats card
|
||||
Rectangle {
|
||||
background: card-background;
|
||||
border-radius: 16px;
|
||||
border-width: 1px;
|
||||
border-color: border-color;
|
||||
drop-shadow-blur: 10px;
|
||||
drop-shadow-color: #00000010;
|
||||
|
||||
VerticalBox {
|
||||
spacing: 20px;
|
||||
padding: 25px;
|
||||
|
||||
Text {
|
||||
text: "Trading Stats";
|
||||
font-size: 18px;
|
||||
color: text-color;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
HorizontalBox {
|
||||
alignment: stretch;
|
||||
spacing: 20px;
|
||||
|
||||
VerticalBox {
|
||||
alignment: center;
|
||||
spacing: 5px;
|
||||
|
||||
Text {
|
||||
text: "24";
|
||||
font-size: 24px;
|
||||
color: primary-color;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Trades";
|
||||
font-size: 12px;
|
||||
color: text-color;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
VerticalBox {
|
||||
alignment: center;
|
||||
spacing: 5px;
|
||||
|
||||
Text {
|
||||
text: "$1,234";
|
||||
font-size: 24px;
|
||||
color: #10b981;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Profit";
|
||||
font-size: 12px;
|
||||
color: text-color;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
VerticalBox {
|
||||
alignment: center;
|
||||
spacing: 5px;
|
||||
|
||||
Text {
|
||||
text: "67%";
|
||||
font-size: 24px;
|
||||
color: #10b981;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Win Rate";
|
||||
font-size: 12px;
|
||||
color: text-color;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ui/widgets/window-controls/index.slint
Normal file
2
ui/widgets/window-controls/index.slint
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Window Controls Widget Public API
|
||||
export { WindowControlsWidget } from "ui/window-controls-widget.slint";
|
||||
190
ui/widgets/window-controls/ui/title-bar.slint
Normal file
190
ui/widgets/window-controls/ui/title-bar.slint
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
import { Button, HorizontalBox } from "std-widgets.slint";
|
||||
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
|
||||
|
||||
// Professional title bar component with theme support
|
||||
export component TitleBar {
|
||||
// Window state
|
||||
in-out property <bool> is-maximized: false;
|
||||
|
||||
// Callbacks for window controls
|
||||
callback minimize-window();
|
||||
callback maximize-window();
|
||||
callback close-window();
|
||||
callback toggle-theme();
|
||||
callback start-drag-window();
|
||||
|
||||
height: 32px;
|
||||
|
||||
Rectangle {
|
||||
background: Theme.surface;
|
||||
border-width: 0px;
|
||||
border-color: Theme.border;
|
||||
|
||||
// Drag area for the title bar
|
||||
drag-area := TouchArea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
moved => {
|
||||
if (self.pressed) {
|
||||
start-drag-window();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalBox {
|
||||
padding: 16px;
|
||||
alignment: stretch;
|
||||
|
||||
// Left side - App branding
|
||||
HorizontalBox {
|
||||
alignment: start;
|
||||
spacing: 8px;
|
||||
|
||||
// App icon
|
||||
Rectangle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
// Ziya logo (layered rectangles)
|
||||
Rectangle {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background: #570df8;
|
||||
border-radius: 3px;
|
||||
|
||||
Rectangle {
|
||||
x: 2px;
|
||||
y: 2px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: #4506cb;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// App name
|
||||
Text {
|
||||
text: "Ziya";
|
||||
color: Theme.text-primary;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
// Right side - Controls
|
||||
HorizontalBox {
|
||||
alignment: end;
|
||||
spacing: 4px;
|
||||
|
||||
// Theme switcher
|
||||
Rectangle {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
|
||||
states [
|
||||
hover when theme-area.has-hover: {
|
||||
background: Theme.nav-hover;
|
||||
}
|
||||
]
|
||||
|
||||
// Theme icon - shows current theme state
|
||||
Text {
|
||||
text: Theme.is-dark-mode ? "🌙" : "☀️";
|
||||
font-size: 14px;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
theme-area := TouchArea {
|
||||
clicked => {
|
||||
Theme.toggle-theme();
|
||||
toggle-theme();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Minimize button
|
||||
Rectangle {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
|
||||
states [
|
||||
hover when min-area.has-hover: {
|
||||
background: Theme.nav-hover;
|
||||
}
|
||||
]
|
||||
|
||||
// Minimize icon
|
||||
Text {
|
||||
text: "−";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 14px;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
min-area := TouchArea {
|
||||
clicked => { minimize-window(); }
|
||||
}
|
||||
}
|
||||
|
||||
// Maximize/Restore button
|
||||
Rectangle {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
|
||||
states [
|
||||
hover when max-area.has-hover: {
|
||||
background: Theme.nav-hover;
|
||||
}
|
||||
]
|
||||
|
||||
// Maximize icon
|
||||
Text {
|
||||
text: is-maximized ? "❐" : "□";
|
||||
color: Theme.text-secondary;
|
||||
font-size: 12px;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
max-area := TouchArea {
|
||||
clicked => { maximize-window(); }
|
||||
}
|
||||
}
|
||||
|
||||
// Close button
|
||||
Rectangle {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
|
||||
states [
|
||||
hover when close-area.has-hover: {
|
||||
background: #ef4444;
|
||||
}
|
||||
]
|
||||
|
||||
// Close icon
|
||||
Text {
|
||||
text: "✕";
|
||||
color: close-area.has-hover ? #ffffff : Theme.text-secondary;
|
||||
font-size: 10px;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
close-area := TouchArea {
|
||||
clicked => { close-window(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
18
ui/widgets/window-controls/ui/window-controls-widget.slint
Normal file
18
ui/widgets/window-controls/ui/window-controls-widget.slint
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { TitleBar } from "title-bar.slint";
|
||||
|
||||
// Window Controls Widget
|
||||
export component WindowControlsWidget {
|
||||
callback theme-toggle-clicked();
|
||||
callback minimize-clicked();
|
||||
callback maximize-clicked();
|
||||
callback close-clicked();
|
||||
callback start-drag-window();
|
||||
|
||||
TitleBar {
|
||||
toggle-theme => { root.theme-toggle-clicked(); }
|
||||
minimize-window => { root.minimize-clicked(); }
|
||||
maximize-window => { root.maximize-clicked(); }
|
||||
close-window => { root.close-clicked(); }
|
||||
start-drag-window => { root.start-drag-window(); }
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue