@kupola/kupola 1.2.0 → 1.3.1

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 (97) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +330 -286
  3. package/adapters/axios.d.ts +34 -0
  4. package/adapters/axios.js +122 -0
  5. package/adapters/navios-http.d.ts +110 -0
  6. package/adapters/navios-http.js +151 -0
  7. package/dist/css/accessibility.css +119 -0
  8. package/dist/css/animations.css +224 -0
  9. package/dist/css/brand-themes.css +300 -0
  10. package/dist/css/colors_and_type.css +441 -0
  11. package/dist/css/components-ext.css +4165 -0
  12. package/dist/css/components.css +1483 -0
  13. package/dist/css/responsive.css +697 -0
  14. package/dist/css/scaffold.css +145 -0
  15. package/dist/css/states.css +316 -0
  16. package/dist/css/theme-dark.css +296 -0
  17. package/dist/css/theme-light.css +296 -0
  18. package/dist/css/utilities.css +171 -0
  19. package/dist/kupola.cjs.js +219 -161
  20. package/dist/kupola.cjs.js.map +1 -1
  21. package/dist/kupola.esm.js +6643 -5709
  22. package/dist/kupola.esm.js.map +1 -1
  23. package/dist/kupola.umd.js +219 -161
  24. package/dist/kupola.umd.js.map +1 -1
  25. package/dist/plugins/vite-plugin-kupola.js +120 -0
  26. package/dist/types/kupola.d.ts +421 -323
  27. package/js/calendar.js +334 -25
  28. package/js/carousel.js +182 -48
  29. package/js/collapse.js +148 -34
  30. package/js/color-picker.js +416 -108
  31. package/js/component.js +8 -19
  32. package/js/countdown.js +9 -8
  33. package/js/data-bind.js +73 -16
  34. package/js/datepicker.js +488 -110
  35. package/js/depends.js +710 -0
  36. package/js/dialog.js +4 -2
  37. package/js/drawer.js +172 -8
  38. package/js/dropdown.js +272 -17
  39. package/js/dynamic-tags.js +156 -40
  40. package/js/fileupload.js +9 -8
  41. package/js/form.js +280 -254
  42. package/js/global-events.js +281 -188
  43. package/js/heatmap.js +10 -7
  44. package/js/i18n.js +18 -10
  45. package/js/icons.js +141 -161
  46. package/js/image-preview.js +146 -2
  47. package/js/initializer.js +113 -71
  48. package/js/kupola-core.js +123 -45
  49. package/js/kupola-lifecycle.js +13 -11
  50. package/js/message.js +8 -1
  51. package/js/modal.js +207 -59
  52. package/js/notification.js +8 -1
  53. package/js/numberinput.js +9 -8
  54. package/js/pagination.js +263 -0
  55. package/js/registry.js +29 -12
  56. package/js/select.js +482 -27
  57. package/js/slide-captcha.js +11 -2
  58. package/js/slider.js +442 -25
  59. package/js/statcard.js +9 -7
  60. package/js/table.js +1210 -0
  61. package/js/tag.js +268 -14
  62. package/js/theme.js +14 -43
  63. package/js/timepicker.js +335 -66
  64. package/js/tooltip.js +317 -86
  65. package/js/utils.js +6 -2
  66. package/js/validation.js +6 -2
  67. package/js/virtual-list.js +11 -7
  68. package/js/web-components.js +288 -0
  69. package/package.json +77 -67
  70. package/plugins/vite-plugin-kupola.js +120 -0
  71. package/types/kupola.d.ts +421 -323
  72. package/CHANGELOG.md +0 -130
  73. package/INTEGRATION.md +0 -440
  74. package/PROJECT_SUMMARY.md +0 -312
  75. package/SKILL.md +0 -572
  76. package/dist/utils/utils/Kupola.cs +0 -77
  77. package/dist/utils/utils/Kupola.java +0 -104
  78. package/dist/utils/utils/kupola.go +0 -120
  79. package/dist/utils/utils/kupola.js +0 -63
  80. package/dist/utils/utils/kupola.py +0 -1392
  81. package/dist/utils/utils/kupola.rb +0 -69
  82. package/js/composition-api.js +0 -458
  83. package/js/error-handler.js +0 -181
  84. package/js/http.js +0 -419
  85. package/js/kupola-devtools.js +0 -598
  86. package/js/performance.js +0 -250
  87. package/js/router.js +0 -396
  88. package/js/security.js +0 -189
  89. package/js/test-utils.js +0 -251
  90. package/templates/base.html +0 -30
  91. package/templates/base_dashboard.html +0 -99
  92. package/utils/Kupola.cs +0 -77
  93. package/utils/Kupola.java +0 -104
  94. package/utils/kupola.go +0 -120
  95. package/utils/kupola.js +0 -63
  96. package/utils/kupola.py +0 -1392
  97. package/utils/kupola.rb +0 -69
