js-kompo-utils 1.0.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 (67) hide show
  1. package/README.md +1 -0
  2. package/app.js +22 -0
  3. package/components/VlApexChart.vue +89 -0
  4. package/components/VlCKEditorTemplate.vue +52 -0
  5. package/components/VlCKEditorWithVars.vue +80 -0
  6. package/components/VlCollapsible.vue +91 -0
  7. package/components/VlCopyBox.vue +61 -0
  8. package/components/VlCreditCardInput.vue +104 -0
  9. package/components/VlDateMonthDay.vue +327 -0
  10. package/components/VlDateTextInput.vue +151 -0
  11. package/components/VlInternationalPhoneInput.vue +902 -0
  12. package/components/VlPartialDate.vue +283 -0
  13. package/components/VlPasswordInput.vue +358 -0
  14. package/components/VlQrCodeScanner.vue +91 -0
  15. package/components/VlSwipeableTab.vue +35 -0
  16. package/components/VlSwipeableTabs.vue +325 -0
  17. package/components/VlText.vue +72 -0
  18. package/components/VlTutorialStepBuilder.vue +671 -0
  19. package/components/VlValidatedInput.vue +262 -0
  20. package/components/data/countries.js +253 -0
  21. package/components/getAllDefaultComponents.js +12 -0
  22. package/docs/architecture.md +71 -0
  23. package/docs/tutorials.md +247 -0
  24. package/docs/usage.md +128 -0
  25. package/functions/index.js +7 -0
  26. package/functions/inputs.js +64 -0
  27. package/functions/loading.js +20 -0
  28. package/kompo-ckeditor-1.0.17/index.js +5 -0
  29. package/kompo-ckeditor-1.0.17/komponents/CKEditor.vue +36 -0
  30. package/kompo-ckeditor-1.0.17/komponents/CKEditorExtended.vue +66 -0
  31. package/kompo-ckeditor-1.0.17/komponents/EditableCKEditor.vue +42 -0
  32. package/kompo-ckeditor-1.0.17/komponents/TranslatableEditor.vue +28 -0
  33. package/kompo-ckeditor-1.0.17/mixins/CKEditor.js +291 -0
  34. package/kompo-ckeditor-1.0.17/mixins/CKEditorUtilities.js +52 -0
  35. package/kompo-ckeditor-1.0.17/mixins/CkUploadAdapter.js +95 -0
  36. package/kompo-ckeditor-1.0.17/mixins/translations/en.js +1 -0
  37. package/kompo-ckeditor-1.0.17/mixins/translations/fr.js +1 -0
  38. package/kompo-ckeditor-1.0.17/plugins/JsonBlockCommand.js +100 -0
  39. package/kompo-ckeditor-1.0.17/plugins/JsonBlockEditing.js +225 -0
  40. package/kompo-ckeditor-1.0.17/plugins/JsonBlockUi.js +21 -0
  41. package/kompo-ckeditor-1.0.17/plugins/MentionPlugin.js +118 -0
  42. package/orchestrator/KompoJsBuilder.js +333 -0
  43. package/package.json +25 -0
  44. package/raw_animations/count-up-animation.js +220 -0
  45. package/raw_animations/magic-poof.js +210 -0
  46. package/tutorials/TutorialConfig.js +34 -0
  47. package/tutorials/TutorialEngine.js +448 -0
  48. package/tutorials/index.js +2 -0
  49. package/tutorials/modules/AutoNext.js +86 -0
  50. package/tutorials/modules/Avatar.js +94 -0
  51. package/tutorials/modules/Bubble.js +617 -0
  52. package/tutorials/modules/Cursor.js +315 -0
  53. package/tutorials/modules/Highlight.js +282 -0
  54. package/tutorials/modules/HoverForcer.js +250 -0
  55. package/tutorials/modules/Mobile.js +148 -0
  56. package/tutorials/modules/Options.js +98 -0
  57. package/tutorials/modules/Overlay.js +142 -0
  58. package/tutorials/modules/Scroll.js +37 -0
  59. package/tutorials/modules/Typewriter.js +132 -0
  60. package/tutorials/step-builder/step-builder-bridge.js +436 -0
  61. package/tutorials/step-builder/utils/bezier-editor.js +379 -0
  62. package/tutorials/step-builder/utils/code-generator.js +127 -0
  63. package/tutorials/step-builder/utils/element-picker.js +125 -0
  64. package/tutorials/tutorial.scss +816 -0
  65. package/tutorials/utils/selectors.js +225 -0
  66. package/tutorials/utils/stability.js +76 -0
  67. package/tutorials/utils/svg.js +46 -0
