|
| 1 | +# Bespoke Generalised Components |
| 2 | + |
| 3 | +This directory contains reusable components for creating embedded applications that share a consistent design system and user experience. |
| 4 | + |
| 5 | +## Components |
| 6 | + |
| 7 | +### 1. `bespoke.css` |
| 8 | +The core CSS framework providing: |
| 9 | +- Consistent design tokens (colors, spacing, typography) |
| 10 | +- Light and dark theme support |
| 11 | +- Reusable component styles (buttons, forms, modals, cards) |
| 12 | +- Responsive design utilities |
| 13 | + |
| 14 | +### 2. `template.html` |
| 15 | +A base HTML template that includes: |
| 16 | +- Navigation header with app name and help button |
| 17 | +- Main layout structure (sidebar + content area) |
| 18 | +- Help modal integration |
| 19 | +- Proper CSS and JavaScript loading |
| 20 | + |
| 21 | +### 3. `io.js` |
| 22 | +Generic data persistence functions: |
| 23 | +- Load/save from local files |
| 24 | +- localStorage operations with configurable keys |
| 25 | +- Server save operations with configurable endpoints |
| 26 | +- Data validation and error handling |
| 27 | + |
| 28 | +### 4. `auto-save.js` |
| 29 | +Automatic data persistence system: |
| 30 | +- Immediate localStorage saves |
| 31 | +- Periodic server synchronization |
| 32 | +- Configurable intervals and retry logic |
| 33 | +- Status reporting and error handling |
| 34 | + |
| 35 | +### 5. `help-modal.js` |
| 36 | +A dependency-free JavaScript module for the help modal system: |
| 37 | +- Consistent modal behavior across all apps |
| 38 | +- Keyboard navigation (ESC to close) |
| 39 | +- Focus management |
| 40 | +- Custom event system |
| 41 | + |
| 42 | +### 6. `help-content-template.html` |
| 43 | +A template for creating consistent help content: |
| 44 | +- Table of contents navigation |
| 45 | +- Standardized section structure |
| 46 | +- FAQ with collapsible details |
| 47 | +- Image integration guidelines |
| 48 | + |
| 49 | +## Usage Instructions |
| 50 | + |
| 51 | +### Setting Up a New Application |
| 52 | + |
| 53 | +1. **Copy the template files** to your new application directory |
| 54 | +2. **Customize the HTML template** by replacing placeholders: |
| 55 | + - `<!-- APP_TITLE -->` - Your application title |
| 56 | + - `<!-- APP_NAME -->` - Your application name (appears in header) |
| 57 | + - `<!-- APP_SPECIFIC_HEADER_CONTENT -->` - Any additional header elements |
| 58 | + - `<!-- APP_SPECIFIC_SIDEBAR -->` - Your sidebar content |
| 59 | + - `<!-- APP_SPECIFIC_MAIN_CONTENT -->` - Your main content area |
| 60 | + - `<!-- APP_SPECIFIC_CSS -->` - Links to your app-specific CSS files |
| 61 | + - `<!-- APP_SPECIFIC_SCRIPTS -->` - Links to your app-specific JavaScript files |
| 62 | + |
| 63 | +3. **Create your help content** using the help content template |
| 64 | +4. **Initialize the auto-save system** in your JavaScript: |
| 65 | + |
| 66 | +```javascript |
| 67 | +// Your application data |
| 68 | +let appData = { |
| 69 | + // Your data structure here |
| 70 | +}; |
| 71 | + |
| 72 | +// Initialize auto-save |
| 73 | +const autoSave = AutoSave.init({ |
| 74 | + data: appData, |
| 75 | + filename: 'solution.json', |
| 76 | + localStorageKey: 'myapp:data', |
| 77 | + saveInterval: 1000, |
| 78 | + onStatusChange: setStatus, |
| 79 | + onDataChange: (data) => { |
| 80 | + // Optional: Custom logic when data changes |
| 81 | + }, |
| 82 | + onError: (message, error) => { |
| 83 | + console.error('Auto-save error:', message, error); |
| 84 | + } |
| 85 | +}); |
| 86 | + |
| 87 | +// Load existing data |
| 88 | +const savedData = autoSave.loadFromLocalStorage(); |
| 89 | +if (savedData) { |
| 90 | + appData = savedData; |
| 91 | +} |
| 92 | +``` |
| 93 | + |
| 94 | +5. **Initialize the help modal** in your JavaScript: |
| 95 | + |
| 96 | +```javascript |
| 97 | +// Load your help content (from file, API, or inline) |
| 98 | +const helpContent = `<!-- Your help content here -->`; |
| 99 | + |
| 100 | +// Initialize the help modal |
| 101 | +HelpModal.init({ |
| 102 | + triggerSelector: '#btn-help', |
| 103 | + content: helpContent, |
| 104 | + theme: 'auto' // or 'light' or 'dark' |
| 105 | +}); |
| 106 | +``` |
| 107 | + |
| 108 | +### Example Implementation |
| 109 | + |
| 110 | +```html |
| 111 | +<!doctype html> |
| 112 | +<html lang="en"> |
| 113 | +<head> |
| 114 | + <meta charset="utf-8" /> |
| 115 | + <title>My App</title> |
| 116 | + <meta name="viewport" content="width=device-width, initial-scale=1" /> |
| 117 | + <link rel="stylesheet" href="./bespoke.css" /> |
| 118 | + <link rel="stylesheet" href="./my-app.css" /> |
| 119 | +</head> |
| 120 | +<body class="bespoke"> |
| 121 | + <header class="header"> |
| 122 | + <h1>My App</h1> |
| 123 | + <button id="btn-save">Save</button> |
| 124 | + <div class="spacer"></div> |
| 125 | + <div id="status" class="status">Ready</div> |
| 126 | + <button id="btn-help" class="as-button ghost">Help</button> |
| 127 | + </header> |
| 128 | + |
| 129 | + <main class="main-layout"> |
| 130 | + <aside class="sidebar"> |
| 131 | + <!-- Your app controls go here --> |
| 132 | + </aside> |
| 133 | + <div class="content-area"> |
| 134 | + <!-- Your main app content goes here --> |
| 135 | + </div> |
| 136 | + </main> |
| 137 | + |
| 138 | + <script src="./help-modal.js"></script> |
| 139 | + <script src="./my-app.js"></script> |
| 140 | + <script> |
| 141 | + HelpModal.init({ |
| 142 | + triggerSelector: '#btn-help', |
| 143 | + content: myHelpContent, |
| 144 | + theme: 'auto' |
| 145 | + }); |
| 146 | + </script> |
| 147 | +</body> |
| 148 | +</html> |
| 149 | +``` |
| 150 | + |
| 151 | +### Customizing Help Content |
| 152 | + |
| 153 | +Use the `help-content-template.html` as a starting point: |
| 154 | + |
| 155 | +1. **Replace placeholders** like `<!-- APP_NAME -->` with your actual content |
| 156 | +2. **Add sections** as needed for your application |
| 157 | +3. **Include images** by placing them in a `help/img/` directory |
| 158 | +4. **Use the provided structure** for consistency across applications |
| 159 | + |
| 160 | +### CSS Customization |
| 161 | + |
| 162 | +The `bespoke.css` file uses CSS custom properties for easy theming: |
| 163 | + |
| 164 | +```css |
| 165 | +.bespoke { |
| 166 | + --bespoke-accent: #1062fb; /* Primary accent color */ |
| 167 | + --bespoke-bg: #ffffff; /* Background color */ |
| 168 | + --bespoke-fg: rgb(24, 33, 57); /* Text color */ |
| 169 | + /* ... many more variables */ |
| 170 | +} |
| 171 | +``` |
| 172 | + |
| 173 | +You can override these variables in your app-specific CSS: |
| 174 | + |
| 175 | +```css |
| 176 | +.my-app { |
| 177 | + --bespoke-accent: #ff6b6b; /* Custom accent color */ |
| 178 | + --bespoke-bg: #f8f9fa; /* Custom background */ |
| 179 | +} |
| 180 | +``` |
| 181 | + |
| 182 | +### Auto-Save API |
| 183 | + |
| 184 | +The `AutoSave` class provides several methods: |
| 185 | + |
| 186 | +```javascript |
| 187 | +// Initialize |
| 188 | +const autoSave = AutoSave.init({ |
| 189 | + data: appData, |
| 190 | + filename: 'solution.json', |
| 191 | + localStorageKey: 'myapp:data', |
| 192 | + saveInterval: 1000, |
| 193 | + onStatusChange: setStatus, |
| 194 | + onDataChange: (data) => { /* custom logic */ }, |
| 195 | + onError: (message, error) => { /* error handling */ } |
| 196 | +}); |
| 197 | + |
| 198 | +// Mark data as changed |
| 199 | +autoSave.markDirty(); |
| 200 | + |
| 201 | +// Manual save |
| 202 | +autoSave.saveNow(); |
| 203 | + |
| 204 | +// Load from localStorage |
| 205 | +const data = autoSave.loadFromLocalStorage(); |
| 206 | + |
| 207 | +// Destroy the auto-save system |
| 208 | +autoSave.destroy(); |
| 209 | +``` |
| 210 | + |
| 211 | +### IO API |
| 212 | + |
| 213 | +The `IO` object provides generic data persistence functions: |
| 214 | + |
| 215 | +```javascript |
| 216 | +// Load from file |
| 217 | +const data = await IO.loadFromFile('data.json'); |
| 218 | + |
| 219 | +// Save to localStorage |
| 220 | +IO.saveToLocalStorage(data, 'myapp:data'); |
| 221 | + |
| 222 | +// Load from localStorage |
| 223 | +const data = IO.loadFromLocalStorage('myapp:data'); |
| 224 | + |
| 225 | +// Save to server |
| 226 | +await IO.saveToServer(data, 'solution.json', '/api/save'); |
| 227 | + |
| 228 | +// Validate data |
| 229 | +IO.validateData(data); |
| 230 | +``` |
| 231 | + |
| 232 | +### Help Modal API |
| 233 | + |
| 234 | +The `HelpModal` class provides several methods: |
| 235 | + |
| 236 | +```javascript |
| 237 | +// Initialize |
| 238 | +const modal = HelpModal.init({ |
| 239 | + triggerSelector: '#btn-help', |
| 240 | + content: helpContent, |
| 241 | + theme: 'auto' |
| 242 | +}); |
| 243 | + |
| 244 | +// Update content dynamically |
| 245 | +modal.updateContent(newHelpContent); |
| 246 | + |
| 247 | +// Destroy the modal |
| 248 | +modal.destroy(); |
| 249 | +``` |
| 250 | + |
| 251 | +### Events |
| 252 | + |
| 253 | +The help modal dispatches custom events: |
| 254 | + |
| 255 | +```javascript |
| 256 | +document.getElementById('btn-help').addEventListener('helpModal:open', (e) => { |
| 257 | + console.log('Help modal opened'); |
| 258 | +}); |
| 259 | + |
| 260 | +document.getElementById('btn-help').addEventListener('helpModal:close', (e) => { |
| 261 | + console.log('Help modal closed'); |
| 262 | +}); |
| 263 | +``` |
| 264 | + |
| 265 | +## Design Principles |
| 266 | + |
| 267 | +1. **Consistency**: All applications share the same visual language |
| 268 | +2. **Accessibility**: Proper focus management, keyboard navigation, and ARIA labels |
| 269 | +3. **Responsiveness**: Works on desktop and mobile devices |
| 270 | +4. **Theme Support**: Automatic light/dark mode detection |
| 271 | +5. **Modularity**: Components can be used independently |
| 272 | +6. **Zero Dependencies**: No external JavaScript libraries required |
| 273 | + |
| 274 | +## File Structure |
| 275 | + |
| 276 | +``` |
| 277 | +generalised/ |
| 278 | +├── bespoke.css # Core CSS framework |
| 279 | +├── template.html # Base HTML template |
| 280 | +├── help-modal.js # Help modal JavaScript |
| 281 | +├── help-content-template.html # Help content template |
| 282 | +└── README.md # This file |
| 283 | +``` |
| 284 | + |
| 285 | +## Browser Support |
| 286 | + |
| 287 | +- Modern browsers (Chrome, Firefox, Safari, Edge) |
| 288 | +- ES6+ features (classes, arrow functions, template literals) |
| 289 | +- CSS Grid and Flexbox |
| 290 | +- CSS Custom Properties |
| 291 | + |
| 292 | +## Contributing |
| 293 | + |
| 294 | +When adding new components or modifying existing ones: |
| 295 | + |
| 296 | +1. Maintain backward compatibility |
| 297 | +2. Follow the established naming conventions |
| 298 | +3. Test across different themes and screen sizes |
| 299 | +4. Update this README with any new features |
| 300 | +5. Ensure accessibility standards are met |
0 commit comments