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