quantum-framework 0.9.0__py3-none-any.whl

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.
Files changed (262) hide show
  1. quantum/__init__.py +1 -0
  2. quantum/cli/__init__.py +2 -0
  3. quantum/cli/commands/__init__.py +15 -0
  4. quantum/cli/commands/build.py +417 -0
  5. quantum/cli/commands/dev.py +185 -0
  6. quantum/cli/commands/docs.py +329 -0
  7. quantum/cli/commands/lint.py +523 -0
  8. quantum/cli/commands/migrate.py +527 -0
  9. quantum/cli/commands/new.py +622 -0
  10. quantum/cli/commands/serve.py +190 -0
  11. quantum/cli/commands/test.py +193 -0
  12. quantum/cli/deploy.py +810 -0
  13. quantum/cli/hot_reload.py +951 -0
  14. quantum/cli/jobs.py +356 -0
  15. quantum/cli/mq.py +582 -0
  16. quantum/cli/pkg.py +390 -0
  17. quantum/cli/runner.py +547 -0
  18. quantum/cli/server_process.py +159 -0
  19. quantum/cli/utils.py +334 -0
  20. quantum/compiler/__init__.py +30 -0
  21. quantum/compiler/base_generator.py +367 -0
  22. quantum/compiler/cli.py +295 -0
  23. quantum/compiler/expression_transformer.py +444 -0
  24. quantum/compiler/javascript/__init__.py +10 -0
  25. quantum/compiler/javascript/generator.py +659 -0
  26. quantum/compiler/optimizer.py +270 -0
  27. quantum/compiler/python/__init__.py +10 -0
  28. quantum/compiler/python/generator.py +883 -0
  29. quantum/compiler/python/runtime.py +863 -0
  30. quantum/compiler/transpiler.py +330 -0
  31. quantum/core/__init__.py +3 -0
  32. quantum/core/ast_nodes.py +2611 -0
  33. quantum/core/expression_diagnostics.py +87 -0
  34. quantum/core/expression_stdlib.py +148 -0
  35. quantum/core/expressions.py +591 -0
  36. quantum/core/features/agents/src/__init__.py +30 -0
  37. quantum/core/features/agents/src/ast_node.py +540 -0
  38. quantum/core/features/conditionals/src/__init__.py +8 -0
  39. quantum/core/features/conditionals/src/ast_node.py +68 -0
  40. quantum/core/features/data_fetching/src/__init__.py +21 -0
  41. quantum/core/features/data_fetching/src/ast_node.py +312 -0
  42. quantum/core/features/data_fetching/src/desktop_adapter.py +351 -0
  43. quantum/core/features/data_fetching/src/html_adapter.py +474 -0
  44. quantum/core/features/data_fetching/src/parser.py +225 -0
  45. quantum/core/features/data_import/src/__init__.py +0 -0
  46. quantum/core/features/data_import/src/ast_node.py +291 -0
  47. quantum/core/features/data_import/src/runtime.py +538 -0
  48. quantum/core/features/dump/src/__init__.py +12 -0
  49. quantum/core/features/dump/src/ast_node.py +106 -0
  50. quantum/core/features/dump/src/parser.py +61 -0
  51. quantum/core/features/dump/src/runtime.py +246 -0
  52. quantum/core/features/functions/src/__init__.py +8 -0
  53. quantum/core/features/functions/src/ast_node.py +149 -0
  54. quantum/core/features/game_engine_2d/src/__init__.py +19 -0
  55. quantum/core/features/game_engine_2d/src/ast_nodes.py +1719 -0
  56. quantum/core/features/game_engine_2d/src/parser.py +983 -0
  57. quantum/core/features/invocation/src/__init__.py +0 -0
  58. quantum/core/features/invocation/src/ast_node.py +146 -0
  59. quantum/core/features/invocation/src/runtime.py +327 -0
  60. quantum/core/features/knowledge_base/src/__init__.py +6 -0
  61. quantum/core/features/knowledge_base/src/ast_node.py +113 -0
  62. quantum/core/features/knowledge_base/src/parser.py +82 -0
  63. quantum/core/features/logging/src/__init__.py +12 -0
  64. quantum/core/features/logging/src/ast_node.py +111 -0
  65. quantum/core/features/logging/src/parser.py +50 -0
  66. quantum/core/features/logging/src/runtime.py +190 -0
  67. quantum/core/features/loops/src/__init__.py +8 -0
  68. quantum/core/features/loops/src/ast_node.py +60 -0
  69. quantum/core/features/query/src/__init__.py +0 -0
  70. quantum/core/features/query/src/database_service.py +322 -0
  71. quantum/core/features/query/src/query_validators.py +20 -0
  72. quantum/core/features/state_management/src/__init__.py +11 -0
  73. quantum/core/features/state_management/src/ast_node.py +228 -0
  74. quantum/core/features/terminal_engine/src/__init__.py +21 -0
  75. quantum/core/features/terminal_engine/src/ast_nodes.py +560 -0
  76. quantum/core/features/terminal_engine/src/parser.py +361 -0
  77. quantum/core/features/testing_engine/src/__init__.py +41 -0
  78. quantum/core/features/testing_engine/src/ast_nodes.py +1212 -0
  79. quantum/core/features/testing_engine/src/parser.py +604 -0
  80. quantum/core/features/theming/src/__init__.py +48 -0
  81. quantum/core/features/theming/src/ast_node.py +137 -0
  82. quantum/core/features/theming/src/presets.py +405 -0
  83. quantum/core/features/ui_engine/src/__init__.py +20 -0
  84. quantum/core/features/ui_engine/src/ast_nodes.py +1854 -0
  85. quantum/core/features/ui_engine/src/parser.py +1106 -0
  86. quantum/core/features/websocket/src/__init__.py +24 -0
  87. quantum/core/features/websocket/src/ast_node.py +247 -0
  88. quantum/core/html_compat.py +299 -0
  89. quantum/core/parser.py +1235 -0
  90. quantum/core/parser_registry.py +213 -0
  91. quantum/core/parsers/__init__.py +76 -0
  92. quantum/core/parsers/ai/__init__.py +12 -0
  93. quantum/core/parsers/ai/agent_parser.py +106 -0
  94. quantum/core/parsers/ai/knowledge_parser.py +86 -0
  95. quantum/core/parsers/ai/llm_parser.py +78 -0
  96. quantum/core/parsers/ai/team_parser.py +88 -0
  97. quantum/core/parsers/base.py +322 -0
  98. quantum/core/parsers/composition/__init__.py +10 -0
  99. quantum/core/parsers/composition/import_parser.py +50 -0
  100. quantum/core/parsers/composition/slot_parser.py +48 -0
  101. quantum/core/parsers/control_flow/__init__.py +11 -0
  102. quantum/core/parsers/control_flow/if_parser.py +68 -0
  103. quantum/core/parsers/control_flow/loop_parser.py +105 -0
  104. quantum/core/parsers/control_flow/set_parser.py +89 -0
  105. quantum/core/parsers/data/__init__.py +12 -0
  106. quantum/core/parsers/data/data_parser.py +217 -0
  107. quantum/core/parsers/data/invoke_parser.py +116 -0
  108. quantum/core/parsers/data/query_parser.py +188 -0
  109. quantum/core/parsers/data/transaction_parser.py +77 -0
  110. quantum/core/parsers/events/__init__.py +9 -0
  111. quantum/core/parsers/events/dispatch_event_parser.py +44 -0
  112. quantum/core/parsers/forms/__init__.py +11 -0
  113. quantum/core/parsers/forms/action_parser.py +54 -0
  114. quantum/core/parsers/forms/flash_parser.py +34 -0
  115. quantum/core/parsers/forms/redirect_parser.py +33 -0
  116. quantum/core/parsers/functions/__init__.py +11 -0
  117. quantum/core/parsers/functions/function_parser.py +137 -0
  118. quantum/core/parsers/functions/param_parser.py +66 -0
  119. quantum/core/parsers/functions/return_parser.py +31 -0
  120. quantum/core/parsers/html/__init__.py +10 -0
  121. quantum/core/parsers/html/component_call_parser.py +130 -0
  122. quantum/core/parsers/html/html_parser.py +115 -0
  123. quantum/core/parsers/jobs/__init__.py +11 -0
  124. quantum/core/parsers/jobs/job_parser.py +71 -0
  125. quantum/core/parsers/jobs/schedule_parser.py +62 -0
  126. quantum/core/parsers/jobs/thread_parser.py +57 -0
  127. quantum/core/parsers/messaging/__init__.py +17 -0
  128. quantum/core/parsers/messaging/message_ack_parser.py +30 -0
  129. quantum/core/parsers/messaging/message_nack_parser.py +30 -0
  130. quantum/core/parsers/messaging/message_parser.py +114 -0
  131. quantum/core/parsers/messaging/queue_parser.py +61 -0
  132. quantum/core/parsers/messaging/websocket_parser.py +121 -0
  133. quantum/core/parsers/persistence/__init__.py +9 -0
  134. quantum/core/parsers/persistence/persist_parser.py +64 -0
  135. quantum/core/parsers/routing/__init__.py +9 -0
  136. quantum/core/parsers/routing/route_parser.py +41 -0
  137. quantum/core/parsers/scripting/__init__.py +12 -0
  138. quantum/core/parsers/scripting/pyclass_parser.py +62 -0
  139. quantum/core/parsers/scripting/pydecorator_parser.py +68 -0
  140. quantum/core/parsers/scripting/pyimport_parser.py +52 -0
  141. quantum/core/parsers/scripting/python_parser.py +49 -0
  142. quantum/core/parsers/services/__init__.py +12 -0
  143. quantum/core/parsers/services/dump_parser.py +52 -0
  144. quantum/core/parsers/services/file_parser.py +48 -0
  145. quantum/core/parsers/services/log_parser.py +46 -0
  146. quantum/core/parsers/services/mail_parser.py +65 -0
  147. quantum/core/tiers.py +82 -0
  148. quantum/packages/__init__.py +28 -0
  149. quantum/packages/manager.py +413 -0
  150. quantum/packages/manifest.py +351 -0
  151. quantum/packages/registry.py +399 -0
  152. quantum/packages/resolver.py +336 -0
  153. quantum/plugins/__init__.py +33 -0
  154. quantum/plugins/hooks.py +329 -0
  155. quantum/plugins/loader.py +479 -0
  156. quantum/plugins/manifest.py +336 -0
  157. quantum/plugins/registry.py +371 -0
  158. quantum/runtime/__init__.py +28 -0
  159. quantum/runtime/action_handler.py +443 -0
  160. quantum/runtime/adapters/__init__.py +88 -0
  161. quantum/runtime/adapters/memory_adapter.py +690 -0
  162. quantum/runtime/adapters/rabbitmq_adapter.py +715 -0
  163. quantum/runtime/adapters/redis_adapter.py +582 -0
  164. quantum/runtime/adapters/sqlite_adapter.py +414 -0
  165. quantum/runtime/agent_service.py +1133 -0
  166. quantum/runtime/api_server.py +86 -0
  167. quantum/runtime/ast_cache.py +506 -0
  168. quantum/runtime/auth_service.py +267 -0
  169. quantum/runtime/component.py +990 -0
  170. quantum/runtime/component_composer.py +319 -0
  171. quantum/runtime/component_resolver.py +174 -0
  172. quantum/runtime/database_service.py +598 -0
  173. quantum/runtime/email_service.py +162 -0
  174. quantum/runtime/error_handler.py +295 -0
  175. quantum/runtime/execution_context.py +286 -0
  176. quantum/runtime/executor_registry.py +171 -0
  177. quantum/runtime/executors/__init__.py +71 -0
  178. quantum/runtime/executors/ai/__init__.py +12 -0
  179. quantum/runtime/executors/ai/agent_executor.py +217 -0
  180. quantum/runtime/executors/ai/knowledge_executor.py +114 -0
  181. quantum/runtime/executors/ai/llm_executor.py +153 -0
  182. quantum/runtime/executors/ai/team_executor.py +171 -0
  183. quantum/runtime/executors/base.py +262 -0
  184. quantum/runtime/executors/control_flow/__init__.py +11 -0
  185. quantum/runtime/executors/control_flow/if_executor.py +93 -0
  186. quantum/runtime/executors/control_flow/loop_executor.py +307 -0
  187. quantum/runtime/executors/control_flow/set_executor.py +412 -0
  188. quantum/runtime/executors/data/__init__.py +12 -0
  189. quantum/runtime/executors/data/data_executor.py +145 -0
  190. quantum/runtime/executors/data/invoke_executor.py +176 -0
  191. quantum/runtime/executors/data/query_executor.py +256 -0
  192. quantum/runtime/executors/data/transaction_executor.py +91 -0
  193. quantum/runtime/executors/jobs/__init__.py +11 -0
  194. quantum/runtime/executors/jobs/job_executor.py +190 -0
  195. quantum/runtime/executors/jobs/schedule_executor.py +132 -0
  196. quantum/runtime/executors/jobs/thread_executor.py +127 -0
  197. quantum/runtime/executors/messaging/__init__.py +17 -0
  198. quantum/runtime/executors/messaging/message_ack_executor.py +51 -0
  199. quantum/runtime/executors/messaging/message_executor.py +174 -0
  200. quantum/runtime/executors/messaging/queue_executor.py +103 -0
  201. quantum/runtime/executors/messaging/websocket_executor.py +197 -0
  202. quantum/runtime/executors/scripting/__init__.py +11 -0
  203. quantum/runtime/executors/scripting/pyclass_executor.py +90 -0
  204. quantum/runtime/executors/scripting/pyimport_executor.py +81 -0
  205. quantum/runtime/executors/scripting/python_executor.py +249 -0
  206. quantum/runtime/executors/services/__init__.py +12 -0
  207. quantum/runtime/executors/services/dump_executor.py +72 -0
  208. quantum/runtime/executors/services/file_executor.py +89 -0
  209. quantum/runtime/executors/services/log_executor.py +77 -0
  210. quantum/runtime/executors/services/mail_executor.py +81 -0
  211. quantum/runtime/expression_cache.py +498 -0
  212. quantum/runtime/file_upload_service.py +326 -0
  213. quantum/runtime/function_registry.py +118 -0
  214. quantum/runtime/game_builder.py +166 -0
  215. quantum/runtime/game_code_generator.py +2371 -0
  216. quantum/runtime/game_templates.py +2006 -0
  217. quantum/runtime/godot_code_generator.py +4681 -0
  218. quantum/runtime/godot_templates.py +1449 -0
  219. quantum/runtime/job_executor.py +1599 -0
  220. quantum/runtime/knowledge_service.py +500 -0
  221. quantum/runtime/llm_cache.py +100 -0
  222. quantum/runtime/llm_providers.py +704 -0
  223. quantum/runtime/llm_service.py +287 -0
  224. quantum/runtime/logging_setup.py +140 -0
  225. quantum/runtime/message_broker.py +364 -0
  226. quantum/runtime/message_queue_service.py +571 -0
  227. quantum/runtime/param_validation.py +184 -0
  228. quantum/runtime/pypy_compat.py +315 -0
  229. quantum/runtime/python_bridge.py +698 -0
  230. quantum/runtime/query_validators.py +304 -0
  231. quantum/runtime/renderer.py +733 -0
  232. quantum/runtime/service_container.py +444 -0
  233. quantum/runtime/terminal_builder.py +76 -0
  234. quantum/runtime/terminal_code_generator.py +607 -0
  235. quantum/runtime/terminal_templates.py +243 -0
  236. quantum/runtime/testing_builder.py +77 -0
  237. quantum/runtime/testing_code_generator.py +833 -0
  238. quantum/runtime/testing_templates.py +85 -0
  239. quantum/runtime/ui_builder.py +188 -0
  240. quantum/runtime/ui_desktop_adapter.py +1730 -0
  241. quantum/runtime/ui_desktop_templates.py +307 -0
  242. quantum/runtime/ui_html_adapter.py +2691 -0
  243. quantum/runtime/ui_html_templates.py +2297 -0
  244. quantum/runtime/ui_mobile_adapter.py +1832 -0
  245. quantum/runtime/ui_mobile_templates.py +1003 -0
  246. quantum/runtime/ui_textual_adapter.py +1866 -0
  247. quantum/runtime/ui_textual_templates.py +45 -0
  248. quantum/runtime/ui_tokens.py +465 -0
  249. quantum/runtime/ui_validator.py +365 -0
  250. quantum/runtime/validators.py +256 -0
  251. quantum/runtime/web_server.py +1766 -0
  252. quantum/runtime/websocket_adapter.py +501 -0
  253. quantum/runtime/websocket_service.py +585 -0
  254. quantum/runtime/websocket_transport.py +289 -0
  255. quantum/runtime/wsgi.py +101 -0
  256. quantum/utils/__init__.py +1 -0
  257. quantum_framework-0.9.0.dist-info/METADATA +244 -0
  258. quantum_framework-0.9.0.dist-info/RECORD +262 -0
  259. quantum_framework-0.9.0.dist-info/WHEEL +5 -0
  260. quantum_framework-0.9.0.dist-info/entry_points.txt +2 -0
  261. quantum_framework-0.9.0.dist-info/licenses/LICENSE +21 -0
  262. quantum_framework-0.9.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,137 @@