package/js/tag.js CHANGED
@@ -1,17 +1,30 @@
1
1
  class Tag {
2
- constructor(element) {
2
+ constructor(element, options = {}) {
3
3
  this.element = element;
4
4
  this.closeBtn = element.querySelector('.ds-tag__close');
5
+ this.checkbox = element.querySelector('.ds-tag__checkbox');
6
+ this.editInput = element.querySelector('.ds-tag__input');
7
+
5
8
  this._listeners = [];
9
+
10
+ this.color = options.color || element.getAttribute('data-tag-color') || 'default';
11
+ this.size = options.size || element.getAttribute('data-tag-size') || 'default';
12
+ this.checkable = options.checkable || element.hasAttribute('data-tag-checkable');
13
+ this.checked = options.checked || element.hasAttribute('data-tag-checked');
14
+ this.editable = options.editable || element.hasAttribute('data-tag-editable');
15
+ this.maxLength = options.maxLength || parseInt(element.getAttribute('data-tag-maxlength')) || 50;
16
+
6
17
  this.init();
7
18
  }
8
19
 
9
20
  init() {
21
+ this._applyStyles();
22
+
10
23
  if (this.closeBtn) {
11
24
  const closeHandler = (e) => {
12
25
  e.stopPropagation();
13
- this.element.dispatchEvent(new CustomEvent('ds-tag-remove', {
14
- detail: { tag: this.element },
26
+ this.element.dispatchEvent(new CustomEvent('kupola:tag-remove', {
27
+ detail: { tag: this.element, content: this.getContent() },
15
28
  bubbles: true
16
29
  }));
17
30
  this.element.remove();
@@ -19,9 +32,81 @@ class Tag {
19
32
  this.closeBtn.addEventListener('click', closeHandler);
20
33
  this._listeners.push({ el: this.closeBtn, event: 'click', handler: closeHandler });
21
34
  }
35
+
36
+ if (this.checkable) {
37
+ const clickHandler = (e) => {
38
+ if (e.target !== this.checkbox && e.target !== this.closeBtn) {
39
+ this.toggleChecked();
40
+ }
41
+ };
42
+ this.element.addEventListener('click', clickHandler);
43
+ this._listeners.push({ el: this.element, event: 'click', handler: clickHandler });
44
+
45
+ if (this.checkbox) {
46
+ const checkboxHandler = () => {
47
+ this.toggleChecked();
48
+ };
49
+ this.checkbox.addEventListener('change', checkboxHandler);
50
+ this._listeners.push({ el: this.checkbox, event: 'change', handler: checkboxHandler });
51
+ }
52
+ }
53
+
54
+ if (this.editable) {
55
+ const dblclickHandler = () => {
56
+ this.startEdit();
57
+ };
58
+ this.element.addEventListener('dblclick', dblclickHandler);
59
+ this._listeners.push({ el: this.element, event: 'dblclick', handler: dblclickHandler });
60
+
61
+ if (this.editInput) {
62
+ const blurHandler = () => {
63
+ this.endEdit();
64
+ };
65
+ const keydownHandler = (e) => {
66
+ if (e.key === 'Enter') {
67
+ this.endEdit();
68
+ } else if (e.key === 'Escape') {
69
+ this.cancelEdit();
70
+ }
71
+ };
72
+ this.editInput.addEventListener('blur', blurHandler);
73
+ this.editInput.addEventListener('keydown', keydownHandler);
74
+ this._listeners.push({ el: this.editInput, event: 'blur', handler: blurHandler });
75
+ this._listeners.push({ el: this.editInput, event: 'keydown', handler: keydownHandler });
76
+ }
77
+ }
78
+ }
79
+
80
+ _applyStyles() {
81
+ const colorClasses = ['ds-tag--default', 'ds-tag--primary', 'ds-tag--success', 'ds-tag--warning', 'ds-tag--danger', 'ds-tag--info'];
82
+ const sizeClasses = ['ds-tag--default', 'ds-tag--small', 'ds-tag--large'];
83
+
84
+ colorClasses.forEach(cls => this.element.classList.remove(cls));
85
+ sizeClasses.forEach(cls => this.element.classList.remove(cls));
86
+
87
+ if (colorClasses.includes(`ds-tag--${this.color}`)) {
88
+ this.element.classList.add(`ds-tag--${this.color}`);
89
+ }
90
+ if (sizeClasses.includes(`ds-tag--${this.size}`)) {
91
+ this.element.classList.add(`ds-tag--${this.size}`);
92
+ }
93
+
94
+ if (this.checkable) {
95
+ this.element.classList.add('ds-tag--checkable');
96
+ }
97
+ if (this.checked) {
98
+ this.element.classList.add('is-checked');
99
+ }
100
+ if (this.editable) {
101
+ this.element.classList.add('ds-tag--editable');
102
+ }
22
103
  }
23
104
 
24
105
  setContent(content) {
106
+ if (this.editable && this.editInput) {
107
+ this.editInput.value = content;
108
+ }
109
+
25
110
  const textNodes = [];
26
111
  this.element.childNodes.forEach(node => {
27
112
  if (node.nodeType === Node.TEXT_NODE) {
@@ -29,27 +114,195 @@ class Tag {
29
114
  }
30
115
  });
31
116
  textNodes.forEach(node => node.remove());
32
- this.element.insertBefore(document.createTextNode(content), this.closeBtn || null);
117
+
118
+ const closeBtn = this.element.querySelector('.ds-tag__close');
119
+ const checkbox = this.element.querySelector('.ds-tag__checkbox');
120
+ const input = this.element.querySelector('.ds-tag__input');
121
+
122
+ const insertBeforeEl = closeBtn || checkbox || input || null;
123
+ this.element.insertBefore(document.createTextNode(content), insertBeforeEl);
124
+
125
+ this.element.dispatchEvent(new CustomEvent('kupola:tag-change', {
126
+ detail: { tag: this.element, content },
127
+ bubbles: true
128
+ }));
33
129
  }
34
130
 
35
131
  getContent() {
132
+ if (this.editable && this.editInput && this.element.classList.contains('is-editing')) {
133
+ return this.editInput.value;
134
+ }
36
135
  return this.element.textContent.trim();
37
136
  }
38
137
 
138
+ setColor(color) {
139
+ const validColors = ['default', 'primary', 'success', 'warning', 'danger', 'info'];
140
+ if (validColors.includes(color)) {
141
+ this.color = color;
142
+ this.element.setAttribute('data-tag-color', color);
143
+ this._applyStyles();
144
+ }
145
+ }
146
+
147
+ getColor() {
148
+ return this.color;
149
+ }
150
+
151
+ setSize(size) {
152
+ const validSizes = ['default', 'small', 'large'];
153
+ if (validSizes.includes(size)) {
154
+ this.size = size;
155
+ this.element.setAttribute('data-tag-size', size);
156
+ this._applyStyles();
157
+ }
158
+ }
159
+
160
+ getSize() {
161
+ return this.size;
162
+ }
163
+
164
+ toggleChecked() {
165
+ this.checked = !this.checked;
166
+ this.element.setAttribute('data-tag-checked', this.checked ? 'true' : 'false');
167
+ this._applyStyles();
168
+
169
+ if (this.checkbox) {
170
+ this.checkbox.checked = this.checked;
171
+ }
172
+
173
+ this.element.dispatchEvent(new CustomEvent('kupola:tag-check', {
174
+ detail: { tag: this.element, checked: this.checked, content: this.getContent() },
175
+ bubbles: true
176
+ }));
177
+ }
178
+
179
+ setChecked(checked) {
180
+ this.checked = checked;
181
+ this.element.setAttribute('data-tag-checked', checked ? 'true' : 'false');
182
+ this._applyStyles();
183
+
184
+ if (this.checkbox) {
185
+ this.checkbox.checked = checked;
186
+ }
187
+ }
188
+
189
+ isChecked() {
190
+ return this.checked;
191
+ }
192
+
193
+ startEdit() {
194
+ if (!this.editable) return;
195
+
196
+ const content = this.getContent();
197
+
198
+ if (!this.editInput) {
199
+ const input = document.createElement('input');
200
+ input.type = 'text';
201
+ input.className = 'ds-tag__input';
202
+ input.value = content;
203
+ input.maxLength = this.maxLength;
204
+ this.editInput = input;
205
+
206
+ const closeBtn = this.element.querySelector('.ds-tag__close');
207
+ this.element.insertBefore(input, closeBtn);
208
+
209
+ const blurHandler = () => this.endEdit();
210
+ const keydownHandler = (e) => {
211
+ if (e.key === 'Enter') {
212
+ this.endEdit();
213
+ } else if (e.key === 'Escape') {
214
+ this.cancelEdit();
215
+ }
216
+ };
217
+ input.addEventListener('blur', blurHandler);
218
+ input.addEventListener('keydown', keydownHandler);
219
+ this._listeners.push({ el: input, event: 'blur', handler: blurHandler });
220
+ this._listeners.push({ el: input, event: 'keydown', handler: keydownHandler });
221
+ } else {
222
+ this.editInput.value = content;
223
+ }
224
+
225
+ this.element.classList.add('is-editing');
226
+
227
+ setTimeout(() => {
228
+ if (this.editInput) {
229
+ this.editInput.focus();
230
+ this.editInput.select();
231
+ }
232
+ }, 0);
233
+ }
234
+
235
+ endEdit() {
236
+ if (!this.editable || !this.element.classList.contains('is-editing')) return;
237
+
238
+ const newContent = this.editInput.value.trim();
239
+ this.element.classList.remove('is-editing');
240
+
241
+ if (newContent && newContent !== this.getContent()) {
242
+ this.setContent(newContent);
243
+ this.element.dispatchEvent(new CustomEvent('kupola:tag-edit', {
244
+ detail: { tag: this.element, content: newContent },
245
+ bubbles: true
246
+ }));
247
+ }
248
+ }
249
+
250
+ cancelEdit() {
251
+ if (!this.editable || !this.element.classList.contains('is-editing')) return;
252
+
253
+ this.element.classList.remove('is-editing');
254
+ if (this.editInput) {
255
+ this.editInput.value = this.getContent();
256
+ }
257
+ }
258
+
259
+ setEditable(editable) {
260
+ this.editable = editable;
261
+ if (editable) {
262
+ this.element.setAttribute('data-tag-editable', '');
263
+ } else {
264
+ this.element.removeAttribute('data-tag-editable');
265
+ }
266
+ this._applyStyles();
267
+ }
268
+
269
+ isEditable() {
270
+ return this.editable;
271
+ }
272
+
273
+ setCheckable(checkable) {
274
+ if (this.checkable !== checkable) {
275
+ this.destroy();
276
+ this.checkable = checkable;
277
+ if (checkable) {
278
+ this.element.setAttribute('data-tag-checkable', '');
279
+ } else {
280
+ this.element.removeAttribute('data-tag-checkable');
281
+ }
282
+ this.init();
283
+ }
284
+ }
285
+
286
+ isCheckable() {
287
+ return this.checkable;
288
+ }
289
+
39
290
  destroy() {
40
291
  this._listeners.forEach(({ el, event, handler }) => {
41
292
  el.removeEventListener(event, handler);
42
293
  });
43
- this._listeners = null;
294
+ this._listeners = [];
44
295
  this.closeBtn = null;
296
+ this.checkbox = null;
297
+ this.editInput = null;
45
298
  this.element = null;
46
299
  }
47
300
  }
48
301
 
49
- function initTag(element) {
302
+ function initTag(element, options) {
50
303
  if (element.__kupolaInitialized) return;
51
304
 
52
- const instance = new Tag(element);
305
+ const instance = new Tag(element, options);
53
306
  element.__kupolaInstance = instance;
54
307
  element.__kupolaInitialized = true;
55
308
  }
@@ -70,14 +323,15 @@ function initTags() {
70
323
  });
71
324
  }
72
325
 
73
- if (typeof module !== 'undefined' && module.exports) {
74
- module.exports = { Tag, initTags, initTag, cleanupTag };
75
- } else {
326
+ export { Tag, initTags, initTag, cleanupTag };
327
+
328
+ if (typeof window !== 'undefined') {
76
329
  window.Tag = Tag;
77
330
  window.initTag = initTag;
78
331
  window.cleanupTag = cleanupTag;
79
- }
80
-
81
- if (window.kupolaInitializer) {
82
- window.kupolaInitializer.register('tag', initTag, cleanupTag);
332
+ window.initTags = initTags;
333
+
334
+ if (window.kupolaInitializer) {
335
+ window.kupolaInitializer.register('tag', initTag, cleanupTag);
336
+ }
83
337
  }
package/js/theme.js CHANGED
@@ -316,48 +316,19 @@ function createBrandPicker() {
316
316
  return { toggleBtn, container };
317
317
  }
318
318
 
319
- function loadDevTools() {
320
- const urlParams = new URLSearchParams(window.location.search);
321
- const enabled = urlParams.has('dev') || urlParams.has('debug');
322
-
323
- if (!enabled) return;
324
-
325
- const themeScript = document.querySelector('script[src*="theme.js"]');
326
- if (!themeScript || !themeScript.src) return;
327
-
328
- const scriptPath = themeScript.src.substring(0, themeScript.src.lastIndexOf('/') + 1);
329
-
330
- const devToolsScript = document.createElement('script');
331
- devToolsScript.src = scriptPath + 'kupola-devtools.js?v=15';
332
- devToolsScript.async = true;
333
-
334
- document.head.appendChild(devToolsScript);
335
- }
319
+ export {
320
+ getTheme, setTheme, initTheme, createThemeToggle,
321
+ getBrand, setBrand, BRAND_OPTIONS, createBrandPicker,
322
+ THEME_KEY, BRAND_KEY
323
+ };
336
324
 
337
- if (typeof module !== 'undefined' && module.exports) {
338
- module.exports = {
339
- getTheme, setTheme, initTheme, createThemeToggle,
340
- getBrand, setBrand, BRAND_OPTIONS, createBrandPicker,
341
- loadDevTools
342
- };
343
- } else {
344
- if (!window.__kupolaThemeInitialized) {
345
- window.__kupolaThemeInitialized = true;
346
-
347
- function runInit() {
348
- initTheme();
349
- loadDevTools();
350
- }
351
-
352
- if (document.readyState === 'loading') {
353
- document.addEventListener('readystatechange', function readyStateHandler() {
354
- if (document.readyState !== 'loading') {
355
- document.removeEventListener('readystatechange', readyStateHandler);
356
- runInit();
357
- }
358
- });
359
- } else {
360
- setTimeout(runInit, 0);
361
- }
362
- }
325
+ if (typeof window !== 'undefined') {
326
+ window.getTheme = getTheme;
327
+ window.setTheme = setTheme;
328
+ window.initTheme = initTheme;
329
+ window.createThemeToggle = createThemeToggle;
330
+ window.getBrand = getBrand;
331
+ window.setBrand = setBrand;
332
+ window.BRAND_OPTIONS = BRAND_OPTIONS;
333
+ window.createBrandPicker = createBrandPicker;
363
334
  }