@kiliannnnn/lushland
v0.1.0
Published
A package to use windows elements inside a website
Readme
Lushland - Developer Documentation
A web-based window management system built with Web Components. This guide covers using HTML tags, configuring templates and features, and extending the system.
Quick Start
Basic Setup (Auto-initialization)
<lushland-house contain="true" mode="free">
<lushland-window template="small"></lushland-window>
</lushland-house>
<lushland-manager orientation="horizontal" position="bot-right"></lushland-manager>
<lushland-menu orientation="vertical"></lushland-menu>
<script type="module" src="index.js"></script>Custom Configuration
Lushland supports customization through configuration files and inline options.
Option 1: Load Config from JSON File
Create a lushland-config.json:
{
"CONFIG": {
"defaultWidth": 300,
"defaultHeight": 250,
"snapDistance": 15,
"templates": {
"custom": {
"title": "Custom Size",
"height": 500,
"width": 800
}
}
},
"THEMES": ["dark", "light", "cyberpunk", "custom"]
}Then initialize in your HTML:
<script type="module">
import { initLushland } from './index.js';
await initLushland({
configFile: './lushland-config.json',
cssFile: './lushland-theme.css' // Optional custom CSS
});
</script>
<lushland-house contain="true">
<lushland-window template="small"></lushland-window>
</lushland-house>
<lushland-manager></lushland-manager>
<lushland-menu></lushland-menu>Option 2: Inline Configuration Object
<script type="module">
import { initLushland } from './index.js';
await initLushland({
config: {
CONFIG: {
defaultWidth: 400,
defaultHeight: 300,
templates: {
large: {
title: 'Extra Large',
height: 600,
width: 1000
}
}
}
}
});
</script>
<lushland-house></lushland-house>
<lushland-manager></lushland-manager>
</lushland-menu>Option 3: Config File + Custom CSS
<script type="module">
import { initLushland } from './index.js';
await initLushland({
configFile: './custom-config.json',
cssFile: './custom-theme.css' // Custom CSS variables override defaults
});
</script>Create custom-theme.css:
/* Your custom CSS variables override Lushland defaults */
:root {
--ll-color-bg-primary: #1a1a1a;
--ll-color-accent-primary: #00ff00;
--ll-spacing-md: 15px;
}Contents
- Quick Start
- HTML Tags
- Configuration
- Adding Templates
- Adding Features
- Custom Themes
- Example Files
- Markdown Support
- Quick Tips
HTML Tags
<lushland-house>
Main container for windows. Creates draggable, resizable window instances.
Attributes: None required
Example:
<lushland-house id="app"></lushland-house>JavaScript Access:
const house = document.getElementById('app');
const windowElement = house.children[0]; // Access first window<lushland-manager>
Control bar for adding windows, toggling themes, and managing the application.
Attributes: None
Features:
+button: Add new window (opens feature menu)- Theme toggle button: Cycles through dark → light → cyberpunk
- Displays current application state
Example:
<lushland-manager id="manager"></lushland-manager><lushland-menu>
Displays list of open windows. Click window names to focus, click X to close.
Attributes: None
Auto-scales height based on open windows (0 to 30vh)
Example:
<lushland-menu id="menu"></lushland-menu><lushland-window>
Individual window element (created programmatically, not in HTML).
Attributes:
x- Window X position (pixels)y- Window Y position (pixels)width- Window width (pixels)height- Window height (pixels)title- Window titlefeature- Feature name to load (e.g., 'notepad', 'calculator')z-index- Stacking order
Example (created via JavaScript):
const window = document.createElement('lushland-window');
window.setAttribute('x', '100');
window.setAttribute('y', '100');
window.setAttribute('width', '400');
window.setAttribute('height', '300');
window.setAttribute('title', 'My Window');
window.setAttribute('feature', 'notepad');
document.getElementById('app').appendChild(window);Mouse Interactions:
- Drag by header to move
- Drag bottom-right corner to resize
- Click to focus
- F button: Change feature
- S button: Snap to grid
- X button: Close window
feature-menu
Menu for selecting which feature to load in a window. Created automatically.
Example:
// Created automatically when F button is clickedConfiguration
Using the initLushland API
The recommended way to customize Lushland is through the initLushland() function:
import { initLushland } from './index.js';
await initLushland({
configFile: './my-config.json', // Optional: path to JSON config
config: { /* inline config */ }, // Optional: inline configuration object
cssFile: './my-theme.css' // Optional: custom CSS variables
});Configuration Priority (lowest to highest):
- Lushland defaults
configFilesettings (if provided)configobject settings (if provided)- User CSS variables (highest priority for styling)
CONFIG Object Properties
All settings in the CONFIG object are customizable:
{
zIndex: { focused: 100, default: 1 },
snapDistance: 20, // Grid snap size in pixels
gridDefaults: { size: 20 }, // Default grid size
defaultTitle: 'Window',
defaultHeight: 200,
defaultWidth: 200,
defaultFeature: 'notepad',
buttons: {
feature: 'F', // Button to change feature
snap: 'S', // Button to snap to grid
close: 'X' // Button to close window
},
templates: {
small: { title: 'Small', height: 150, width: 200 },
medium: { title: 'Medium', height: 300, width: 400 },
large: { title: 'Large', height: 450, width: 600 }
},
manager: {
defaultPosition: 'top-left',
defaultOrientation: 'vertical'
},
menu: {
defaultPosition: 'bot-left',
defaultOrientation: 'vertical',
defaultWidth: '200px',
defaultHeight: '50px'
}
}Import and Use Exports
If you need programmatic access to configuration or managers:
import {
initLushland,
CONFIG,
FEATURES,
CALCULATOR_CONFIG,
THEMES,
templateManager,
featureRegistry,
windowsManager
} from './index.js';
await initLushland();
// Access or modify config after initialization
console.log(CONFIG.defaultWidth);
CONFIG.defaultWidth = 500;
// Register custom features
featureRegistry.register('mytool', (container) => {
container.innerHTML = '<div>My Tool</div>';
});Legacy Approach (Direct Import)
For backward compatibility, you can still import directly from config.js:
import { CONFIG, FEATURES, CALCULATOR_CONFIG, MANAGER_BUTTONS, THEMES } from './config.js';However, this won't merge with custom configurations. Use initLushland() for customization support.
Adding Templates
Add window size templates in CONFIG.templates:
CONFIG.templates = {
custom: {
title: 'Custom Size',
height: 500,
width: 800
}
}Create a window from a template:
const template = CONFIG.templates.large;
const window = document.createElement('lushland-window');
window.setAttribute('width', template.width);
window.setAttribute('height', template.height);
window.setAttribute('title', template.title);
window.setAttribute('feature', 'notepad');
document.getElementById('app').appendChild(window);Adding Features
Features are renderers that populate window content.
1. Define Feature in Config
Add to your lushland-config.json:
{
"FEATURES": {
"mynotes": {
"label": "My Notes",
"icon": {
"viewBox": "0 0 24 24",
"paths": [
{ "d": "M4 4H20V20H4Z", "stroke": "white", "stroke-width": "2" }
]
}
}
}
}2. Register Feature Renderer
After initializing Lushland:
import { initLushland, featureRegistry } from './index.js';
await initLushland({
configFile: './lushland-config.json'
});
// Register the renderer
featureRegistry.register('mynotes', (container) => {
const content = document.createElement('div');
content.innerHTML = '<h2>My Notes</h2><textarea></textarea>';
content.style.padding = 'var(--ll-spacing-md)';
container.appendChild(content);
});3. Use in Window
const window = document.createElement('lushland-window');
window.setAttribute('feature', 'mynotes');
document.getElementById('app').appendChild(window);Alternative: Global Feature Registration
Register features globally before initialization:
window.addEventListener('DOMContentLoaded', () => {
window.lushlandRegisterFeature('mynotes', (container) => {
// Your feature code
});
});Markdown Support
The Notepad feature includes Obsidian-style markdown.
Supported Elements
| Syntax | Output |
|--------|--------|
| # Heading 1 | Large heading |
| ## Heading 2 | Medium heading |
| ### Heading 3 | Small heading |
| #### Heading 4 | Small heading |
| ##### Heading 5 | Smaller heading |
| ###### Heading 6 | Smallest heading |
| **bold** or __bold__ | Bold text |
| *italic* or _italic_ | Italic text |
| ***bold italic*** | Bold + italic |
| ~~strikethrough~~ | Crossed out text |
| ==highlighted== | Yellow highlight |
| `code` | Inline code |
| ```language\ncode``` | Code block |
| [text](url) | Link (opens in new tab) |
|  | Image (responsive) |
| [[Page]] | Wiki link to page |
| [[Page\|Display]] | Wiki link with custom text |
| - item | Unordered list |
| 1. item | Ordered list |
| - [ ] task | Unchecked task |
| - [x] task | Checked task |
| > quote | Blockquote |
| --- or *** | Horizontal rule |
| %%comment%% | Hidden comment |
Toggle Preview
Click the 👁️ button (bottom-left) to toggle between edit and preview modes. The button changes to ✏️ in preview mode.
Example Files
Lushland includes example configuration and theme files to help you get started:
lushland-config.example.json
A complete configuration template showing all customizable options:
cp lushland-config.example.json my-config.json
# Then edit my-config.json with your custom valuesUse it:
await initLushland({
configFile: './my-config.json'
});lushland-theme.example.css
A template for customizing CSS variables:
cp lushland-theme.example.css my-theme.css
# Then edit my-theme.css to override variablesUse it:
await initLushland({
cssFile: './my-theme.css'
});Combining Both
await initLushland({
configFile: './my-config.json',
cssFile: './my-theme.css'
});Themes
Three built-in themes: dark, light, cyberpunk.
Switching Themes
Set theme programmatically:
document.documentElement.setAttribute('data-theme', 'light');
// or remove attribute for default dark theme
document.documentElement.removeAttribute('data-theme');The Manager component has a built-in theme toggle button that cycles through available themes.
Custom Themes
Method 1: CSS Variables File (Recommended)
Create my-custom-theme.css:
:root {
/* Override only the variables you want to customize */
--ll-color-bg-primary: #0a0a0a;
--ll-color-accent-primary: #ff00ff;
--ll-spacing-md: 12px;
/* Other variables use defaults */
}
/* Theme-specific overrides */
html[data-theme="dark"] {
--ll-color-bg-primary: #000000;
}
html[data-theme="myTheme"] {
--ll-color-bg-primary: #1a1a1a;
--ll-color-text-primary: #00ff00;
--ll-color-accent-primary: #00ff00;
}Then load it:
await initLushland({
cssFile: './my-custom-theme.css'
});Method 2: Update THEMES Array in Config
Add theme names to your config:
{
"THEMES": ["dark", "light", "cyberpunk", "myTheme", "highContrast"]
}Then define the styles in your CSS file.
Available CSS Variables
Color Variables (all use --ll- prefix):
--ll-color-bg-primary, --ll-color-bg-secondary, --ll-color-bg-tertiary, --ll-color-bg-quaternary, --ll-color-bg-hover
--ll-color-text-primary, --ll-color-text-secondary, --ll-color-text-muted
--ll-color-border-primary, --ll-color-border-secondary
--ll-color-accent-primary, --ll-color-accent-info, --ll-color-accent-danger, --ll-color-accent-successSpacing: --ll-spacing-xs, --ll-spacing-sm, --ll-spacing-md, --ll-spacing-lg
Other: --ll-radius-sm, --ll-radius-md, --ll-radius-circle, --ll-shadow-sm, --ll-shadow-md, --ll-shadow-focus, --ll-transition-default
All variables are namespaced with --ll- to prevent conflicts with other libraries.
Quick Tips
Initialization
Auto-initialize (backward compatible):
<script type="module" src="index.js"></script>Initialize with custom config:
import { initLushland } from './index.js';
await initLushland({
configFile: './my-config.json',
cssFile: './my-theme.css'
});Initialize with inline config:
await initLushland({
config: {
CONFIG: {
defaultWidth: 500,
defaultHeight: 400
}
}
});Window Management
Programmatically add a window:
import { windowsManager } from './index.js';
const w = document.createElement('lushland-window');
w.setAttribute('x', '50');
w.setAttribute('y', '50');
w.setAttribute('title', 'My Window');
w.setAttribute('feature', 'notepad');
document.getElementById('app').appendChild(w);
windowsManager.addWindow(w.id, w);Get all open windows:
import { windowsManager } from './index.js';
const allWindows = windowsManager.getAllWindows();
Object.entries(allWindows).forEach(([id, window]) => {
console.log(id, window.getAttribute('title'));
});Close all windows:
document.getElementById('app').innerHTML = '';Feature Registration
Register a custom feature:
import { initLushland, featureRegistry } from './index.js';
await initLushland();
featureRegistry.register('custom', (container) => {
container.innerHTML = '<h1>Custom Feature</h1>';
});Use the registered feature:
const w = document.createElement('lushland-window');
w.setAttribute('feature', 'custom');
document.getElementById('app').appendChild(w);Theme Management
Switch theme programmatically:
document.documentElement.setAttribute('data-theme', 'light');Get available themes:
import { THEMES } from './index.js';
console.log(THEMES); // ['dark', 'light', 'cyberpunk']Advanced Config Access
Access configuration after initialization:
import { initLushland, CONFIG, templateManager } from './index.js';
await initLushland();
// Modify config at runtime
CONFIG.defaultWidth = 600;
// Access template manager
const templates = templateManager.getAllTemplates();Listen for window manager updates:
document.addEventListener('windowsManagerUpdate', (event) => {
console.log('Windows updated:', event.detail);
});Clear localStorage theme:
localStorage.removeItem('lushland-theme');License
© 2025 Lushland. All rights reserved.