1
+ """
2
+ AST Nodes for Theming System
3
+
4
+ UIThemeNode: Represents <ui:theme> tag for theme configuration
5
+ UIColorNode: Represents <ui:color> tag for custom color definitions
6
+ """
7
+
8
+ from typing import Dict, Any, List, Optional
9
+ import sys
10
+ from pathlib import Path
11
+ from quantum.core.ast_nodes import QuantumNode
12
+
13
+
14
+ class UIColorNode(QuantumNode):
15
+ """
16
+ Represents <ui:color> - Custom color definition within a theme.
17
+
18
+ Attributes:
19
+ name: Color token name (e.g., 'primary', 'background', 'text')
20
+ value: CSS color value (e.g., '#ff6b6b', 'rgb(255, 107, 107)')
21
+
22
+ Example:
23
+ <ui:color name="primary" value="#3b82f6" />
24
+ <ui:color name="danger" value="rgb(239, 68, 68)" />
25
+ """
26
+
27
+ def __init__(self):
28
+ self.name: str = ""
29
+ self.value: str = ""
30
+
31
+ def to_dict(self) -> Dict[str, Any]:
32
+ return {
33
+ "type": "ui_color",
34
+ "name": self.name,
35
+ "value": self.value,
36
+ }
37
+
38
+ def validate(self) -> List[str]:
39
+ errors = []
40
+ if not self.name:
41
+ errors.append("Color name is required")
42
+ if not self.value:
43
+ errors.append(f"Color value is required for '{self.name}'")
44
+ return errors
45
+
46
+
47
+ class UIThemeNode(QuantumNode):
48
+ """
49
+ Represents <ui:theme> - Theme configuration for the UI.
50
+
51
+ Supports:
52
+ - Preset themes: 'light', 'dark'
53
+ - Custom themes with color definitions
54
+ - Runtime theme switching
55
+
56
+ Attributes:
57
+ name: Theme name (for custom themes)
58
+ preset: Preset theme to extend ('light', 'dark')
59
+ colors: List of custom color overrides
60
+ auto_switch: Enable automatic dark/light switching based on system preference
61
+
62
+ Examples:
63
+ <!-- Use dark preset -->
64
+ <ui:theme preset="dark" />
65
+
66
+ <!-- Custom theme extending light -->
67
+ <ui:theme name="ocean" preset="light">
68
+ <ui:color name="primary" value="#0ea5e9" />
69
+ <ui:color name="secondary" value="#06b6d4" />
70
+ </ui:theme>
71
+
72
+ <!-- Auto-switch based on system preference -->
73
+ <ui:theme preset="light" auto-switch="true" />
74
+ """
75
+
76
+ # Valid preset names
77
+ VALID_PRESETS = {'light', 'dark', 'high-contrast', 'sepia', 'nord', 'dracula'}
78
+
79
+ # Valid color token names (matching design tokens)
80
+ VALID_COLOR_NAMES = {
81
+ 'primary', 'secondary', 'success', 'danger', 'warning', 'info',
82
+ 'light', 'dark', 'background', 'text', 'border', 'muted',
83
+ # Extended color tokens
84
+ 'surface', 'overlay', 'accent', 'focus',
85
+ # Font size tokens (for completeness)
86
+ 'font-xs', 'font-sm', 'font-md', 'font-lg', 'font-xl', 'font-2xl',
87
+ }
88
+
89
+ def __init__(self):
90
+ self.name: Optional[str] = None
91
+ self.preset: str = "light" # Default to light theme
92
+ self.colors: List[UIColorNode] = []
93
+ self.auto_switch: bool = False
94
+
95
+ def add_color(self, color: UIColorNode):
96
+ """Add a custom color override."""
97
+ self.colors.append(color)
98
+
99
+ def get_color(self, name: str) -> Optional[str]:
100
+ """Get color value by name, or None if not defined."""
101
+ for color in self.colors:
102
+ if color.name == name:
103
+ return color.value
104
+ return None
105
+
106
+ def get_color_overrides(self) -> Dict[str, str]:
107
+ """Return all custom colors as a dict."""
108
+ return {c.name: c.value for c in self.colors}
109
+
110
+ def to_dict(self) -> Dict[str, Any]:
111
+ return {
112
+ "type": "ui_theme",
113
+ "name": self.name,
114
+ "preset": self.preset,
115
+ "auto_switch": self.auto_switch,
116
+ "colors": [c.to_dict() for c in self.colors],
117
+ }
118
+
119
+ def validate(self) -> List[str]:
120
+ errors = []
121
+
122
+ # Validate preset
123
+ if self.preset and self.preset not in self.VALID_PRESETS:
124
+ errors.append(
125
+ f"Invalid theme preset '{self.preset}'. "
126
+ f"Valid presets: {', '.join(sorted(self.VALID_PRESETS))}"
127
+ )
128
+
129
+ # Validate colors
130
+ for color in self.colors:
131
+ errors.extend(color.validate())
132
+ # Warn about unknown color names (soft validation)
133
+ if color.name and color.name not in self.VALID_COLOR_NAMES:
134
+ # This is a warning, not an error - custom colors are allowed
135
+ pass
136
+
137
+ return errors
@@ -0,0 +1,405 @@
1
+ """
2
+ Theme Presets for Quantum UI Engine
3
+
4
+ Provides predefined color schemes for light and dark modes.
5
+ Colors are defined as CSS custom properties (variables) that integrate
6
+ with the existing design tokens system.
7
+ """
8
+
9
+ from typing import Dict, Optional
10
+
11
+
12
+ # ==========================================================================
13
+ # Light Theme (Default)
14
+ # ==========================================================================
15
+
16
+ THEME_LIGHT: Dict[str, str] = {
17
+ # Primary colors
18
+ 'primary': '#3b82f6', # Blue 500
19
+ 'secondary': '#64748b', # Slate 500
20
+ 'success': '#22c55e', # Green 500
21
+ 'danger': '#ef4444', # Red 500
22
+ 'warning': '#f59e0b', # Amber 500
23
+ 'info': '#06b6d4', # Cyan 500
24
+
25
+ # Neutral colors
26
+ 'light': '#f8fafc', # Slate 50
27
+ 'dark': '#1e293b', # Slate 800
28
+ 'background': '#ffffff', # White
29
+ 'text': '#1e293b', # Slate 800
30
+ 'border': '#e2e8f0', # Slate 200
31
+ 'muted': '#94a3b8', # Slate 400
32
+
33
+ # Extended colors
34
+ 'surface': '#f8fafc', # Slate 50
35
+ 'overlay': 'rgba(0,0,0,0.5)',
36
+ 'accent': '#8b5cf6', # Violet 500
37
+ 'focus': 'rgba(59,130,246,0.5)', # Primary with alpha
38
+
39
+ # UI elements
40
+ 'radius': '6px',
41
+ 'shadow': '0 1px 3px rgba(0,0,0,0.1)',
42
+
43
+ # Font sizes (rem units)
44
+ 'font-xs': '0.75rem',
45
+ 'font-sm': '0.875rem',
46
+ 'font-md': '1rem',
47
+ 'font-lg': '1.25rem',
48
+ 'font-xl': '1.5rem',
49
+ 'font-2xl': '2rem',
50
+ }
51
+
52
+
53
+ # ==========================================================================
54
+ # Dark Theme
55
+ # ==========================================================================
56
+
57
+ THEME_DARK: Dict[str, str] = {
58
+ # Primary colors (slightly adjusted for dark bg)
59
+ 'primary': '#60a5fa', # Blue 400
60
+ 'secondary': '#94a3b8', # Slate 400
61
+ 'success': '#4ade80', # Green 400
62
+ 'danger': '#f87171', # Red 400
63
+ 'warning': '#fbbf24', # Amber 400
64
+ 'info': '#22d3ee', # Cyan 400
65
+
66
+ # Neutral colors (inverted for dark mode)
67
+ 'light': '#334155', # Slate 700
68
+ 'dark': '#f8fafc', # Slate 50
69
+ 'background': '#0f172a', # Slate 900
70
+ 'text': '#f1f5f9', # Slate 100
71
+ 'border': '#334155', # Slate 700
72
+ 'muted': '#64748b', # Slate 500
73
+
74
+ # Extended colors
75
+ 'surface': '#1e293b', # Slate 800
76
+ 'overlay': 'rgba(0,0,0,0.7)',
77
+ 'accent': '#a78bfa', # Violet 400
78
+ 'focus': 'rgba(96,165,250,0.5)', # Primary with alpha
79
+
80
+ # UI elements (same as light, could be customized)
81
+ 'radius': '6px',
82
+ 'shadow': '0 1px 3px rgba(0,0,0,0.3)',
83
+
84
+ # Font sizes (same as light)
85
+ 'font-xs': '0.75rem',
86
+ 'font-sm': '0.875rem',
87
+ 'font-md': '1rem',
88
+ 'font-lg': '1.25rem',
89
+ 'font-xl': '1.5rem',
90
+ 'font-2xl': '2rem',
91
+ }
92
+
93
+
94
+ # ==========================================================================
95
+ # High Contrast Theme (Accessibility)
96
+ # ==========================================================================
97
+
98
+ THEME_HIGH_CONTRAST: Dict[str, str] = {
99
+ # Primary colors (high saturation)
100
+ 'primary': '#0066ff', # Bright blue
101
+ 'secondary': '#595959', # Dark gray
102
+ 'success': '#00aa00', # Bright green
103
+ 'danger': '#dd0000', # Bright red
104
+ 'warning': '#cc6600', # Bright orange
105
+ 'info': '#0088cc', # Bright cyan
106
+
107
+ # Neutral colors (maximum contrast)
108
+ 'light': '#ffffff', # Pure white
109
+ 'dark': '#000000', # Pure black
110
+ 'background': '#ffffff', # White
111
+ 'text': '#000000', # Black
112
+ 'border': '#000000', # Black border
113
+ 'muted': '#595959', # Dark gray
114
+
115
+ # Extended colors
116
+ 'surface': '#f0f0f0', # Light gray
117
+ 'overlay': 'rgba(0,0,0,0.7)',
118
+ 'accent': '#6600cc', # Purple
119
+ 'focus': 'rgba(0,102,255,0.5)',
120
+
121
+ # UI elements (thicker borders, no shadows)
122
+ 'radius': '0px', # Sharp corners for clarity
123
+ 'shadow': 'none',
124
+
125
+ # Font sizes (slightly larger)
126
+ 'font-xs': '0.875rem',
127
+ 'font-sm': '1rem',
128
+ 'font-md': '1.125rem',
129
+ 'font-lg': '1.375rem',
130
+ 'font-xl': '1.625rem',
131
+ 'font-2xl': '2.25rem',
132
+ }
133
+
134
+
135
+ # ==========================================================================
136
+ # Sepia Theme (Reading/Paper)
137
+ # ==========================================================================
138
+
139
+ THEME_SEPIA: Dict[str, str] = {
140
+ # Primary colors (warm tones)
141
+ 'primary': '#8b4513', # Saddle brown
142
+ 'secondary': '#6b5344', # Warm gray
143
+ 'success': '#5d8a4a', # Olive green
144
+ 'danger': '#c24b3f', # Brick red
145
+ 'warning': '#d4a03b', # Golden
146
+ 'info': '#4a7a8a', # Teal
147
+
148
+ # Neutral colors (sepia tones)
149
+ 'light': '#f4ecd8', # Cream
150
+ 'dark': '#3c2f2f', # Dark brown
151
+ 'background': '#faf4e8', # Warm white
152
+ 'text': '#3c2f2f', # Dark brown
153
+ 'border': '#d4c5a9', # Tan
154
+ 'muted': '#8b7355', # Medium brown
155
+
156
+ # Extended colors
157
+ 'surface': '#f0e6d2', # Light cream
158
+ 'overlay': 'rgba(60,47,47,0.5)',
159
+ 'accent': '#9a5b4a', # Terra cotta
160
+ 'focus': 'rgba(139,69,19,0.3)',
161
+
162
+ # UI elements
163
+ 'radius': '4px',
164
+ 'shadow': '0 1px 3px rgba(60,47,47,0.1)',
165
+
166
+ # Font sizes
167
+ 'font-xs': '0.75rem',
168
+ 'font-sm': '0.875rem',
169
+ 'font-md': '1rem',
170
+ 'font-lg': '1.25rem',
171
+ 'font-xl': '1.5rem',
172
+ 'font-2xl': '2rem',
173
+ }
174
+
175
+
176
+ # ==========================================================================
177
+ # Nord Theme (Popular dark theme)
178
+ # ==========================================================================
179
+
180
+ THEME_NORD: Dict[str, str] = {
181
+ # Nord color palette
182
+ 'primary': '#88c0d0', # Nord8 - Frost
183
+ 'secondary': '#81a1c1', # Nord9 - Frost
184
+ 'success': '#a3be8c', # Nord14 - Aurora
185
+ 'danger': '#bf616a', # Nord11 - Aurora
186
+ 'warning': '#ebcb8b', # Nord13 - Aurora
187
+ 'info': '#5e81ac', # Nord10 - Frost
188
+
189
+ # Neutral colors (Nord Polar Night)
190
+ 'light': '#4c566a', # Nord3
191
+ 'dark': '#eceff4', # Nord6 - Snow
192
+ 'background': '#2e3440', # Nord0
193
+ 'text': '#eceff4', # Nord6
194
+ 'border': '#4c566a', # Nord3
195
+ 'muted': '#d8dee9', # Nord4
196
+
197
+ # Extended colors
198
+ 'surface': '#3b4252', # Nord1
199
+ 'overlay': 'rgba(46,52,64,0.8)',
200
+ 'accent': '#b48ead', # Nord15 - Aurora
201
+ 'focus': 'rgba(136,192,208,0.4)',
202
+
203
+ # UI elements
204
+ 'radius': '4px',
205
+ 'shadow': '0 2px 8px rgba(0,0,0,0.3)',
206
+
207
+ # Font sizes
208
+ 'font-xs': '0.75rem',
209
+ 'font-sm': '0.875rem',
210
+ 'font-md': '1rem',
211
+ 'font-lg': '1.25rem',
212
+ 'font-xl': '1.5rem',
213
+ 'font-2xl': '2rem',
214
+ }
215
+
216
+
217
+ # ==========================================================================
218
+ # Dracula Theme (Popular dark theme)
219
+ # ==========================================================================
220
+
221
+ THEME_DRACULA: Dict[str, str] = {
222
+ # Dracula color palette
223
+ 'primary': '#bd93f9', # Purple
224
+ 'secondary': '#6272a4', # Comment
225
+ 'success': '#50fa7b', # Green
226
+ 'danger': '#ff5555', # Red
227
+ 'warning': '#ffb86c', # Orange
228
+ 'info': '#8be9fd', # Cyan
229
+
230
+ # Neutral colors
231
+ 'light': '#44475a', # Current Line
232
+ 'dark': '#f8f8f2', # Foreground
233
+ 'background': '#282a36', # Background
234
+ 'text': '#f8f8f2', # Foreground
235
+ 'border': '#44475a', # Current Line
236
+ 'muted': '#6272a4', # Comment
237
+
238
+ # Extended colors
239
+ 'surface': '#21222c', # Darker background
240
+ 'overlay': 'rgba(40,42,54,0.9)',
241
+ 'accent': '#ff79c6', # Pink
242
+ 'focus': 'rgba(189,147,249,0.4)',
243
+
244
+ # UI elements
245
+ 'radius': '6px',
246
+ 'shadow': '0 2px 10px rgba(0,0,0,0.4)',
247
+
248
+ # Font sizes
249
+ 'font-xs': '0.75rem',
250
+ 'font-sm': '0.875rem',
251
+ 'font-md': '1rem',
252
+ 'font-lg': '1.25rem',
253
+ 'font-xl': '1.5rem',
254
+ 'font-2xl': '2rem',
255
+ }
256
+
257
+
258
+ # ==========================================================================
259
+ # Theme Presets Registry
260
+ # ==========================================================================
261
+
262
+ THEME_PRESETS: Dict[str, Dict[str, str]] = {
263
+ 'light': THEME_LIGHT,
264
+ 'dark': THEME_DARK,
265
+ 'high-contrast': THEME_HIGH_CONTRAST,
266
+ 'sepia': THEME_SEPIA,
267
+ 'nord': THEME_NORD,
268
+ 'dracula': THEME_DRACULA,
269
+ }
270
+
271
+
272
+ def get_theme_preset(name: str) -> Optional[Dict[str, str]]:
273
+ """Get a theme preset by name."""
274
+ return THEME_PRESETS.get(name)
275
+
276
+
277
+ def get_theme_css(
278
+ preset: str = 'light',
279
+ overrides: Optional[Dict[str, str]] = None,
280
+ auto_switch: bool = False
281
+ ) -> str:
282
+ """
283
+ Generate CSS for a theme.
284
+
285
+ Args:
286
+ preset: Base theme preset ('light' or 'dark')
287
+ overrides: Custom color overrides to apply on top of preset
288
+ auto_switch: If True, adds media query for automatic dark/light switching
289
+
290
+ Returns:
291
+ CSS string with custom properties
292
+ """
293
+ base_theme = THEME_PRESETS.get(preset, THEME_LIGHT)
294
+
295
+ # Merge overrides
296
+ theme = dict(base_theme)
297
+ if overrides:
298
+ theme.update(overrides)
299
+
300
+ # Generate CSS variables
301
+ css_vars = _theme_to_css_vars(theme)
302
+
303
+ if auto_switch:
304
+ # Generate both light and dark with media query
305
+ light_vars = _theme_to_css_vars(THEME_LIGHT)
306
+ dark_vars = _theme_to_css_vars(THEME_DARK)
307
+
308
+ # Apply overrides to both if provided
309
+ if overrides:
310
+ light_theme = dict(THEME_LIGHT)
311
+ light_theme.update(overrides)
312
+ light_vars = _theme_to_css_vars(light_theme)
313
+
314
+ dark_theme = dict(THEME_DARK)
315
+ dark_theme.update(overrides)
316
+ dark_vars = _theme_to_css_vars(dark_theme)
317
+
318
+ return f""":root {{
319
+ {light_vars}
320
+ }}
321
+
322
+ @media (prefers-color-scheme: dark) {{
323
+ :root {{
324
+ {dark_vars}
325
+ }}
326
+ }}
327
+
328
+ [data-theme="light"] {{
329
+ {light_vars}
330
+ }}
331
+
332
+ [data-theme="dark"] {{
333
+ {dark_vars}
334
+ }}
335
+ """
336
+ else:
337
+ # Single theme
338
+ return f""":root {{
339
+ {css_vars}
340
+ }}
341
+
342
+ [data-theme="{preset}"] {{
343
+ {css_vars}
344
+ }}
345
+ """
346
+
347
+
348
+ def _theme_to_css_vars(theme: Dict[str, str]) -> str:
349
+ """Convert theme dict to CSS variable declarations."""
350
+ lines = []
351
+ for key, value in theme.items():
352
+ # Convert key to CSS variable name
353
+ css_var = f"--q-{key}"
354
+ lines.append(f" {css_var}: {value};")
355
+ return '\n'.join(lines)
356
+
357
+
358
+ # ==========================================================================
359
+ # Runtime Theme Switching JavaScript
360
+ # ==========================================================================
361
+
362
+ THEME_SWITCH_JS = """\
363
+ <script>
364
+ (function() {
365
+ // Get initial theme from localStorage or default
366
+ var stored = localStorage.getItem('quantum-theme');
367
+ var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
368
+ var initial = stored || (prefersDark ? 'dark' : 'light');
369
+ document.documentElement.setAttribute('data-theme', initial);
370
+
371
+ // Theme switching function
372
+ window.__quantumSetTheme = function(theme) {
373
+ document.documentElement.setAttribute('data-theme', theme);
374
+ localStorage.setItem('quantum-theme', theme);
375
+ };
376
+
377
+ // Toggle between light and dark
378
+ window.__quantumToggleTheme = function() {
379
+ var current = document.documentElement.getAttribute('data-theme') || 'light';
380
+ var next = current === 'light' ? 'dark' : 'light';
381
+ window.__quantumSetTheme(next);
382
+ return next;
383
+ };
384
+
385
+ // Get current theme
386
+ window.__quantumGetTheme = function() {
387
+ return document.documentElement.getAttribute('data-theme') || 'light';
388
+ };
389
+
390
+ // Listen for system preference changes (if auto-switch enabled)
391
+ if (window.matchMedia) {
392
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
393
+ if (!localStorage.getItem('quantum-theme')) {
394
+ document.documentElement.setAttribute('data-theme', e.matches ? 'dark' : 'light');
395
+ }
396
+ });
397
+ }
398
+ })();
399
+ </script>
400
+ """
401
+
402
+
403
+ def get_theme_switch_js() -> str:
404
+ """Get the JavaScript for runtime theme switching."""
405
+ return THEME_SWITCH_JS
@@ -0,0 +1,20 @@
1
+ """
2
+ UI Engine - Multi-target UI components (ui: namespace)
3
+
4
+ Compiles declarative XML to HTML/CSS, Python Textual (TUI), or Desktop (pywebview).
5
+ """
6
+
7
+ from .ast_nodes import (
8
+ UIWindowNode, UIHBoxNode, UIVBoxNode, UIPanelNode,
9
+ UITabPanelNode, UITabNode, UIGridNode, UIAccordionNode,
10
+ UISectionNode, UIDividedBoxNode, UIFormNode, UIFormItemNode,
11
+ UISpacerNode, UIScrollBoxNode,
12
+ UITextNode, UIButtonNode, UIInputNode, UICheckboxNode,
13
+ UIRadioNode, UISwitchNode, UISelectNode, UITableNode,
14
+ UIColumnNode, UIListNode, UIItemNode, UIImageNode,
15
+ UILinkNode, UIProgressNode, UITreeNode, UIMenuNode,
16
+ UIOptionNode, UILogNode, UIMarkdownNode, UIHeaderNode,
17
+ UIFooterNode, UIRuleNode, UILoadingNode, UIBadgeNode,
18
+ )
19
+
20
+ from .parser import UIParser, UIParseError