@@ -0,0 +1,262 @@
1
+ <template>
2
+ <vl-form-field v-bind="$_wrapperAttributes">
3
+ <div :class="'vlInputGroup rounded-lg ' + (showError ? invalidClass : '')">
4
+ <input :value="visualValue" class="vlFormControl" v-bind="$_attributes" v-on="$_events"
5
+ @input="onInputValue" @focus="onFocus" @blur="focused = false" ref="input" />
6
+ <div class="justify-center flex items-center px-4" v-if="showError">
7
+ <span class="invalid-icon">!</span>
8
+ </div>
9
+ </div>
10
+ </vl-form-field>
11
+ </template>
12
+
13
+ <script>
14
+ import Field from 'vue-kompo/js/form/mixins/Field'
15
+ import HasInputAttributes from 'vue-kompo/js/form/mixins/HasInputAttributes'
16
+
17
+ export default {
18
+ mixins: [Field, HasInputAttributes],
19
+ data() {
20
+ return {
21
+ rawValue: this.component?.value || '',
22
+ pastValue: this.component?.value || '',
23
+ focused: false,
24
+ dirty: false
25
+ }
26
+ },
27
+ watch: {
28
+ 'component.value'(value) {
29
+ this.rawValue = value ?? '';
30
+ this.pastValue = value ?? '';
31
+ }
32
+ },
33
+ computed: {
34
+ visualValue() {
35
+ return this.formatToModel(this.rawValue)
36
+ },
37
+ $_attributes() {
38
+ return {
39
+ ...this.$_defaultFieldAttributes,
40
+ ...this.$_defaultInputAttributes
41
+ }
42
+ },
43
+ focusOnLoad() { return this.$_config('focusOnLoad') },
44
+ invalidClass() { return this.$_config('invalidClass') },
45
+ formatModels() { return this.$_config('formatModels') },
46
+ validateFormat() { return this.$_config('validateFormat') },
47
+ allowFormat() { return this.$_config('allowFormat') },
48
+ keepFormat() { return this.$_config('keepFormat') },
49
+ showError() {
50
+ return !this.isValidValue && !this.focused && this.dirty;
51
+ },
52
+ isValidValue() {
53
+ const valueToValidate = this.keepFormat
54
+ ? (this.component?.value || '')
55
+ : this.formatToModel(this.component?.value || '');
56
+ return (new RegExp(this.validateFormat)).test(valueToValidate);
57
+ }
58
+ },
59
+ methods: {
60
+ onInputValue(e) {
61
+ const input = e.target;
62
+ const oldFormatted = this.visualValue;
63
+ const newFormatted = input.value;
64
+ const oldRaw = this.rawValue;
65
+ const cursorPos = input.selectionStart;
66
+ const selectionEnd = input.selectionEnd;
67
+
68
+ // Detect operation type
69
+ const operation = this.detectOperation(oldFormatted, newFormatted, cursorPos, selectionEnd);
70
+
71
+ // Extract raw value considering the operation
72
+ const extractionResult = this.extractRawValue(newFormatted, oldFormatted, oldRaw, operation);
73
+
74
+ if (!extractionResult.valid) {
75
+ // Restore previous state
76
+ this.$nextTick(() => {
77
+ input.value = oldFormatted;
78
+ input.setSelectionRange(operation.originalCursor, operation.originalCursor);
79
+ });
80
+ return;
81
+ }
82
+
83
+ // Update raw value
84
+ this.rawValue = extractionResult.raw;
85
+ this.component.value = this.keepFormat
86
+ ? this.formatToModel(extractionResult.raw)
87
+ : extractionResult.raw;
88
+
89
+ // Calculate new cursor position
90
+ this.$nextTick(() => {
91
+ const formattedValue = this.formatToModel(extractionResult.raw);
92
+ const newCursorPos = this.calculateNewCursorPosition(
93
+ operation,
94
+ extractionResult.raw,
95
+ formattedValue,
96
+ extractionResult.rawCursorPos
97
+ );
98
+
99
+ input.value = formattedValue;
100
+ input.setSelectionRange(newCursorPos, newCursorPos);
101
+ });
102
+ },
103
+
104
+ detectOperation(oldFormatted, newFormatted, cursorPos, selectionEnd) {
105
+ const lengthDiff = newFormatted.length - oldFormatted.length;
106
+ const hasSelection = selectionEnd > cursorPos;
107
+
108
+ return {
109
+ type: lengthDiff > 0 ? 'insert' : lengthDiff < 0 ? 'delete' : 'replace',
110
+ lengthDiff,
111
+ cursorPos,
112
+ selectionEnd,
113
+ hasSelection,
114
+ originalCursor: cursorPos
115
+ };
116
+ },
117
+
118
+ extractRawValue(newFormatted, oldFormatted, oldRaw, operation) {
119
+ let raw = '';
120
+ let rawCursorPos = 0;
121
+
122
+ // For delete operations, check if we're deleting at a format boundary
123
+ if (operation.type === 'delete' && operation.lengthDiff === -1) {
124
+ // Find what was deleted
125
+ let deletedIndex = -1;
126
+ for (let i = 0; i < oldFormatted.length; i++) {
127
+ if (i >= newFormatted.length || oldFormatted[i] !== newFormatted[i]) {
128
+ deletedIndex = i;
129
+ break;
130
+ }
131
+ }
132
+
133
+ const deletedChar = oldFormatted[deletedIndex];
134
+ const isFormattingChar = !(new RegExp(this.allowFormat)).test(deletedChar);
135
+
136
+ if (isFormattingChar) {
137
+ // A formatting character was deleted
138
+ let rawIndexBeforeDeletion = 0;
139
+ for (let i = 0; i < deletedIndex; i++) {
140
+ if ((new RegExp(this.allowFormat)).test(oldFormatted[i])) {
141
+ rawIndexBeforeDeletion++;
142
+ }
143
+ }
144
+
145
+ raw = oldRaw.slice(0, rawIndexBeforeDeletion - 1) + oldRaw.slice(rawIndexBeforeDeletion);
146
+ rawCursorPos = rawIndexBeforeDeletion - 1;
147
+ } else {
148
+ // Normal character deletion
149
+ // Calculate raw position where deletion occurred
150
+ let rawDeletePos = 0;
151
+ for (let i = 0; i < deletedIndex; i++) {
152
+ if ((new RegExp(this.allowFormat)).test(oldFormatted[i])) {
153
+ rawDeletePos++;
154
+ }
155
+ }
156
+
157
+ // Build new raw by removing character at rawDeletePos
158
+ raw = oldRaw.slice(0, rawDeletePos) + oldRaw.slice(rawDeletePos + 1);
159
+ rawCursorPos = rawDeletePos; // Cursor stays at deletion point
160
+ }
161
+ } else {
162
+ // Insert or replace - normal extraction
163
+ for (let i = 0; i < newFormatted.length; i++) {
164
+ const char = newFormatted[i];
165
+ if ((new RegExp(this.allowFormat)).test(char)) {
166
+ raw += char;
167
+ if (i < operation.cursorPos) {
168
+ rawCursorPos++;
169
+ }
170
+ }
171
+ }
172
+ }
173
+
174
+ const isValid = (new RegExp(this.allowFormat)).test(raw || '');
175
+
176
+ return {
177
+ raw,
178
+ rawCursorPos,
179
+ valid: isValid
180
+ };
181
+ },
182
+
183
+ buildFormattedToRawMapping(formatted, raw) {
184
+ const mapping = [];
185
+ let rawIndex = 0;
186
+
187
+ for (let i = 0; i < formatted.length; i++) {
188
+ const char = formatted[i];
189
+ const isRawChar = (new RegExp(this.allowFormat)).test(char);
190
+
191
+ mapping.push({
192
+ formattedIndex: i,
193
+ rawIndex: isRawChar ? rawIndex++ : -1,
194
+ isRawChar,
195
+ char
196
+ });
197
+ }
198
+
199
+ return mapping;
200
+ },
201
+
202
+ calculateNewCursorPosition(operation, newRaw, newFormatted, rawCursorPos) {
203
+ // Si estamos al final del raw, posicionar al final del formatted
204
+ if (rawCursorPos >= newRaw.length) {
205
+ return newFormatted.length;
206
+ }
207
+
208
+ // Build the mapping for the new formatted string
209
+ const mapping = this.buildFormattedToRawMapping(newFormatted, newRaw);
210
+
211
+ // Find the formatted position that corresponds to our raw cursor position
212
+ let targetRawIndex = rawCursorPos;
213
+ let formattedPos = 0;
214
+
215
+ for (let i = 0; i < mapping.length; i++) {
216
+ const entry = mapping[i];
217
+
218
+ if (entry.isRawChar && entry.rawIndex === targetRawIndex) {
219
+ formattedPos = i;
220
+ break;
221
+ } else if (entry.isRawChar && entry.rawIndex > targetRawIndex) {
222
+ // We've passed our target, position cursor before this character
223
+ formattedPos = i;
224
+ break;
225
+ }
226
+ }
227
+
228
+ // Remove the special handling that was causing issues
229
+ // The cursor position is already correctly calculated above
230
+
231
+ return formattedPos;
232
+ },
233
+ onFocus() {
234
+ this.focused = true;
235
+ this.dirty = true;
236
+ },
237
+ formatToModel(value) {
238
+ if (!value) return '';
239
+
240
+ if (this.formatModels && Object.entries(this.formatModels).length > 0) {
241
+ Object.entries(this.formatModels).forEach(([from, to]) => {
242
+ value = value.replace(new RegExp(from), to)
243
+ })
244
+ }
245
+ return value;
246
+ }
247
+ },
248
+ mounted() {
249
+ if (this.focusOnLoad)
250
+ this.focus()
251
+ },
252
+ }
253
+ </script>
254
+
255
+ <style scoped>
256
+ .invalid-icon {
257
+ color: red;
258
+ font-weight: bold;
259
+ margin-left: 8px;
260
+ cursor: pointer;
261
+ }
262
+ </style>
@@ -0,0 +1,253 @@
1
+ // Static countries data with flags and dial codes
2
+ export const COUNTRIES_DATA = [
3
+ { code: 'AD', name: 'Andorra', dialCode: '376', flag: 'https://flagcdn.com/w20/ad.png' },
4
+ { code: 'AE', name: 'United Arab Emirates', dialCode: '971', flag: 'https://flagcdn.com/w20/ae.png' },
5
+ { code: 'AF', name: 'Afghanistan', dialCode: '93', flag: 'https://flagcdn.com/w20/af.png' },
6
+ { code: 'AG', name: 'Antigua and Barbuda', dialCode: '1268', flag: 'https://flagcdn.com/w20/ag.png' },
7
+ { code: 'AI', name: 'Anguilla', dialCode: '1264', flag: 'https://flagcdn.com/w20/ai.png' },
8
+ { code: 'AL', name: 'Albania', dialCode: '355', flag: 'https://flagcdn.com/w20/al.png' },
9
+ { code: 'AM', name: 'Armenia', dialCode: '374', flag: 'https://flagcdn.com/w20/am.png' },
10
+ { code: 'AO', name: 'Angola', dialCode: '244', flag: 'https://flagcdn.com/w20/ao.png' },
11
+ { code: 'AQ', name: 'Antarctica', dialCode: '672', flag: 'https://flagcdn.com/w20/aq.png' },
12
+ { code: 'AR', name: 'Argentina', dialCode: '54', flag: 'https://flagcdn.com/w20/ar.png' },
13
+ { code: 'AS', name: 'American Samoa', dialCode: '1684', flag: 'https://flagcdn.com/w20/as.png' },
14
+ { code: 'AT', name: 'Austria', dialCode: '43', flag: 'https://flagcdn.com/w20/at.png' },
15
+ { code: 'AU', name: 'Australia', dialCode: '61', flag: 'https://flagcdn.com/w20/au.png' },
16
+ { code: 'AW', name: 'Aruba', dialCode: '297', flag: 'https://flagcdn.com/w20/aw.png' },
17
+ { code: 'AX', name: 'Åland Islands', dialCode: '358', flag: 'https://flagcdn.com/w20/ax.png' },
18
+ { code: 'AZ', name: 'Azerbaijan', dialCode: '994', flag: 'https://flagcdn.com/w20/az.png' },
19
+ { code: 'BA', name: 'Bosnia and Herzegovina', dialCode: '387', flag: 'https://flagcdn.com/w20/ba.png' },
20
+ { code: 'BB', name: 'Barbados', dialCode: '1246', flag: 'https://flagcdn.com/w20/bb.png' },
21
+ { code: 'BD', name: 'Bangladesh', dialCode: '880', flag: 'https://flagcdn.com/w20/bd.png' },
22
+ { code: 'BE', name: 'Belgium', dialCode: '32', flag: 'https://flagcdn.com/w20/be.png' },
23
+ { code: 'BF', name: 'Burkina Faso', dialCode: '226', flag: 'https://flagcdn.com/w20/bf.png' },
24
+ { code: 'BG', name: 'Bulgaria', dialCode: '359', flag: 'https://flagcdn.com/w20/bg.png' },
25
+ { code: 'BH', name: 'Bahrain', dialCode: '973', flag: 'https://flagcdn.com/w20/bh.png' },
26
+ { code: 'BI', name: 'Burundi', dialCode: '257', flag: 'https://flagcdn.com/w20/bi.png' },
27
+ { code: 'BJ', name: 'Benin', dialCode: '229', flag: 'https://flagcdn.com/w20/bj.png' },
28
+ { code: 'BL', name: 'Saint Barthélemy', dialCode: '590', flag: 'https://flagcdn.com/w20/bl.png' },
29
+ { code: 'BM', name: 'Bermuda', dialCode: '1441', flag: 'https://flagcdn.com/w20/bm.png' },
30
+ { code: 'BN', name: 'Brunei', dialCode: '673', flag: 'https://flagcdn.com/w20/bn.png' },
31
+ { code: 'BO', name: 'Bolivia', dialCode: '591', flag: 'https://flagcdn.com/w20/bo.png' },
32
+ { code: 'BQ', name: 'Caribbean Netherlands', dialCode: '599', flag: 'https://flagcdn.com/w20/bq.png' },
33
+ { code: 'BR', name: 'Brazil', dialCode: '55', flag: 'https://flagcdn.com/w20/br.png' },
34
+ { code: 'BS', name: 'Bahamas', dialCode: '1242', flag: 'https://flagcdn.com/w20/bs.png' },
35
+ { code: 'BT', name: 'Bhutan', dialCode: '975', flag: 'https://flagcdn.com/w20/bt.png' },
36
+ { code: 'BV', name: 'Bouvet Island', dialCode: '47', flag: 'https://flagcdn.com/w20/bv.png' },
37
+ { code: 'BW', name: 'Botswana', dialCode: '267', flag: 'https://flagcdn.com/w20/bw.png' },
38
+ { code: 'BY', name: 'Belarus', dialCode: '375', flag: 'https://flagcdn.com/w20/by.png' },
39
+ { code: 'BZ', name: 'Belize', dialCode: '501', flag: 'https://flagcdn.com/w20/bz.png' },
40
+ { code: 'CA', name: 'Canada', dialCode: '1', flag: 'https://flagcdn.com/w20/ca.png' },
41
+ { code: 'CC', name: 'Cocos Islands', dialCode: '61', flag: 'https://flagcdn.com/w20/cc.png' },
42
+ { code: 'CD', name: 'Democratic Republic of the Congo', dialCode: '243', flag: 'https://flagcdn.com/w20/cd.png' },
43
+ { code: 'CF', name: 'Central African Republic', dialCode: '236', flag: 'https://flagcdn.com/w20/cf.png' },
44
+ { code: 'CG', name: 'Republic of the Congo', dialCode: '242', flag: 'https://flagcdn.com/w20/cg.png' },
45
+ { code: 'CH', name: 'Switzerland', dialCode: '41', flag: 'https://flagcdn.com/w20/ch.png' },
46
+ { code: 'CI', name: 'Ivory Coast', dialCode: '225', flag: 'https://flagcdn.com/w20/ci.png' },
47
+ { code: 'CK', name: 'Cook Islands', dialCode: '682', flag: 'https://flagcdn.com/w20/ck.png' },
48
+ { code: 'CL', name: 'Chile', dialCode: '56', flag: 'https://flagcdn.com/w20/cl.png' },
49
+ { code: 'CM', name: 'Cameroon', dialCode: '237', flag: 'https://flagcdn.com/w20/cm.png' },
50
+ { code: 'CN', name: 'China', dialCode: '86', flag: 'https://flagcdn.com/w20/cn.png' },
51
+ { code: 'CO', name: 'Colombia', dialCode: '57', flag: 'https://flagcdn.com/w20/co.png' },
52
+ { code: 'CR', name: 'Costa Rica', dialCode: '506', flag: 'https://flagcdn.com/w20/cr.png' },
53
+ { code: 'CU', name: 'Cuba', dialCode: '53', flag: 'https://flagcdn.com/w20/cu.png' },
54
+ { code: 'CV', name: 'Cape Verde', dialCode: '238', flag: 'https://flagcdn.com/w20/cv.png' },
55
+ { code: 'CW', name: 'Curaçao', dialCode: '599', flag: 'https://flagcdn.com/w20/cw.png' },
56
+ { code: 'CX', name: 'Christmas Island', dialCode: '61', flag: 'https://flagcdn.com/w20/cx.png' },
57
+ { code: 'CY', name: 'Cyprus', dialCode: '357', flag: 'https://flagcdn.com/w20/cy.png' },
58
+ { code: 'CZ', name: 'Czech Republic', dialCode: '420', flag: 'https://flagcdn.com/w20/cz.png' },
59
+ { code: 'DE', name: 'Germany', dialCode: '49', flag: 'https://flagcdn.com/w20/de.png' },
60
+ { code: 'DJ', name: 'Djibouti', dialCode: '253', flag: 'https://flagcdn.com/w20/dj.png' },
61
+ { code: 'DK', name: 'Denmark', dialCode: '45', flag: 'https://flagcdn.com/w20/dk.png' },
62
+ { code: 'DM', name: 'Dominica', dialCode: '1767', flag: 'https://flagcdn.com/w20/dm.png' },
63
+ { code: 'DO', name: 'Dominican Republic', dialCode: '1809', flag: 'https://flagcdn.com/w20/do.png' },
64
+ { code: 'DZ', name: 'Algeria', dialCode: '213', flag: 'https://flagcdn.com/w20/dz.png' },
65
+ { code: 'EC', name: 'Ecuador', dialCode: '593', flag: 'https://flagcdn.com/w20/ec.png' },
66
+ { code: 'EE', name: 'Estonia', dialCode: '372', flag: 'https://flagcdn.com/w20/ee.png' },
67
+ { code: 'EG', name: 'Egypt', dialCode: '20', flag: 'https://flagcdn.com/w20/eg.png' },
68
+ { code: 'EH', name: 'Western Sahara', dialCode: '212', flag: 'https://flagcdn.com/w20/eh.png' },
69
+ { code: 'ER', name: 'Eritrea', dialCode: '291', flag: 'https://flagcdn.com/w20/er.png' },
70
+ { code: 'ES', name: 'Spain', dialCode: '34', flag: 'https://flagcdn.com/w20/es.png' },
71
+ { code: 'ET', name: 'Ethiopia', dialCode: '251', flag: 'https://flagcdn.com/w20/et.png' },
72
+ { code: 'FI', name: 'Finland', dialCode: '358', flag: 'https://flagcdn.com/w20/fi.png' },
73
+ { code: 'FJ', name: 'Fiji', dialCode: '679', flag: 'https://flagcdn.com/w20/fj.png' },
74
+ { code: 'FK', name: 'Falkland Islands', dialCode: '500', flag: 'https://flagcdn.com/w20/fk.png' },
75
+ { code: 'FM', name: 'Micronesia', dialCode: '691', flag: 'https://flagcdn.com/w20/fm.png' },
76
+ { code: 'FO', name: 'Faroe Islands', dialCode: '298', flag: 'https://flagcdn.com/w20/fo.png' },
77
+ { code: 'FR', name: 'France', dialCode: '33', flag: 'https://flagcdn.com/w20/fr.png' },
78
+ { code: 'GA', name: 'Gabon', dialCode: '241', flag: 'https://flagcdn.com/w20/ga.png' },
79
+ { code: 'GB', name: 'United Kingdom', dialCode: '44', flag: 'https://flagcdn.com/w20/gb.png' },
80
+ { code: 'GD', name: 'Grenada', dialCode: '1473', flag: 'https://flagcdn.com/w20/gd.png' },
81
+ { code: 'GE', name: 'Georgia', dialCode: '995', flag: 'https://flagcdn.com/w20/ge.png' },
82
+ { code: 'GF', name: 'French Guiana', dialCode: '594', flag: 'https://flagcdn.com/w20/gf.png' },
83
+ { code: 'GG', name: 'Guernsey', dialCode: '44', flag: 'https://flagcdn.com/w20/gg.png' },
84
+ { code: 'GH', name: 'Ghana', dialCode: '233', flag: 'https://flagcdn.com/w20/gh.png' },
85
+ { code: 'GI', name: 'Gibraltar', dialCode: '350', flag: 'https://flagcdn.com/w20/gi.png' },
86
+ { code: 'GL', name: 'Greenland', dialCode: '299', flag: 'https://flagcdn.com/w20/gl.png' },
87
+ { code: 'GM', name: 'Gambia', dialCode: '220', flag: 'https://flagcdn.com/w20/gm.png' },
88
+ { code: 'GN', name: 'Guinea', dialCode: '224', flag: 'https://flagcdn.com/w20/gn.png' },
89
+ { code: 'GP', name: 'Guadeloupe', dialCode: '590', flag: 'https://flagcdn.com/w20/gp.png' },
90
+ { code: 'GQ', name: 'Equatorial Guinea', dialCode: '240', flag: 'https://flagcdn.com/w20/gq.png' },
91
+ { code: 'GR', name: 'Greece', dialCode: '30', flag: 'https://flagcdn.com/w20/gr.png' },
92
+ { code: 'GS', name: 'South Georgia', dialCode: '500', flag: 'https://flagcdn.com/w20/gs.png' },
93
+ { code: 'GT', name: 'Guatemala', dialCode: '502', flag: 'https://flagcdn.com/w20/gt.png' },
94
+ { code: 'GU', name: 'Guam', dialCode: '1671', flag: 'https://flagcdn.com/w20/gu.png' },
95
+ { code: 'GW', name: 'Guinea-Bissau', dialCode: '245', flag: 'https://flagcdn.com/w20/gw.png' },
96
+ { code: 'GY', name: 'Guyana', dialCode: '592', flag: 'https://flagcdn.com/w20/gy.png' },
97
+ { code: 'HK', name: 'Hong Kong', dialCode: '852', flag: 'https://flagcdn.com/w20/hk.png' },
98
+ { code: 'HM', name: 'Heard Island', dialCode: '672', flag: 'https://flagcdn.com/w20/hm.png' },
99
+ { code: 'HN', name: 'Honduras', dialCode: '504', flag: 'https://flagcdn.com/w20/hn.png' },
100
+ { code: 'HR', name: 'Croatia', dialCode: '385', flag: 'https://flagcdn.com/w20/hr.png' },
101
+ { code: 'HT', name: 'Haiti', dialCode: '509', flag: 'https://flagcdn.com/w20/ht.png' },
102
+ { code: 'HU', name: 'Hungary', dialCode: '36', flag: 'https://flagcdn.com/w20/hu.png' },
103
+ { code: 'ID', name: 'Indonesia', dialCode: '62', flag: 'https://flagcdn.com/w20/id.png' },
104
+ { code: 'IE', name: 'Ireland', dialCode: '353', flag: 'https://flagcdn.com/w20/ie.png' },
105
+ { code: 'IL', name: 'Israel', dialCode: '972', flag: 'https://flagcdn.com/w20/il.png' },
106
+ { code: 'IM', name: 'Isle of Man', dialCode: '44', flag: 'https://flagcdn.com/w20/im.png' },
107
+ { code: 'IN', name: 'India', dialCode: '91', flag: 'https://flagcdn.com/w20/in.png' },
108
+ { code: 'IO', name: 'British Indian Ocean Territory', dialCode: '246', flag: 'https://flagcdn.com/w20/io.png' },
109
+ { code: 'IQ', name: 'Iraq', dialCode: '964', flag: 'https://flagcdn.com/w20/iq.png' },
110
+ { code: 'IR', name: 'Iran', dialCode: '98', flag: 'https://flagcdn.com/w20/ir.png' },
111
+ { code: 'IS', name: 'Iceland', dialCode: '354', flag: 'https://flagcdn.com/w20/is.png' },
112
+ { code: 'IT', name: 'Italy', dialCode: '39', flag: 'https://flagcdn.com/w20/it.png' },
113
+ { code: 'JE', name: 'Jersey', dialCode: '44', flag: 'https://flagcdn.com/w20/je.png' },
114
+ { code: 'JM', name: 'Jamaica', dialCode: '1876', flag: 'https://flagcdn.com/w20/jm.png' },
115
+ { code: 'JO', name: 'Jordan', dialCode: '962', flag: 'https://flagcdn.com/w20/jo.png' },
116
+ { code: 'JP', name: 'Japan', dialCode: '81', flag: 'https://flagcdn.com/w20/jp.png' },
117
+ { code: 'KE', name: 'Kenya', dialCode: '254', flag: 'https://flagcdn.com/w20/ke.png' },
118
+ { code: 'KG', name: 'Kyrgyzstan', dialCode: '996', flag: 'https://flagcdn.com/w20/kg.png' },
119
+ { code: 'KH', name: 'Cambodia', dialCode: '855', flag: 'https://flagcdn.com/w20/kh.png' },
120
+ { code: 'KI', name: 'Kiribati', dialCode: '686', flag: 'https://flagcdn.com/w20/ki.png' },
121
+ { code: 'KM', name: 'Comoros', dialCode: '269', flag: 'https://flagcdn.com/w20/km.png' },
122
+ { code: 'KN', name: 'Saint Kitts and Nevis', dialCode: '1869', flag: 'https://flagcdn.com/w20/kn.png' },
123
+ { code: 'KP', name: 'North Korea', dialCode: '850', flag: 'https://flagcdn.com/w20/kp.png' },
124
+ { code: 'KR', name: 'South Korea', dialCode: '82', flag: 'https://flagcdn.com/w20/kr.png' },
125
+ { code: 'KW', name: 'Kuwait', dialCode: '965', flag: 'https://flagcdn.com/w20/kw.png' },
126
+ { code: 'KY', name: 'Cayman Islands', dialCode: '1345', flag: 'https://flagcdn.com/w20/ky.png' },
127
+ { code: 'KZ', name: 'Kazakhstan', dialCode: '7', flag: 'https://flagcdn.com/w20/kz.png' },
128
+ { code: 'LA', name: 'Laos', dialCode: '856', flag: 'https://flagcdn.com/w20/la.png' },
129
+ { code: 'LB', name: 'Lebanon', dialCode: '961', flag: 'https://flagcdn.com/w20/lb.png' },
130
+ { code: 'LC', name: 'Saint Lucia', dialCode: '1758', flag: 'https://flagcdn.com/w20/lc.png' },
131
+ { code: 'LI', name: 'Liechtenstein', dialCode: '423', flag: 'https://flagcdn.com/w20/li.png' },
132
+ { code: 'LK', name: 'Sri Lanka', dialCode: '94', flag: 'https://flagcdn.com/w20/lk.png' },
133
+ { code: 'LR', name: 'Liberia', dialCode: '231', flag: 'https://flagcdn.com/w20/lr.png' },
134
+ { code: 'LS', name: 'Lesotho', dialCode: '266', flag: 'https://flagcdn.com/w20/ls.png' },
135
+ { code: 'LT', name: 'Lithuania', dialCode: '370', flag: 'https://flagcdn.com/w20/lt.png' },
136
+ { code: 'LU', name: 'Luxembourg', dialCode: '352', flag: 'https://flagcdn.com/w20/lu.png' },
137
+ { code: 'LV', name: 'Latvia', dialCode: '371', flag: 'https://flagcdn.com/w20/lv.png' },
138
+ { code: 'LY', name: 'Libya', dialCode: '218', flag: 'https://flagcdn.com/w20/ly.png' },
139
+ { code: 'MA', name: 'Morocco', dialCode: '212', flag: 'https://flagcdn.com/w20/ma.png' },
140
+ { code: 'MC', name: 'Monaco', dialCode: '377', flag: 'https://flagcdn.com/w20/mc.png' },
141
+ { code: 'MD', name: 'Moldova', dialCode: '373', flag: 'https://flagcdn.com/w20/md.png' },
142
+ { code: 'ME', name: 'Montenegro', dialCode: '382', flag: 'https://flagcdn.com/w20/me.png' },
143
+ { code: 'MF', name: 'Saint Martin', dialCode: '590', flag: 'https://flagcdn.com/w20/mf.png' },
144
+ { code: 'MG', name: 'Madagascar', dialCode: '261', flag: 'https://flagcdn.com/w20/mg.png' },
145
+ { code: 'MH', name: 'Marshall Islands', dialCode: '692', flag: 'https://flagcdn.com/w20/mh.png' },
146
+ { code: 'MK', name: 'North Macedonia', dialCode: '389', flag: 'https://flagcdn.com/w20/mk.png' },
147
+ { code: 'ML', name: 'Mali', dialCode: '223', flag: 'https://flagcdn.com/w20/ml.png' },
148
+ { code: 'MM', name: 'Myanmar', dialCode: '95', flag: 'https://flagcdn.com/w20/mm.png' },
149
+ { code: 'MN', name: 'Mongolia', dialCode: '976', flag: 'https://flagcdn.com/w20/mn.png' },
150
+ { code: 'MO', name: 'Macao', dialCode: '853', flag: 'https://flagcdn.com/w20/mo.png' },
151
+ { code: 'MP', name: 'Northern Mariana Islands', dialCode: '1670', flag: 'https://flagcdn.com/w20/mp.png' },
152
+ { code: 'MQ', name: 'Martinique', dialCode: '596', flag: 'https://flagcdn.com/w20/mq.png' },
153
+ { code: 'MR', name: 'Mauritania', dialCode: '222', flag: 'https://flagcdn.com/w20/mr.png' },
154
+ { code: 'MS', name: 'Montserrat', dialCode: '1664', flag: 'https://flagcdn.com/w20/ms.png' },
155
+ { code: 'MT', name: 'Malta', dialCode: '356', flag: 'https://flagcdn.com/w20/mt.png' },
156
+ { code: 'MU', name: 'Mauritius', dialCode: '230', flag: 'https://flagcdn.com/w20/mu.png' },
157
+ { code: 'MV', name: 'Maldives', dialCode: '960', flag: 'https://flagcdn.com/w20/mv.png' },
158
+ { code: 'MW', name: 'Malawi', dialCode: '265', flag: 'https://flagcdn.com/w20/mw.png' },
159
+ { code: 'MX', name: 'Mexico', dialCode: '52', flag: 'https://flagcdn.com/w20/mx.png' },
160
+ { code: 'MY', name: 'Malaysia', dialCode: '60', flag: 'https://flagcdn.com/w20/my.png' },
161
+ { code: 'MZ', name: 'Mozambique', dialCode: '258', flag: 'https://flagcdn.com/w20/mz.png' },
162
+ { code: 'NA', name: 'Namibia', dialCode: '264', flag: 'https://flagcdn.com/w20/na.png' },
163
+ { code: 'NC', name: 'New Caledonia', dialCode: '687', flag: 'https://flagcdn.com/w20/nc.png' },
164
+ { code: 'NE', name: 'Niger', dialCode: '227', flag: 'https://flagcdn.com/w20/ne.png' },
165
+ { code: 'NF', name: 'Norfolk Island', dialCode: '672', flag: 'https://flagcdn.com/w20/nf.png' },
166
+ { code: 'NG', name: 'Nigeria', dialCode: '234', flag: 'https://flagcdn.com/w20/ng.png' },
167
+ { code: 'NI', name: 'Nicaragua', dialCode: '505', flag: 'https://flagcdn.com/w20/ni.png' },
168
+ { code: 'NL', name: 'Netherlands', dialCode: '31', flag: 'https://flagcdn.com/w20/nl.png' },
169
+ { code: 'NO', name: 'Norway', dialCode: '47', flag: 'https://flagcdn.com/w20/no.png' },
170
+ { code: 'NP', name: 'Nepal', dialCode: '977', flag: 'https://flagcdn.com/w20/np.png' },
171
+ { code: 'NR', name: 'Nauru', dialCode: '674', flag: 'https://flagcdn.com/w20/nr.png' },
172
+ { code: 'NU', name: 'Niue', dialCode: '683', flag: 'https://flagcdn.com/w20/nu.png' },
173
+ { code: 'NZ', name: 'New Zealand', dialCode: '64', flag: 'https://flagcdn.com/w20/nz.png' },
174
+ { code: 'OM', name: 'Oman', dialCode: '968', flag: 'https://flagcdn.com/w20/om.png' },
175
+ { code: 'PA', name: 'Panama', dialCode: '507', flag: 'https://flagcdn.com/w20/pa.png' },
176
+ { code: 'PE', name: 'Peru', dialCode: '51', flag: 'https://flagcdn.com/w20/pe.png' },
177
+ { code: 'PF', name: 'French Polynesia', dialCode: '689', flag: 'https://flagcdn.com/w20/pf.png' },
178
+ { code: 'PG', name: 'Papua New Guinea', dialCode: '675', flag: 'https://flagcdn.com/w20/pg.png' },
179
+ { code: 'PH', name: 'Philippines', dialCode: '63', flag: 'https://flagcdn.com/w20/ph.png' },
180
+ { code: 'PK', name: 'Pakistan', dialCode: '92', flag: 'https://flagcdn.com/w20/pk.png' },
181
+ { code: 'PL', name: 'Poland', dialCode: '48', flag: 'https://flagcdn.com/w20/pl.png' },
182
+ { code: 'PM', name: 'Saint Pierre and Miquelon', dialCode: '508', flag: 'https://flagcdn.com/w20/pm.png' },
183
+ { code: 'PN', name: 'Pitcairn Islands', dialCode: '64', flag: 'https://flagcdn.com/w20/pn.png' },
184
+ { code: 'PR', name: 'Puerto Rico', dialCode: '1787', flag: 'https://flagcdn.com/w20/pr.png' },
185
+ { code: 'PS', name: 'Palestine', dialCode: '970', flag: 'https://flagcdn.com/w20/ps.png' },
186
+ { code: 'PT', name: 'Portugal', dialCode: '351', flag: 'https://flagcdn.com/w20/pt.png' },
187
+ { code: 'PW', name: 'Palau', dialCode: '680', flag: 'https://flagcdn.com/w20/pw.png' },
188
+ { code: 'PY', name: 'Paraguay', dialCode: '595', flag: 'https://flagcdn.com/w20/py.png' },
189
+ { code: 'QA', name: 'Qatar', dialCode: '974', flag: 'https://flagcdn.com/w20/qa.png' },
190
+ { code: 'RE', name: 'Réunion', dialCode: '262', flag: 'https://flagcdn.com/w20/re.png' },
191
+ { code: 'RO', name: 'Romania', dialCode: '40', flag: 'https://flagcdn.com/w20/ro.png' },
192
+ { code: 'RS', name: 'Serbia', dialCode: '381', flag: 'https://flagcdn.com/w20/rs.png' },
193
+ { code: 'RU', name: 'Russia', dialCode: '7', flag: 'https://flagcdn.com/w20/ru.png' },
194
+ { code: 'RW', name: 'Rwanda', dialCode: '250', flag: 'https://flagcdn.com/w20/rw.png' },
195
+ { code: 'SA', name: 'Saudi Arabia', dialCode: '966', flag: 'https://flagcdn.com/w20/sa.png' },
196
+ { code: 'SB', name: 'Solomon Islands', dialCode: '677', flag: 'https://flagcdn.com/w20/sb.png' },
197
+ { code: 'SC', name: 'Seychelles', dialCode: '248', flag: 'https://flagcdn.com/w20/sc.png' },
198
+ { code: 'SD', name: 'Sudan', dialCode: '249', flag: 'https://flagcdn.com/w20/sd.png' },
199
+ { code: 'SE', name: 'Sweden', dialCode: '46', flag: 'https://flagcdn.com/w20/se.png' },
200
+ { code: 'SG', name: 'Singapore', dialCode: '65', flag: 'https://flagcdn.com/w20/sg.png' },
201
+ { code: 'SH', name: 'Saint Helena', dialCode: '290', flag: 'https://flagcdn.com/w20/sh.png' },
202
+ { code: 'SI', name: 'Slovenia', dialCode: '386', flag: 'https://flagcdn.com/w20/si.png' },
203
+ { code: 'SJ', name: 'Svalbard and Jan Mayen', dialCode: '47', flag: 'https://flagcdn.com/w20/sj.png' },
204
+ { code: 'SK', name: 'Slovakia', dialCode: '421', flag: 'https://flagcdn.com/w20/sk.png' },
205
+ { code: 'SL', name: 'Sierra Leone', dialCode: '232', flag: 'https://flagcdn.com/w20/sl.png' },
206
+ { code: 'SM', name: 'San Marino', dialCode: '378', flag: 'https://flagcdn.com/w20/sm.png' },
207
+ { code: 'SN', name: 'Senegal', dialCode: '221', flag: 'https://flagcdn.com/w20/sn.png' },
208
+ { code: 'SO', name: 'Somalia', dialCode: '252', flag: 'https://flagcdn.com/w20/so.png' },
209
+ { code: 'SR', name: 'Suriname', dialCode: '597', flag: 'https://flagcdn.com/w20/sr.png' },
210
+ { code: 'SS', name: 'South Sudan', dialCode: '211', flag: 'https://flagcdn.com/w20/ss.png' },
211
+ { code: 'ST', name: 'São Tomé and Príncipe', dialCode: '239', flag: 'https://flagcdn.com/w20/st.png' },
212
+ { code: 'SV', name: 'El Salvador', dialCode: '503', flag: 'https://flagcdn.com/w20/sv.png' },
213
+ { code: 'SX', name: 'Sint Maarten', dialCode: '1721', flag: 'https://flagcdn.com/w20/sx.png' },
214
+ { code: 'SY', name: 'Syria', dialCode: '963', flag: 'https://flagcdn.com/w20/sy.png' },
215
+ { code: 'SZ', name: 'Eswatini', dialCode: '268', flag: 'https://flagcdn.com/w20/sz.png' },
216
+ { code: 'TC', name: 'Turks and Caicos Islands', dialCode: '1649', flag: 'https://flagcdn.com/w20/tc.png' },
217
+ { code: 'TD', name: 'Chad', dialCode: '235', flag: 'https://flagcdn.com/w20/td.png' },
218
+ { code: 'TF', name: 'French Southern Territories', dialCode: '262', flag: 'https://flagcdn.com/w20/tf.png' },
219
+ { code: 'TG', name: 'Togo', dialCode: '228', flag: 'https://flagcdn.com/w20/tg.png' },
220
+ { code: 'TH', name: 'Thailand', dialCode: '66', flag: 'https://flagcdn.com/w20/th.png' },
221
+ { code: 'TJ', name: 'Tajikistan', dialCode: '992', flag: 'https://flagcdn.com/w20/tj.png' },
222
+ { code: 'TK', name: 'Tokelau', dialCode: '690', flag: 'https://flagcdn.com/w20/tk.png' },
223
+ { code: 'TL', name: 'East Timor', dialCode: '670', flag: 'https://flagcdn.com/w20/tl.png' },
224
+ { code: 'TM', name: 'Turkmenistan', dialCode: '993', flag: 'https://flagcdn.com/w20/tm.png' },
225
+ { code: 'TN', name: 'Tunisia', dialCode: '216', flag: 'https://flagcdn.com/w20/tn.png' },
226
+ { code: 'TO', name: 'Tonga', dialCode: '676', flag: 'https://flagcdn.com/w20/to.png' },
227
+ { code: 'TR', name: 'Turkey', dialCode: '90', flag: 'https://flagcdn.com/w20/tr.png' },
228
+ { code: 'TT', name: 'Trinidad and Tobago', dialCode: '1868', flag: 'https://flagcdn.com/w20/tt.png' },
229
+ { code: 'TV', name: 'Tuvalu', dialCode: '688', flag: 'https://flagcdn.com/w20/tv.png' },
230
+ { code: 'TW', name: 'Taiwan', dialCode: '886', flag: 'https://flagcdn.com/w20/tw.png' },
231
+ { code: 'TZ', name: 'Tanzania', dialCode: '255', flag: 'https://flagcdn.com/w20/tz.png' },
232
+ { code: 'UA', name: 'Ukraine', dialCode: '380', flag: 'https://flagcdn.com/w20/ua.png' },
233
+ { code: 'UG', name: 'Uganda', dialCode: '256', flag: 'https://flagcdn.com/w20/ug.png' },
234
+ { code: 'UM', name: 'United States Minor Outlying Islands', dialCode: '1', flag: 'https://flagcdn.com/w20/um.png' },
235
+ { code: 'US', name: 'United States', dialCode: '1', flag: 'https://flagcdn.com/w20/us.png' },
236
+ { code: 'UY', name: 'Uruguay', dialCode: '598', flag: 'https://flagcdn.com/w20/uy.png' },
237
+ { code: 'UZ', name: 'Uzbekistan', dialCode: '998', flag: 'https://flagcdn.com/w20/uz.png' },
238
+ { code: 'VA', name: 'Vatican City', dialCode: '379', flag: 'https://flagcdn.com/w20/va.png' },
239
+ { code: 'VC', name: 'Saint Vincent and the Grenadines', dialCode: '1784', flag: 'https://flagcdn.com/w20/vc.png' },
240
+ { code: 'VE', name: 'Venezuela', dialCode: '58', flag: 'https://flagcdn.com/w20/ve.png' },
241
+ { code: 'VG', name: 'British Virgin Islands', dialCode: '1284', flag: 'https://flagcdn.com/w20/vg.png' },
242
+ { code: 'VI', name: 'United States Virgin Islands', dialCode: '1340', flag: 'https://flagcdn.com/w20/vi.png' },
243
+ { code: 'VN', name: 'Vietnam', dialCode: '84', flag: 'https://flagcdn.com/w20/vn.png' },
244
+ { code: 'VU', name: 'Vanuatu', dialCode: '678', flag: 'https://flagcdn.com/w20/vu.png' },
245
+ { code: 'WF', name: 'Wallis and Futuna', dialCode: '681', flag: 'https://flagcdn.com/w20/wf.png' },
246
+ { code: 'WS', name: 'Samoa', dialCode: '685', flag: 'https://flagcdn.com/w20/ws.png' },
247
+ { code: 'YE', name: 'Yemen', dialCode: '967', flag: 'https://flagcdn.com/w20/ye.png' },
248
+ { code: 'YT', name: 'Mayotte', dialCode: '262', flag: 'https://flagcdn.com/w20/yt.png' },
249
+ { code: 'ZA', name: 'South Africa', dialCode: '27', flag: 'https://flagcdn.com/w20/za.png' },
250
+ { code: 'ZM', name: 'Zambia', dialCode: '260', flag: 'https://flagcdn.com/w20/zm.png' },
251
+ { code: 'ZW', name: 'Zimbabwe', dialCode: '263', flag: 'https://flagcdn.com/w20/zw.png' }
252
+ ].sort((a, b) => a.name.localeCompare(b.name))
253
+
@@ -0,0 +1,12 @@
1
+ export function getAllDefaultComponents() {
2
+ const defaultComponents = {};
3
+
4
+ const files = require.context('.', true, /\.vue$/i)
5
+
6
+ files.keys().map(file => {
7
+ const componentName = file.match(/\.\/(.*)\.vue/)[1];
8
+ defaultComponents[componentName] = files(file).default;
9
+ });
10
+
11
+ return defaultComponents;
12
+ }
@@ -0,0 +1,71 @@
1
+ # js-kompo-utils - Architecture
2
+
3
+ ## Two Responsibilities
4
+
5
+ The system splits app initialization into two classes with distinct roles:
6
+
7
+ **`KompoJsConfigBuilder`** — Declares *what* the app needs. Knows nothing about how initialization works. Stores components, feature flags, plugins, callbacks. Pure data, no side effects.
8
+
9
+ **`KompoJsInitializer`** — Executes *how* the app boots. Reads the config and runs a fixed sequence of steps. This is the only place where `require()`, `Vue.component()`, and `window` mutation happen.
10
+
11
+ The builder can be shared, extended, and modified across apps. The initializer is the part that would change if you migrated to a different framework or build system.
12
+
13
+ ## Why this separation
14
+
15
+ A typical Laravel `app.js` mixes concerns: imports, global assignments, component registration, library boot, and Vue mounting — all in one imperative file. If one line fails, everything after it breaks.
16
+
17
+ This system separates *configuration* from *execution*:
18
+
19
+ - The consumer declares intent: "I want jQuery, these components, this bootstrap"
20
+ - The initializer handles the mechanics: load order, global assignment, Vue setup
21
+
22
+ This means a consuming app doesn't need to know that Vue must be on `window` before `vue-kompo` loads, or that Google Maps needs a style set before import. The initializer encapsulates that knowledge.
23
+
24
+ ## Initialization sequence
25
+
26
+ ```
27
+ 1. bootstrapExecution — Run the app's Laravel bootstrap (axios, lodash, CSRF)
28
+ 2. requireFilesToImport — Execute file import callbacks (animations, scripts)
29
+ 3. bootJqueryIfRequired — Expose jQuery on window
30
+ 4. bootVue — Load Vue, vue-kompo, register plugins and components
31
+ 5. decorateWindow — Apply window utils and run decorators
32
+ 6. bootCkEditorIfRequired
33
+ 7. bootMapsIfRequired
34
+ 8. instanceApp — Mount Vue on the DOM
35
+ ```
36
+
37
+ Every step supports `addBeforeStepCallback` / `addAfterStepCallback` for app-specific logic at any point in the sequence.
38
+
39
+ ## defaultConfig
40
+
41
+ `app.js` exports a `defaultConfig` — a pre-built `KompoJsConfigBuilder` with sensible defaults for kompo apps: all package components, jQuery, CKEditor, Maps, QR reader, window utilities, animations.
42
+
43
+ A consuming app imports this and layers its own config on top:
44
+
45
+ ```javascript
46
+ const config = defaultConfig
47
+ .bootstrap(() => require('./bootstrap'))
48
+ .excludeComponent('VlApexChart')
49
+ .addWindowDecorator(myDecorator);
50
+ ```
51
+
52
+ This avoids repeating 30+ lines of component registration across every app while keeping full control.
53
+
54
+ ## Error resilience
55
+
56
+ Steps are categorized as **essential** or **non-essential**:
57
+
58
+ - **Essential** (`bootstrapExecution`, `bootVue`, `instanceApp`): If these fail, the app can't function. Errors propagate normally — you want these to break the build or show a clear error.
59
+ - **Non-essential** (everything else): Wrapped in try/catch. A failed CKEditor init or animation import logs a warning but doesn't prevent the app from rendering.
60
+
61
+ This prevents the scenario where a runtime error in a non-critical feature (like tutorials) kills the entire view.
62
+
63
+ ## Replacing the initializer
64
+
65
+ `KompoJsInitializer` is the only class coupled to Vue 2, webpack `require()`, and the specific boot sequence. If you migrate to Vue 3, Vite, or a different framework:
66
+
67
+ 1. Create a new initializer class (e.g., `KompoVue3Initializer`)
68
+ 2. It reads the same `KompoJsConfigBuilder` config
69
+ 3. Implements its own step sequence
70
+
71
+ The config builder stays the same — apps only change which initializer they instantiate.