@bagelink/blox 1.5.13 → 1.5.17

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.
package/dist/index.mjs CHANGED
@@ -184,52 +184,128 @@ var Title_default = /* @__PURE__ */ __plugin_vue_export_helper_default(/* @__PUR
184
184
  };
185
185
  }
186
186
  }), [["__scopeId", "data-v-ae0634d1"]]);
187
- const baseComponentConfigs = [
188
- {
189
- id: "Text",
190
- label: "Text",
191
- icon: "text_fields",
192
- order: 10,
193
- component: Text_default,
194
- content: [{
195
- type: "richtext",
196
- key: "content",
197
- label: "Content",
198
- defaultValue: "<p>Enter your text here...</p>",
199
- height: 200
200
- }],
201
- settings: [{
187
+ const TextConfig = {
188
+ id: "Text",
189
+ label: "Text",
190
+ icon: "text_fields",
191
+ order: 10,
192
+ category: "basic",
193
+ component: Text_default,
194
+ content: [{
195
+ type: "richtext",
196
+ key: "content",
197
+ label: "Content",
198
+ defaultValue: "<p>Enter your text here...</p>",
199
+ height: 200
200
+ }],
201
+ settings: [{
202
+ type: "select",
203
+ key: "tag",
204
+ label: "HTML Tag",
205
+ defaultValue: "div",
206
+ options: [
207
+ {
208
+ label: "Div",
209
+ value: "div"
210
+ },
211
+ {
212
+ label: "Paragraph",
213
+ value: "p"
214
+ },
215
+ {
216
+ label: "Span",
217
+ value: "span"
218
+ },
219
+ {
220
+ label: "Article",
221
+ value: "article"
222
+ },
223
+ {
224
+ label: "Section",
225
+ value: "section"
226
+ }
227
+ ]
228
+ }, {
229
+ type: "select",
230
+ key: "align",
231
+ label: "Text Alignment",
232
+ defaultValue: "left",
233
+ options: [
234
+ {
235
+ label: "Left",
236
+ value: "left"
237
+ },
238
+ {
239
+ label: "Center",
240
+ value: "center"
241
+ },
242
+ {
243
+ label: "Right",
244
+ value: "right"
245
+ },
246
+ {
247
+ label: "Justify",
248
+ value: "justify"
249
+ }
250
+ ]
251
+ }]
252
+ };
253
+ const TitleConfig = {
254
+ id: "Title",
255
+ label: "Title",
256
+ icon: "title",
257
+ order: 5,
258
+ category: "basic",
259
+ component: Title_default,
260
+ content: [{
261
+ type: "text",
262
+ key: "title",
263
+ label: "Title",
264
+ defaultValue: "Your Title Here"
265
+ }, {
266
+ type: "text",
267
+ key: "subtitle",
268
+ label: "Subtitle",
269
+ defaultValue: ""
270
+ }],
271
+ settings: [
272
+ {
202
273
  type: "select",
203
274
  key: "tag",
204
- label: "HTML Tag",
205
- defaultValue: "div",
275
+ label: "Heading Tag",
276
+ defaultValue: "h2",
206
277
  options: [
207
278
  {
208
- label: "Div",
209
- value: "div"
279
+ label: "H1",
280
+ value: "h1"
210
281
  },
211
282
  {
212
- label: "Paragraph",
213
- value: "p"
283
+ label: "H2",
284
+ value: "h2"
214
285
  },
215
286
  {
216
- label: "Span",
217
- value: "span"
287
+ label: "H3",
288
+ value: "h3"
218
289
  },
219
290
  {
220
- label: "Article",
221
- value: "article"
291
+ label: "H4",
292
+ value: "h4"
222
293
  },
223
294
  {
224
- label: "Section",
225
- value: "section"
295
+ label: "H5",
296
+ value: "h5"
297
+ },
298
+ {
299
+ label: "H6",
300
+ value: "h6"
226
301
  }
227
302
  ]
228
- }, {
303
+ },
304
+ {
229
305
  type: "select",
230
306
  key: "align",
231
307
  label: "Text Alignment",
232
- defaultValue: "left",
308
+ defaultValue: "center",
233
309
  options: [
234
310
  {
235
311
  label: "Left",
@@ -242,337 +318,273 @@ const baseComponentConfigs = [
242
318
  {
243
319
  label: "Right",
244
320
  value: "right"
321
+ }
322
+ ]
323
+ },
324
+ {
325
+ type: "number",
326
+ key: "size",
327
+ label: "Font Size (px)",
328
+ defaultValue: 32
329
+ }
330
+ ]
331
+ };
332
+ const ButtonConfig = {
333
+ id: "Button",
334
+ label: "Button",
335
+ icon: "smart_button",
336
+ order: 15,
337
+ category: "basic",
338
+ component: Button_default,
339
+ content: [{
340
+ type: "text",
341
+ key: "btnTxt",
342
+ label: "Button Text",
343
+ defaultValue: "Click Me"
344
+ }, {
345
+ type: "text",
346
+ key: "btnUrl",
347
+ label: "Button URL",
348
+ defaultValue: "#"
349
+ }],
350
+ settings: [
351
+ {
352
+ type: "select",
353
+ key: "variant",
354
+ label: "Button Style",
355
+ defaultValue: "primary",
356
+ options: [
357
+ {
358
+ label: "Primary",
359
+ value: "primary"
360
+ },
361
+ {
362
+ label: "Secondary",
363
+ value: "secondary"
245
364
  },
246
365
  {
247
- label: "Justify",
248
- value: "justify"
366
+ label: "Outline",
367
+ value: "outline"
368
+ },
369
+ {
370
+ label: "Ghost",
371
+ value: "ghost"
249
372
  }
250
373
  ]
251
- }]
252
- },
253
- {
254
- id: "Title",
255
- label: "Title",
256
- icon: "title",
257
- order: 5,
258
- component: Title_default,
259
- content: [{
260
- type: "text",
261
- key: "title",
262
- label: "Title",
263
- defaultValue: "Your Title Here"
264
- }, {
265
- type: "text",
266
- key: "subtitle",
267
- label: "Subtitle",
268
- defaultValue: ""
269
- }],
270
- settings: [
271
- {
272
- type: "select",
273
- key: "tag",
274
- label: "Heading Tag",
275
- defaultValue: "h2",
276
- options: [
277
- {
278
- label: "H1",
279
- value: "h1"
280
- },
281
- {
282
- label: "H2",
283
- value: "h2"
284
- },
285
- {
286
- label: "H3",
287
- value: "h3"
288
- },
289
- {
290
- label: "H4",
291
- value: "h4"
292
- },
293
- {
294
- label: "H5",
295
- value: "h5"
296
- },
297
- {
298
- label: "H6",
299
- value: "h6"
300
- }
301
- ]
302
- },
303
- {
304
- type: "select",
305
- key: "align",
306
- label: "Text Alignment",
307
- defaultValue: "center",
308
- options: [
309
- {
310
- label: "Left",
311
- value: "left"
312
- },
313
- {
314
- label: "Center",
315
- value: "center"
316
- },
317
- {
318
- label: "Right",
319
- value: "right"
320
- }
321
- ]
322
- },
323
- {
324
- type: "number",
325
- key: "size",
326
- label: "Font Size (px)",
327
- defaultValue: 32
328
- }
329
- ]
330
- },
331
- {
332
- id: "Button",
333
- label: "Button",
334
- icon: "smart_button",
335
- order: 15,
336
- component: Button_default,
337
- content: [{
338
- type: "text",
339
- key: "btnTxt",
340
- label: "Button Text",
341
- defaultValue: "Click Me"
342
- }, {
343
- type: "text",
344
- key: "btnUrl",
345
- label: "Button URL",
346
- defaultValue: "#"
347
- }],
348
- settings: [
349
- {
350
- type: "select",
351
- key: "variant",
352
- label: "Button Style",
353
- defaultValue: "primary",
354
- options: [
355
- {
356
- label: "Primary",
357
- value: "primary"
358
- },
359
- {
360
- label: "Secondary",
361
- value: "secondary"
362
- },
363
- {
364
- label: "Outline",
365
- value: "outline"
366
- },
367
- {
368
- label: "Ghost",
369
- value: "ghost"
370
- }
371
- ]
372
- },
373
- {
374
- type: "select",
375
- key: "size",
376
- label: "Size",
377
- defaultValue: "md",
378
- options: [
379
- {
380
- label: "Small",
381
- value: "sm"
382
- },
383
- {
384
- label: "Medium",
385
- value: "md"
386
- },
387
- {
388
- label: "Large",
389
- value: "lg"
390
- }
391
- ]
392
- },
393
- {
394
- type: "select",
395
- key: "align",
396
- label: "Alignment",
397
- defaultValue: "left",
398
- options: [
399
- {
400
- label: "Left",
401
- value: "left"
402
- },
403
- {
404
- label: "Center",
405
- value: "center"
406
- },
407
- {
408
- label: "Right",
409
- value: "right"
410
- }
411
- ]
412
- },
413
- {
414
- type: "checkbox",
415
- key: "fullWidth",
416
- label: "Full Width",
417
- defaultValue: false
418
- },
419
- {
420
- type: "select",
421
- key: "btnTarget",
422
- label: "Link Target",
423
- defaultValue: "_self",
424
- options: [{
425
- label: "Same Window",
426
- value: "_self"
427
- }, {
428
- label: "New Window",
429
- value: "_blank"
430
- }]
431
- }
432
- ]
433
- },
434
- {
435
- id: "Image",
436
- label: "Image",
437
- icon: "image",
438
- order: 20,
439
- component: Image_default,
440
- content: [{
441
- type: "upload",
442
- key: "src",
443
- label: "Image",
444
- defaultValue: "",
445
- height: 200
446
- }, {
447
- type: "text",
448
- key: "alt",
449
- label: "Alt Text",
450
- defaultValue: ""
451
- }],
452
- settings: [
453
- {
454
- type: "select",
455
- key: "objectFit",
456
- label: "Object Fit",
457
- defaultValue: "cover",
458
- options: [
459
- {
460
- label: "Cover",
461
- value: "cover"
462
- },
463
- {
464
- label: "Contain",
465
- value: "contain"
466
- },
467
- {
468
- label: "Fill",
469
- value: "fill"
470
- },
471
- {
472
- label: "None",
473
- value: "none"
474
- },
475
- {
476
- label: "Scale Down",
477
- value: "scale-down"
478
- }
479
- ]
480
- },
481
- {
482
- type: "number",
483
- key: "maxWidth",
484
- label: "Max Width (px)",
485
- defaultValue: null
486
- },
487
- {
488
- type: "number",
489
- key: "height",
490
- label: "Height (px)",
491
- defaultValue: null
492
- },
493
- {
494
- type: "select",
495
- key: "align",
496
- label: "Alignment",
497
- defaultValue: "center",
498
- options: [
499
- {
500
- label: "Left",
501
- value: "left"
502
- },
503
- {
504
- label: "Center",
505
- value: "center"
506
- },
507
- {
508
- label: "Right",
509
- value: "right"
510
- }
511
- ]
512
- }
513
- ]
514
- },
515
- {
516
- id: "Spacer",
517
- label: "Spacer",
518
- icon: "height",
519
- order: 25,
520
- component: Spacer_default,
521
- content: [],
522
- settings: [{
523
- type: "number",
524
- key: "height",
525
- label: "Height (px)",
526
- defaultValue: 40
527
- }]
528
- },
529
- {
530
- id: "Container",
531
- label: "Container",
532
- icon: "view_module",
533
- order: 30,
534
- component: Container_default,
535
- content: [{
536
- type: "richtext",
537
- key: "content",
538
- label: "Content",
539
- defaultValue: "<p>Container content...</p>",
540
- height: 200
541
- }],
542
- settings: [{
374
+ },
375
+ {
543
376
  type: "select",
544
- key: "maxWidth",
545
- label: "Max Width",
546
- defaultValue: "lg",
377
+ key: "size",
378
+ label: "Size",
379
+ defaultValue: "md",
547
380
  options: [
548
381
  {
549
- label: "Small (640px)",
382
+ label: "Small",
550
383
  value: "sm"
551
384
  },
552
385
  {
553
- label: "Medium (768px)",
386
+ label: "Medium",
554
387
  value: "md"
555
388
  },
556
389
  {
557
- label: "Large (1024px)",
390
+ label: "Large",
558
391
  value: "lg"
392
+ }
393
+ ]
394
+ },
395
+ {
396
+ type: "select",
397
+ key: "align",
398
+ label: "Alignment",
399
+ defaultValue: "left",
400
+ options: [
401
+ {
402
+ label: "Left",
403
+ value: "left"
559
404
  },
560
405
  {
561
- label: "Extra Large (1280px)",
562
- value: "xl"
406
+ label: "Center",
407
+ value: "center"
563
408
  },
564
409
  {
565
- label: "Full Width",
566
- value: "full"
410
+ label: "Right",
411
+ value: "right"
567
412
  }
568
413
  ]
569
- }, {
414
+ },
415
+ {
570
416
  type: "checkbox",
571
- key: "centered",
572
- label: "Center Content",
573
- defaultValue: true
574
- }]
575
- }
417
+ key: "fullWidth",
418
+ label: "Full Width",
419
+ defaultValue: false
420
+ },
421
+ {
422
+ type: "select",
423
+ key: "btnTarget",
424
+ label: "Link Target",
425
+ defaultValue: "_self",
426
+ options: [{
427
+ label: "Same Window",
428
+ value: "_self"
429
+ }, {
430
+ label: "New Window",
431
+ value: "_blank"
432
+ }]
433
+ }
434
+ ]
435
+ };
436
+ const ImageConfig = {
437
+ id: "Image",
438
+ label: "Image",
439
+ icon: "image",
440
+ order: 20,
441
+ category: "media",
442
+ component: Image_default,
443
+ content: [{
444
+ type: "upload",
445
+ key: "src",
446
+ label: "Image",
447
+ defaultValue: "",
448
+ height: 200
449
+ }, {
450
+ type: "text",
451
+ key: "alt",
452
+ label: "Alt Text",
453
+ defaultValue: ""
454
+ }],
455
+ settings: [
456
+ {
457
+ type: "select",
458
+ key: "objectFit",
459
+ label: "Object Fit",
460
+ defaultValue: "cover",
461
+ options: [
462
+ {
463
+ label: "Cover",
464
+ value: "cover"
465
+ },
466
+ {
467
+ label: "Contain",
468
+ value: "contain"
469
+ },
470
+ {
471
+ label: "Fill",
472
+ value: "fill"
473
+ },
474
+ {
475
+ label: "None",
476
+ value: "none"
477
+ },
478
+ {
479
+ label: "Scale Down",
480
+ value: "scale-down"
481
+ }
482
+ ]
483
+ },
484
+ {
485
+ type: "number",
486
+ key: "maxWidth",
487
+ label: "Max Width (px)",
488
+ defaultValue: null
489
+ },
490
+ {
491
+ type: "number",
492
+ key: "height",
493
+ label: "Height (px)",
494
+ defaultValue: null
495
+ },
496
+ {
497
+ type: "select",
498
+ key: "align",
499
+ label: "Alignment",
500
+ defaultValue: "center",
501
+ options: [
502
+ {
503
+ label: "Left",
504
+ value: "left"
505
+ },
506
+ {
507
+ label: "Center",
508
+ value: "center"
509
+ },
510
+ {
511
+ label: "Right",
512
+ value: "right"
513
+ }
514
+ ]
515
+ }
516
+ ]
517
+ };
518
+ const SpacerConfig = {
519
+ id: "Spacer",
520
+ label: "Spacer",
521
+ icon: "height",
522
+ order: 25,
523
+ category: "layout",
524
+ component: Spacer_default,
525
+ content: [],
526
+ settings: [{
527
+ type: "number",
528
+ key: "height",
529
+ label: "Height (px)",
530
+ defaultValue: 40
531
+ }]
532
+ };
533
+ const ContainerConfig = {
534
+ id: "Container",
535
+ label: "Container",
536
+ icon: "view_module",
537
+ order: 30,
538
+ category: "layout",
539
+ component: Container_default,
540
+ content: [{
541
+ type: "richtext",
542
+ key: "content",
543
+ label: "Content",
544
+ defaultValue: "<p>Container content...</p>",
545
+ height: 200
546
+ }],
547
+ settings: [{
548
+ type: "select",
549
+ key: "maxWidth",
550
+ label: "Max Width",
551
+ defaultValue: "lg",
552
+ options: [
553
+ {
554
+ label: "Small (640px)",
555
+ value: "sm"
556
+ },
557
+ {
558
+ label: "Medium (768px)",
559
+ value: "md"
560
+ },
561
+ {
562
+ label: "Large (1024px)",
563
+ value: "lg"
564
+ },
565
+ {
566
+ label: "Extra Large (1280px)",
567
+ value: "xl"
568
+ },
569
+ {
570
+ label: "Full Width",
571
+ value: "full"
572
+ }
573
+ ]
574
+ }, {
575
+ type: "checkbox",
576
+ key: "centered",
577
+ label: "Center Content",
578
+ defaultValue: true
579
+ }]
580
+ };
581
+ const baseComponentConfigs = [
582
+ TextConfig,
583
+ TitleConfig,
584
+ ButtonConfig,
585
+ ImageConfig,
586
+ SpacerConfig,
587
+ ContainerConfig
576
588
  ];
577
589
  function getBaseComponentConfigs() {
578
590
  return baseComponentConfigs;
@@ -951,29 +963,6 @@ async function initializePage(pageData) {
951
963
  injectCode(pageData.header_code, "head");
952
964
  injectCode(pageData.body_code, "body");
953
965
  }
954
- function registerBaseComponents() {
955
- const componentMap = {};
956
- baseComponentConfigs.forEach((config) => {
957
- componentMap[config.id] = config.component;
958
- });
959
- registerComponents(componentMap);
960
- console.log("✅ Registered base components:", Object.keys(componentMap));
961
- }
962
- function getAllComponentConfigs(customConfigs = []) {
963
- return [...baseComponentConfigs, ...customConfigs];
964
- }
965
- function createComponentConfig(config) {
966
- return config;
967
- }
968
- function registerCustomComponent(config) {
969
- registerComponent(config.id, config.component);
970
- console.log(`✅ Registered custom component: ${config.id}`);
971
- }
972
- function registerCustomComponents(configs) {
973
- configs.forEach((config) => {
974
- registerCustomComponent(config);
975
- });
976
- }
977
966
  function normalizeComponentData(data) {
978
967
  const normalized = {};
979
968
  const stringFields = [
@@ -1055,7 +1044,7 @@ var ExternalPreview_default = /* @__PURE__ */ __plugin_vue_export_helper_default
1055
1044
  let bridge = null;
1056
1045
  const registeredComponents = getAllComponents();
1057
1046
  const getBlockStyles = computed(() => {
1058
- updateCounter.value;
1047
+ console.log("updateCounter", updateCounter.value);
1059
1048
  return (data, mobile = false) => generateBlockStyles(data, mobile);
1060
1049
  });
1061
1050
  function setFocus(id, emit = false) {
@@ -1211,7 +1200,7 @@ var ExternalPreview_default = /* @__PURE__ */ __plugin_vue_export_helper_default
1211
1200
  }), 128))]);
