返回 presentation-ai
templates.tsx
根目录 / src / components / notebook / presentation / utils / templates.tsx
1 import {
2 ArrowRight,
3 BarChart3,
4 CreditCard,
5 Flower,
6 GitCompare,
7 Grid3x3,
8 Hash,
9 ImageIcon,
10 List,
11 ListOrdered,
12 Quote,
13 Shapes,
14 Square,
15 Triangle,
16 } from "lucide-react";
17 import { nanoid } from "nanoid";
18
19 import {
20 AREA_CHART_ELEMENT,
21 ARROW_LIST,
22 ARROW_LIST_ITEM,
23 BAR_CHART_ELEMENT,
24 BEFORE_AFTER_GROUP,
25 BEFORE_AFTER_SIDE,
26 BOX_GROUP,
27 BOX_ITEM,
28 BOX_PLOT_CHART_ELEMENT,
29 BUBBLE_CHART_ELEMENT,
30 BULLET_GROUP,
31 BULLET_ITEM,
32 CANDLESTICK_CHART_ELEMENT,
33 CHORD_CHART_ELEMENT,
34 CIRCULAR_GRID_GROUP,
35 CIRCULAR_GRID_ITEM,
36 COLUMN_GROUP,
37 COLUMN_ITEM,
38 COMPARE_GROUP,
39 COMPARE_SIDE,
40 COMPOSED_CHART_ELEMENT,
41 CONE_FUNNEL_CHART_ELEMENT,
42 CONNECTED_CIRCLES_GROUP,
43 CONNECTED_CIRCLES_ITEM,
44 CONS_ITEM,
45 CYCLE_GROUP,
46 CYCLE_ITEM,
47 FUNNEL_CHART_ELEMENT,
48 getDefaultChartDataForType,
49 HEATMAP_CHART_ELEMENT,
50 HISTOGRAM_CHART_ELEMENT,
51 ICON_LIST,
52 ICON_LIST_ITEM,
53 LINE_CHART_ELEMENT,
54 LINEAR_GAUGE_ELEMENT,
55 NIGHTINGALE_CHART_ELEMENT,
56 OHLC_CHART_ELEMENT,
57 PIE_CHART_ELEMENT,
58 PRESENTATION_TITLE_ELEMENT,
59 PROS_CONS_GROUP,
60 PROS_ITEM,
61 PYRAMID_CHART_ELEMENT,
62 PYRAMID_GROUP,
63 PYRAMID_ITEM,
64 QUOTE_ELEMENT,
65 RADAR_CHART_ELEMENT,
66 RADIAL_BAR_CHART_ELEMENT,
67 RADIAL_COLUMN_CHART_ELEMENT,
68 RADIAL_GAUGE_ELEMENT,
69 RANGE_AREA_CHART_ELEMENT,
70 RANGE_BAR_CHART_ELEMENT,
71 SANKEY_CHART_ELEMENT,
72 SCATTER_CHART_ELEMENT,
73 SEQUENCE_ARROW_GROUP,
74 SEQUENCE_ARROW_ITEM,
75 SLOPE_GROUP,
76 SLOPE_ITEM,
77 SNAKE_GROUP,
78 SNAKE_ITEM,
79 STAIR_ITEM,
80 STAIRCASE_GROUP,
81 STATS_GROUP,
82 STATS_ITEM,
83 STEPS_GROUP,
84 STEPS_ITEM,
85 SUNBURST_CHART_ELEMENT,
86 TIMELINE_GROUP,
87 TIMELINE_ITEM,
88 TREEMAP_CHART_ELEMENT,
89 WATERFALL_CHART_ELEMENT,
90 } from "../editor/lib";
91 import { type PlateSlide } from "./parser";
92 import * as Previews from "./template-previews";
93
94 export interface TemplateCategory {
95 id: string;
96 name: string;
97 icon: React.ReactNode;
98 }
99
100 export interface TemplateDefinition {
101 id: string;
102 legacyIds?: string[];
103 name: string;
104 categoryId: string;
105 preview: React.ReactNode;
106 template: Omit<PlateSlide, "id">;
107 }
108
109 export function getTemplateSelectionIds(
110 template: TemplateDefinition,
111 ): string[] {
112 return [template.id, ...(template.legacyIds ?? [])];
113 }
114
115 export function isTemplateSelected(
116 selectedTemplateIds: readonly string[],
117 template: TemplateDefinition,
118 ): boolean {
119 const templateIds = new Set(getTemplateSelectionIds(template));
120
121 return selectedTemplateIds.some((templateId) => templateIds.has(templateId));
122 }
123
124 export function removeTemplateSelection(
125 selectedTemplateIds: readonly string[],
126 template: TemplateDefinition,
127 ): string[] {
128 const templateIds = new Set(getTemplateSelectionIds(template));
129
130 return selectedTemplateIds.filter(
131 (templateId) => !templateIds.has(templateId),
132 );
133 }
134
135 const createBaseContent = (
136 title: string = "Main message",
137 desc: string = "One concise supporting sentence that explains the point.",
138 ) => [
139 { type: "h2", id: nanoid(), children: [{ text: title }] },
140 {
141 type: "p",
142 id: nanoid(),
143 children: [{ text: desc }],
144 },
145 ];
146
147 const createTitleDescriptionContent = (
148 title: string = "Title",
149 desc: string = "A short supporting description that explains the main point.",
150 ) => [
151 {
152 type: PRESENTATION_TITLE_ELEMENT,
153 id: nanoid(),
154 variant: "title",
155 children: [{ text: title }],
156 },
157 {
158 type: "p",
159 id: nanoid(),
160 children: [{ text: desc }],
161 },
162 ];
163
164 const createTextImageColumnContent = ({
165 imageFirst,
166 }: {
167 imageFirst: boolean;
168 }) => {
169 const textColumn = {
170 type: COLUMN_ITEM,
171 id: nanoid(),
172 children: createTitleDescriptionContent(
173 "Title",
174 "Description text goes here.",
175 ),
176 };
177 const imageColumn = {
178 type: COLUMN_ITEM,
179 id: nanoid(),
180 children: [
181 {
182 type: "img",
183 query: "relevant topic visual",
184 id: nanoid(),
185 children: [{ text: "" }],
186 },
187 ],
188 };
189
190 return [
191 {
192 type: COLUMN_GROUP,
193 id: nanoid(),
194 layout: [1, 1],
195 children: imageFirst
196 ? [imageColumn, textColumn]
197 : [textColumn, imageColumn],
198 },
199 ];
200 };
201
202 const createListContent = ({
203 type = "basic",
204 items = 4,
205 }: {
206 type?: "basic" | "numbered" | "arrow";
207 items?: number;
208 }) => [
209 { type: "h2", id: nanoid(), children: [{ text: "List Title" }] },
210 {
211 type: BULLET_GROUP,
212 id: nanoid(),
213 bulletType: type, // Default to basic
214 children: Array.from({ length: items }).map((_, index) => ({
215 type: BULLET_ITEM,
216 id: nanoid(),
217 children: createDiagramTextChildren(
218 `Point ${index + 1}`,
219 "Short evidence or implication.",
220 ),
221 })),
222 },
223 ];
224
225 const createBoxContent = (
226 variant:
227 | "solid"
228 | "outline"
229 | "icon"
230 | "sideline"
231 | "side-label"
232 | "top-label"
233 | "top-circle"
234 | "joined"
235 | "joined-icon"
236 | "leaf"
237 | "labeled"
238 | "alternating",
239 items: number = 4,
240 ) => [
241 { type: "h2", id: nanoid(), children: [{ text: "Box Layout" }] },
242 {
243 type: BOX_GROUP,
244 id: nanoid(),
245 boxType: variant,
246 columnSize: "md",
247 children: Array.from({ length: items }).map((_, index) => ({
248 type: BOX_ITEM,
249 id: nanoid(),
250 icon: variant.includes("icon") ? "idea" : undefined,
251 children: createDiagramTextChildren(
252 `Card ${index + 1}`,
253 "Compact supporting detail.",
254 ),
255 })),
256 },
257 ];
258 const createChartContent = (type: string, title: string, variant?: string) => {
259 return [
260 { type: "h2", id: nanoid(), children: [{ text: title }] },
261 {
262 type,
263 id: nanoid(),
264 data: getDefaultChartDataForType(type),
265 variant,
266 children: [{ text: "" }], // Void element
267 },
268 ];
269 };
270
271 const createCycleContent = (items: number = 4) => [
272 { type: "h2", id: nanoid(), children: [{ text: "Cycle Process" }] },
273 {
274 type: CYCLE_GROUP,
275 id: nanoid(),
276 children: Array.from({ length: items }).map(() => ({
277 type: CYCLE_ITEM,
278 id: nanoid(),
279 children: [{ text: "Step" }],
280 })),
281 },
282 ];
283
284 const createDiagramTextChildren = (title: string, desc: string) => [
285 { type: "h3", id: nanoid(), children: [{ text: title }] },
286 { type: "p", id: nanoid(), children: [{ text: desc }] },
287 ];
288
289 const createSlopeContent = () => [
290 { type: "h2", id: nanoid(), children: [{ text: "Growth Path" }] },
291 {
292 type: SLOPE_GROUP,
293 id: nanoid(),
294 children: ["Ideate", "Prototype", "Validate", "Scale"].map((title) => ({
295 type: SLOPE_ITEM,
296 id: nanoid(),
297 icon: "idea",
298 children: [{ type: "h4", id: nanoid(), children: [{ text: title }] }],
299 })),
300 },
301 ];
302
303 const createConnectedCirclesContent = () => [
304 { type: "h2", id: nanoid(), children: [{ text: "Connected Priorities" }] },
305 {
306 type: CONNECTED_CIRCLES_GROUP,
307 id: nanoid(),
308 children: (
309 [
310 ["Plan", "Define goals and align stakeholders."],
311 ["Build", "Develop features while iterating."],
312 ["Validate", "Test assumptions and refine direction."],
313 ["Scale", "Expand reach while preserving quality."],
314 ] satisfies ReadonlyArray<readonly [string, string]>
315 ).map(([title, desc]) => ({
316 type: CONNECTED_CIRCLES_ITEM,
317 id: nanoid(),
318 children: createDiagramTextChildren(title, desc),
319 })),
320 },
321 ];
322
323 const createCircularGridContent = () => [
324 { type: "h2", id: nanoid(), children: [{ text: "Smart Diagram" }] },
325 {
326 type: CIRCULAR_GRID_GROUP,
327 id: nanoid(),
328 centerText: "Smart Diagram",
329 children: (
330 [
331 ["Objective", "Define the main goal."],
332 ["Signals", "Capture the inputs that matter."],
333 ["Actions", "Translate insights into work."],
334 ["Metrics", "Track the change over time."],
335 ["Risks", "Surface assumptions early."],
336 ["Learning", "Feed results into the next cycle."],
337 ] satisfies ReadonlyArray<readonly [string, string]>
338 ).map(([title, desc]) => ({
339 type: CIRCULAR_GRID_ITEM,
340 id: nanoid(),
341 children: createDiagramTextChildren(title, desc),
342 })),
343 },
344 ];
345
346 const createSnakeContent = () => [
347 { type: "h2", id: nanoid(), children: [{ text: "Delivery Flow" }] },
348 {
349 type: SNAKE_GROUP,
350 id: nanoid(),
351 children: (
352 [
353 ["Assess", "Evaluate needs and current state."],
354 ["Plan", "Define strategy and roadmap."],
355 ["Build", "Develop solutions and integrations."],
356 ["Validate", "Test, iterate, and refine."],
357 ["Scale", "Deploy broadly and optimize."],
358 ] satisfies ReadonlyArray<readonly [string, string]>
359 ).map(([title, desc]) => ({
360 type: SNAKE_ITEM,
361 id: nanoid(),
362 children: createDiagramTextChildren(title, desc),
363 })),
364 },
365 ];
366
367 const createStaircaseContent = (items: number = 4) => [
368 { type: "h2", id: nanoid(), children: [{ text: "Staircase" }] },
369 {
370 type: STAIRCASE_GROUP,
371 id: nanoid(),
372 variant: "inside",
373 children: Array.from({ length: items }).map((_, index) => ({
374 type: STAIR_ITEM,
375 id: nanoid(),
376 children: createDiagramTextChildren(
377 `Level ${index + 1}`,
378 "Progress marker.",
379 ),
380 })),
381 },
382 ];
383
384 const createPyramidContent = (variant: "pyramid" | "funnel") => [
385 {
386 type: "h2",
387 id: nanoid(),
388 children: [{ text: variant === "pyramid" ? "Pyramid" : "Funnel" }],
389 },
390 {
391 type: PYRAMID_GROUP,
392 id: nanoid(),
393 isFunnel: variant === "funnel",
394 variant: "inside",
395 children: Array.from({ length: 4 }).map((_, index) => ({
396 type: PYRAMID_ITEM,
397 id: nanoid(),
398 children: createDiagramTextChildren(
399 variant === "pyramid" ? `Layer ${index + 1}` : `Stage ${index + 1}`,
400 "Short label.",
401 ),
402 })),
403 },
404 ];
405
406 const createTimelineContent = (
407 variant: "timeline" | "arrow" | "pill" | "parallelogram" | "arrow-vertical",
408 items: number = 4,
409 ) => {
410 let groupType = TIMELINE_GROUP;
411 let itemType = TIMELINE_ITEM;
412 let extraProps = {};
413
414 if (variant === "arrow") {
415 groupType = ARROW_LIST;
416 itemType = ARROW_LIST_ITEM;
417 extraProps = { svgType: "arrow" };
418 } else if (variant === "pill") {
419 groupType = ARROW_LIST;
420 itemType = ARROW_LIST_ITEM;
421 extraProps = { svgType: "pill" };
422 } else if (variant === "parallelogram") {
423 groupType = ARROW_LIST;
424 itemType = ARROW_LIST_ITEM;
425 extraProps = { svgType: "parallelogram" };
426 } else if (variant === "arrow-vertical") {
427 groupType = SEQUENCE_ARROW_GROUP;
428 itemType = SEQUENCE_ARROW_ITEM;
429 }
430
431 return [
432 { type: "h2", id: nanoid(), children: [{ text: "Timeline / Sequence" }] },
433 {
434 type: groupType,
435 id: nanoid(),
436 ...extraProps,
437 orientation: variant === "arrow-vertical" ? "vertical" : "horizontal",
438 numbered: true,
439 showLine: true,
440 children: Array.from({ length: items }).map((_, index) => ({
441 type: itemType,
442 id: nanoid(),
443 children: createDiagramTextChildren(
444 `Step ${index + 1}`,
445 "Outcome of this stage.",
446 ),
447 })),
448 },
449 ];
450 };
451
452 const createStatsContent = (
453 variant:
454 | "plain"
455 | "circle"
456 | "star"
457 | "bar"
458 | "dot-grid"
459 | "dot-line"
460 | "circle-bold",
461 items: number = 3,
462 ) => [
463 { type: "h2", id: nanoid(), children: [{ text: "Statistics" }] },
464 {
465 type: STATS_GROUP,
466 id: nanoid(),
467 statsType: variant,
468 columnSize: "md",
469 children: Array.from({ length: items }).map((_, index) => ({
470 type: STATS_ITEM,
471 id: nanoid(),
472 stat: `${72 + index * 8}%`,
473 children: [
474 {
475 type: "p",
476 id: nanoid(),
477 children: [{ text: `Metric ${index + 1}` }],
478 },
479 ],
480 })),
481 },
482 ];
483
484 const createColumnContent = (
485 cols: number = 2,
486 options: { includeImages?: boolean } = {},
487 ) => [
488 { type: "h2", id: nanoid(), children: [{ text: "Columns Layout" }] },
489 {
490 type: COLUMN_GROUP,
491 id: nanoid(),
492 columnSize: "md",
493 layout: Array(cols).fill(1),
494 children: Array.from({ length: cols }).map((_, index) => ({
495 type: COLUMN_ITEM,
496 id: nanoid(),
497 children: [
498 ...(options.includeImages
499 ? [
500 {
501 type: "img",
502 query: `topic image ${index + 1}`,
503 id: nanoid(),
504 children: [{ text: "" }],
505 },
506 ]
507 : []),
508 {
509 type: "h3",
510 id: nanoid(),
511 children: [{ text: `Column ${index + 1}` }],
512 },
513 {
514 type: "p",
515 id: nanoid(),
516 children: [{ text: "Parallel supporting detail." }],
517 },
518 ],
519 })),
520 },
521 ];
522
523 const createQuoteContent = (
524 variant: "large" | "sidequote-icon" | "sidequote",
525 ) => [
526 {
527 type: QUOTE_ELEMENT,
528 id: nanoid(),
529 variant,
530 author: "Author Name",
531 children: [
532 {
533 text: "This is an inspiring quote that captures the essence of your message.",
534 },
535 ],
536 },
537 ];
538
539 const createCompareContent = (variant: "compare" | "before-after") => {
540 const groupType = variant === "compare" ? COMPARE_GROUP : BEFORE_AFTER_GROUP;
541 const sideType = variant === "compare" ? COMPARE_SIDE : BEFORE_AFTER_SIDE;
542 const labels =
543 variant === "compare"
544 ? (["Option A", "Option B"] as const)
545 : (["Before", "After"] as const);
546
547 return [
548 { type: "h2", id: nanoid(), children: [{ text: "Comparison" }] },
549 {
550 type: groupType,
551 id: nanoid(),
552 children: labels.map((label) => ({
553 type: sideType,
554 id: nanoid(),
555 children: [
556 { type: "h3", id: nanoid(), children: [{ text: label }] },
557 { type: "p", id: nanoid(), children: [{ text: "Key difference." }] },
558 {
559 type: "p",
560 id: nanoid(),
561 children: [{ text: "Important implication." }],
562 },
563 ],
564 })),
565 },
566 ];
567 };
568
569 const createProsConsContent = () => [
570 { type: "h2", id: nanoid(), children: [{ text: "Trade-offs" }] },
571 {
572 type: PROS_CONS_GROUP,
573 id: nanoid(),
574 children: [
575 {
576 type: PROS_ITEM,
577 id: nanoid(),
578 children: [
579 { type: "h3", id: nanoid(), children: [{ text: "Pros" }] },
580 {
581 type: "p",
582 id: nanoid(),
583 indent: 1,
584 listStyleType: "disc",
585 children: [{ text: "Positive impact." }],
586 },
587 {
588 type: "p",
589 id: nanoid(),
590 indent: 1,
591 listStyleType: "disc",
592 children: [{ text: "Why it helps." }],
593 },
594 ],
595 },
596 {
597 type: CONS_ITEM,
598 id: nanoid(),
599 children: [
600 { type: "h3", id: nanoid(), children: [{ text: "Cons" }] },
601 {
602 type: "p",
603 id: nanoid(),
604 indent: 1,
605 listStyleType: "disc",
606 children: [{ text: "Potential limitation." }],
607 },
608 {
609 type: "p",
610 id: nanoid(),
611 indent: 1,
612 listStyleType: "disc",
613 children: [{ text: "What to watch." }],
614 },
615 ],
616 },
617 ],
618 },
619 ];
620
621 const createIconListContent = () => [
622 { type: "h2", id: nanoid(), children: [{ text: "Key Signals" }] },
623 {
624 type: ICON_LIST,
625 id: nanoid(),
626 orientation: "side",
627 variant: "icon",
628 children: (
629 [
630 ["analytics", "Signal one", "What the signal tells us."],
631 ["shield", "Signal two", "Why it matters."],
632 ["growth", "Signal three", "Expected effect."],
633 ] satisfies ReadonlyArray<readonly [string, string, string]>
634 ).map(([icon, title, desc]) => ({
635 type: ICON_LIST_ITEM,
636 id: nanoid(),
637 icon,
638 children: createDiagramTextChildren(title, desc),
639 })),
640 },
641 ];
642
643 const createStepsContent = () => [
644 { type: "h2", id: nanoid(), children: [{ text: "Action Plan" }] },
645 {
646 type: STEPS_GROUP,
647 id: nanoid(),
648 variant: "arrow",
649 columnSize: "md",
650 children: ["Discover", "Build", "Launch"].map((title, index) => ({
651 type: STEPS_ITEM,
652 id: nanoid(),
653 icon: ["search", "settings", "growth"][index],
654 children: createDiagramTextChildren(title, "Short action detail."),
655 })),
656 },
657 ];
658
659 export const TEMPLATE_CATEGORIES: TemplateCategory[] = [
660 { id: "basic", name: "Basic", icon: <Grid3x3 className="size-4" /> },
661 { id: "boxes", name: "Boxes", icon: <Square className="size-4" /> },
662 { id: "bullets", name: "Bullets", icon: <List className="size-4" /> },
663 {
664 id: "card-layouts",
665 name: "Card layouts",
666 icon: <CreditCard className="size-4" />,
667 },
668 {
669 id: "charts",
670 name: "Charts & data",
671 icon: <BarChart3 className="size-4" />,
672 },
673 {
674 id: "comparison",
675 name: "Comparison",
676 icon: <GitCompare className="size-4" />,
677 },
678 { id: "circles", name: "Circles", icon: <Flower className="size-4" /> },
679 { id: "icons", name: "Icons", icon: <Shapes className="size-4" /> },
680 { id: "images", name: "Images", icon: <ImageIcon className="size-4" /> },
681 { id: "numbers", name: "Numbers", icon: <Hash className="size-4" /> },
682 { id: "pyramids", name: "Pyramids", icon: <Triangle className="size-4" /> },
683 { id: "sequence", name: "Sequence", icon: <ArrowRight className="size-4" /> },
684 { id: "steps", name: "Steps", icon: <ListOrdered className="size-4" /> },
685 { id: "quotes", name: "Quotes", icon: <Quote className="size-4" /> },
686 ];
687
688 export const TEMPLATE_DEFINITIONS: TemplateDefinition[] = [
689 // Basic
690 {
691 id: "text-and-heading",
692 legacyIds: ["text-boxes"],
693 name: "Text and Heading",
694 categoryId: "basic",
695 preview: <Previews.TextAndHeadingPreview />,
696 template: {
697 layoutType: "vertical",
698 content: createTitleDescriptionContent(
699 "Title",
700 "A concise description introduces the slide and frames the main point.",
701 ),
702 },
703 },
704 {
705 id: "text-and-image",
706 name: "Text and image",
707 categoryId: "basic",
708 preview: <Previews.TextAndImagePreview />,
709 template: {
710 content: createTextImageColumnContent({ imageFirst: false }),
711 },
712 },
713 {
714 id: "image-and-text",
715 name: "Image and text",
716 categoryId: "basic",
717 preview: <Previews.ImageAndTextPreview />,
718 template: {
719 content: createTextImageColumnContent({ imageFirst: true }),
720 },
721 },
722 {
723 id: "two-columns",
724 name: "Two columns",
725 categoryId: "comparison",
726 preview: <Previews.TwoColumnsPreview />,
727 template: {
728 content: [
729 {
730 type: COLUMN_GROUP,
731 id: nanoid(),
732 layout: [1, 1],
733 children: [
734 {
735 type: COLUMN_ITEM,
736 id: nanoid(),
737 children: [
738 {
739 type: "h3",
740 id: nanoid(),
741 children: [{ text: "First Column" }],
742 },
743 {
744 type: "p",
745 id: nanoid(),
746 children: [{ text: "Description text goes here." }],
747 },
748 ],
749 },
750 {
751 type: COLUMN_ITEM,
752 id: nanoid(),
753 children: [
754 {
755 type: "h3",
756 id: nanoid(),
757 children: [{ text: "Second Column" }],
758 },
759 {
760 type: "p",
761 id: nanoid(),
762 children: [{ text: "Description text goes here." }],
763 },
764 ],
765 },
766 ],
767 },
768 ],
769 },
770 },
771 {
772 id: "two-columns-with-heading",
773 name: "Two columns with heading",
774 categoryId: "comparison",
775 preview: <Previews.TwoColumnsWithHeadingPreview />,
776 template: {
777 content: [
778 {
779 type: "h2",
780 id: nanoid(),
781 children: [{ text: "Two columns with heading" }],
782 },
783 {
784 type: COLUMN_GROUP,
785 id: nanoid(),
786 layout: [1, 1],
787 children: [
788 {
789 type: COLUMN_ITEM,
790 id: nanoid(),
791 children: [
792 {
793 type: "h3",
794 id: nanoid(),
795 children: [{ text: "First Column" }],
796 },
797 {
798 type: "p",
799 id: nanoid(),
800 children: [{ text: "Description text goes here." }],
801 },
802 ],
803 },
804 {
805 type: COLUMN_ITEM,
806 id: nanoid(),
807 children: [
808 { type: "h3", id: nanoid(), children: [{ text: "Title" }] },
809 {
810 type: "p",
811 id: nanoid(),
812 children: [{ text: "Description text goes here." }],
813 },
814 ],
815 },
816 ],
817 },
818 ],
819 },
820 },
821
822 // Boxes
823 {
824 id: "solid-boxes",
825 name: "Solid boxes",
826 categoryId: "boxes",
827 preview: <Previews.SolidBoxesPreview />,
828 template: { content: createBoxContent("solid") },
829 },
830 {
831 id: "outline-boxes",
832 name: "Outline boxes",
833 categoryId: "boxes",
834 preview: <Previews.OutlineBoxesPreview />,
835 template: { content: createBoxContent("outline") },
836 },
837 {
838 id: "side-line-boxes",
839 name: "Side line boxes",
840 categoryId: "boxes",
841 preview: <Previews.SideLineBoxesPreview />,
842 template: { content: createBoxContent("sideline") },
843 },
844 {
845 id: "side-line-text",
846 name: "Side line text",
847 categoryId: "boxes",
848 preview: <Previews.SideLineTextPreview />,
849 template: { content: createBoxContent("side-label", 3) },
850 },
851 {
852 id: "top-line-text",
853 name: "Top line text",
854 categoryId: "boxes",
855 preview: <Previews.TopLineTextPreview />,
856 template: { content: createBoxContent("top-label", 3) },
857 },
858 {
859 id: "top-circle-boxes",
860 name: "Top circle boxes",
861 categoryId: "boxes",
862 preview: <Previews.TopCircleBoxesPreview />,
863 template: { content: createBoxContent("top-circle", 3) },
864 },
865 {
866 id: "joined-boxes",
867 name: "Joined boxes",
868 categoryId: "boxes",
869 preview: <Previews.JoinedBoxesPreview />,
870 template: { content: createBoxContent("joined") },
871 },
872 {
873 id: "boxes-with-icons",
874 name: "Joined boxes with icons",
875 categoryId: "boxes",
876 preview: <Previews.BoxesWithIconsPreview />,
877 template: { content: createBoxContent("joined-icon", 3) },
878 },
879 {
880 id: "leaf-boxes",
881 name: "Leaf boxes",
882 categoryId: "boxes",
883 preview: <Previews.LeafBoxesPreview />,
884 template: { content: createBoxContent("leaf") },
885 },
886 {
887 id: "labeled-boxes",
888 name: "Labeled boxes",
889 categoryId: "boxes",
890 preview: <Previews.LabeledBoxesPreview />,
891 template: { content: createBoxContent("labeled", 3) },
892 },
893 {
894 id: "alternating-boxes",
895 name: "Alternating boxes",
896 categoryId: "boxes",
897 preview: <Previews.AlternatingBoxesPreview />,
898 template: { content: createBoxContent("alternating", 3) },
899 },
900
901 // Bullets
902 {
903 id: "numbered-bullets",
904 name: "Numbered bullets",
905 categoryId: "bullets",
906 preview: <Previews.LargeBulletsPreview />,
907 template: { content: createListContent({ type: "numbered" }) },
908 },
909 {
910 id: "small-bullets",
911 name: "Small bullets",
912 categoryId: "bullets",
913 preview: <Previews.SmallBulletsPreview />,
914 template: { content: createListContent({ type: "basic" }) },
915 },
916 {
917 id: "arrow-bullets",
918 name: "Arrow bullets",
919 categoryId: "bullets",
920 preview: <Previews.ArrowBulletsPreview />,
921 template: { content: createListContent({ type: "arrow" }) },
922 },
923
924 // Card Layouts
925 {
926 id: "accent-left-layout",
927 name: "Accent left",
928 categoryId: "card-layouts",
929 preview: <Previews.AccentLeftPreview />,
930 template: {
931 layoutType: "left",
932 content: createBaseContent(),
933 rootImage: {
934 query: "relevant vertical accent visual",
935 layoutType: "left",
936 },
937 },
938 },
939 {
940 id: "accent-right-layout",
941 name: "Accent right",
942 categoryId: "card-layouts",
943 preview: <Previews.AccentRightPreview />,
944 template: {
945 content: createBaseContent(),
946 layoutType: "right",
947 rootImage: {
948 query: "relevant vertical accent visual",
949 layoutType: "right",
950 },
951 },
952 },
953 {
954 id: "accent-top-layout",
955 name: "Accent top",
956 categoryId: "card-layouts",
957 preview: <Previews.AccentTopPreview />,
958 template: {
959 content: createBaseContent(),
960 layoutType: "vertical",
961 rootImage: {
962 query: "relevant wide header visual",
963 layoutType: "vertical",
964 },
965 },
966 },
967 {
968 id: "accent-right-fit",
969 name: "Accent right (fit)",
970 categoryId: "card-layouts",
971 preview: <Previews.AccentRightFitPreview />,
972 template: {
973 content: createBaseContent(),
974 layoutType: "right",
975 rootImage: {
976 query: "relevant contained visual",
977 layoutType: "right",
978 cropSettings: {
979 objectFit: "contain",
980 objectPosition: {
981 x: 50,
982 y: 50,
983 },
984 },
985 },
986 },
987 },
988 {
989 id: "accent-left-fit",
990 name: "Accent left (fit)",
991 categoryId: "card-layouts",
992 preview: <Previews.AccentLeftFitPreview />,
993 template: {
994 content: createBaseContent(),
995 layoutType: "left",
996 rootImage: {
997 query: "relevant contained visual",
998 layoutType: "left",
999 cropSettings: {
1000 objectFit: "contain",
1001 objectPosition: {
1002 x: 50,
1003 y: 50,
1004 },
1005 },
1006 },
1007 },
1008 },
1009 {
1010 id: "accent-background",
1011 name: "Accent background",
1012 categoryId: "card-layouts",
1013 preview: <Previews.AccentBackgroundPreview />,
1014 template: {
1015 content: createBaseContent(),
1016 layoutType: "background",
1017 rootImage: {
1018 query: "relevant full slide background",
1019 layoutType: "background",
1020 },
1021 },
1022 },
1023
1024 {
1025 id: "bar-chart",
1026 name: "Bar chart",
1027 categoryId: "charts",
1028 preview: <Previews.BarChartPreview />,
1029 template: {
1030 content: createChartContent(BAR_CHART_ELEMENT, "Bar Chart", "horizontal"),
1031 },
1032 },
1033 {
1034 id: "line-chart",
1035 name: "Line chart",
1036 categoryId: "charts",
1037 preview: <Previews.LineChartPreview />,
1038 template: {
1039 content: createChartContent(LINE_CHART_ELEMENT, "Line Chart"),
1040 },
1041 },
1042 {
1043 id: "pie-chart",
1044 name: "Pie chart",
1045 categoryId: "charts",
1046 preview: <Previews.PieChartPreview />,
1047 template: { content: createChartContent(PIE_CHART_ELEMENT, "Pie Chart") },
1048 },
1049 {
1050 id: "donut-chart",
1051 name: "Donut chart",
1052 categoryId: "charts",
1053 preview: <Previews.DonutChartPreview />,
1054 template: {
1055 content: createChartContent(PIE_CHART_ELEMENT, "Donut Chart", "donut"),
1056 },
1057 },
1058 // New chart templates
1059 {
1060 id: "area-chart",
1061 name: "Area chart",
1062 categoryId: "charts",
1063 preview: <Previews.AreaChartPreview />,
1064 template: { content: createChartContent(AREA_CHART_ELEMENT, "Area Chart") },
1065 },
1066 {
1067 id: "scatter-chart",
1068 name: "Scatter chart",
1069 categoryId: "charts",
1070 preview: <Previews.ScatterChartPreview />,
1071 template: {
1072 content: createChartContent(SCATTER_CHART_ELEMENT, "Scatter Chart"),
1073 },
1074 },
1075 {
1076 id: "bubble-chart",
1077 name: "Bubble chart",
1078 categoryId: "charts",
1079 preview: <Previews.BubbleChartPreview />,
1080 template: {
1081 content: createChartContent(BUBBLE_CHART_ELEMENT, "Bubble Chart"),
1082 },
1083 },
1084 {
1085 id: "histogram-chart",
1086 name: "Histogram",
1087 categoryId: "charts",
1088 preview: <Previews.HistogramChartPreview />,
1089 template: {
1090 content: createChartContent(HISTOGRAM_CHART_ELEMENT, "Histogram Chart"),
1091 },
1092 },
1093 {
1094 id: "range-bar-chart",
1095 name: "Range Bar",
1096 categoryId: "charts",
1097 preview: <Previews.RangeBarChartPreview />,
1098 template: {
1099 content: createChartContent(RANGE_BAR_CHART_ELEMENT, "Range Bar Chart"),
1100 },
1101 },
1102 {
1103 id: "range-area-chart",
1104 name: "Range Area",
1105 categoryId: "charts",
1106 preview: <Previews.RangeAreaChartPreview />,
1107 template: {
1108 content: createChartContent(RANGE_AREA_CHART_ELEMENT, "Range Area Chart"),
1109 },
1110 },
1111 {
1112 id: "waterfall-chart",
1113 name: "Waterfall",
1114 categoryId: "charts",
1115 preview: <Previews.WaterfallChartPreview />,
1116 template: {
1117 content: createChartContent(WATERFALL_CHART_ELEMENT, "Waterfall Chart"),
1118 },
1119 },
1120 {
1121 id: "box-plot-chart",
1122 name: "Box Plot",
1123 categoryId: "charts",
1124 preview: <Previews.BoxPlotChartPreview />,
1125 template: {
1126 content: createChartContent(BOX_PLOT_CHART_ELEMENT, "Box Plot Chart"),
1127 },
1128 },
1129 {
1130 id: "candlestick-chart",
1131 name: "Candlestick",
1132 categoryId: "charts",
1133 preview: <Previews.CandlestickChartPreview />,
1134 template: {
1135 content: createChartContent(
1136 CANDLESTICK_CHART_ELEMENT,
1137 "Candlestick Chart",
1138 ),
1139 },
1140 },
1141 {
1142 id: "ohlc-chart",
1143 name: "OHLC",
1144 categoryId: "charts",
1145 preview: <Previews.OHLCChartPreview />,
1146 template: {
1147 content: createChartContent(OHLC_CHART_ELEMENT, "OHLC Chart"),
1148 },
1149 },
1150 {
1151 id: "radar-line-chart",
1152 name: "Radar Line",
1153 categoryId: "charts",
1154 preview: <Previews.RadarLineChartPreview />,
1155 template: {
1156 content: createChartContent(RADAR_CHART_ELEMENT, "Radar Chart"),
1157 },
1158 },
1159 {
1160 id: "radar-area-chart",
1161 name: "Radar Area",
1162 categoryId: "charts",
1163 preview: <Previews.RadarAreaChartPreview />,
1164 template: {
1165 content: createChartContent(
1166 RADAR_CHART_ELEMENT,
1167 "Radar Chart",
1168 "outline",
1169 ),
1170 },
1171 },
1172 {
1173 id: "nightingale-chart",
1174 name: "Nightingale",
1175 categoryId: "charts",
1176 preview: <Previews.NightingaleChartPreview />,
1177 template: {
1178 content: createChartContent(
1179 NIGHTINGALE_CHART_ELEMENT,
1180 "Nightingale Chart",
1181 ),
1182 },
1183 },
1184 {
1185 id: "radial-column-chart",
1186 name: "Radial Column",
1187 categoryId: "charts",
1188 preview: <Previews.RadialColumnChartPreview />,
1189 template: {
1190 content: createChartContent(
1191 RADIAL_COLUMN_CHART_ELEMENT,
1192 "Radial Column Chart",
1193 ),
1194 },
1195 },
1196 {
1197 id: "radial-bar-chart",
1198 name: "Radial Bar",
1199 categoryId: "charts",
1200 preview: <Previews.RadialBarChartPreview />,
1201 template: {
1202 content: createChartContent(RADIAL_BAR_CHART_ELEMENT, "Radial Bar Chart"),
1203 },
1204 },
1205 {
1206 id: "sunburst-chart",
1207 name: "Sunburst",
1208 categoryId: "charts",
1209 preview: <Previews.SunburstChartPreview />,
1210 template: {
1211 content: createChartContent(SUNBURST_CHART_ELEMENT, "Sunburst Chart"),
1212 },
1213 },
1214 {
1215 id: "treemap-chart",
1216 name: "Treemap",
1217 categoryId: "charts",
1218 preview: <Previews.TreemapChartPreview />,
1219 template: {
1220 content: createChartContent(TREEMAP_CHART_ELEMENT, "Treemap Chart"),
1221 },
1222 },
1223 {
1224 id: "heatmap-chart",
1225 name: "Heatmap",
1226 categoryId: "charts",
1227 preview: <Previews.HeatmapChartPreview />,
1228 template: {
1229 content: createChartContent(HEATMAP_CHART_ELEMENT, "Heatmap Chart"),
1230 },
1231 },
1232 {
1233 id: "sankey-chart",
1234 name: "Sankey",
1235 categoryId: "charts",
1236 preview: <Previews.SankeyChartPreview />,
1237 template: {
1238 content: createChartContent(SANKEY_CHART_ELEMENT, "Sankey Chart"),
1239 },
1240 },
1241 {
1242 id: "chord-chart",
1243 name: "Chord",
1244 categoryId: "charts",
1245 preview: <Previews.ChordChartPreview />,
1246 template: {
1247 content: createChartContent(CHORD_CHART_ELEMENT, "Chord Chart"),
1248 },
1249 },
1250 {
1251 id: "funnel-chart",
1252 name: "Funnel",
1253 categoryId: "charts",
1254 preview: <Previews.FunnelChartPreview />,
1255 template: {
1256 content: createChartContent(FUNNEL_CHART_ELEMENT, "Funnel Chart"),
1257 },
1258 },
1259 {
1260 id: "cone-funnel-chart",
1261 name: "Cone Funnel",
1262 categoryId: "charts",
1263 preview: <Previews.ConeFunnelChartPreview />,
1264 template: {
1265 content: createChartContent(
1266 CONE_FUNNEL_CHART_ELEMENT,
1267 "Cone Funnel Chart",
1268 ),
1269 },
1270 },
1271 {
1272 id: "pyramid-chart",
1273 name: "Pyramid Chart",
1274 categoryId: "charts",
1275 preview: <Previews.PyramidChartPreview2 />,
1276 template: {
1277 content: createChartContent(PYRAMID_CHART_ELEMENT, "Pyramid Chart"),
1278 },
1279 },
1280 {
1281 id: "radial-gauge-chart",
1282 name: "Radial Gauge",
1283 categoryId: "charts",
1284 preview: <Previews.RadialGaugeChartPreview />,
1285 template: {
1286 content: createChartContent(RADIAL_GAUGE_ELEMENT, "Radial Gauge"),
1287 },
1288 },
1289 {
1290 id: "linear-gauge-chart",
1291 name: "Linear Gauge",
1292 categoryId: "charts",
1293 preview: <Previews.LinearGaugeChartPreview />,
1294 template: {
1295 content: createChartContent(LINEAR_GAUGE_ELEMENT, "Linear Gauge"),
1296 },
1297 },
1298 {
1299 id: "combination-chart",
1300 name: "Combination",
1301 categoryId: "charts",
1302 preview: <Previews.CombinationChartPreview />,
1303 template: {
1304 content: createChartContent(COMPOSED_CHART_ELEMENT, "Combination Chart"),
1305 },
1306 },
1307
1308 {
1309 id: "comparison",
1310 name: "Comparison",
1311 categoryId: "comparison",
1312 preview: <Previews.TwoColumnsPreview />,
1313 template: { content: createCompareContent("compare") },
1314 },
1315 {
1316 id: "before-after",
1317 name: "Before and after",
1318 categoryId: "comparison",
1319 preview: <Previews.TwoColumnsWithHeadingPreview />,
1320 template: { content: createCompareContent("before-after") },
1321 },
1322 {
1323 id: "pros-cons",
1324 name: "Pros and cons",
1325 categoryId: "comparison",
1326 preview: <Previews.SideLineBoxesPreview />,
1327 template: { content: createProsConsContent() },
1328 },
1329
1330 {
1331 id: "cycle",
1332 name: "Cycle",
1333 categoryId: "circles",
1334 preview: <Previews.CyclePreview />,
1335 template: { content: createCycleContent(4) },
1336 },
1337 {
1338 id: "connected-circles",
1339 name: "Connected circles",
1340 categoryId: "circles",
1341 preview: <Previews.ConnectedCirclesDiagramPreview />,
1342 template: { content: createConnectedCirclesContent() },
1343 },
1344 {
1345 id: "circular-grid",
1346 name: "Circular grid",
1347 categoryId: "circles",
1348 preview: <Previews.CircularGridDiagramPreview />,
1349 template: { content: createCircularGridContent() },
1350 },
1351
1352 {
1353 id: "icon-list",
1354 name: "Icon list",
1355 categoryId: "icons",
1356 preview: <Previews.BoxesWithIconsPreview />,
1357 template: { content: createIconListContent() },
1358 },
1359
1360 {
1361 id: "two-image-columns",
1362 name: "2 Image columns",
1363 categoryId: "images",
1364 preview: <Previews.TwoImageColumnsPreview />,
1365 template: { content: createColumnContent(2, { includeImages: true }) },
1366 },
1367 {
1368 id: "three-image-columns",
1369 name: "3 Image columns",
1370 categoryId: "images",
1371 preview: <Previews.ThreeImageColumnsCardPreview />,
1372 template: { content: createColumnContent(3, { includeImages: true }) },
1373 },
1374 {
1375 id: "four-image-columns",
1376 name: "4 image columns",
1377 categoryId: "images",
1378 preview: <Previews.FourImageColumnsPreview />,
1379 template: { content: createColumnContent(4, { includeImages: true }) },
1380 },
1381 {
1382 id: "images-with-text",
1383 name: "Images with text",
1384 categoryId: "images",
1385 preview: <Previews.ImagesWithTextPreview />,
1386 template: { content: createColumnContent(3, { includeImages: true }) },
1387 },
1388 {
1389 id: "image-gallery",
1390 name: "Image gallery",
1391 categoryId: "images",
1392 preview: <Previews.ImageGalleryPreview />,
1393 template: { content: createColumnContent(3, { includeImages: true }) },
1394 },
1395 {
1396 id: "team-photos",
1397 name: "Team photos",
1398 categoryId: "images",
1399 preview: <Previews.TeamPhotosPreview />,
1400 template: { content: createColumnContent(4, { includeImages: true }) },
1401 },
1402
1403 {
1404 id: "stats",
1405 name: "Stats",
1406 categoryId: "numbers",
1407 preview: <Previews.StatsPreview />,
1408 template: { content: createStatsContent("plain") },
1409 },
1410 {
1411 id: "circle-stats",
1412 name: "Circle stats",
1413 categoryId: "numbers",
1414 preview: <Previews.CircleStatsPreview />,
1415 template: { content: createStatsContent("circle") },
1416 },
1417 {
1418 id: "bar-stats",
1419 name: "Bar stats",
1420 categoryId: "numbers",
1421 preview: <Previews.BarStatsPreview />,
1422 template: { content: createStatsContent("bar") },
1423 },
1424 {
1425 id: "star-rating",
1426 name: "Star rating",
1427 categoryId: "numbers",
1428 preview: <Previews.StarRatingPreview />,
1429 template: { content: createStatsContent("star") },
1430 },
1431 {
1432 id: "dot-grid-stats",
1433 name: "Dot grid stats",
1434 categoryId: "numbers",
1435 preview: <Previews.DotGridStatsPreview />,
1436 template: { content: createStatsContent("dot-grid") },
1437 },
1438 {
1439 id: "dot-line-stats",
1440 name: "Dot line stats",
1441 categoryId: "numbers",
1442 preview: <Previews.DotLineStatsPreview />,
1443 template: { content: createStatsContent("dot-line") },
1444 },
1445 {
1446 id: "circle-stats-bold",
1447 name: "Circle stats (bold)",
1448 categoryId: "numbers",
1449 preview: <Previews.CircleStatsMiddleBoldPreview />,
1450 template: { content: createStatsContent("circle-bold") },
1451 },
1452
1453 // Pyramids
1454
1455 {
1456 id: "pyramid",
1457 name: "Pyramid",
1458 categoryId: "pyramids",
1459 preview: <Previews.PyramidPreview />,
1460 template: { content: createPyramidContent("pyramid") },
1461 },
1462 {
1463 id: "vertical-funnel",
1464 name: "Vertical funnel",
1465 categoryId: "pyramids",
1466 preview: <Previews.VerticalFunnelPreview />,
1467 template: { content: createPyramidContent("funnel") },
1468 },
1469
1470 // Sequence
1471 {
1472 id: "timeline-sequence",
1473 name: "Timeline",
1474 categoryId: "sequence",
1475 preview: <Previews.TimelineSequencePreview />,
1476 template: { content: createTimelineContent("timeline") },
1477 },
1478 {
1479 id: "minimal-timeline",
1480 name: "Minimal timeline",
1481 categoryId: "sequence",
1482 preview: <Previews.MinimalTimelinePreview />,
1483 template: { content: createTimelineContent("timeline") },
1484 },
1485 {
1486 id: "minimal-timeline-boxes",
1487 name: "Minimal timeline boxes",
1488 categoryId: "sequence",
1489 preview: <Previews.MinimalTimelineWithBoxesPreview />,
1490 template: { content: createTimelineContent("timeline") },
1491 },
1492 {
1493 id: "arrows-sequence",
1494 name: "Arrows",
1495 categoryId: "sequence",
1496 preview: <Previews.ArrowListPreview />,
1497 template: { content: createTimelineContent("arrow") },
1498 },
1499 {
1500 id: "pills-sequence",
1501 name: "Pills",
1502 categoryId: "sequence",
1503 preview: <Previews.PillsSequencePreview />,
1504 template: { content: createTimelineContent("pill") },
1505 },
1506 {
1507 id: "slanted-labels",
1508 name: "Slanted labels",
1509 categoryId: "sequence",
1510 preview: <Previews.SlantedLabelsPreview />,
1511 template: { content: createTimelineContent("parallelogram") },
1512 },
1513 {
1514 id: "snake-flow",
1515 name: "Snake flow",
1516 categoryId: "sequence",
1517 preview: <Previews.SnakeDiagramPreview />,
1518 template: { content: createSnakeContent() },
1519 },
1520
1521 // Steps
1522 {
1523 id: "staircase",
1524 name: "Staircase",
1525 categoryId: "steps",
1526 preview: <Previews.StaircasePreview />,
1527 template: { content: createStaircaseContent() },
1528 },
1529 {
1530 id: "steps",
1531 name: "Steps",
1532 categoryId: "steps",
1533 preview: <Previews.LargeBulletsPreview />,
1534 template: { content: createStepsContent() },
1535 },
1536 {
1537 id: "sequence-arrow",
1538 name: "Sequence Arrow",
1539 categoryId: "steps",
1540 preview: <Previews.SequenceArrowPreview />,
1541 template: { content: createTimelineContent("arrow-vertical") },
1542 },
1543 {
1544 id: "slope",
1545 name: "Slope",
1546 categoryId: "steps",
1547 preview: <Previews.SlopeDiagramPreview />,
1548 template: { content: createSlopeContent() },
1549 },
1550
1551 // Quotes
1552 {
1553 id: "large-quote",
1554 name: "Large quote",
1555 categoryId: "quotes",
1556 preview: <Previews.LargeQuotePreview />,
1557 template: { content: createQuoteContent("large") },
1558 },
1559 {
1560 id: "side-quote-icon",
1561 name: "Side quote with icon",
1562 categoryId: "quotes",
1563 preview: <Previews.SideQuoteWithIconPreview />,
1564 template: { content: createQuoteContent("sidequote-icon") },
1565 },
1566 {
1567 id: "simple-side-quote",
1568 name: "Simple side quote",
1569 categoryId: "quotes",
1570 preview: <Previews.SimpleSideQuotePreview />,
1571 template: { content: createQuoteContent("sidequote") },
1572 },
1573 ];
1574
1574 lines Plain Text