@kupola/kupola 1.2.0 → 1.4.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.
Files changed (111) 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/css/components-ext.css +157 -0
  8. package/css/components.css +69 -0
  9. package/css/theme-dark.css +5 -5
  10. package/css/utilities.css +119 -1
  11. package/dist/css/accessibility.css +119 -0
  12. package/dist/css/animations.css +224 -0
  13. package/dist/css/brand-themes.css +300 -0
  14. package/dist/css/colors_and_type.css +441 -0
  15. package/dist/css/components-ext.css +4165 -0
  16. package/dist/css/components.css +1483 -0
  17. package/dist/css/kupola.css +1 -12
  18. package/dist/css/kupola.min.css +1 -0
  19. package/dist/css/responsive.css +697 -0
  20. package/dist/css/scaffold.css +145 -0
  21. package/dist/css/states.css +316 -0
  22. package/dist/css/theme-dark.css +296 -0
  23. package/dist/css/theme-light.css +296 -0
  24. package/dist/css/utilities.css +171 -0
  25. package/dist/icons.svg +284 -0
  26. package/dist/kupola.cjs.js +17409 -257
  27. package/dist/kupola.cjs.js.map +1 -1
  28. package/dist/kupola.css +9000 -0
  29. package/dist/kupola.esm.js +17183 -7597
  30. package/dist/kupola.esm.js.map +1 -1
  31. package/dist/kupola.min.css +1 -0
  32. package/dist/kupola.min.js +2 -0
  33. package/dist/kupola.min.js.map +1 -0
  34. package/dist/kupola.umd.js +17415 -257
  35. package/dist/kupola.umd.js.map +1 -1
  36. package/dist/plugins/vite-plugin-kupola.js +120 -0
  37. package/dist/types/kupola.d.ts +421 -323
  38. package/js/calendar.js +334 -25
  39. package/js/carousel.js +182 -48
  40. package/js/collapse.js +148 -34
  41. package/js/color-picker.js +416 -108
  42. package/js/component.js +8 -19
  43. package/js/countdown.js +9 -8
  44. package/js/data-bind.js +73 -16
  45. package/js/datepicker.js +488 -110
  46. package/js/depends.js +710 -0
  47. package/js/dialog.js +4 -2
  48. package/js/drawer.js +172 -8
  49. package/js/dropdown.js +272 -17
  50. package/js/dynamic-tags.js +156 -40
  51. package/js/fileupload.js +9 -8
  52. package/js/form.js +280 -254
  53. package/js/global-events.js +281 -188
  54. package/js/heatmap.js +10 -7
  55. package/js/i18n.js +18 -10
  56. package/js/icons.js +141 -161
  57. package/js/image-preview.js +146 -2
  58. package/js/initializer.js +151 -71
  59. package/js/kupola-core.js +123 -45
  60. package/js/kupola-lifecycle.js +13 -11
  61. package/js/message.js +8 -1
  62. package/js/modal.js +207 -59
  63. package/js/notification.js +8 -1
  64. package/js/numberinput.js +9 -8
  65. package/js/pagination.js +263 -0
  66. package/js/registry.js +29 -12
  67. package/js/select.js +482 -27
  68. package/js/slide-captcha.js +11 -2
  69. package/js/slider.js +442 -25
  70. package/js/statcard.js +9 -7
  71. package/js/table.js +1210 -0
  72. package/js/tag.js +268 -14
  73. package/js/theme-standalone.js +88 -0
  74. package/js/theme.js +14 -43
  75. package/js/timepicker.js +335 -66
  76. package/js/tooltip.js +317 -86
  77. package/js/utils.js +6 -2
  78. package/js/validation.js +6 -2
  79. package/js/virtual-list.js +11 -7
  80. package/js/web-components.js +288 -0
  81. package/package.json +81 -67
  82. package/plugins/vite-plugin-kupola.js +120 -0
  83. package/scripts/build-css.cjs +113 -0
  84. package/scripts/build-svg-sprite.cjs +107 -0
  85. package/types/kupola.d.ts +421 -323
  86. package/CHANGELOG.md +0 -130
  87. package/INTEGRATION.md +0 -440
  88. package/PROJECT_SUMMARY.md +0 -312
  89. package/SKILL.md +0 -572
  90. package/dist/utils/utils/Kupola.cs +0 -77
  91. package/dist/utils/utils/Kupola.java +0 -104
  92. package/dist/utils/utils/kupola.go +0 -120
  93. package/dist/utils/utils/kupola.js +0 -63
  94. package/dist/utils/utils/kupola.py +0 -1392
  95. package/dist/utils/utils/kupola.rb +0 -69
  96. package/js/composition-api.js +0 -458
  97. package/js/error-handler.js +0 -181
  98. package/js/http.js +0 -419
  99. package/js/kupola-devtools.js +0 -598
  100. package/js/performance.js +0 -250
  101. package/js/router.js +0 -396
  102. package/js/security.js +0 -189
  103. package/js/test-utils.js +0 -251
  104. package/templates/base.html +0 -30
  105. package/templates/base_dashboard.html +0 -99
  106. package/utils/Kupola.cs +0 -77
  107. package/utils/Kupola.java +0 -104
  108. package/utils/kupola.go +0 -120
  109. package/utils/kupola.js +0 -63
  110. package/utils/kupola.py +0 -1392
  111. package/utils/kupola.rb +0 -69
