add documentation site with markdown rendering (M12)
This commit is contained in:
395
portal/internal/web/docs/guides/ui-design.md
Normal file
395
portal/internal/web/docs/guides/ui-design.md
Normal file
@@ -0,0 +1,395 @@
|
||||
# UI Design Guide
|
||||
|
||||
Mosis uses RML (RmlUi Markup Language) and RCSS (RmlUi CSS) for building user interfaces. If you know HTML and CSS, you'll feel right at home.
|
||||
|
||||
## RML Basics
|
||||
|
||||
RML is similar to HTML but with some differences optimized for UI rendering.
|
||||
|
||||
### Document Structure
|
||||
|
||||
```xml
|
||||
<rml>
|
||||
<head>
|
||||
<title>App Title</title>
|
||||
<link type="text/rcss" href="styles.rcss"/>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Your UI here -->
|
||||
</body>
|
||||
</rml>
|
||||
```
|
||||
|
||||
### Common Elements
|
||||
|
||||
| Element | Usage |
|
||||
|---------|-------|
|
||||
| `<div>` | Container/layout |
|
||||
| `<p>` | Paragraph text |
|
||||
| `<span>` | Inline text |
|
||||
| `<h1>` - `<h6>` | Headings |
|
||||
| `<img>` | Images |
|
||||
| `<button>` | Clickable buttons |
|
||||
| `<input>` | Text input fields |
|
||||
| `<select>` | Dropdown menus |
|
||||
| `<progress>` | Progress bars |
|
||||
|
||||
### Layout Example
|
||||
|
||||
```xml
|
||||
<div class="app-bar">
|
||||
<div class="app-bar-nav" onclick="goBack()">
|
||||
<img src="../../icons/back.tga"/>
|
||||
</div>
|
||||
<span class="app-bar-title">My App</span>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="card">
|
||||
<h2>Welcome</h2>
|
||||
<p>This is a card component.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dock">
|
||||
<button class="dock-item" onclick="navigateTo('home')">
|
||||
<img src="icons/home.tga"/>
|
||||
</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## RCSS Styling
|
||||
|
||||
RCSS is CSS with some limitations and extensions.
|
||||
|
||||
### Supported Properties
|
||||
|
||||
**Layout:**
|
||||
- `display` (block, inline, inline-block, flex, none)
|
||||
- `position` (static, relative, absolute, fixed)
|
||||
- `width`, `height`, `min-width`, `max-width`, `min-height`, `max-height`
|
||||
- `margin`, `padding` (including directional variants)
|
||||
- `flex`, `flex-direction`, `flex-wrap`, `justify-content`, `align-items`
|
||||
- `overflow` (visible, hidden, scroll, auto)
|
||||
|
||||
**Visual:**
|
||||
- `background-color`, `background` (with decorators)
|
||||
- `color`
|
||||
- `border`, `border-radius`
|
||||
- `opacity`
|
||||
- `box-shadow` (via decorators)
|
||||
|
||||
**Typography:**
|
||||
- `font-family`
|
||||
- `font-size`
|
||||
- `font-weight` (normal, bold)
|
||||
- `font-style` (normal, italic)
|
||||
- `text-align` (left, center, right)
|
||||
- `line-height`
|
||||
- `text-decoration`
|
||||
|
||||
### Units
|
||||
|
||||
| Unit | Description |
|
||||
|------|-------------|
|
||||
| `dp` | Density-independent pixels (recommended) |
|
||||
| `px` | Pixels |
|
||||
| `%` | Percentage of parent |
|
||||
| `em` | Relative to font size |
|
||||
|
||||
Always use `dp` for consistent sizing across devices:
|
||||
|
||||
```css
|
||||
.button {
|
||||
padding: 12dp 24dp;
|
||||
font-size: 16dp;
|
||||
border-radius: 8dp;
|
||||
}
|
||||
```
|
||||
|
||||
### Colors
|
||||
|
||||
```css
|
||||
/* Hex colors */
|
||||
color: #ffffff;
|
||||
color: #fff;
|
||||
color: #00d4ff80; /* with alpha */
|
||||
|
||||
/* RGB/RGBA */
|
||||
color: rgb(255, 255, 255);
|
||||
color: rgba(0, 212, 255, 0.5);
|
||||
```
|
||||
|
||||
### Pseudo-classes
|
||||
|
||||
```css
|
||||
button {
|
||||
background-color: #00d4ff;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #00b8e6;
|
||||
}
|
||||
|
||||
button:active {
|
||||
background-color: #0099cc;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
border: 2dp solid #ffffff;
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
```
|
||||
|
||||
## Flexbox Layout
|
||||
|
||||
RCSS supports flexbox for modern layouts:
|
||||
|
||||
```css
|
||||
.row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10dp;
|
||||
}
|
||||
|
||||
.grow {
|
||||
flex: 1;
|
||||
}
|
||||
```
|
||||
|
||||
```xml
|
||||
<div class="row">
|
||||
<span>Left</span>
|
||||
<span class="grow"></span>
|
||||
<span>Right</span>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Images
|
||||
|
||||
Images should be in TGA format for best performance:
|
||||
|
||||
```xml
|
||||
<img src="icons/star.tga"/>
|
||||
```
|
||||
|
||||
Supported formats:
|
||||
- TGA (recommended)
|
||||
- PNG
|
||||
- JPEG
|
||||
|
||||
### Image Sizing
|
||||
|
||||
```css
|
||||
img {
|
||||
width: 32dp;
|
||||
height: 32dp;
|
||||
}
|
||||
|
||||
/* Aspect ratio maintained */
|
||||
img.icon {
|
||||
width: 24dp;
|
||||
height: auto;
|
||||
}
|
||||
```
|
||||
|
||||
## Input Elements
|
||||
|
||||
### Text Input
|
||||
|
||||
```xml
|
||||
<input type="text" id="username" placeholder="Enter username"/>
|
||||
```
|
||||
|
||||
```css
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 12dp;
|
||||
background-color: #2a2a4e;
|
||||
border: 1dp solid #3a3a5e;
|
||||
border-radius: 8dp;
|
||||
color: #ffffff;
|
||||
font-size: 16dp;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
border-color: #00d4ff;
|
||||
}
|
||||
```
|
||||
|
||||
### Select/Dropdown
|
||||
|
||||
```xml
|
||||
<select id="country">
|
||||
<option value="us">United States</option>
|
||||
<option value="uk">United Kingdom</option>
|
||||
<option value="ca">Canada</option>
|
||||
</select>
|
||||
```
|
||||
|
||||
### Progress Bar
|
||||
|
||||
```xml
|
||||
<progress id="loading" value="0.5" max="1"/>
|
||||
```
|
||||
|
||||
```css
|
||||
progress {
|
||||
width: 100%;
|
||||
height: 8dp;
|
||||
background-color: #2a2a4e;
|
||||
border-radius: 4dp;
|
||||
}
|
||||
|
||||
progress fill {
|
||||
background-color: #00d4ff;
|
||||
border-radius: 4dp;
|
||||
}
|
||||
```
|
||||
|
||||
## Scrolling
|
||||
|
||||
```xml
|
||||
<div class="scroll-container">
|
||||
<div class="scroll-content">
|
||||
<!-- Long content here -->
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
```css
|
||||
.scroll-container {
|
||||
height: 300dp;
|
||||
overflow: auto;
|
||||
}
|
||||
```
|
||||
|
||||
## Decorators
|
||||
|
||||
RCSS uses decorators for advanced visual effects:
|
||||
|
||||
```css
|
||||
/* Gradient background */
|
||||
.gradient {
|
||||
decorator: horizontal-gradient(#1a1a2e #2a2a4e);
|
||||
}
|
||||
|
||||
/* Image background */
|
||||
.card {
|
||||
decorator: image(background.tga);
|
||||
}
|
||||
|
||||
/* Border image */
|
||||
.fancy-border {
|
||||
decorator: ninepatch(border.tga, 10dp, 10dp, 10dp, 10dp);
|
||||
}
|
||||
```
|
||||
|
||||
## Animations
|
||||
|
||||
RCSS supports keyframe animations:
|
||||
|
||||
```css
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fade-in 0.3s ease-out;
|
||||
}
|
||||
```
|
||||
|
||||
### Transitions
|
||||
|
||||
```css
|
||||
.button {
|
||||
transition: background-color 0.2s, transform 0.1s;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: #00b8e6;
|
||||
}
|
||||
|
||||
.button:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
```
|
||||
|
||||
## Responsive Design
|
||||
|
||||
Design for the Mosis phone screen (1080x1920 logical pixels):
|
||||
|
||||
```css
|
||||
/* Base styles for portrait */
|
||||
.content {
|
||||
padding: 16dp;
|
||||
}
|
||||
|
||||
/* Adjust for available space */
|
||||
.app-bar {
|
||||
height: 56dp;
|
||||
padding: 0 16dp;
|
||||
}
|
||||
|
||||
.dock {
|
||||
height: 64dp;
|
||||
padding: 8dp;
|
||||
}
|
||||
```
|
||||
|
||||
## Design Tokens
|
||||
|
||||
Use CSS variables for consistent theming:
|
||||
|
||||
```css
|
||||
:root {
|
||||
--primary: #00d4ff;
|
||||
--primary-dark: #00b8e6;
|
||||
--background: #1a1a2e;
|
||||
--surface: #2a2a4e;
|
||||
--text-primary: #ffffff;
|
||||
--text-secondary: #a0a0a0;
|
||||
--spacing-sm: 8dp;
|
||||
--spacing-md: 16dp;
|
||||
--spacing-lg: 24dp;
|
||||
--radius-sm: 4dp;
|
||||
--radius-md: 8dp;
|
||||
--radius-lg: 16dp;
|
||||
}
|
||||
|
||||
.button {
|
||||
background-color: var(--primary);
|
||||
padding: var(--spacing-md);
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use dp units** - Ensures consistent sizing across devices
|
||||
2. **Test touch targets** - Minimum 48dp for touchable elements
|
||||
3. **Maintain contrast** - Ensure text is readable (4.5:1 ratio minimum)
|
||||
4. **Use semantic structure** - Proper headings, lists, etc.
|
||||
5. **Optimize images** - Use TGA format, appropriate sizes
|
||||
6. **Keep it simple** - Mobile-first design, avoid clutter
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Lua Scripting Guide](lua-scripting.md) - Add interactivity
|
||||
- [Components Library](components.md) - Pre-built UI components
|
||||
- [Theme Reference](theme.md) - Complete theming guide
|
||||
Reference in New Issue
Block a user