@getvitops/emdash 1.0.0-alpha.0 → 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.
- package/CHANGELOG.md +210 -3
- package/README.md +66 -21
- package/dist/index.d.mts +49 -17
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +368 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -13
- package/src/astro/blocks/Accordion.astro +39 -0
- package/src/astro/blocks/ActionLink.astro +4 -2
- package/src/astro/blocks/Cards.astro +52 -0
- package/src/astro/blocks/Carousel.astro +25 -8
- package/src/astro/blocks/Gallery.astro +40 -0
- package/src/astro/blocks/Hero.astro +61 -0
- package/src/astro/blocks/ImageCompare.astro +5 -2
- package/src/astro/blocks/Marquee.astro +38 -0
- package/src/astro/blocks/value.test.ts +21 -0
- package/src/astro/blocks/value.ts +26 -1
- package/src/astro/index.ts +10 -0
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { designSystemPath, formatConfig, getAt, isConfig, mergePatch, resolveInp
|
|
|
4
4
|
import { buildReverseIndex, patchToOverrideCss, validateColorContract } from "@getvitops/generator/tokens";
|
|
5
5
|
import { commitFile } from "@getvitops/utils/git";
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
// src/icon-options.ts
|
|
8
8
|
/**
|
|
9
9
|
* Semantic icon names, as Block Kit combobox options.
|
|
10
10
|
*
|
|
@@ -25,8 +25,7 @@ const SEMANTIC_ICON_OPTIONS = Object.keys(iconMap.fa7).sort().map((name) => ({
|
|
|
25
25
|
value: name
|
|
26
26
|
}));
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
//#region src/blocks.ts
|
|
28
|
+
// src/blocks.ts
|
|
30
29
|
const BLOCKS = [
|
|
31
30
|
{
|
|
32
31
|
/**
|
|
@@ -270,17 +269,34 @@ const BLOCKS = [
|
|
|
270
269
|
type: "vitops.carousel",
|
|
271
270
|
label: "Carousel",
|
|
272
271
|
placeholder: "Image carousel",
|
|
272
|
+
category: "Media",
|
|
273
273
|
fields: [
|
|
274
|
+
{
|
|
275
|
+
type: "repeater",
|
|
276
|
+
action_id: "slides",
|
|
277
|
+
label: "Slides",
|
|
278
|
+
item_label: "slide",
|
|
279
|
+
min_items: 1,
|
|
280
|
+
fields: [{
|
|
281
|
+
type: "text_input",
|
|
282
|
+
action_id: "src",
|
|
283
|
+
label: "Image URL"
|
|
284
|
+
}, {
|
|
285
|
+
type: "text_input",
|
|
286
|
+
action_id: "alt",
|
|
287
|
+
label: "Alt text"
|
|
288
|
+
}]
|
|
289
|
+
},
|
|
274
290
|
{
|
|
275
291
|
type: "text_input",
|
|
276
292
|
action_id: "images",
|
|
277
|
-
label: "Image URLs
|
|
293
|
+
label: "Image URLs, one per line (legacy — use Slides)",
|
|
278
294
|
multiline: true
|
|
279
295
|
},
|
|
280
296
|
{
|
|
281
297
|
type: "text_input",
|
|
282
298
|
action_id: "alts",
|
|
283
|
-
label: "Alt texts
|
|
299
|
+
label: "Alt texts, one per line (legacy — use Slides)",
|
|
284
300
|
multiline: true
|
|
285
301
|
},
|
|
286
302
|
{
|
|
@@ -308,11 +324,302 @@ const BLOCKS = [
|
|
|
308
324
|
initial_value: "16 / 9"
|
|
309
325
|
}
|
|
310
326
|
]
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
type: "vitops.gallery",
|
|
330
|
+
label: "Gallery",
|
|
331
|
+
placeholder: "Thumbnail grid that opens a lightbox carousel",
|
|
332
|
+
category: "Media",
|
|
333
|
+
fields: [
|
|
334
|
+
{
|
|
335
|
+
type: "text_input",
|
|
336
|
+
action_id: "label",
|
|
337
|
+
label: "Accessible name",
|
|
338
|
+
initial_value: "Gallery"
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
type: "repeater",
|
|
342
|
+
action_id: "images",
|
|
343
|
+
label: "Images",
|
|
344
|
+
item_label: "image",
|
|
345
|
+
min_items: 1,
|
|
346
|
+
fields: [
|
|
347
|
+
{
|
|
348
|
+
type: "text_input",
|
|
349
|
+
action_id: "src",
|
|
350
|
+
label: "Image URL"
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
type: "text_input",
|
|
354
|
+
action_id: "alt",
|
|
355
|
+
label: "Alt text"
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
type: "text_input",
|
|
359
|
+
action_id: "caption",
|
|
360
|
+
label: "Caption"
|
|
361
|
+
}
|
|
362
|
+
]
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
type: "text_input",
|
|
366
|
+
action_id: "aspect",
|
|
367
|
+
label: "Thumbnail aspect ratio",
|
|
368
|
+
initial_value: "1"
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
type: "toggle",
|
|
372
|
+
action_id: "loop",
|
|
373
|
+
label: "Wrap around at the ends",
|
|
374
|
+
initial_value: false
|
|
375
|
+
}
|
|
376
|
+
]
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
type: "vitops.cards",
|
|
380
|
+
label: "Cards",
|
|
381
|
+
placeholder: "A grid of cards",
|
|
382
|
+
category: "Sections",
|
|
383
|
+
fields: [{
|
|
384
|
+
type: "repeater",
|
|
385
|
+
action_id: "cards",
|
|
386
|
+
label: "Cards",
|
|
387
|
+
item_label: "card",
|
|
388
|
+
min_items: 1,
|
|
389
|
+
fields: [
|
|
390
|
+
{
|
|
391
|
+
type: "text_input",
|
|
392
|
+
action_id: "title",
|
|
393
|
+
label: "Title"
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
type: "text_input",
|
|
397
|
+
action_id: "body",
|
|
398
|
+
label: "Text",
|
|
399
|
+
multiline: true
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
type: "text_input",
|
|
403
|
+
action_id: "image",
|
|
404
|
+
label: "Image URL"
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
type: "text_input",
|
|
408
|
+
action_id: "imageAlt",
|
|
409
|
+
label: "Image alt text"
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
type: "text_input",
|
|
413
|
+
action_id: "href",
|
|
414
|
+
label: "Link URL (makes the whole card clickable)"
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
type: "text_input",
|
|
418
|
+
action_id: "linkLabel",
|
|
419
|
+
label: "Link text",
|
|
420
|
+
initial_value: "Read more"
|
|
421
|
+
}
|
|
422
|
+
]
|
|
423
|
+
}, {
|
|
424
|
+
type: "select",
|
|
425
|
+
action_id: "columns",
|
|
426
|
+
label: "Columns",
|
|
427
|
+
initial_value: "3",
|
|
428
|
+
options: [
|
|
429
|
+
{
|
|
430
|
+
label: "1",
|
|
431
|
+
value: "1"
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
label: "2",
|
|
435
|
+
value: "2"
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
label: "3",
|
|
439
|
+
value: "3"
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
label: "4",
|
|
443
|
+
value: "4"
|
|
444
|
+
}
|
|
445
|
+
]
|
|
446
|
+
}]
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
type: "vitops.accordion",
|
|
450
|
+
label: "Accordion",
|
|
451
|
+
placeholder: "A group of collapsible sections",
|
|
452
|
+
category: "Sections",
|
|
453
|
+
fields: [{
|
|
454
|
+
type: "repeater",
|
|
455
|
+
action_id: "items",
|
|
456
|
+
label: "Items",
|
|
457
|
+
item_label: "item",
|
|
458
|
+
min_items: 1,
|
|
459
|
+
fields: [
|
|
460
|
+
{
|
|
461
|
+
type: "text_input",
|
|
462
|
+
action_id: "summary",
|
|
463
|
+
label: "Summary (always visible)"
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
type: "text_input",
|
|
467
|
+
action_id: "body",
|
|
468
|
+
label: "Body (revealed)",
|
|
469
|
+
multiline: true
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
type: "toggle",
|
|
473
|
+
action_id: "open",
|
|
474
|
+
label: "Open by default",
|
|
475
|
+
initial_value: false
|
|
476
|
+
}
|
|
477
|
+
]
|
|
478
|
+
}, {
|
|
479
|
+
type: "toggle",
|
|
480
|
+
action_id: "exclusive",
|
|
481
|
+
label: "Only one open at a time",
|
|
482
|
+
initial_value: false
|
|
483
|
+
}]
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
type: "vitops.hero",
|
|
487
|
+
label: "Hero",
|
|
488
|
+
placeholder: "Page opener: heading, text, buttons and an optional image",
|
|
489
|
+
category: "Sections",
|
|
490
|
+
fields: [
|
|
491
|
+
{
|
|
492
|
+
type: "text_input",
|
|
493
|
+
action_id: "eyebrow",
|
|
494
|
+
label: "Eyebrow (small line above)"
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
type: "text_input",
|
|
498
|
+
action_id: "heading",
|
|
499
|
+
label: "Heading"
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
type: "text_input",
|
|
503
|
+
action_id: "body",
|
|
504
|
+
label: "Text",
|
|
505
|
+
multiline: true
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
type: "text_input",
|
|
509
|
+
action_id: "primaryLabel",
|
|
510
|
+
label: "Main button text"
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
type: "text_input",
|
|
514
|
+
action_id: "primaryHref",
|
|
515
|
+
label: "Main button URL"
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
type: "text_input",
|
|
519
|
+
action_id: "secondaryLabel",
|
|
520
|
+
label: "Second link text"
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
type: "text_input",
|
|
524
|
+
action_id: "secondaryHref",
|
|
525
|
+
label: "Second link URL"
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
type: "text_input",
|
|
529
|
+
action_id: "image",
|
|
530
|
+
label: "Image URL (split layout)"
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
type: "text_input",
|
|
534
|
+
action_id: "imageAlt",
|
|
535
|
+
label: "Image alt text"
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
type: "select",
|
|
539
|
+
action_id: "layout",
|
|
540
|
+
label: "Layout",
|
|
541
|
+
initial_value: "centered",
|
|
542
|
+
options: [{
|
|
543
|
+
label: "Centered",
|
|
544
|
+
value: "centered"
|
|
545
|
+
}, {
|
|
546
|
+
label: "Text and image side by side",
|
|
547
|
+
value: "split"
|
|
548
|
+
}]
|
|
549
|
+
}
|
|
550
|
+
]
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
type: "vitops.marquee",
|
|
554
|
+
label: "Marquee",
|
|
555
|
+
placeholder: "A continuously scrolling row (logos, quotes, badges)",
|
|
556
|
+
category: "Media",
|
|
557
|
+
fields: [
|
|
558
|
+
{
|
|
559
|
+
type: "repeater",
|
|
560
|
+
action_id: "items",
|
|
561
|
+
label: "Items",
|
|
562
|
+
item_label: "item",
|
|
563
|
+
min_items: 1,
|
|
564
|
+
fields: [
|
|
565
|
+
{
|
|
566
|
+
type: "text_input",
|
|
567
|
+
action_id: "text",
|
|
568
|
+
label: "Text"
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
type: "text_input",
|
|
572
|
+
action_id: "image",
|
|
573
|
+
label: "Image URL (shown instead of text)"
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
type: "text_input",
|
|
577
|
+
action_id: "alt",
|
|
578
|
+
label: "Image alt text"
|
|
579
|
+
}
|
|
580
|
+
]
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
type: "toggle",
|
|
584
|
+
action_id: "pauseOnHover",
|
|
585
|
+
label: "Pause on hover",
|
|
586
|
+
initial_value: true
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
type: "toggle",
|
|
590
|
+
action_id: "reverse",
|
|
591
|
+
label: "Scroll the other way",
|
|
592
|
+
initial_value: false
|
|
593
|
+
}
|
|
594
|
+
]
|
|
311
595
|
}
|
|
312
596
|
];
|
|
597
|
+
/**
|
|
598
|
+
* Resolve {@link BlockSelection} against {@link BLOCKS}.
|
|
599
|
+
*
|
|
600
|
+
* Pure so a misconfiguration fails at plugin construction, with the offending name in the
|
|
601
|
+
* message, rather than as an editor menu that is quietly missing something.
|
|
602
|
+
*/
|
|
603
|
+
function selectBlocks(selection = {}) {
|
|
604
|
+
const known = new Set(BLOCKS.map((b) => b.type));
|
|
605
|
+
const check = (names, option) => {
|
|
606
|
+
for (const name of names ?? []) if (!known.has(name)) throw new Error(`[vitops] blocks.${option}: unknown block '${name}'. Known: ${[...known].join(", ")}.`);
|
|
607
|
+
};
|
|
608
|
+
check(selection.include, "include");
|
|
609
|
+
check(selection.exclude, "exclude");
|
|
610
|
+
const include = selection.include ? new Set(selection.include) : null;
|
|
611
|
+
const exclude = new Set(selection.exclude);
|
|
612
|
+
const base = BLOCKS.filter((b) => (!include || include.has(b.type)) && !exclude.has(b.type));
|
|
613
|
+
const extra = selection.extra ?? [];
|
|
614
|
+
const taken = new Set(BLOCKS.map((b) => b.type));
|
|
615
|
+
for (const block of extra) {
|
|
616
|
+
if (taken.has(block.type)) throw new Error(`[vitops] blocks.extra: type '${block.type}' is already defined.`);
|
|
617
|
+
taken.add(block.type);
|
|
618
|
+
}
|
|
619
|
+
return [...base, ...extra];
|
|
620
|
+
}
|
|
313
621
|
|
|
314
|
-
|
|
315
|
-
//#region src/design-system-route.ts
|
|
622
|
+
// src/design-system-route.ts
|
|
316
623
|
/**
|
|
317
624
|
* The `vitops.design-system` plugin route — what `<wc-theme-editor>` probes
|
|
318
625
|
* and POSTs its patch to when mounted inside the EmDash admin (see this
|
|
@@ -453,8 +760,53 @@ async function designSystemOverrideFragment(ctx, opts) {
|
|
|
453
760
|
};
|
|
454
761
|
}
|
|
455
762
|
|
|
456
|
-
|
|
457
|
-
|
|
763
|
+
// src/blocks-doc.ts
|
|
764
|
+
const cell = (s) => (s ?? "").replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
765
|
+
function describe(f) {
|
|
766
|
+
const bits = [];
|
|
767
|
+
if ("options" in f && Array.isArray(f.options) && f.options.length) {
|
|
768
|
+
const values = f.options.map((o) => String(o.value));
|
|
769
|
+
bits.push(values.length > 8 ? `one of ${values.length} values (e.g. ${values.slice(0, 4).join(", ")})` : `one of ${values.join(", ")}`);
|
|
770
|
+
}
|
|
771
|
+
if ("initial_value" in f && f.initial_value !== void 0) bits.push(`default \`${String(f.initial_value)}\``);
|
|
772
|
+
if (f.type === "repeater" && "min_items" in f && f.min_items) bits.push(`min ${f.min_items} rows`);
|
|
773
|
+
return bits.join("; ");
|
|
774
|
+
}
|
|
775
|
+
function fieldRows(fields, prefix = "") {
|
|
776
|
+
return fields.flatMap((f) => {
|
|
777
|
+
const own = `| \`${prefix}${f.action_id}\` | ${f.type} | ${cell(f.label)} | ${cell(describe(f))} |`;
|
|
778
|
+
return f.type === "repeater" ? [own, ...fieldRows(f.fields, `${f.action_id}[].`)] : [own];
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* The block reference an agent reads via `vitops docs blocks`: every Portable Text `_type`,
|
|
783
|
+
* its fields and what each saves. Rendered from the same `BLOCKS` the editor menu uses, so
|
|
784
|
+
* it cannot describe a field the editor doesn't offer.
|
|
785
|
+
*/
|
|
786
|
+
function renderBlocksDoc(blocks = BLOCKS) {
|
|
787
|
+
const out = [
|
|
788
|
+
"---",
|
|
789
|
+
"type: concept",
|
|
790
|
+
"title: EmDash blocks",
|
|
791
|
+
"description: Portable Text block types from @getvitops/emdash, with every field",
|
|
792
|
+
"---",
|
|
793
|
+
"",
|
|
794
|
+
"# EmDash blocks",
|
|
795
|
+
"",
|
|
796
|
+
"Each block is a Portable Text object: `{ \"_type\": \"vitops.cards\", \"_key\": \"<unique>\", ...fields }`.",
|
|
797
|
+
"Blocks are flat — a block cannot contain other blocks, and a repeater row holds scalar fields only.",
|
|
798
|
+
"Give every block a unique `_key`; gallery and carousel derive their element id from it.",
|
|
799
|
+
""
|
|
800
|
+
];
|
|
801
|
+
for (const b of blocks) {
|
|
802
|
+
out.push(`## \`${b.type}\` — ${b.label}`, "");
|
|
803
|
+
if (b.placeholder) out.push(`${b.placeholder}.`, "");
|
|
804
|
+
if (b.fields?.length) out.push("| Field | Type | Label | Notes |", "| --- | --- | --- | --- |", ...fieldRows(b.fields), "");
|
|
805
|
+
}
|
|
806
|
+
return out.join("\n");
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
// src/hosting.ts
|
|
458
810
|
const TARGETS = ["cloudflare", "node"];
|
|
459
811
|
/**
|
|
460
812
|
* Import an optional hosting dependency. The specifier is passed as a
|
|
@@ -483,7 +835,8 @@ async function vitopsHosting(options = {}) {
|
|
|
483
835
|
adapter: cloudflare(),
|
|
484
836
|
database: d1({
|
|
485
837
|
binding: cf.dbBinding ?? "DB",
|
|
486
|
-
session: cf.session ?? "auto"
|
|
838
|
+
session: cf.session ?? "auto",
|
|
839
|
+
coalesce: cf.coalesce ?? true
|
|
487
840
|
}),
|
|
488
841
|
storage: r2({ binding: cf.mediaBinding ?? "MEDIA" })
|
|
489
842
|
};
|
|
@@ -513,12 +866,10 @@ async function vitopsHosting(options = {}) {
|
|
|
513
866
|
throw new Error(`[vitops] unknown hosting target '${target}' (from ${process.env.HOSTING ? "HOSTING env var" : "options.target"}). Valid targets: ${TARGETS.join(", ")}.`);
|
|
514
867
|
}
|
|
515
868
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
var version = "1.0.0-alpha.0";
|
|
869
|
+
// package.json
|
|
870
|
+
var version = "1.0.0";
|
|
519
871
|
|
|
520
|
-
|
|
521
|
-
//#region src/index.ts
|
|
872
|
+
// src/index.ts
|
|
522
873
|
/**
|
|
523
874
|
* @getvitops/emdash — EmDash CMS native plugin for the Vitops design system.
|
|
524
875
|
*
|
|
@@ -605,7 +956,7 @@ function createPlugin(options = {}) {
|
|
|
605
956
|
...editor ? { allowedHosts: ["api.github.com"] } : {},
|
|
606
957
|
...fragmentsEnabled ? { hooks: { "page:fragments": pageFragments } } : {},
|
|
607
958
|
admin: {
|
|
608
|
-
portableTextBlocks:
|
|
959
|
+
portableTextBlocks: selectBlocks(options.blocks),
|
|
609
960
|
...editor ? {
|
|
610
961
|
entry: "@getvitops/emdash/admin",
|
|
611
962
|
pages: [{
|
|
@@ -619,6 +970,5 @@ function createPlugin(options = {}) {
|
|
|
619
970
|
});
|
|
620
971
|
}
|
|
621
972
|
|
|
622
|
-
|
|
623
|
-
export { BLOCKS, createPlugin, createPlugin as default, vitopsEmdash, vitopsHosting };
|
|
973
|
+
export { BLOCKS, createPlugin, createPlugin as default, renderBlocksDoc, selectBlocks, vitopsEmdash, vitopsHosting };
|
|
624
974
|
//# sourceMappingURL=index.mjs.map
|