1212
1201
  };
1213
1202
  }
1214
- }), [["__scopeId", "data-v-8110f424"]]);
1203
+ }), [["__scopeId", "data-v-2fc74f90"]]);
1215
1204
  var _hoisted_1 = { class: "blox-page-wrapper" };
1216
1205
  var _hoisted_2 = {
1217
1206
  key: 0,
@@ -1235,7 +1224,7 @@ var RenderPage_default = /* @__PURE__ */ __plugin_vue_export_helper_default(/* @
1235
1224
  const updateCounter = ref(0);
1236
1225
  const registeredComponents = getAllComponents();
1237
1226
  const getBlockStyles = computed(() => {
1238
- updateCounter.value;
1227
+ console.log("updateCounter", updateCounter.value);
1239
1228
  return (data, mobile = false) => generateBlockStyles(data, mobile);
1240
1229
  });
1241
1230
  function updateMobileStatus() {
@@ -1268,5 +1257,197 @@ var RenderPage_default = /* @__PURE__ */ __plugin_vue_export_helper_default(/* @
1268
1257
  }), 128))]);
1269
1258
  };
1270
1259
  }
1271
- }), [["__scopeId", "data-v-1a340b1b"]]);
1272
- export { Button_default as Button, CommunicationBridge, Container_default as Container, ExternalPreview_default as ExternalPreview, Image_default as Image, RenderPage_default as RenderPage, Spacer_default as Spacer, Text_default as Text, Title_default as Title, applyGlobalFont, applyPageSettings, baseComponentConfigs, clearRegistry, createCommunicationBridge, createComponentConfig, createNamespacedRegistry, deepClone, deepMerge, generateBlockStyles, getAllComponentConfigs, getAllComponents, getBaseComponentConfig, getBaseComponentConfigs, getComponent, getRegisteredTypes, getResponsiveCSS, getResponsiveClasses, hasComponent, initializePage, injectCode, injectResponsiveCSS, loadComponentFonts, loadGoogleFont, normalizeComponentData, registerBaseComponents, registerComponent, registerComponents, registerCustomComponent, registerCustomComponents, registry, sendMessage, unregisterComponent };
1260
+ }), [["__scopeId", "data-v-bd9da6cc"]]);
1261
+ var ComponentValidationError = class extends Error {
1262
+ constructor(message, componentId) {
1263
+ super(message);
1264
+ this.componentId = componentId;
1265
+ this.name = "ComponentValidationError";
1266
+ }
1267
+ };
1268
+ function validateComponentConfig(config) {
1269
+ const errors = [];
1270
+ if (!config.id || typeof config.id !== "string") errors.push("Component must have a valid \"id\" (string)");
1271
+ if (!config.label || typeof config.label !== "string") errors.push("Component must have a valid \"label\" (string)");
1272
+ if (!config.component) errors.push("Component must have a \"component\" property (Vue component or async function)");
1273
+ if (config.component && typeof config.component !== "function" && typeof config.component !== "object") errors.push("Component \"component\" must be a Vue component or async function");
1274
+ if (config.content && !Array.isArray(config.content)) errors.push("Component \"content\" must be an array");
1275
+ if (config.settings && !Array.isArray(config.settings)) errors.push("Component \"settings\" must be an array");
1276
+ if (errors.length > 0) throw new ComponentValidationError(`Invalid component configuration for "${config.id || "unknown"}":\n${errors.map((e) => ` - ${e}`).join("\n")}`, config.id);
1277
+ }
1278
+ function levenshteinDistance(a, b) {
1279
+ const matrix = [];
1280
+ for (let i = 0; i <= b.length; i++) matrix[i] = [i];
1281
+ for (let j = 0; j <= a.length; j++) matrix[0][j] = j;
1282
+ for (let i = 1; i <= b.length; i++) for (let j = 1; j <= a.length; j++) if (b.charAt(i - 1) === a.charAt(j - 1)) matrix[i][j] = matrix[i - 1][j - 1];
1283
+ else matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j] + 1);
1284
+ return matrix[b.length][a.length];
1285
+ }
1286
+ function findSimilarIds(targetId, allIds, maxSuggestions = 3) {
1287
+ return allIds.map((id) => ({
1288
+ id,
1289
+ distance: levenshteinDistance(targetId.toLowerCase(), id.toLowerCase())
1290
+ })).filter((item) => item.distance <= 3).sort((a, b) => a.distance - b.distance).slice(0, maxSuggestions).map((item) => item.id);
1291
+ }
1292
+ function createMissingComponentError(id, registeredIds) {
1293
+ const suggestions = findSimilarIds(id, registeredIds);
1294
+ let message = `Component "${id}" is not registered.`;
1295
+ if (suggestions.length > 0) message += `\n\nDid you mean: ${suggestions.map((s) => `"${s}"`).join(", ")}?`;
1296
+ message += `\n\nAvailable components: ${registeredIds.join(", ")}`;
1297
+ return new Error(message);
1298
+ }
1299
+ function createBlox(options = {}) {
1300
+ const { debug = false, autoRegisterBaseComponents = true } = options;
1301
+ const registeredConfigs = [];
1302
+ let hasRegisteredBaseComponents = false;
1303
+ const log = (...args) => {
1304
+ if (debug) console.log("[Blox]", ...args);
1305
+ };
1306
+ const instance = {
1307
+ registerComponents(components, registerOptions = {}) {
1308
+ const { category, skipValidation = false } = registerOptions;
1309
+ const configs = Array.isArray(components) ? components : [components];
1310
+ if (!hasRegisteredBaseComponents && autoRegisterBaseComponents) {
1311
+ const componentMap = {};
1312
+ baseComponentConfigs.forEach((config) => {
1313
+ componentMap[config.id] = config.component;
1314
+ registeredConfigs.push(config);
1315
+ });
1316
+ registerComponents(componentMap);
1317
+ hasRegisteredBaseComponents = true;
1318
+ log("Registered base components:", Object.keys(componentMap));
1319
+ if (!debug) console.log("✅ Registered base components:", Object.keys(componentMap));
1320
+ }
1321
+ configs.forEach((config) => {
1322
+ if (!skipValidation) try {
1323
+ validateComponentConfig(config);
1324
+ } catch (error) {
1325
+ if (error instanceof ComponentValidationError) {
1326
+ console.error("❌ Component validation failed:");
1327
+ console.error(error.message);
1328
+ if (debug) console.error("Component config:", config);
1329
+ throw error;
1330
+ }
1331
+ throw error;
1332
+ }
1333
+ const finalConfig = category ? {
1334
+ ...config,
1335
+ category
1336
+ } : config;
1337
+ if (registeredConfigs.some((c) => c.id === finalConfig.id)) {
1338
+ const msg = `Component "${finalConfig.id}" is already registered. Overwriting...`;
1339
+ console.warn(`⚠️ ${msg}`);
1340
+ const index = registeredConfigs.findIndex((c) => c.id === finalConfig.id);
1341
+ registeredConfigs.splice(index, 1);
1342
+ }
1343
+ registerComponent(finalConfig.id, finalConfig.component);
1344
+ registeredConfigs.push(finalConfig);
1345
+ const categoryMsg = finalConfig.category ? ` (${finalConfig.category})` : "";
1346
+ log(`Registered component: ${finalConfig.id}${categoryMsg}`);
1347
+ if (!debug) console.log(`✅ Registered component: ${finalConfig.id}${categoryMsg}`);
1348
+ });
1349
+ return instance;
1350
+ },
1351
+ registerRoutes(router, routeOptions = {}) {
1352
+ const { basePath = "/blox", previewPath = "/preview/:pageId?", renderPath = "/render/:pageId?", meta = {} } = routeOptions;
1353
+ router.addRoute({
1354
+ path: `${basePath}${previewPath}`,
1355
+ name: "blox-preview",
1356
+ component: ExternalPreview_default,
1357
+ meta: {
1358
+ blox: true,
1359
+ ...meta
1360
+ }
1361
+ });
1362
+ router.addRoute({
1363
+ path: `${basePath}${renderPath}`,
1364
+ name: "blox-render",
1365
+ component: RenderPage_default,
1366
+ meta: {
1367
+ blox: true,
1368
+ ...meta
1369
+ }
1370
+ });
1371
+ const routes = {
1372
+ preview: `${basePath}${previewPath}`,
1373
+ render: `${basePath}${renderPath}`
1374
+ };
1375
+ log("Registered Blox routes:", routes);
1376
+ if (!debug) console.log("✅ Registered Blox routes:", routes);
1377
+ return instance;
1378
+ },
1379
+ getRegisteredComponents() {
1380
+ return [...registeredConfigs];
1381
+ },
1382
+ getComponentsByCategory(category) {
1383
+ return registeredConfigs.filter((config) => config.category === category);
1384
+ },
1385
+ getComponentIds() {
1386
+ return registeredConfigs.map((config) => config.id);
1387
+ },
1388
+ hasComponent(id) {
1389
+ return registeredConfigs.some((config) => config.id === id);
1390
+ },
1391
+ install(app) {
1392
+ app.config.globalProperties.$blox = {
1393
+ configs: registeredConfigs,
1394
+ getComponent: (id) => {
1395
+ const config = registeredConfigs.find((c) => c.id === id);
1396
+ if (!config && debug) {
1397
+ const error = createMissingComponentError(id, this.getComponentIds());
1398
+ console.error(error.message);
1399
+ }
1400
+ return config;
1401
+ },
1402
+ getComponentsByCategory: (category) => this.getComponentsByCategory(category),
1403
+ hasComponent: (id) => registeredConfigs.some((c) => c.id === id)
1404
+ };
1405
+ app.provide("blox", {
1406
+ configs: registeredConfigs,
1407
+ getComponent: (id) => {
1408
+ const config = registeredConfigs.find((c) => c.id === id);
1409
+ if (!config && debug) {
1410
+ const error = createMissingComponentError(id, this.getComponentIds());
1411
+ console.error(error.message);
1412
+ }
1413
+ return config;
1414
+ },
1415
+ getComponentsByCategory: (category) => this.getComponentsByCategory(category),
1416
+ hasComponent: (id) => registeredConfigs.some((c) => c.id === id)
1417
+ });
1418
+ log("Blox plugin installed with", registeredConfigs.length, "components");
1419
+ if (!debug) console.log("✅ Blox plugin installed");
1420
+ if (debug) {
1421
+ console.log("[Blox] Registered components:", this.getComponentIds());
1422
+ const categories = [...new Set(registeredConfigs.map((c) => c.category).filter((cat) => Boolean(cat)))];
1423
+ console.log("[Blox] Categories:", categories);
1424
+ console.log("[Blox] Debug mode enabled");
1425
+ }
1426
+ }
1427
+ };
1428
+ return instance;
1429
+ }
1430
+ function createComponentConfig(config) {
1431
+ return config;
1432
+ }
1433
+ function getAllComponentConfigs(customConfigs = []) {
1434
+ return [...baseComponentConfigs, ...customConfigs];
1435
+ }
1436
+ function registerBaseComponents() {
1437
+ const componentMap = {};
1438
+ baseComponentConfigs.forEach((config) => {
1439
+ componentMap[config.id] = config.component;
1440
+ });
1441
+ registerComponents(componentMap);
1442
+ console.log("✅ Registered base components:", Object.keys(componentMap));
1443
+ }
1444
+ function registerCustomComponent(config) {
1445
+ registerComponent(config.id, config.component);
1446
+ console.log(`✅ Registered custom component: ${config.id}`);
1447
+ }
1448
+ function registerCustomComponents(configs) {
1449
+ configs.forEach((config) => {
1450
+ registerCustomComponent(config);
1451
+ });
1452
+ }
1453
+ export { Button_default as Button, ButtonConfig, CommunicationBridge, ComponentValidationError, Container_default as Container, ContainerConfig, ExternalPreview_default as ExternalPreview, Image_default as Image, ImageConfig, RenderPage_default as RenderPage, Spacer_default as Spacer, SpacerConfig, Text_default as Text, TextConfig, Title_default as Title, TitleConfig, applyGlobalFont, applyPageSettings, baseComponentConfigs, clearRegistry, createBlox, createCommunicationBridge, createComponentConfig, createNamespacedRegistry, deepClone, deepMerge, generateBlockStyles, getAllComponentConfigs, getAllComponents, getBaseComponentConfig, getBaseComponentConfigs, getComponent, getRegisteredTypes, getResponsiveCSS, getResponsiveClasses, hasComponent, initializePage, injectCode, injectResponsiveCSS, loadComponentFonts, loadGoogleFont, normalizeComponentData, registerBaseComponents, registerComponent, registerComponents, registerCustomComponent, registerCustomComponents, registry, sendMessage, unregisterComponent };