Skip to content
← Testimonial Carousel
Edit Testimonial Carousel
Name
Also known as (comma separated)
Brief definition
Rotating display of testimonials.
Notes
Tier
Core
Useful
Reference
Deleted
Controls schema (JSON array)
[ { "id": "activeSlide", "type": "select", "label": "Active slide", "default": "1", "options": [ "1", "2", "3" ] }, { "id": "accent", "type": "color", "label": "Accent colour", "default": "#241430", "presets": [ "#241430", "#A8E6C1", "#F5C2E0", "#BFD9F2", "#D9C8F0", "#E8A020" ] }, { "id": "showArrows", "type": "toggle", "label": "Show arrows", "default": true } ]
Templates (JSON object keyed by format)
{ "html": "<div class=\"carousel\" data-active=\"{{activeSlide}}\" style=\"--accent:{{accent}};\">\n {{#if showArrows}}<button type=\"button\" class=\"carousel__arrow carousel__arrow--prev\" aria-label=\"Previous testimonial\">‹</button>{{/if}}\n <div class=\"carousel__track\">\n <blockquote class=\"carousel__slide\" data-slide=\"1\">“Cut our reporting time in half.”<cite>— Priya, Northwind</cite></blockquote>\n <blockquote class=\"carousel__slide\" data-slide=\"2\">“Support that actually responds fast.”<cite>— Omar, Cobalt</cite></blockquote>\n <blockquote class=\"carousel__slide\" data-slide=\"3\">“Rolled out to 40 people in a day.”<cite>— Lena, Fenwick</cite></blockquote>\n </div>\n {{#if showArrows}}<button type=\"button\" class=\"carousel__arrow carousel__arrow--next\" aria-label=\"Next testimonial\">›</button>{{/if}}\n <div class=\"carousel__dots\" role=\"tablist\" aria-label=\"Testimonials\">\n <span class=\"carousel__dot\" data-dot=\"1\"></span>\n <span class=\"carousel__dot\" data-dot=\"2\"></span>\n <span class=\"carousel__dot\" data-dot=\"3\"></span>\n </div>\n</div>\n<style>\n.carousel { font: 16px/1.5 system-ui, sans-serif; color: #241430; max-width: 360px; text-align: center; padding: 24px; position: relative; }\n.carousel__slide { display: none; margin: 0 0 16px; font-size: 17px; font-weight: 500; }\n.carousel__slide cite { display: block; margin-top: 10px; font-size: 13px; font-style: normal; color: #241430aa; }\n.carousel[data-active=\"1\"] .carousel__slide[data-slide=\"1\"],\n.carousel[data-active=\"2\"] .carousel__slide[data-slide=\"2\"],\n.carousel[data-active=\"3\"] .carousel__slide[data-slide=\"3\"] { display: block; }\n.carousel__arrow { position: absolute; top: 50%; transform: translateY(-50%); background: none; border: none; font-size: 26px; color: var(--accent); cursor: pointer; padding: 4px 8px; }\n.carousel__arrow--prev { left: 0; }\n.carousel__arrow--next { right: 0; }\n.carousel__arrow:hover, .carousel__arrow:focus-visible { opacity: .7; }\n.carousel__dots { display: flex; gap: 8px; justify-content: center; }\n.carousel__dot { width: 8px; height: 8px; border-radius: 50%; background: #24143025; }\n.carousel[data-active=\"1\"] .carousel__dot[data-dot=\"1\"],\n.carousel[data-active=\"2\"] .carousel__dot[data-dot=\"2\"],\n.carousel[data-active=\"3\"] .carousel__dot[data-dot=\"3\"] { background: var(--accent); }\n</style>", "tailwind": "<div class=\"carousel-tw carousel-tw--{{activeSlide}} relative font-sans text-[#241430] max-w-[360px] text-center p-6\" style=\"--accent:{{accent}};\">\n {{#if showArrows}}<button type=\"button\" class=\"absolute top-1/2 left-0 -translate-y-1/2 bg-transparent border-0 text-2xl cursor-pointer px-2 hover:opacity-70\" style=\"color:{{accent}};\" aria-label=\"Previous testimonial\">‹</button>{{/if}}\n <div>\n <blockquote class=\"carousel-tw__slide hidden m-0 mb-4 text-[17px] font-medium\" data-slide=\"1\">“Cut our reporting time in half.”<cite class=\"block mt-2.5 text-[13px] not-italic text-[#241430]/65\">— Priya, Northwind</cite></blockquote>\n <blockquote class=\"carousel-tw__slide hidden m-0 mb-4 text-[17px] font-medium\" data-slide=\"2\">“Support that actually responds fast.”<cite class=\"block mt-2.5 text-[13px] not-italic text-[#241430]/65\">— Omar, Cobalt</cite></blockquote>\n <blockquote class=\"carousel-tw__slide hidden m-0 mb-4 text-[17px] font-medium\" data-slide=\"3\">“Rolled out to 40 people in a day.”<cite class=\"block mt-2.5 text-[13px] not-italic text-[#241430]/65\">— Lena, Fenwick</cite></blockquote>\n </div>\n {{#if showArrows}}<button type=\"button\" class=\"absolute top-1/2 right-0 -translate-y-1/2 bg-transparent border-0 text-2xl cursor-pointer px-2 hover:opacity-70\" style=\"color:{{accent}};\" aria-label=\"Next testimonial\">›</button>{{/if}}\n <div class=\"flex gap-2 justify-center\" role=\"tablist\" aria-label=\"Testimonials\">\n <span class=\"carousel-tw__dot w-2 h-2 rounded-full bg-[#24143025]\" data-dot=\"1\"></span>\n <span class=\"carousel-tw__dot w-2 h-2 rounded-full bg-[#24143025]\" data-dot=\"2\"></span>\n <span class=\"carousel-tw__dot w-2 h-2 rounded-full bg-[#24143025]\" data-dot=\"3\"></span>\n </div>\n</div>\n<style>\n.carousel-tw--1 .carousel-tw__slide[data-slide=\"1\"], .carousel-tw--2 .carousel-tw__slide[data-slide=\"2\"], .carousel-tw--3 .carousel-tw__slide[data-slide=\"3\"] { display: block; }\n.carousel-tw--1 .carousel-tw__dot[data-dot=\"1\"], .carousel-tw--2 .carousel-tw__dot[data-dot=\"2\"], .carousel-tw--3 .carousel-tw__dot[data-dot=\"3\"] { background: var(--accent); }\n</style>", "react": "import { useState } from \"react\";\n\nexport function TestimonialCarousel({\n activeSlide = \"{{activeSlide}}\",\n accent = \"{{accent}}\",\n showArrows = {{showArrows}},\n}) {\n const slides = [\n { quote: \"Cut our reporting time in half.\", cite: \"Priya, Northwind\" },\n { quote: \"Support that actually responds fast.\", cite: \"Omar, Cobalt\" },\n { quote: \"Rolled out to 40 people in a day.\", cite: \"Lena, Fenwick\" },\n ];\n const [index, setIndex] = useState(Number(activeSlide) - 1);\n const move = (delta) => setIndex((i) => (i + delta + slides.length) % slides.length);\n return (\n <div style={{ font: \"16px/1.5 system-ui, sans-serif\", color: \"#241430\", maxWidth: 360, textAlign: \"center\",\n padding: 24, position: \"relative\" }}>\n {showArrows && (\n <button type=\"button\" onClick={() => move(-1)} aria-label=\"Previous testimonial\" style={{ position: \"absolute\",\n top: \"50%\", left: 0, transform: \"translateY(-50%)\", background: \"none\", border: \"none\", fontSize: 26,\n color: accent, cursor: \"pointer\", padding: \"4px 8px\" }}>‹</button>\n )}\n <blockquote style={{ margin: \"0 0 16px\", fontSize: 17, fontWeight: 500 }}>\n “{slides[index].quote}”\n <cite style={{ display: \"block\", marginTop: 10, fontSize: 13, fontStyle: \"normal\", color: \"#241430aa\" }}>— {slides[index].cite}</cite>\n </blockquote>\n {showArrows && (\n <button type=\"button\" onClick={() => move(1)} aria-label=\"Next testimonial\" style={{ position: \"absolute\",\n top: \"50%\", right: 0, transform: \"translateY(-50%)\", background: \"none\", border: \"none\", fontSize: 26,\n color: accent, cursor: \"pointer\", padding: \"4px 8px\" }}>›</button>\n )}\n <div role=\"tablist\" aria-label=\"Testimonials\" style={{ display: \"flex\", gap: 8, justifyContent: \"center\" }}>\n {slides.map((_, i) => (\n <span key={i} style={{ width: 8, height: 8, borderRadius: \"50%\", background: i === index ? accent : \"#24143025\" }} />\n ))}\n </div>\n </div>\n );\n}" }
Save
History