@@ -1,8 +1,13 @@
1
1
  class DynamicTags {
2
- constructor(element) {
2
+ constructor(element, options = {}) {
3
3
  this.element = element;
4
4
  this.input = element.querySelector('.ds-dynamic-tags__input');
5
5
  this._listeners = [];
6
+
7
+ this.maxCount = options.maxCount || parseInt(element.getAttribute('data-dynamic-tags-max')) || Infinity;
8
+ this.allowDuplicates = options.allowDuplicates !== false;
9
+ this.color = options.color || element.getAttribute('data-dynamic-tags-color') || 'default';
10
+
6
11
  this.init();
7
12
  }
8
13
 
@@ -11,17 +16,17 @@ class DynamicTags {
11
16
  }
12
17
 
13
18
  bindEvents() {
14
- this.element.querySelectorAll('.ds-dynamic-tags__remove').forEach(removeBtn => {
15
- const removeHandler = (e) => {
16
- e.stopPropagation();
17
- const tag = removeBtn.closest('.ds-dynamic-tags__tag');
18
- if (tag) {
19
+ this.element.querySelectorAll('.ds-dynamic-tags__tag').forEach(tag => {
20
+ const removeBtn = tag.querySelector('.ds-dynamic-tags__remove');
21
+ if (removeBtn) {
22
+ const removeHandler = (e) => {
23
+ e.stopPropagation();
19
24
  tag.remove();
20
25
  this.dispatchChange();
21
- }
22
- };
23
- removeBtn.addEventListener('click', removeHandler);
24
- this._listeners.push({ el: removeBtn, event: 'click', handler: removeHandler });
26
+ };
27
+ removeBtn.addEventListener('click', removeHandler);
28
+ this._listeners.push({ el: removeBtn, event: 'click', handler: removeHandler });
29
+ }
25
30
  });
26
31
 
27
32
  if (this.input) {
@@ -29,23 +34,20 @@ class DynamicTags {
29
34
  const value = this.input.value.trim();
30
35
  if (!value) return;
31
36
 
32
- const tag = document.createElement('span');
33
- tag.className = 'ds-dynamic-tags__tag';
34
- const textNode = document.createTextNode(value);
35
- tag.appendChild(textNode);
36
- const removeBtn = document.createElement('button');
37
- removeBtn.className = 'ds-dynamic-tags__remove';
38
- removeBtn.innerHTML = '<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>';
39
- tag.appendChild(removeBtn);
37
+ if (!this.allowDuplicates && this.hasTag(value)) {
38
+ this.input.value = '';
39
+ return;
40
+ }
40
41
 
41
- const tagRemoveHandler = (e) => {
42
- e.stopPropagation();
43
- tag.remove();
44
- this.dispatchChange();
45
- };
46
- removeBtn.addEventListener('click', tagRemoveHandler);
47
- this._listeners.push({ el: removeBtn, event: 'click', handler: tagRemoveHandler });
42
+ if (this.getTags().length >= this.maxCount) {
43
+ this.input.value = '';
44
+ this.element.dispatchEvent(new CustomEvent('kupola:dynamic-tags-max', {
45
+ detail: { maxCount: this.maxCount }
46
+ }));
47
+ return;
48
+ }
48
49
 
50
+ const tag = this.createTag(value);
49
51
  this.element.insertBefore(tag, this.input);
50
52
  this.input.value = '';
51
53
  this.input.focus();
@@ -70,10 +72,61 @@ class DynamicTags {
70
72
  }
71
73
  }
72
74
 
73
- addTag(value) {
75
+ createTag(value) {
76
+ const tag = document.createElement('span');
77
+ tag.className = `ds-dynamic-tags__tag ds-dynamic-tags__tag--${this.color}`;
78
+ const textNode = document.createTextNode(value);
79
+ tag.appendChild(textNode);
80
+ const removeBtn = document.createElement('button');
81
+ removeBtn.className = 'ds-dynamic-tags__remove';
82
+ removeBtn.innerHTML = '<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>';
83
+ tag.appendChild(removeBtn);
84
+
85
+ const tagRemoveHandler = (e) => {
86
+ e.stopPropagation();
87
+ tag.remove();
88
+ this.dispatchChange();
89
+ };
90
+ removeBtn.addEventListener('click', tagRemoveHandler);
91
+ this._listeners.push({ el: removeBtn, event: 'click', handler: tagRemoveHandler });
92
+
93
+ return tag;
94
+ }
95
+
96
+ hasTag(value) {
97
+ const tags = this.element.querySelectorAll('.ds-dynamic-tags__tag');
98
+ for (const tag of tags) {
99
+ if (tag.textContent.trim() === value) {
100
+ return true;
101
+ }
102
+ }
103
+ return false;
104
+ }
105
+
106
+ addTag(value, color) {
74
107
  if (!value || !this.input) return;
75
- this.input.value = value;
76
- this.input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
108
+
109
+ if (!this.allowDuplicates && this.hasTag(value)) {
110
+ return;
111
+ }
112
+
113
+ if (this.getTags().length >= this.maxCount) {
114
+ this.element.dispatchEvent(new CustomEvent('kupola:dynamic-tags-max', {
115
+ detail: { maxCount: this.maxCount }
116
+ }));
117
+ return;
118
+ }
119
+
120
+ const tag = this.createTag(value);
121
+ if (color) {
122
+ const colorClasses = ['ds-dynamic-tags__tag--default', 'ds-dynamic-tags__tag--primary', 'ds-dynamic-tags__tag--success', 'ds-dynamic-tags__tag--warning', 'ds-dynamic-tags__tag--danger', 'ds-dynamic-tags__tag--info'];
123
+ colorClasses.forEach(cls => tag.classList.remove(cls));
124
+ if (colorClasses.includes(`ds-dynamic-tags__tag--${color}`)) {
125
+ tag.classList.add(`ds-dynamic-tags__tag--${color}`);
126
+ }
127
+ }
128
+ this.element.insertBefore(tag, this.input);
129
+ this.dispatchChange();
77
130
  }
78
131
 
79
132
  removeTag(index) {
@@ -85,10 +138,30 @@ class DynamicTags {
85
138
  }
86
139
  }
87
140
 
141
+ removeTagByValue(value) {
142
+ const tags = this.element.querySelectorAll('.ds-dynamic-tags__tag');
143
+ for (const tag of tags) {
144
+ if (tag.textContent.trim() === value) {
145
+ tag.remove();
146
+ this.dispatchChange();
147
+ return;
148
+ }
149
+ }
150
+ }
151
+
88
152
  getTags() {
89
153
  const tags = [];
90
154
  this.element.querySelectorAll('.ds-dynamic-tags__tag').forEach(tag => {
91
- tags.push(tag.textContent);
155
+ tags.push(tag.textContent.trim());
156
+ });
157
+ return tags;
158
+ }
159
+
160
+ getTagsWithColor() {
161
+ const tags = [];
162
+ this.element.querySelectorAll('.ds-dynamic-tags__tag').forEach(tag => {
163
+ const color = Array.from(tag.classList).find(cls => cls.startsWith('ds-dynamic-tags__tag--'))?.replace('ds-dynamic-tags__tag--', '') || 'default';
164
+ tags.push({ value: tag.textContent.trim(), color });
92
165
  });
93
166
  return tags;
94
167
  }
@@ -100,11 +173,53 @@ class DynamicTags {
100
173
  this.dispatchChange();
101
174
  }
102
175
 
176
+ setTags(tags) {
177
+ this.clearTags();
178
+ tags.forEach(tag => {
179
+ if (typeof tag === 'string') {
180
+ this.addTag(tag);
181
+ } else if (tag && typeof tag === 'object' && tag.value) {
182
+ this.addTag(tag.value, tag.color);
183
+ }
184
+ });
185
+ }
186
+
187
+ setMaxCount(max) {
188
+ this.maxCount = max;
189
+ this.element.setAttribute('data-dynamic-tags-max', max);
190
+ }
191
+
192
+ getMaxCount() {
193
+ return this.maxCount;
194
+ }
195
+
196
+ setAllowDuplicates(allow) {
197
+ this.allowDuplicates = allow;
198
+ }
199
+
200
+ isAllowDuplicates() {
201
+ return this.allowDuplicates;
202
+ }
203
+
204
+ setColor(color) {
205
+ const validColors = ['default', 'primary', 'success', 'warning', 'danger', 'info'];
206
+ if (validColors.includes(color)) {
207
+ this.color = color;
208
+ this.element.setAttribute('data-dynamic-tags-color', color);
209
+ }
210
+ }
211
+
212
+ getColor() {
213
+ return this.color;
214
+ }
215
+
103
216
  dispatchChange() {
104
- this.element.dispatchEvent(new CustomEvent('ds-dynamic-tags-change', {
217
+ this.element.dispatchEvent(new CustomEvent('kupola:dynamic-tags-change', {
105
218
  detail: {
106
219
  tags: this.getTags(),
107
- count: this.getTags().length
220
+ tagsWithColor: this.getTagsWithColor(),
221
+ count: this.getTags().length,
222
+ maxCount: this.maxCount
108
223
  }
109
224
  }));
110
225
  }
@@ -119,10 +234,10 @@ class DynamicTags {
119
234
  }
120
235
  }
121
236
 
122
- function initDynamicTags(element) {
237
+ function initDynamicTags(element, options) {
123
238
  if (element.__kupolaInitialized) return;
124
239
 
125
- const instance = new DynamicTags(element);
240
+ const instance = new DynamicTags(element, options);
126
241
  element.__kupolaInstance = instance;
127
242
  element.__kupolaInitialized = true;
128
243
  }
@@ -143,14 +258,15 @@ function initDynamicTagsAll() {
143
258
  });
144
259
  }
145
260
 
146
- if (typeof module !== 'undefined' && module.exports) {
147
- module.exports = { DynamicTags, initDynamicTagsAll, initDynamicTags, cleanupDynamicTags };
148
- } else {
261
+ export { DynamicTags, initDynamicTagsAll, initDynamicTags, cleanupDynamicTags };
262
+
263
+ if (typeof window !== 'undefined') {
149
264
  window.DynamicTags = DynamicTags;
150
265
  window.initDynamicTags = initDynamicTags;
151
266
  window.cleanupDynamicTags = cleanupDynamicTags;
152
- }
153
-
154
- if (window.kupolaInitializer) {
155
- window.kupolaInitializer.register('dynamic-tags', initDynamicTags, cleanupDynamicTags);
267
+ window.initDynamicTagsAll = initDynamicTagsAll;
268
+
269
+ if (window.kupolaInitializer) {
270
+ window.kupolaInitializer.register('dynamic-tags', initDynamicTags, cleanupDynamicTags);
271
+ }
156
272
  }
package/js/fileupload.js CHANGED
@@ -332,7 +332,7 @@ class FileUpload {
332
332
  }
333
333
 
334
334
  dispatchChange() {
335
- this.element.dispatchEvent(new CustomEvent('ds-fileupload-change', {
335
+ this.element.dispatchEvent(new CustomEvent('kupola:fileupload-change', {
336
336
  detail: {
337
337
  files: this.getFiles(),
338
338
  count: this.files.length
@@ -379,14 +379,15 @@ function initFileUploads() {
379
379
  });
380
380
  }
381
381
 
382
- if (typeof module !== 'undefined' && module.exports) {
383
- module.exports = { FileUpload, initFileUploads, initFileUpload, cleanupFileUpload };
384
- } else {
382
+ export { FileUpload, initFileUploads, initFileUpload, cleanupFileUpload };
383
+
384
+ if (typeof window !== 'undefined') {
385
385
  window.FileUpload = FileUpload;
386
386
  window.initFileUpload = initFileUpload;
387
387
  window.cleanupFileUpload = cleanupFileUpload;
388
- }
389
-
390
- if (window.kupolaInitializer) {
391
- window.kupolaInitializer.register('fileupload', initFileUpload, cleanupFileUpload);
388
+ window.initFileUploads = initFileUploads;
389
+
390
+ if (window.kupolaInitializer) {
391
+ window.kupolaInitializer.register('fileupload', initFileUpload, cleanupFileUpload);
392
+ }
392
393
  }