jsgui3-server 0.0.147 → 0.0.149

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 (145) hide show
  1. package/.github/workflows/control-scan-manifest-check.yml +31 -0
  2. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-071799b982906680f5fd699d.js +40 -0
  3. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-07352945ad5c92654fcb8b65.js +39 -0
  4. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-138a601fadb6191ea314c6fd.js +39 -0
  5. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-171f6c381c2cadf2e9fa7087.js +39 -0
  6. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-1d973388156b84a04373fac9.js +39 -0
  7. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-20e117bc8a10d2cd16234bbe.js +40 -0
  8. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-2b028a82b0e5efddba42425f.js +39 -0
  9. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-4518556cd5c7e059e82b22b8.js +40 -0
  10. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5bac1aa0f213902f718ed74f.js +40 -0
  11. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5f9996ac7822caf777d92f56.js +39 -0
  12. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-60a92c702e65fd9cf748e3ec.js +39 -0
  13. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6164c1f8f738995c541895d2.js +44 -0
  14. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6718a85eb9e5aa782dd47a05.js +45 -0
  15. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-69e280f14e37aee76a1d4675.js +39 -0
  16. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7570d1b030d44b111ed59c4c.js +39 -0
  17. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7798c9bbd55e510d5039f936.js +42 -0
  18. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-78cd511ea1ef18ecb03d1be5.js +40 -0
  19. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7d482e0b95bcb5e3c543118b.js +43 -0
  20. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-80e9476d1127c55b40fdb36f.js +40 -0
  21. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-810ced55d5320a3088a05b13.js +40 -0
  22. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-8423565f1a40e329afc8c6cf.js +40 -0
  23. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-900bef783b8cee36506ec282.js +39 -0
  24. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-a1a37aff6416fdad74040ddf.js +39 -0
  25. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-ad48d5e8eda40f175b4df090.js +39 -0
  26. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-aec5a2d963015528c9099462.js +39 -0
  27. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-af9d34e0f1722fab9e28c269.js +39 -0
  28. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-b818e4015e2f1fe86280b5ab.js +41 -0
  29. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bcb2541adc70b7aba61768c5.js +44 -0
  30. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bfe89d2c78ed44f95ed7dd73.js +40 -0
  31. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c06f04806a1e688e1187110c.js +40 -0
  32. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c3f3adf904f585afc544b96a.js +39 -0
  33. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-d45acb873e1d8e32d5e60f2e.js +39 -0
  34. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-db06f132533706f4a0163b8c.js +39 -0
  35. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f660f40d78b135fc8560a862.js +39 -0
  36. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f9dee4ec18a96e09bee06bae.js +39 -0
  37. package/README.md +85 -3
  38. package/admin-ui/client.js +213 -0
  39. package/admin-ui/server.js +104 -0
  40. package/client/controls/auto-observable.js +207 -0
  41. package/dev-status.svg +139 -0
  42. package/docs/api-reference.md +301 -43
  43. package/docs/books/admin-ui/01-introduction.md +32 -0
  44. package/docs/books/admin-ui/02-architecture.md +92 -0
  45. package/docs/books/admin-ui/03-controls.md +194 -0
  46. package/docs/books/admin-ui/04-implementation-plan.md +62 -0
  47. package/docs/books/admin-ui/README.md +26 -0
  48. package/docs/books/jsgui3-bundling-research-book/00-table-of-contents.md +35 -0
  49. package/docs/books/jsgui3-bundling-research-book/01-pipeline-and-runtime-semantics.md +34 -0
  50. package/docs/books/jsgui3-bundling-research-book/02-javascript-bundling-core.md +36 -0
  51. package/docs/books/jsgui3-bundling-research-book/03-style-extraction-and-css-compilation.md +35 -0
  52. package/docs/books/jsgui3-bundling-research-book/04-static-publishing-and-delivery.md +39 -0
  53. package/docs/books/jsgui3-bundling-research-book/05-current-limits-and-size-bloat-vectors.md +25 -0
  54. package/docs/books/jsgui3-bundling-research-book/06-unused-module-elimination-strategy.md +77 -0
  55. package/docs/books/jsgui3-bundling-research-book/07-jsgui3-html-control-and-mixin-pruning.md +63 -0
  56. package/docs/books/jsgui3-bundling-research-book/08-test-and-verification-methodology.md +43 -0
  57. package/docs/books/jsgui3-bundling-research-book/09-roadmap-and-rollout.md +42 -0
  58. package/docs/books/jsgui3-bundling-research-book/10-further-research-strategies-and-upgrades.md +211 -0
  59. package/docs/books/jsgui3-bundling-research-book/README.md +35 -0
  60. package/docs/bundling-system-deep-dive.md +9 -4
  61. package/docs/comprehensive-documentation.md +49 -18
  62. package/docs/configuration-reference.md +152 -27
  63. package/docs/core/README.md +19 -0
  64. package/docs/core/jsgui3-server-core-book/00-table-of-contents.md +21 -0
  65. package/docs/core/jsgui3-server-core-book/01-startup-readiness-state-machine.md +41 -0
  66. package/docs/core/jsgui3-server-core-book/02-resource-abstraction-and-lifecycle.md +92 -0
  67. package/docs/core/jsgui3-server-core-book/03-resource-pool-and-event-topology.md +47 -0
  68. package/docs/core/jsgui3-server-core-book/04-sse-publisher-semantics.md +41 -0
  69. package/docs/core/jsgui3-server-core-book/05-serve-factory-resource-wiring.md +46 -0
  70. package/docs/core/jsgui3-server-core-book/06-e2e-testing-methodology.md +48 -0
  71. package/docs/core/jsgui3-server-core-book/07-defect-detection-and-hardening-loop.md +47 -0
  72. package/docs/publishers-guide.md +59 -4
  73. package/docs/resources-guide.md +184 -35
  74. package/docs/simple-server-api-design.md +72 -17
  75. package/docs/system-architecture.md +18 -14
  76. package/examples/controls/15) window, observable SSE/server.js +6 -1
  77. package/examples/controls/19) window, auto observable ui/client.js +125 -0
  78. package/examples/controls/19) window, auto observable ui/server.js +73 -0
  79. package/examples/controls/20) window, task manager app/README.md +133 -0
  80. package/examples/controls/20) window, task manager app/client.js +797 -0
  81. package/examples/controls/20) window, task manager app/server.js +178 -0
  82. package/examples/controls/6) window, color_palette/client.js +165 -68
  83. package/examples/controls/9) window, date picker/client.js +362 -76
  84. package/examples/controls/9b) window, shared data.model mirrored date pickers/client.js +104 -83
  85. package/examples/jsgui3-html/06) theming/client.js +22 -1
  86. package/examples/jsgui3-html/10) binding-debugger/client.js +137 -1
  87. package/http/responders/static/Static_Route_HTTP_Responder.js +52 -34
  88. package/lab/experiments/capture-color-controls.js +196 -0
  89. package/lab/results/screenshots/color-controls/full_page.png +0 -0
  90. package/lab/results/screenshots/color-controls/section_1_color_grid_12x12.png +0 -0
  91. package/lab/results/screenshots/color-controls/section_2_color_grid_4x2.png +0 -0
  92. package/lab/results/screenshots/color-controls/section_3_color_palette.png +0 -0
  93. package/lab/results/screenshots/color-controls/section_4_palette_comparison.png +0 -0
  94. package/lab/results/screenshots/color-controls/section_5_raw_swatches.png +0 -0
  95. package/lab/results/screenshots/color-controls/section_6_optimized_crayola.png +0 -0
  96. package/lab/results/screenshots/color-controls/section_7_pastel_palette.png +0 -0
  97. package/lab/results/screenshots/color-controls/section_8_extended_144.png +0 -0
  98. package/lab/screenshot-utils.js +248 -0
  99. package/module.js +11 -4
  100. package/package.json +14 -4
  101. package/publishers/Publishers.js +4 -3
  102. package/publishers/helpers/assigners/static-compressed-response-buffers/Single_Control_Webpage_Server_Static_Compressed_Response_Buffers_Assigner.js +5 -5
  103. package/publishers/http-observable-publisher.js +8 -0
  104. package/publishers/http-sse-publisher.js +341 -0
  105. package/publishers/http-webpage-publisher.js +13 -3
  106. package/publishers/http-webpageorsite-publisher.js +18 -0
  107. package/resources/process-resource.js +950 -0
  108. package/resources/processors/bundlers/js/esbuild/Advanced_JS_Bundler_Using_ESBuild.js +164 -46
  109. package/resources/processors/bundlers/js/esbuild/Core_JS_Non_Minifying_Bundler_Using_ESBuild.js +18 -7
  110. package/resources/processors/bundlers/js/esbuild/JSGUI3_HTML_Control_Optimizer.js +829 -0
  111. package/resources/remote-process-resource.js +355 -0
  112. package/resources/server-resource-pool.js +354 -41
  113. package/serve-factory.js +441 -259
  114. package/server.js +161 -16
  115. package/tests/README.md +66 -4
  116. package/tests/admin-ui-render.test.js +24 -0
  117. package/tests/assigners.test.js +56 -40
  118. package/tests/bundling-default-control-elimination.puppeteer.test.js +260 -0
  119. package/tests/configuration-validation.test.js +21 -18
  120. package/tests/content-analysis.test.js +7 -6
  121. package/tests/control-optimizer-cache-behavior.test.js +52 -0
  122. package/tests/control-scan-manifest-regression.test.js +144 -0
  123. package/tests/end-to-end.test.js +15 -14
  124. package/tests/error-handling.test.js +222 -179
  125. package/tests/fixtures/bundling-default-button-client.js +37 -0
  126. package/tests/fixtures/bundling-default-window-client.js +34 -0
  127. package/tests/fixtures/control_scan_manifest_expectations.json +48 -0
  128. package/tests/fixtures/resource-monitor-client.js +319 -0
  129. package/tests/helpers/puppeteer-e2e-harness.js +317 -0
  130. package/tests/http-sse-publisher.test.js +136 -0
  131. package/tests/performance.test.js +69 -65
  132. package/tests/process-resource.test.js +138 -0
  133. package/tests/publishers.test.js +7 -7
  134. package/tests/remote-process-resource.test.js +160 -0
  135. package/tests/sass-controls.e2e.test.js +7 -1
  136. package/tests/serve-resources.test.js +270 -0
  137. package/tests/serve.test.js +120 -50
  138. package/tests/server-resource-pool.test.js +106 -0
  139. package/tests/small-controls-bundle-size.test.js +252 -0
  140. package/tests/test-runner.js +13 -1
  141. package/tests/window-examples.puppeteer.test.js +204 -1
  142. package/tests/window-resource-integration.puppeteer.test.js +585 -0
  143. package/tests/temp_invalid.js +0 -7
  144. package/tests/temp_invalid_utf8.js +0 -1
  145. package/tests/temp_malformed.js +0 -10
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Task Manager Application Server
3
+ *
4
+ * Demonstrates:
5
+ * - Server.serve() with a control
6
+ * - API endpoints for CRUD operations
7
+ * - In-memory data store (could be replaced with database)
8
+ */
9
+
10
+ const jsgui = require('./client');
11
+ const Server = require('../../../server');
12
+ const { Task_Manager_App } = jsgui.controls;
13
+
14
+ // In-memory task store
15
+ let tasks = [
16
+ { id: 1, text: 'Welcome to Task Manager!', project: 'Personal', completed: false, created: new Date() },
17
+ { id: 2, text: 'Try adding a new task', project: 'Personal', completed: false, created: new Date() },
18
+ { id: 3, text: 'Click checkbox to complete', project: 'Work', completed: true, created: new Date() },
19
+ { id: 4, text: 'Use the filter to sort by project', project: 'Work', completed: false, created: new Date() },
20
+ { id: 5, text: 'Check the Stats tab', project: 'Personal', completed: false, created: new Date() }
21
+ ];
22
+
23
+ let next_id = 6;
24
+
25
+ // Helper to get tasks array (ensures we return a copy)
26
+ const get_tasks = () => [...tasks];
27
+
28
+ if (require.main === module) {
29
+ const server = new Server({
30
+ Ctrl: Task_Manager_App,
31
+ src_path_client_js: require.resolve('./client.js')
32
+ });
33
+
34
+ server.on('ready', () => {
35
+ console.log('Server ready, setting up API endpoints...');
36
+
37
+ // GET /api/tasks/list - Get all tasks
38
+ server.publish('tasks/list', () => {
39
+ return {
40
+ success: true,
41
+ tasks: get_tasks(),
42
+ count: tasks.length
43
+ };
44
+ });
45
+
46
+ // POST /api/tasks/add - Add a new task
47
+ server.publish('tasks/add', (data) => {
48
+ if (!data || !data.text || typeof data.text !== 'string') {
49
+ return { success: false, error: 'Task text is required' };
50
+ }
51
+
52
+ const new_task = {
53
+ id: next_id++,
54
+ text: data.text.trim(),
55
+ project: data.project || 'Personal',
56
+ completed: false,
57
+ created: new Date()
58
+ };
59
+
60
+ tasks.push(new_task);
61
+
62
+ return {
63
+ success: true,
64
+ task: new_task,
65
+ tasks: get_tasks()
66
+ };
67
+ });
68
+
69
+ // POST /api/tasks/toggle - Toggle task completion
70
+ server.publish('tasks/toggle', (data) => {
71
+ if (!data || typeof data.id !== 'number') {
72
+ return { success: false, error: 'Task ID is required' };
73
+ }
74
+
75
+ const task = tasks.find(t => t.id === data.id);
76
+ if (!task) {
77
+ return { success: false, error: 'Task not found' };
78
+ }
79
+
80
+ task.completed = !task.completed;
81
+
82
+ return {
83
+ success: true,
84
+ task,
85
+ tasks: get_tasks()
86
+ };
87
+ });
88
+
89
+ // POST /api/tasks/delete - Delete a task
90
+ server.publish('tasks/delete', (data) => {
91
+ if (!data || typeof data.id !== 'number') {
92
+ return { success: false, error: 'Task ID is required' };
93
+ }
94
+
95
+ const index = tasks.findIndex(t => t.id === data.id);
96
+ if (index === -1) {
97
+ return { success: false, error: 'Task not found' };
98
+ }
99
+
100
+ const deleted = tasks.splice(index, 1)[0];
101
+
102
+ return {
103
+ success: true,
104
+ deleted,
105
+ tasks: get_tasks()
106
+ };
107
+ });
108
+
109
+ // POST /api/tasks/clear-completed - Remove all completed tasks
110
+ server.publish('tasks/clear-completed', () => {
111
+ const before_count = tasks.length;
112
+ tasks = tasks.filter(t => !t.completed);
113
+ const removed = before_count - tasks.length;
114
+
115
+ return {
116
+ success: true,
117
+ removed,
118
+ tasks: get_tasks()
119
+ };
120
+ });
121
+
122
+ // GET /api/stats - Get task statistics
123
+ server.publish('stats', () => {
124
+ const total = tasks.length;
125
+ const completed = tasks.filter(t => t.completed).length;
126
+ const pending = total - completed;
127
+ const rate = total > 0 ? Math.round((completed / total) * 100) : 0;
128
+
129
+ // Group by project
130
+ const by_project = {};
131
+ for (const task of tasks) {
132
+ if (!by_project[task.project]) {
133
+ by_project[task.project] = { total: 0, completed: 0 };
134
+ }
135
+ by_project[task.project].total++;
136
+ if (task.completed) {
137
+ by_project[task.project].completed++;
138
+ }
139
+ }
140
+
141
+ return {
142
+ total,
143
+ completed,
144
+ pending,
145
+ completion_rate: rate,
146
+ by_project
147
+ };
148
+ });
149
+
150
+ console.log('API endpoints registered:');
151
+ console.log(' GET /api/tasks/list');
152
+ console.log(' POST /api/tasks/add');
153
+ console.log(' POST /api/tasks/toggle');
154
+ console.log(' POST /api/tasks/delete');
155
+ console.log(' POST /api/tasks/clear-completed');
156
+ console.log(' GET /api/stats');
157
+
158
+ // Start server
159
+ const port = parseInt(process.env.PORT, 10) || 52021;
160
+ server.start(port, (err) => {
161
+ if (err) throw err;
162
+ console.log('');
163
+ console.log('='.repeat(50));
164
+ console.log('Task Manager Application');
165
+ console.log('='.repeat(50));
166
+ console.log(`Open http://localhost:${port} in your browser`);
167
+ console.log('');
168
+ console.log('Features:');
169
+ console.log(' - Add, complete, and delete tasks');
170
+ console.log(' - Filter tasks by project');
171
+ console.log(' - View statistics and completion rate');
172
+ console.log(' - Quick add floating window');
173
+ console.log('='.repeat(50));
174
+ });
175
+ });
176
+ }
177
+
178
+ module.exports = { tasks, get_tasks };
@@ -1,68 +1,165 @@
1
- const jsgui = require('jsgui3-client');
2
- const {controls, Control, mixins} = jsgui;
3
- const {dragable} = mixins;
4
- const {Grid, Color_Palette} = controls;
5
- const Active_HTML_Document = require('../../../controls/Active_HTML_Document');
6
- class Demo_UI extends Active_HTML_Document {
7
- constructor(spec = {}) {
8
- spec.__type_name = spec.__type_name || 'demo_ui';
9
- super(spec);
10
- const {context} = this;
11
- if (typeof this.body.add_class === 'function') {
12
- this.body.add_class('demo-ui');
13
- }
14
- const compose = () => {
15
- const window = new controls.Window({
16
- context: context,
17
- title: 'jsgui3-html Color_Palette Control',
18
- pos: [10, 10]
19
- });
20
- const color_palette = new Color_Palette({
21
- context,
22
- //grid_size: [10, 10],
23
- size: [280, 180]
24
- })
25
- window.inner.add(color_palette);
26
- this.body.add(window);
27
- }
28
- if (!spec.el) {
29
- compose();
30
- }
31
- }
32
- activate() {
33
- if (!this.__active) {
34
- super.activate();
35
- const {context} = this;
36
- context.on('window-resize', e_resize => {
37
-
38
- });
39
- }
40
- }
41
- }
42
-
43
-
44
- Demo_UI.css = `
45
- * {
46
- margin: 0;
47
- padding: 0;
48
- }
49
- body {
50
- overflow-x: hidden;
51
- overflow-y: hidden;
52
- background-color: #E0E0E0;
53
- }
54
- .demo-ui {
55
- /*
56
- display: flex;
57
- flex-wrap: wrap;
58
-
59
- flex-direction: column;
60
- justify-content: center;
61
- align-items: center;
62
- text-align: center;
63
- min-height: 100vh;
64
- */
65
- }
66
- `;
67
- controls.Demo_UI = Demo_UI;
68
- module.exports = jsgui;
1
+ const jsgui = require('jsgui3-client');
2
+ const { controls, Control } = jsgui;
3
+ const Active_HTML_Document = require('../../../controls/Active_HTML_Document');
4
+ const { Color_Picker } = controls;
5
+
6
+ if (typeof Color_Picker !== 'function') {
7
+ throw new Error('Expected controls.Color_Picker to be exported from jsgui3-client/jsgui3-html.');
8
+ }
9
+
10
+ class Demo_UI extends Active_HTML_Document {
11
+ constructor(spec = {}) {
12
+ spec.__type_name = spec.__type_name || 'demo_ui';
13
+ super(spec);
14
+
15
+ if (typeof this.body.add_class === 'function') {
16
+ this.body.add_class('demo-ui');
17
+ }
18
+
19
+ if (!spec.el) {
20
+ this.compose_ui();
21
+ }
22
+ }
23
+
24
+ compose_ui() {
25
+ const { context } = this;
26
+
27
+ const window_ctrl = new controls.Window({
28
+ context,
29
+ title: 'jsgui3-html Color_Picker Controls',
30
+ pos: [10, 10],
31
+ size: [620, 520]
32
+ });
33
+
34
+ const intro_text = new Control({ context, tag_name: 'p' });
35
+ intro_text.add_class('picker-intro');
36
+ intro_text.add('Improved color picking controls from jsgui3-html.');
37
+ window_ctrl.inner.add(intro_text);
38
+
39
+ const color_picker_default = new Color_Picker({
40
+ context,
41
+ value: '#3b82f6'
42
+ });
43
+ color_picker_default.add_class('demo-color-picker-default');
44
+ window_ctrl.inner.add(color_picker_default);
45
+
46
+ const color_picker_compact = new Color_Picker({
47
+ context,
48
+ value: '#ef4444',
49
+ show_wheel: false,
50
+ show_rgb_inputs: true,
51
+ show_alpha: true,
52
+ layout: 'compact',
53
+ output_format: 'rgba'
54
+ });
55
+ color_picker_compact.add_class('demo-color-picker-compact');
56
+ window_ctrl.inner.add(color_picker_compact);
57
+
58
+ const compact_value_readout = new Control({ context, tag_name: 'div' });
59
+ compact_value_readout.add_class('demo-color-picker-readout');
60
+ compact_value_readout.add(`Selected: ${color_picker_compact.value}`);
61
+ window_ctrl.inner.add(compact_value_readout);
62
+
63
+ this._ctrl_fields = {
64
+ color_picker_compact,
65
+ compact_value_readout
66
+ };
67
+
68
+ this.body.add(window_ctrl);
69
+ }
70
+
71
+ activate() {
72
+ if (!this.__active) {
73
+ super.activate();
74
+
75
+ const root_el = (this.body && this.body.dom && this.body.dom.el) || (this.dom && this.dom.el) || null;
76
+ if (!root_el) {
77
+ return;
78
+ }
79
+
80
+ const compact_root_el = root_el.querySelector('.demo-color-picker-compact');
81
+ const readout_el = root_el.querySelector('.demo-color-picker-readout');
82
+ if (!compact_root_el || !readout_el) {
83
+ return;
84
+ }
85
+
86
+ const build_rgba_value_text = () => {
87
+ const input_r = compact_root_el.querySelector('.cp-rgb-r');
88
+ const input_g = compact_root_el.querySelector('.cp-rgb-g');
89
+ const input_b = compact_root_el.querySelector('.cp-rgb-b');
90
+ const alpha_slider = compact_root_el.querySelector('.cp-slider-a');
91
+
92
+ const has_rgb_inputs = input_r && input_g && input_b;
93
+ if (!has_rgb_inputs) {
94
+ const hex_input = compact_root_el.querySelector('.cp-hex-input');
95
+ return hex_input ? String(hex_input.value || '') : '';
96
+ }
97
+
98
+ const red_value = Number(input_r.value);
99
+ const green_value = Number(input_g.value);
100
+ const blue_value = Number(input_b.value);
101
+ const alpha_value = alpha_slider ? (Number(alpha_slider.value) / 100) : 1;
102
+
103
+ if (!Number.isFinite(red_value) || !Number.isFinite(green_value) || !Number.isFinite(blue_value)) {
104
+ return '';
105
+ }
106
+ return `rgba(${red_value}, ${green_value}, ${blue_value}, ${alpha_value})`;
107
+ };
108
+
109
+ const set_readout_text = () => {
110
+ const value_text = build_rgba_value_text();
111
+ readout_el.textContent = `Selected: ${value_text}`;
112
+ };
113
+
114
+ set_readout_text();
115
+ const schedule_set_readout_text = () => {
116
+ setTimeout(set_readout_text, 0);
117
+ };
118
+
119
+ compact_root_el.addEventListener('input', schedule_set_readout_text);
120
+ compact_root_el.addEventListener('change', schedule_set_readout_text);
121
+ compact_root_el.addEventListener('click', schedule_set_readout_text);
122
+ this.on('destroy', () => {
123
+ compact_root_el.removeEventListener('input', schedule_set_readout_text);
124
+ compact_root_el.removeEventListener('change', schedule_set_readout_text);
125
+ compact_root_el.removeEventListener('click', schedule_set_readout_text);
126
+ });
127
+ }
128
+ }
129
+ }
130
+
131
+ Demo_UI.css = `
132
+ * {
133
+ margin: 0;
134
+ padding: 0;
135
+ box-sizing: border-box;
136
+ }
137
+
138
+ body {
139
+ overflow-x: hidden;
140
+ overflow-y: hidden;
141
+ background-color: #e0e0e0;
142
+ }
143
+
144
+ .picker-intro {
145
+ margin: 8px 0 10px 0;
146
+ font-family: 'Segoe UI', sans-serif;
147
+ font-size: 13px;
148
+ color: #34495e;
149
+ }
150
+
151
+ .demo-color-picker-default {
152
+ margin-bottom: 14px;
153
+ }
154
+
155
+ .demo-color-picker-readout {
156
+ margin-top: 10px;
157
+ font-family: 'Consolas', 'Courier New', monospace;
158
+ font-size: 12px;
159
+ color: #263238;
160
+ }
161
+ `;
162
+
163
+ controls.Demo_UI = Demo_UI;
164
+ controls.Color_Picker = Color_Picker;
165
+ module.exports = jsgui;