@kupola/kupola 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +130 -0
- package/INTEGRATION.md +440 -0
- package/PROJECT_SUMMARY.md +312 -0
- package/README.md +286 -0
- package/SKILL.md +572 -0
- package/css/accessibility.css +119 -0
- package/css/animations.css +224 -0
- package/css/brand-themes.css +300 -0
- package/css/colors_and_type.css +441 -0
- package/css/components-ext.css +4165 -0
- package/css/components.css +1483 -0
- package/css/kupola.css +12 -0
- package/css/responsive.css +697 -0
- package/css/scaffold.css +145 -0
- package/css/states.css +316 -0
- package/css/theme-dark.css +296 -0
- package/css/theme-light.css +296 -0
- package/css/utilities.css +171 -0
- package/dist/css/kupola.css +12 -0
- package/dist/icons/icons/activity.svg +3 -0
- package/dist/icons/icons/alert-circle.svg +1 -0
- package/dist/icons/icons/alert-triangle.svg +1 -0
- package/dist/icons/icons/alert.d27e24.svg +1 -0
- package/dist/icons/icons/alert.svg +1 -0
- package/dist/icons/icons/apple.svg +1 -0
- package/dist/icons/icons/arrow-down.svg +1 -0
- package/dist/icons/icons/arrow-expand.svg +1 -0
- package/dist/icons/icons/arrow-left.svg +1 -0
- package/dist/icons/icons/arrow-minimize.svg +1 -0
- package/dist/icons/icons/arrow-right-to-line.svg +1 -0
- package/dist/icons/icons/arrow-right.svg +1 -0
- package/dist/icons/icons/arrow-up-right.svg +1 -0
- package/dist/icons/icons/arrow-up.0c0c0d.svg +1 -0
- package/dist/icons/icons/arrow-up.svg +1 -0
- package/dist/icons/icons/at.svg +1 -0
- package/dist/icons/icons/atom.0c0c0d.svg +1 -0
- package/dist/icons/icons/atom.svg +1 -0
- package/dist/icons/icons/bar-chart-2.svg +1 -0
- package/dist/icons/icons/bar.svg +1 -0
- package/dist/icons/icons/bell.svg +1 -0
- package/dist/icons/icons/box.svg +1 -0
- package/dist/icons/icons/bug.svg +1 -0
- package/dist/icons/icons/button.svg +1 -0
- package/dist/icons/icons/calendar.svg +1 -0
- package/dist/icons/icons/check-circle.33c192.svg +1 -0
- package/dist/icons/icons/check-circle.svg +1 -0
- package/dist/icons/icons/check-square.svg +4 -0
- package/dist/icons/icons/check.d1d3db.svg +1 -0
- package/dist/icons/icons/check.svg +1 -0
- package/dist/icons/icons/chevron-down.svg +1 -0
- package/dist/icons/icons/chevron-left.svg +1 -0
- package/dist/icons/icons/chevron-right.svg +1 -0
- package/dist/icons/icons/chevron-up.svg +1 -0
- package/dist/icons/icons/circle.svg +1 -0
- package/dist/icons/icons/clock.svg +1 -0
- package/dist/icons/icons/cmd.svg +1 -0
- package/dist/icons/icons/code.svg +1 -0
- package/dist/icons/icons/columns.svg +1 -0
- package/dist/icons/icons/copy.svg +1 -0
- package/dist/icons/icons/cpu.svg +1 -0
- package/dist/icons/icons/dashboard.0c0c0d.svg +1 -0
- package/dist/icons/icons/dashboard.svg +1 -0
- package/dist/icons/icons/dollar.svg +1 -0
- package/dist/icons/icons/download.svg +1 -0
- package/dist/icons/icons/edit.svg +1 -0
- package/dist/icons/icons/extensions.svg +1 -0
- package/dist/icons/icons/external.svg +1 -0
- package/dist/icons/icons/eye.svg +1 -0
- package/dist/icons/icons/file-text.svg +1 -0
- package/dist/icons/icons/file.svg +1 -0
- package/dist/icons/icons/files.svg +1 -0
- package/dist/icons/icons/filter.svg +1 -0
- package/dist/icons/icons/folder-open.svg +4 -0
- package/dist/icons/icons/folder.svg +1 -0
- package/dist/icons/icons/gear.svg +1 -0
- package/dist/icons/icons/git.svg +1 -0
- package/dist/icons/icons/github.svg +1 -0
- package/dist/icons/icons/globe.svg +1 -0
- package/dist/icons/icons/grid-2x2.svg +1 -0
- package/dist/icons/icons/hash.svg +1 -0
- package/dist/icons/icons/heart.svg +1 -0
- package/dist/icons/icons/help-circle.svg +5 -0
- package/dist/icons/icons/help.svg +1 -0
- package/dist/icons/icons/home.svg +1 -0
- package/dist/icons/icons/icons.svg +153 -0
- package/dist/icons/icons/image.svg +1 -0
- package/dist/icons/icons/info-circle.svg +1 -0
- package/dist/icons/icons/info-square.svg +1 -0
- package/dist/icons/icons/info.387bff.svg +1 -0
- package/dist/icons/icons/info.svg +1 -0
- package/dist/icons/icons/input.svg +1 -0
- package/dist/icons/icons/key.svg +1 -0
- package/dist/icons/icons/layers.svg +1 -0
- package/dist/icons/icons/layout-grid.svg +6 -0
- package/dist/icons/icons/layout.svg +1 -0
- package/dist/icons/icons/link.svg +1 -0
- package/dist/icons/icons/list.svg +1 -0
- package/dist/icons/icons/lock.svg +1 -0
- package/dist/icons/icons/log-out.svg +1 -0
- package/dist/icons/icons/logo.svg +1 -0
- package/dist/icons/icons/mail.svg +1 -0
- package/dist/icons/icons/menu.svg +1 -0
- package/dist/icons/icons/message-circle.svg +1 -0
- package/dist/icons/icons/message-plus.svg +1 -0
- package/dist/icons/icons/message-square.svg +1 -0
- package/dist/icons/icons/mic.svg +1 -0
- package/dist/icons/icons/minus.svg +1 -0
- package/dist/icons/icons/moon.svg +1 -0
- package/dist/icons/icons/more-h.svg +1 -0
- package/dist/icons/icons/mouse.svg +1 -0
- package/dist/icons/icons/palette.svg +1 -0
- package/dist/icons/icons/panel-bottom.svg +1 -0
- package/dist/icons/icons/pause.svg +1 -0
- package/dist/icons/icons/play.svg +1 -0
- package/dist/icons/icons/plug.svg +1 -0
- package/dist/icons/icons/plus.0c0c0d.svg +1 -0
- package/dist/icons/icons/plus.svg +1 -0
- package/dist/icons/icons/refresh.svg +1 -0
- package/dist/icons/icons/ruler.svg +1 -0
- package/dist/icons/icons/scroll-text.svg +1 -0
- package/dist/icons/icons/search-menu.svg +1 -0
- package/dist/icons/icons/search.svg +1 -0
- package/dist/icons/icons/send.0c0c0d.svg +1 -0
- package/dist/icons/icons/send.svg +1 -0
- package/dist/icons/icons/settings.0c0c0d.svg +1 -0
- package/dist/icons/icons/settings.svg +1 -0
- package/dist/icons/icons/shield.svg +1 -0
- package/dist/icons/icons/sidebar-left.svg +1 -0
- package/dist/icons/icons/sidebar-right.svg +1 -0
- package/dist/icons/icons/sliders.svg +1 -0
- package/dist/icons/icons/sparkles.32f08c.svg +1 -0
- package/dist/icons/icons/sparkles.svg +1 -0
- package/dist/icons/icons/square.svg +1 -0
- package/dist/icons/icons/star.svg +1 -0
- package/dist/icons/icons/sun.svg +1 -0
- package/dist/icons/icons/table.svg +1 -0
- package/dist/icons/icons/terminal.svg +1 -0
- package/dist/icons/icons/trash.svg +1 -0
- package/dist/icons/icons/trending-down.svg +1 -0
- package/dist/icons/icons/trending-up.svg +1 -0
- package/dist/icons/icons/type.svg +1 -0
- package/dist/icons/icons/upload.svg +1 -0
- package/dist/icons/icons/user-circle.svg +1 -0
- package/dist/icons/icons/user-plus.svg +6 -0
- package/dist/icons/icons/user.svg +1 -0
- package/dist/icons/icons/users.svg +1 -0
- package/dist/icons/icons/warning.svg +1 -0
- package/dist/icons/icons/wrench.svg +1 -0
- package/dist/icons/icons/x-circle.svg +1 -0
- package/dist/icons/icons/x.svg +1 -0
- package/dist/icons/icons/zap.0c0c0d.svg +1 -0
- package/dist/icons/icons/zap.svg +1 -0
- package/dist/kupola.cjs.js +258 -0
- package/dist/kupola.cjs.js.map +1 -0
- package/dist/kupola.esm.js +7640 -0
- package/dist/kupola.esm.js.map +1 -0
- package/dist/kupola.umd.js +258 -0
- package/dist/kupola.umd.js.map +1 -0
- package/dist/types/kupola.d.ts +1359 -0
- package/dist/utils/utils/Kupola.cs +77 -0
- package/dist/utils/utils/Kupola.java +104 -0
- package/dist/utils/utils/kupola.go +120 -0
- package/dist/utils/utils/kupola.js +63 -0
- package/dist/utils/utils/kupola.py +1392 -0
- package/dist/utils/utils/kupola.rb +69 -0
- package/icons/activity.svg +3 -0
- package/icons/alert-circle.svg +1 -0
- package/icons/alert-triangle.svg +1 -0
- package/icons/alert.d27e24.svg +1 -0
- package/icons/alert.svg +1 -0
- package/icons/apple.svg +1 -0
- package/icons/arrow-down.svg +1 -0
- package/icons/arrow-expand.svg +1 -0
- package/icons/arrow-left.svg +1 -0
- package/icons/arrow-minimize.svg +1 -0
- package/icons/arrow-right-to-line.svg +1 -0
- package/icons/arrow-right.svg +1 -0
- package/icons/arrow-up-right.svg +1 -0
- package/icons/arrow-up.0c0c0d.svg +1 -0
- package/icons/arrow-up.svg +1 -0
- package/icons/at.svg +1 -0
- package/icons/atom.0c0c0d.svg +1 -0
- package/icons/atom.svg +1 -0
- package/icons/bar-chart-2.svg +1 -0
- package/icons/bar.svg +1 -0
- package/icons/bell.svg +1 -0
- package/icons/box.svg +1 -0
- package/icons/bug.svg +1 -0
- package/icons/button.svg +1 -0
- package/icons/calendar.svg +1 -0
- package/icons/check-circle.33c192.svg +1 -0
- package/icons/check-circle.svg +1 -0
- package/icons/check-square.svg +4 -0
- package/icons/check.d1d3db.svg +1 -0
- package/icons/check.svg +1 -0
- package/icons/chevron-down.svg +1 -0
- package/icons/chevron-left.svg +1 -0
- package/icons/chevron-right.svg +1 -0
- package/icons/chevron-up.svg +1 -0
- package/icons/circle.svg +1 -0
- package/icons/clock.svg +1 -0
- package/icons/cmd.svg +1 -0
- package/icons/code.svg +1 -0
- package/icons/columns.svg +1 -0
- package/icons/copy.svg +1 -0
- package/icons/cpu.svg +1 -0
- package/icons/dashboard.0c0c0d.svg +1 -0
- package/icons/dashboard.svg +1 -0
- package/icons/dollar.svg +1 -0
- package/icons/download.svg +1 -0
- package/icons/edit.svg +1 -0
- package/icons/extensions.svg +1 -0
- package/icons/external.svg +1 -0
- package/icons/eye.svg +1 -0
- package/icons/file-text.svg +1 -0
- package/icons/file.svg +1 -0
- package/icons/files.svg +1 -0
- package/icons/filter.svg +1 -0
- package/icons/folder-open.svg +4 -0
- package/icons/folder.svg +1 -0
- package/icons/gear.svg +1 -0
- package/icons/git.svg +1 -0
- package/icons/github.svg +1 -0
- package/icons/globe.svg +1 -0
- package/icons/grid-2x2.svg +1 -0
- package/icons/hash.svg +1 -0
- package/icons/heart.svg +1 -0
- package/icons/help-circle.svg +5 -0
- package/icons/help.svg +1 -0
- package/icons/home.svg +1 -0
- package/icons/icons.svg +153 -0
- package/icons/image.svg +1 -0
- package/icons/info-circle.svg +1 -0
- package/icons/info-square.svg +1 -0
- package/icons/info.387bff.svg +1 -0
- package/icons/info.svg +1 -0
- package/icons/input.svg +1 -0
- package/icons/key.svg +1 -0
- package/icons/layers.svg +1 -0
- package/icons/layout-grid.svg +6 -0
- package/icons/layout.svg +1 -0
- package/icons/link.svg +1 -0
- package/icons/list.svg +1 -0
- package/icons/lock.svg +1 -0
- package/icons/log-out.svg +1 -0
- package/icons/logo.svg +1 -0
- package/icons/mail.svg +1 -0
- package/icons/menu.svg +1 -0
- package/icons/message-circle.svg +1 -0
- package/icons/message-plus.svg +1 -0
- package/icons/message-square.svg +1 -0
- package/icons/mic.svg +1 -0
- package/icons/minus.svg +1 -0
- package/icons/moon.svg +1 -0
- package/icons/more-h.svg +1 -0
- package/icons/mouse.svg +1 -0
- package/icons/palette.svg +1 -0
- package/icons/panel-bottom.svg +1 -0
- package/icons/pause.svg +1 -0
- package/icons/play.svg +1 -0
- package/icons/plug.svg +1 -0
- package/icons/plus.0c0c0d.svg +1 -0
- package/icons/plus.svg +1 -0
- package/icons/refresh.svg +1 -0
- package/icons/ruler.svg +1 -0
- package/icons/scroll-text.svg +1 -0
- package/icons/search-menu.svg +1 -0
- package/icons/search.svg +1 -0
- package/icons/send.0c0c0d.svg +1 -0
- package/icons/send.svg +1 -0
- package/icons/settings.0c0c0d.svg +1 -0
- package/icons/settings.svg +1 -0
- package/icons/shield.svg +1 -0
- package/icons/sidebar-left.svg +1 -0
- package/icons/sidebar-right.svg +1 -0
- package/icons/sliders.svg +1 -0
- package/icons/sparkles.32f08c.svg +1 -0
- package/icons/sparkles.svg +1 -0
- package/icons/square.svg +1 -0
- package/icons/star.svg +1 -0
- package/icons/sun.svg +1 -0
- package/icons/table.svg +1 -0
- package/icons/terminal.svg +1 -0
- package/icons/trash.svg +1 -0
- package/icons/trending-down.svg +1 -0
- package/icons/trending-up.svg +1 -0
- package/icons/type.svg +1 -0
- package/icons/upload.svg +1 -0
- package/icons/user-circle.svg +1 -0
- package/icons/user-plus.svg +6 -0
- package/icons/user.svg +1 -0
- package/icons/users.svg +1 -0
- package/icons/warning.svg +1 -0
- package/icons/wrench.svg +1 -0
- package/icons/x-circle.svg +1 -0
- package/icons/x.svg +1 -0
- package/icons/zap.0c0c0d.svg +1 -0
- package/icons/zap.svg +1 -0
- package/js/calendar.js +184 -0
- package/js/carousel.js +173 -0
- package/js/collapse.js +127 -0
- package/js/color-picker.js +144 -0
- package/js/component.js +276 -0
- package/js/composition-api.js +458 -0
- package/js/countdown.js +144 -0
- package/js/data-bind.js +1286 -0
- package/js/datepicker.js +270 -0
- package/js/dialog.js +131 -0
- package/js/drawer.js +118 -0
- package/js/dropdown.js +122 -0
- package/js/dynamic-tags.js +156 -0
- package/js/error-handler.js +181 -0
- package/js/fileupload.js +392 -0
- package/js/form.js +291 -0
- package/js/global-events.js +203 -0
- package/js/heatmap.js +405 -0
- package/js/http.js +419 -0
- package/js/i18n.js +228 -0
- package/js/icons.js +165 -0
- package/js/image-preview.js +218 -0
- package/js/initializer.js +162 -0
- package/js/kupola-core.js +66 -0
- package/js/kupola-devtools.js +598 -0
- package/js/kupola-lifecycle.js +510 -0
- package/js/message.js +60 -0
- package/js/modal.js +191 -0
- package/js/notification.js +73 -0
- package/js/numberinput.js +146 -0
- package/js/performance.js +250 -0
- package/js/registry.js +205 -0
- package/js/router.js +396 -0
- package/js/security.js +189 -0
- package/js/select.js +143 -0
- package/js/slide-captcha.js +504 -0
- package/js/slider.js +94 -0
- package/js/statcard.js +219 -0
- package/js/tag.js +83 -0
- package/js/test-utils.js +251 -0
- package/js/theme.js +363 -0
- package/js/timepicker.js +238 -0
- package/js/tooltip.js +122 -0
- package/js/utils.js +1458 -0
- package/js/validation.js +553 -0
- package/js/virtual-list.js +593 -0
- package/package.json +105 -0
- package/templates/base.html +30 -0
- package/templates/base_dashboard.html +99 -0
- package/types/kupola.d.ts +1359 -0
- package/utils/Kupola.cs +77 -0
- package/utils/Kupola.java +104 -0
- package/utils/kupola.go +120 -0
- package/utils/kupola.js +63 -0
- package/utils/kupola.py +1392 -0
- package/utils/kupola.rb +69 -0
package/SKILL.md
ADDED
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
# Kupola
|
|
2
|
+
|
|
3
|
+
> Lightweight UI toolkit for any web project. No heavy frontend frameworks required. Works seamlessly with Flask, Django, Gin, Spring Boot, ASP.NET Core, Express, and any backend framework that outputs HTML.
|
|
4
|
+
|
|
5
|
+
## Library Layout
|
|
6
|
+
|
|
7
|
+
> The library root directory is `kupola/`. All paths are relative to this root.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
kupola/
|
|
11
|
+
├── css/ # CSS stylesheets
|
|
12
|
+
│ ├── kupola.css # Main CSS bundle
|
|
13
|
+
│ ├── colors_and_type.css # Token definitions
|
|
14
|
+
│ ├── components.css # Component styles
|
|
15
|
+
│ ├── components-ext.css # Extended component styles
|
|
16
|
+
│ ├── scaffold.css # Reset and utilities
|
|
17
|
+
│ ├── brand-themes.css # 11 brand color themes
|
|
18
|
+
│ ├── theme-dark.css # Dark theme tokens (default)
|
|
19
|
+
│ ├── theme-light.css # Light theme tokens
|
|
20
|
+
│ ├── states.css # Component states
|
|
21
|
+
│ ├── utilities.css # Utility classes
|
|
22
|
+
│ ├── responsive.css # Responsive design (PC/Pad/Phone)
|
|
23
|
+
│ ├── accessibility.css # a11y support
|
|
24
|
+
│ └── animations.css # Transitions and animations
|
|
25
|
+
├── js/ # JavaScript utilities
|
|
26
|
+
│ ├── kupola-core.js # Core framework (KupolaHttp, KupolaComponent)
|
|
27
|
+
│ ├── component.js # Base component class
|
|
28
|
+
│ ├── kupola-lifecycle.js # Lifecycle management
|
|
29
|
+
│ ├── composition-api.js # Composition API (reactive, computed, watch)
|
|
30
|
+
│ ├── initializer.js # Auto initialization manager
|
|
31
|
+
│ ├── registry.js # Component registry
|
|
32
|
+
│ ├── global-events.js # Global event manager
|
|
33
|
+
│ ├── router.js # Client-side router
|
|
34
|
+
│ ├── http.js # HTTP client (fetch-based)
|
|
35
|
+
│ ├── data-bind.js # Data binding and event bus
|
|
36
|
+
│ ├── validation.js # Form validation
|
|
37
|
+
│ ├── theme.js # Theme/brand switching
|
|
38
|
+
│ ├── icons.js # Icon renderer
|
|
39
|
+
│ ├── tooltip.js # Tooltip system
|
|
40
|
+
│ ├── datepicker.js # Datepicker component
|
|
41
|
+
│ ├── timepicker.js # Timepicker component
|
|
42
|
+
│ ├── numberinput.js # Number input component
|
|
43
|
+
│ ├── fileupload.js # File upload component
|
|
44
|
+
│ ├── select.js # Select component
|
|
45
|
+
│ ├── slider.js # Slider component
|
|
46
|
+
│ ├── modal.js # Modal component
|
|
47
|
+
│ ├── dialog.js # Dialog component
|
|
48
|
+
│ ├── drawer.js # Drawer component
|
|
49
|
+
│ ├── dropdown.js # Dropdown component
|
|
50
|
+
│ ├── slide-captcha.js # Slide captcha component
|
|
51
|
+
│ ├── heatmap.js # Heatmap component
|
|
52
|
+
│ ├── virtual-list.js # Virtual list component
|
|
53
|
+
│ ├── statcard.js # Statistic card component
|
|
54
|
+
│ ├── image-preview.js # Image preview component
|
|
55
|
+
│ ├── carousel.js # Carousel component
|
|
56
|
+
│ ├── countdown.js # Countdown component
|
|
57
|
+
│ ├── calendar.js # Calendar component
|
|
58
|
+
│ ├── collapse.js # Collapse component
|
|
59
|
+
│ ├── tag.js # Tag component
|
|
60
|
+
│ ├── dynamic-tags.js # Dynamic tags component
|
|
61
|
+
│ ├── color-picker.js # Color picker component
|
|
62
|
+
│ ├── notification.js # Notification component
|
|
63
|
+
│ ├── message.js # Message component
|
|
64
|
+
│ ├── form.js # Form utilities
|
|
65
|
+
│ ├── security.js # Security utilities (XSS/CSRF)
|
|
66
|
+
│ ├── utils.js # General utilities
|
|
67
|
+
│ ├── error-handler.js # Global error handler
|
|
68
|
+
│ ├── performance.js # Performance monitoring
|
|
69
|
+
│ ├── i18n.js # Internationalization
|
|
70
|
+
│ ├── kupola-devtools.js # DevTools panel
|
|
71
|
+
│ └── test-utils.js # Testing utilities
|
|
72
|
+
├── icons/ # 121 SVG icons (+ sprite)
|
|
73
|
+
│ ├── *.svg # Individual icons
|
|
74
|
+
│ └── icons.svg # SVG sprite
|
|
75
|
+
├── dist/ # Build output
|
|
76
|
+
│ ├── kupola.esm.js # ES Module format
|
|
77
|
+
│ ├── kupola.cjs.js # CommonJS format
|
|
78
|
+
│ ├── kupola.umd.js # UMD format
|
|
79
|
+
│ └── types/kupola.d.ts # TypeScript types
|
|
80
|
+
├── src/ # Build entry points
|
|
81
|
+
├── dashboard/ # Dashboard layout framework
|
|
82
|
+
│ ├── dashboard.css # Layout styles
|
|
83
|
+
│ ├── dashboard.html # Complete demo
|
|
84
|
+
│ └── dashboard.js # Interactivity
|
|
85
|
+
├── templates/ # Flask/Gin templates
|
|
86
|
+
│ ├── base.html # Base template
|
|
87
|
+
│ └── base_dashboard.html # Dashboard base template
|
|
88
|
+
├── utils/ # Multi-language utility functions
|
|
89
|
+
│ ├── kupola.py # Python component generation functions
|
|
90
|
+
│ ├── kupola.go # Go component generation functions
|
|
91
|
+
│ ├── Kupola.java # Java component generation functions
|
|
92
|
+
│ ├── Kupola.cs # C# component generation functions
|
|
93
|
+
│ ├── kupola.js # Node.js component generation functions
|
|
94
|
+
│ └── kupola.rb # Ruby component generation functions
|
|
95
|
+
├── docs/ # Documentation
|
|
96
|
+
│ ├── api.md # API documentation
|
|
97
|
+
│ └── kupola-vs-vue-react.md # Framework comparison
|
|
98
|
+
├── examples/ # Example projects
|
|
99
|
+
│ ├── basic_example.html # HTML demo
|
|
100
|
+
│ └── flask_example/ # Flask complete example
|
|
101
|
+
├── snippets/ # IDE code snippets
|
|
102
|
+
│ └── kupola.code-snippets # VS Code snippets
|
|
103
|
+
├── version.json # Version information
|
|
104
|
+
├── CHANGELOG.md # Changelog
|
|
105
|
+
├── INTEGRATION.md # Integration guide
|
|
106
|
+
├── PROJECT_SUMMARY.md # Project summary
|
|
107
|
+
└── README.md # Usage guide
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Brand Essentials
|
|
111
|
+
|
|
112
|
+
- **Surface**: dark canvas `--bg-base-default #1A1B1D`
|
|
113
|
+
- **Primary text**: `--text-default #D1D3DB`
|
|
114
|
+
- **Brand accent**: `--bg-brand #535164` (曾青, default) with 10 alternative colors
|
|
115
|
+
- **Status palette**: primary / success / alert / warning / error
|
|
116
|
+
- **Typography**: SF Pro / SF Pro Text / JetBrains Mono
|
|
117
|
+
- **Radii**: `2 / 4 / 6 / 8 / 10 / full`
|
|
118
|
+
- **Spacers**: `0 / 4 / 6 / 8 / 12 / 16 / 24 / 32 / 40`
|
|
119
|
+
|
|
120
|
+
## Brand Colors
|
|
121
|
+
|
|
122
|
+
| ID | Name | Color | Text Color |
|
|
123
|
+
|----|------|-------|------------|
|
|
124
|
+
| zengqing | 曾青 | #535164 | white (default) |
|
|
125
|
+
| green | 翠绿 | #32F08C | dark |
|
|
126
|
+
| xionghuang | 雄黄 | #FF9900 | dark |
|
|
127
|
+
| jianghuang | 姜黄 | #E2C027 | dark |
|
|
128
|
+
| lanlv | 蓝绿 | #12A182 | white |
|
|
129
|
+
| kongquelan | 孔雀蓝 | #0EB0C9 | dark |
|
|
130
|
+
| meiguizi | 玫瑰紫 | #BA2F7B | white |
|
|
131
|
+
| shihong | 柿红 | #F2481B | white |
|
|
132
|
+
| shanchahong | 山茶红 | #F05A46 | white |
|
|
133
|
+
| quhong | 紫云 | #B1A6CC | dark |
|
|
134
|
+
| roulan | 柔蓝 | #106898 | white |
|
|
135
|
+
|
|
136
|
+
## Components (40+)
|
|
137
|
+
|
|
138
|
+
| Slug | Type | Notes |
|
|
139
|
+
|------|------|-------|
|
|
140
|
+
| activity-rail | IDE rail | vertical activity bar with active state + divider |
|
|
141
|
+
| alert | Notification | 4 tones × simple/complex |
|
|
142
|
+
| avatar | User chip | sm/md/lg, square/accent |
|
|
143
|
+
| badge | Status tag | default / success / warning / danger / brand |
|
|
144
|
+
| button | Button | 8 variants × 3 sizes × 4 states |
|
|
145
|
+
| card | Surface card | header / actions |
|
|
146
|
+
| chat-composer | AI input | tool row + model chip + mic + send |
|
|
147
|
+
| checkbox | Form control | checked / unchecked / disabled |
|
|
148
|
+
| collapse | Accordion | collapsible sections |
|
|
149
|
+
| color-picker | Color selector | preset colors + custom input |
|
|
150
|
+
| date-picker | Date input | calendar popup, month navigation |
|
|
151
|
+
| dialog | Modal | overlay + footer |
|
|
152
|
+
| divider | Separator | horizontal rule |
|
|
153
|
+
| drawer | Side panel | slide-in panel from left/right |
|
|
154
|
+
| dynamic-tags | Tag input | add/remove tags dynamically |
|
|
155
|
+
| editor-tabs | IDE tabs | layered tab strip + close affordance + actions |
|
|
156
|
+
| empty | Empty state | placeholder for empty content |
|
|
157
|
+
| file-tree | File explorer | multi-depth, chevron |
|
|
158
|
+
| file-upload | File input | drag & drop, preview, delete |
|
|
159
|
+
| form | Form controls | input / textarea / select / checkbox / radio / switch |
|
|
160
|
+
| Heatmap | Data visualization | calendar-based heatmap with color levels |
|
|
161
|
+
| image | Media | image with placeholder, fallback, and error states |
|
|
162
|
+
| image-list | Media | image grid with selection support |
|
|
163
|
+
| image-preview | Image viewer | full-size image preview |
|
|
164
|
+
| stat-card | Data visualization | KPI card with number animation and trend indicators |
|
|
165
|
+
| kbd | Shortcut hint | keyboard key caps |
|
|
166
|
+
| menu | Dropdown | section labels, shortcut |
|
|
167
|
+
| message | Toast | floating message notifications |
|
|
168
|
+
| nav-list | Sidebar nav | grouped items with active state |
|
|
169
|
+
| notification | Notification | popup notifications |
|
|
170
|
+
| number-input | Numeric input | +/- buttons, min/max constraints |
|
|
171
|
+
| page-header | Page head | title + actions region |
|
|
172
|
+
| pagination | Page navigator | numeric with ellipsis |
|
|
173
|
+
| progress | Progress bar | determinate / indeterminate |
|
|
174
|
+
| progress-circle | Circular progress | SVG-based circular indicator |
|
|
175
|
+
| radio | Form control | single selection among options |
|
|
176
|
+
| select | Dropdown select | options dropdown |
|
|
177
|
+
| setting-row | Preference row | title + description + control |
|
|
178
|
+
| slide-captcha | Security | circle / slider mode, error refresh |
|
|
179
|
+
| slider | Range input | horizontal slider with value display |
|
|
180
|
+
| spin | Loading | spinner indicator |
|
|
181
|
+
| stat-card | KPI card | tabular numerals + delta |
|
|
182
|
+
| status-bar | IDE status bar | status items + dot indicators |
|
|
183
|
+
| switch | Toggle | on/off switch with thumb |
|
|
184
|
+
| table | Data table | avatar + tag cells |
|
|
185
|
+
| table-panel | Table container | bordered table with toolbar + footer pagination |
|
|
186
|
+
| tabs | Tabs | underline / filled / closable |
|
|
187
|
+
| tag | Status tag | default / success / warning / danger / brand |
|
|
188
|
+
| time-picker | Time input | time selection popup |
|
|
189
|
+
| timeline | Timeline | chronological event list |
|
|
190
|
+
| tooltip | Hint | custom tooltip with data-title |
|
|
191
|
+
| virtual-list | List | virtualized scrolling for large datasets |
|
|
192
|
+
| workbench-titlebar | IDE top bar | traffic lights + project selector + icon actions |
|
|
193
|
+
|
|
194
|
+
## Dashboard Framework
|
|
195
|
+
|
|
196
|
+
Complete 4-section layout:
|
|
197
|
+
- **Header** (48px): Logo + center menu + right icons (theme/brand/user)
|
|
198
|
+
- **Sidebar** (48px): Icon-only navigation with tooltips
|
|
199
|
+
- **Content**: Scrollable main area
|
|
200
|
+
- **Footer** (24px): Status indicators
|
|
201
|
+
|
|
202
|
+
## Templates
|
|
203
|
+
|
|
204
|
+
| Template | Description |
|
|
205
|
+
|----------|-------------|
|
|
206
|
+
| base.html | Minimal base template with CSS/JS includes |
|
|
207
|
+
| base_dashboard.html | Full dashboard layout with all features |
|
|
208
|
+
|
|
209
|
+
## Language-Specific Utilities
|
|
210
|
+
|
|
211
|
+
Kupola provides helper functions for popular backend languages:
|
|
212
|
+
|
|
213
|
+
### Python Utilities
|
|
214
|
+
|
|
215
|
+
`utils/kupola.py` provides component generation functions for Flask/Django:
|
|
216
|
+
|
|
217
|
+
| Function | Description |
|
|
218
|
+
|----------|-------------|
|
|
219
|
+
| kupola_button() | Generate button HTML |
|
|
220
|
+
| kupola_input() | Generate input field |
|
|
221
|
+
| kupola_card() | Generate card |
|
|
222
|
+
| kupola_table() | Generate table |
|
|
223
|
+
| kupola_dashboard_layout() | Generate dashboard layout |
|
|
224
|
+
| kupola_stat_card() | Generate stat card |
|
|
225
|
+
| kupola_html_tag() | Generate HTML tag with theme/brand |
|
|
226
|
+
| kupola_theme_script() | Generate theme script tag |
|
|
227
|
+
| kupola_brand_toggle() | Generate brand toggle button |
|
|
228
|
+
|
|
229
|
+
## Go Utilities
|
|
230
|
+
|
|
231
|
+
`utils/kupola.go` provides component generation functions for Gin/Echo/Beego:
|
|
232
|
+
|
|
233
|
+
| Function | Description |
|
|
234
|
+
|----------|-------------|
|
|
235
|
+
| Button(label, variant, size) | Generate button HTML |
|
|
236
|
+
| Input(label, name, placeholder, validate) | Generate input field |
|
|
237
|
+
| Card(title, body, footer) | Generate card |
|
|
238
|
+
| StatCard(title, value, trend, trendType) | Generate stat card |
|
|
239
|
+
| Badge(text, variant) | Generate badge |
|
|
240
|
+
| Avatar(initials, size, variant) | Generate avatar |
|
|
241
|
+
| ThemeScript(theme, brand) | Generate theme initialization script |
|
|
242
|
+
| DataBind(key, bindType) | Generate data-bind attribute |
|
|
243
|
+
| DataComponent(name) | Generate data-component attribute |
|
|
244
|
+
| DataValidate(rules) | Generate data-validate attribute |
|
|
245
|
+
|
|
246
|
+
### Java Utilities
|
|
247
|
+
|
|
248
|
+
`utils/Kupola.java` provides component generation functions for Spring Boot/Quarkus:
|
|
249
|
+
|
|
250
|
+
| Function | Description |
|
|
251
|
+
|----------|-------------|
|
|
252
|
+
| button(label, variant, size) | Generate button HTML |
|
|
253
|
+
| input(label, name, placeholder, validate) | Generate input field |
|
|
254
|
+
| card(title, body, footer) | Generate card |
|
|
255
|
+
| statCard(title, value, trend, trendType) | Generate stat card |
|
|
256
|
+
| badge(text, variant) | Generate badge |
|
|
257
|
+
| avatar(initials, size, variant) | Generate avatar |
|
|
258
|
+
| themeScript(theme, brand) | Generate theme initialization script |
|
|
259
|
+
| dataBind(key, bindType) | Generate data-bind attribute |
|
|
260
|
+
| dataComponent(name) | Generate data-component attribute |
|
|
261
|
+
| dataValidate(rules) | Generate data-validate attribute |
|
|
262
|
+
|
|
263
|
+
### C# Utilities
|
|
264
|
+
|
|
265
|
+
`utils/Kupola.cs` provides component generation functions for ASP.NET Core:
|
|
266
|
+
|
|
267
|
+
| Function | Description |
|
|
268
|
+
|----------|-------------|
|
|
269
|
+
| Button(label, variant, size) | Generate button HTML |
|
|
270
|
+
| Input(label, name, placeholder, validate) | Generate input field |
|
|
271
|
+
| Card(title, body, footer) | Generate card |
|
|
272
|
+
| StatCard(title, value, trend, trendType) | Generate stat card |
|
|
273
|
+
| Badge(text, variant) | Generate badge |
|
|
274
|
+
| Avatar(initials, size, variant) | Generate avatar |
|
|
275
|
+
| ThemeScript(theme, brand) | Generate theme initialization script |
|
|
276
|
+
| DataBind(key, bindType) | Generate data-bind attribute |
|
|
277
|
+
| DataComponent(name) | Generate data-component attribute |
|
|
278
|
+
| DataValidate(rules) | Generate data-validate attribute |
|
|
279
|
+
|
|
280
|
+
### Node.js Utilities
|
|
281
|
+
|
|
282
|
+
`utils/kupola.js` provides component generation functions for Express/Koa:
|
|
283
|
+
|
|
284
|
+
| Function | Description |
|
|
285
|
+
|----------|-------------|
|
|
286
|
+
| button(label, variant, size) | Generate button HTML |
|
|
287
|
+
| input(label, name, placeholder, validate) | Generate input field |
|
|
288
|
+
| card(title, body, footer) | Generate card |
|
|
289
|
+
| statCard(title, value, trend, trendType) | Generate stat card |
|
|
290
|
+
| badge(text, variant) | Generate badge |
|
|
291
|
+
| avatar(initials, size, variant) | Generate avatar |
|
|
292
|
+
| themeScript(theme, brand) | Generate theme initialization script |
|
|
293
|
+
| dataBind(key, bindType) | Generate data-bind attribute |
|
|
294
|
+
| dataComponent(name) | Generate data-component attribute |
|
|
295
|
+
| dataValidate(rules) | Generate data-validate attribute |
|
|
296
|
+
|
|
297
|
+
### Ruby Utilities
|
|
298
|
+
|
|
299
|
+
`utils/kupola.rb` provides component generation functions for Ruby on Rails:
|
|
300
|
+
|
|
301
|
+
| Function | Description |
|
|
302
|
+
|----------|-------------|
|
|
303
|
+
| button(label, variant, size) | Generate button HTML |
|
|
304
|
+
| input(label, name, placeholder, validate) | Generate input field |
|
|
305
|
+
| card(title, body, footer) | Generate card |
|
|
306
|
+
| stat_card(title, value, trend, trend_type) | Generate stat card |
|
|
307
|
+
| badge(text, variant) | Generate badge |
|
|
308
|
+
| avatar(initials, size, variant) | Generate avatar |
|
|
309
|
+
| theme_script(theme, brand) | Generate theme initialization script |
|
|
310
|
+
| data_bind(key, bind_type) | Generate data-bind attribute |
|
|
311
|
+
| data_component(name) | Generate data-component attribute |
|
|
312
|
+
| data_validate(rules) | Generate data-validate attribute |
|
|
313
|
+
|
|
314
|
+
## Usage
|
|
315
|
+
|
|
316
|
+
### HTML Only
|
|
317
|
+
|
|
318
|
+
```html
|
|
319
|
+
<link rel="stylesheet" href="/kupola/css/kupola.css">
|
|
320
|
+
<script src="/kupola/js/kupola-core.js"></script>
|
|
321
|
+
|
|
322
|
+
<button class="ds-btn ds-btn--brand">Submit</button>
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Flask Integration
|
|
326
|
+
|
|
327
|
+
```python
|
|
328
|
+
from kupola.utils.kupola import kupola_button
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
```html
|
|
332
|
+
{% extends "base_dashboard.html" %}
|
|
333
|
+
|
|
334
|
+
{% block content %}
|
|
335
|
+
<h1>Dashboard</h1>
|
|
336
|
+
{% endblock %}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Gin Integration
|
|
340
|
+
|
|
341
|
+
```go
|
|
342
|
+
package main
|
|
343
|
+
|
|
344
|
+
import (
|
|
345
|
+
"github.com/gin-gonic/gin"
|
|
346
|
+
"your-project/kupola"
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
func main() {
|
|
350
|
+
r := gin.Default()
|
|
351
|
+
r.Static("/kupola", "./assets/kupola")
|
|
352
|
+
r.LoadHTMLGlob("templates/*")
|
|
353
|
+
|
|
354
|
+
r.GET("/", func(c *gin.Context) {
|
|
355
|
+
c.HTML(200, "dashboard.html", gin.H{
|
|
356
|
+
"Button": kupola.Button,
|
|
357
|
+
"Card": kupola.Card,
|
|
358
|
+
"StatCard": kupola.StatCard,
|
|
359
|
+
})
|
|
360
|
+
})
|
|
361
|
+
|
|
362
|
+
r.Run(":8080")
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
```html
|
|
367
|
+
<!-- templates/dashboard.html -->
|
|
368
|
+
<!DOCTYPE html>
|
|
369
|
+
<html>
|
|
370
|
+
<head>
|
|
371
|
+
<link rel="stylesheet" href="/kupola/css/kupola.css">
|
|
372
|
+
</head>
|
|
373
|
+
<body>
|
|
374
|
+
{{.Card "Welcome" "Hello Kupola!" ""}}
|
|
375
|
+
{{.Button "Click Me" "brand" "md"}}
|
|
376
|
+
<script src="/kupola/js/kupola-core.js"></script>
|
|
377
|
+
</body>
|
|
378
|
+
</html>
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Spring Boot Integration
|
|
382
|
+
|
|
383
|
+
```java
|
|
384
|
+
@Configuration
|
|
385
|
+
public class WebConfig implements WebMvcConfigurer {
|
|
386
|
+
@Override
|
|
387
|
+
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
|
388
|
+
registry.addResourceHandler("/kupola/**")
|
|
389
|
+
.addResourceLocations("classpath:/static/kupola/");
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
```html
|
|
395
|
+
<!-- templates/dashboard.html -->
|
|
396
|
+
<!DOCTYPE html>
|
|
397
|
+
<html xmlns:th="http://www.thymeleaf.org">
|
|
398
|
+
<head>
|
|
399
|
+
<link rel="stylesheet" th:href="@{/kupola/css/kupola.css}">
|
|
400
|
+
</head>
|
|
401
|
+
<body>
|
|
402
|
+
<div class="ds-card">
|
|
403
|
+
<div class="ds-card__body">
|
|
404
|
+
<button class="ds-btn ds-btn--brand">Submit</button>
|
|
405
|
+
</div>
|
|
406
|
+
</div>
|
|
407
|
+
<script th:src="@{/kupola/js/kupola-core.js}"></script>
|
|
408
|
+
</body>
|
|
409
|
+
</html>
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### ASP.NET Core Integration
|
|
413
|
+
|
|
414
|
+
```csharp
|
|
415
|
+
public void Configure(IApplicationBuilder app)
|
|
416
|
+
{
|
|
417
|
+
app.UseStaticFiles();
|
|
418
|
+
app.UseStaticFiles(new StaticFileOptions
|
|
419
|
+
{
|
|
420
|
+
FileProvider = new PhysicalFileProvider(
|
|
421
|
+
Path.Combine(Directory.GetCurrentDirectory(), "assets", "kupola")),
|
|
422
|
+
RequestPath = "/kupola"
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
```html
|
|
428
|
+
<!-- Views/Home/Index.cshtml -->
|
|
429
|
+
<!DOCTYPE html>
|
|
430
|
+
<html>
|
|
431
|
+
<head>
|
|
432
|
+
<link rel="stylesheet" href="/kupola/css/kupola.css">
|
|
433
|
+
</head>
|
|
434
|
+
<body>
|
|
435
|
+
<div class="ds-card">
|
|
436
|
+
<div class="ds-card__body">
|
|
437
|
+
<button class="ds-btn ds-btn--brand">Submit</button>
|
|
438
|
+
</div>
|
|
439
|
+
</div>
|
|
440
|
+
<script src="/kupola/js/kupola-core.js"></script>
|
|
441
|
+
</body>
|
|
442
|
+
</html>
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Express.js Integration
|
|
446
|
+
|
|
447
|
+
```javascript
|
|
448
|
+
// app.js
|
|
449
|
+
const express = require('express');
|
|
450
|
+
const { button, card } = require('./utils/kupola.js');
|
|
451
|
+
|
|
452
|
+
const app = express();
|
|
453
|
+
app.use('/kupola', express.static('public/kupola'));
|
|
454
|
+
|
|
455
|
+
app.get('/', (req, res) => {
|
|
456
|
+
const html = `<!DOCTYPE html>
|
|
457
|
+
<html>
|
|
458
|
+
<head>
|
|
459
|
+
<link rel="stylesheet" href="/kupola/css/kupola.css">
|
|
460
|
+
</head>
|
|
461
|
+
<body>
|
|
462
|
+
${card('Welcome', 'Hello Kupola!', '')}
|
|
463
|
+
${button('Click Me', 'brand', 'md')}
|
|
464
|
+
<script src="/kupola/js/kupola-core.js"></script>
|
|
465
|
+
</body>
|
|
466
|
+
</html>`;
|
|
467
|
+
res.send(html);
|
|
468
|
+
});
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Ruby on Rails Integration
|
|
472
|
+
|
|
473
|
+
```ruby
|
|
474
|
+
# app/helpers/kupola_helper.rb
|
|
475
|
+
module KupolaHelper
|
|
476
|
+
def button(label, variant = 'brand', size = 'md')
|
|
477
|
+
"<button class=\"ds-btn ds-btn--#{variant} ds-btn--#{size}\">#{label}</button>".html_safe
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
def card(title, body, footer = '')
|
|
481
|
+
footer_html = footer.empty? ? '' : "<div class=\"ds-card__footer\">#{footer}</div>"
|
|
482
|
+
"<div class=\"ds-card\"><div class=\"ds-card__header\"><h3 class=\"ds-card__title\">#{title}</h3></div><div class=\"ds-card__body\">#{body}</div>#{footer_html}</div>".html_safe
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
```erb
|
|
488
|
+
<!-- app/views/home/index.html.erb -->
|
|
489
|
+
<!DOCTYPE html>
|
|
490
|
+
<html>
|
|
491
|
+
<head>
|
|
492
|
+
<%= stylesheet_link_tag '/kupola/css/kupola.css' %>
|
|
493
|
+
</head>
|
|
494
|
+
<body>
|
|
495
|
+
<%= card 'Welcome', 'Hello Kupola!', '' %>
|
|
496
|
+
<%= button 'Click Me', 'brand', 'md' %>
|
|
497
|
+
<%= javascript_include_tag '/kupola/js/kupola-core.js' %>
|
|
498
|
+
</body>
|
|
499
|
+
</html>
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
## Responsive Design
|
|
503
|
+
|
|
504
|
+
Three breakpoints supported:
|
|
505
|
+
- **Phone**: < 768px - Sidebar moves to bottom, single column layout
|
|
506
|
+
- **Pad**: 768px - 1024px - 2-column grid, adjusted spacing
|
|
507
|
+
- **PC**: > 1024px - Full 4-column grid, standard layout
|
|
508
|
+
|
|
509
|
+
## Accessibility (a11y)
|
|
510
|
+
|
|
511
|
+
- ARIA labels for all interactive components
|
|
512
|
+
- Keyboard navigation support
|
|
513
|
+
- Focus-visible styles
|
|
514
|
+
- Skip link for screen readers
|
|
515
|
+
- High contrast mode support
|
|
516
|
+
- Reduced motion preference support
|
|
517
|
+
|
|
518
|
+
## Form Validation
|
|
519
|
+
|
|
520
|
+
Built-in validation via `data-validate` attribute:
|
|
521
|
+
- `required` - Field is required
|
|
522
|
+
- `email` - Valid email format
|
|
523
|
+
- `url` - Valid URL format
|
|
524
|
+
- `minLength:N` - Minimum length
|
|
525
|
+
- `maxLength:N` - Maximum length
|
|
526
|
+
- `pattern:regex` - Custom pattern
|
|
527
|
+
- `min:N` - Minimum value
|
|
528
|
+
- `max:N` - Maximum value
|
|
529
|
+
- `equalTo:id` - Match another field
|
|
530
|
+
|
|
531
|
+
## Data Binding
|
|
532
|
+
|
|
533
|
+
Two-way data binding via `data-bind` attribute:
|
|
534
|
+
- `data-bind="key:text"` - Bind text content
|
|
535
|
+
- `data-bind="key:value"` - Bind input value
|
|
536
|
+
- `data-bind="key:checked"` - Bind checkbox state
|
|
537
|
+
- `data-bind="key:disabled"` - Bind disabled state
|
|
538
|
+
- `data-bind="key:class:className"` - Conditional class
|
|
539
|
+
|
|
540
|
+
## Event Bus
|
|
541
|
+
|
|
542
|
+
Publish/subscribe event system:
|
|
543
|
+
```javascript
|
|
544
|
+
kupolaEvents.on('eventName', callback);
|
|
545
|
+
kupolaEvents.emit('eventName', data);
|
|
546
|
+
kupolaEvents.off('eventName', callback);
|
|
547
|
+
kupolaEvents.once('eventName', callback);
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
## Authoring Rules
|
|
551
|
+
|
|
552
|
+
1. **Never hardcode hex values.** Always reference `var(--token)`.
|
|
553
|
+
2. **Use utility classes.** Prefer `.flex`, `.grid`, `.gap-*` over custom CSS.
|
|
554
|
+
3. **Components are fluid.** All `.ds-*` components are fluid (`min-width: 0` + `1fr`).
|
|
555
|
+
4. **Icons use currentColor.** SVG icons inherit text color via `stroke="currentColor"`.
|
|
556
|
+
5. **Add ARIA labels.** All interactive components should have proper ARIA attributes.
|
|
557
|
+
|
|
558
|
+
## Workflow Commands
|
|
559
|
+
|
|
560
|
+
- **Add component**: `add-component` - Add a new component template
|
|
561
|
+
- **Add brand color**: `add-brand-color` - Add a new brand color theme
|
|
562
|
+
- **Generate template**: `generate-template` - Generate a new Flask template
|
|
563
|
+
- **Update documentation**: `update-docs` - Update API documentation
|
|
564
|
+
- **Update examples**: `update-examples` - Update example projects
|
|
565
|
+
|
|
566
|
+
## Version
|
|
567
|
+
|
|
568
|
+
Current version: `1.2.0` (see `version.json`)
|
|
569
|
+
|
|
570
|
+
## License
|
|
571
|
+
|
|
572
|
+
MIT
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/* Accessibility (a11y) */
|
|
2
|
+
|
|
3
|
+
/* Focus styles */
|
|
4
|
+
*:focus-visible {
|
|
5
|
+
outline: 2px solid var(--bg-brand);
|
|
6
|
+
outline-offset: 2px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
*:focus:not(:focus-visible) {
|
|
10
|
+
outline: none;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* Skip link */
|
|
14
|
+
.skip-link {
|
|
15
|
+
position: absolute;
|
|
16
|
+
top: -40px;
|
|
17
|
+
left: 0;
|
|
18
|
+
padding: 8px 12px;
|
|
19
|
+
background-color: var(--bg-brand);
|
|
20
|
+
color: var(--text-onbrand);
|
|
21
|
+
font-size: 13px;
|
|
22
|
+
font-weight: 500;
|
|
23
|
+
text-decoration: none;
|
|
24
|
+
z-index: 1000;
|
|
25
|
+
transition: top 0.2s ease;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.skip-link:focus {
|
|
29
|
+
top: 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* Screen reader only */
|
|
33
|
+
.sr-only {
|
|
34
|
+
position: absolute;
|
|
35
|
+
width: 1px;
|
|
36
|
+
height: 1px;
|
|
37
|
+
padding: 0;
|
|
38
|
+
margin: -1px;
|
|
39
|
+
overflow: hidden;
|
|
40
|
+
clip: rect(0, 0, 0, 0);
|
|
41
|
+
white-space: nowrap;
|
|
42
|
+
border: 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* High contrast mode */
|
|
46
|
+
@media (prefers-contrast: high) {
|
|
47
|
+
:root {
|
|
48
|
+
--border-neutral-l1: #000000;
|
|
49
|
+
--border-neutral-l2: #000000;
|
|
50
|
+
--border-neutral-l3: #000000;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.ds-btn {
|
|
54
|
+
border-width: 2px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.ds-input {
|
|
58
|
+
border-width: 2px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.ds-card {
|
|
62
|
+
border-width: 2px;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Reduced motion */
|
|
67
|
+
@media (prefers-reduced-motion: reduce) {
|
|
68
|
+
*,
|
|
69
|
+
*::before,
|
|
70
|
+
*::after {
|
|
71
|
+
animation-duration: 0.01ms !important;
|
|
72
|
+
animation-iteration-count: 1 !important;
|
|
73
|
+
transition-duration: 0.01ms !important;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Keyboard navigation */
|
|
78
|
+
.ds-btn:not(:disabled):focus-visible,
|
|
79
|
+
.ds-input:focus-visible,
|
|
80
|
+
.ds-toggle input:focus-visible + .ds-toggle__track {
|
|
81
|
+
outline: 2px solid var(--bg-brand);
|
|
82
|
+
outline-offset: 2px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Active states for keyboard users */
|
|
86
|
+
.ds-btn:not(:disabled):active,
|
|
87
|
+
.ds-btn:not(:disabled):focus:active {
|
|
88
|
+
transform: translateY(1px);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Visible focus for better keyboard navigation */
|
|
92
|
+
.ds-dashboard__sidebar-item:focus-visible,
|
|
93
|
+
.ds-activityrail__item:focus-visible,
|
|
94
|
+
.ds-statusbar__item:focus-visible {
|
|
95
|
+
outline: 2px solid var(--bg-brand);
|
|
96
|
+
outline-offset: 2px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Color contrast */
|
|
100
|
+
.ds-statcard__delta.is-up {
|
|
101
|
+
color: var(--status-success-default);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.ds-statcard__delta.is-down {
|
|
105
|
+
color: var(--status-error-default);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Selection color */
|
|
109
|
+
::selection {
|
|
110
|
+
background-color: var(--bg-brand-popup);
|
|
111
|
+
color: var(--text-brand);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* Clearfix */
|
|
115
|
+
.ds-clearfix::after {
|
|
116
|
+
content: '';
|
|
117
|
+
display: table;
|
|
118
|
+
clear: both;
|
|
119
|
+
}
|