Testimonial Featured
Блок в стиле кейса: крупная цитата, логотип компании и ключевые метрики результата.
testimonialscase-studyquotemetrics
Живое превью
Orbitly
We replaced three tools and a chart library with this kit. Our product pages load twice as fast and our conversion rate has never been higher.
- faster page loads
- 2.1×
- trial conversion
- +38%
- front-end bundle size
- −64%
Использование
Скопируйте и вставьте этот код в ваш React-компонент:
tsx
import { TestimonialFeatured } from 'react-component-kit-ui/sections';
<TestimonialFeatured quote="Our pages load twice as fast." name="Elena Vasquez" role="VP Marketing, Orbitly" company="Orbitly" metrics={[{ value: '2.1×', label: 'faster loads' }]} variant="card" />Ручная установка
Если вы не используете пакет npm, создайте файл и вставьте следующий код: src/components/sections/TestimonialFeatured.tsx + TestimonialFeatured.css:
TestimonialFeatured.tsx
'use client';
import './TestimonialFeatured.css';
/**
* TestimonialFeatured — A single large customer quote paired with the company's
* headline results (case-study style), plus a link to the full story.
*
* @param {string} quote - The testimonial text.
* @param {string} name - Author name.
* @param {string} role - Author role and company.
* @param {string} company - Company wordmark text.
* @param {Array<{value: string, label: string}>} metrics - Outcome stats.
* @param {{label: string, href: string}} link - Case study link.
* @param {string} variant - Layout style (split|centered|card).
* @param {string} size - Vertical rhythm (sm|md|lg).
* @param {string} className - Extra CSS class.
*/
export interface TestimonialFeaturedProps {
quote?: string;
name?: string;
role?: string;
company?: string;
metrics?: Array<{ value: string; label: string }>;
link?: { label: string; href: string };
variant?: 'split' | 'centered' | 'card';
size?: 'sm' | 'md' | 'lg';
className?: string;
}
export function TestimonialFeatured({
quote = 'We replaced three tools and a chart library with this kit. Our product pages load twice as fast and our conversion rate has never been higher.',
name = 'Elena Vasquez',
role = 'VP of Marketing, Orbitly',
company = 'Orbitly',
metrics = [
{ value: '2.1×', label: 'faster page loads' },
{ value: '+38%', label: 'trial conversion' },
{ value: '−64%', label: 'front-end bundle size' },
],
link = { label: 'Read the case study', href: '#' },
variant = 'split',
size = 'md',
className = '',
}: TestimonialFeaturedProps) {
const initials = name.split(' ').map((p) => p[0]).slice(0, 2).join('');
return (
<>
<div className="cq-testimonial-featured-cq" data-rk-bd39f1="">
<section className={`tf tf--${variant} tf--${size} ${className}`} aria-label={`Customer story: ${company}`} data-rk-bd39f1="">
<div className="tf__inner" data-rk-bd39f1="">
<figure className="tf__figure" data-rk-bd39f1="">
<p className="tf__company" aria-hidden="true" data-rk-bd39f1="">
<svg width="22" height="22" viewBox="0 0 24 24" aria-hidden="true" data-rk-bd39f1=""><circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" strokeWidth="2" data-rk-bd39f1="" /><circle cx="12" cy="12" r="4" fill="currentColor" data-rk-bd39f1="" /></svg>
{company}
</p>
<svg className="tf__mark" width="48" height="36" viewBox="0 0 48 36" aria-hidden="true" data-rk-bd39f1=""><path d="M0 36V22C0 9 7 2 20 0l2 5C14 7 11 12 11 18h9v18H0zm28 0V22C28 9 35 2 48 0l2 5c-8 2-11 7-11 13h9v18H28z" fill="currentColor" data-rk-bd39f1="" /></svg>
<blockquote className="tf__quote" data-rk-bd39f1=""><p data-rk-bd39f1="">{quote}</p></blockquote>
<figcaption className="tf__author" data-rk-bd39f1="">
<span className="tf__avatar" aria-hidden="true" data-rk-bd39f1="">{initials}</span>
<span data-rk-bd39f1=""><strong data-rk-bd39f1="">{name}</strong><span className="tf__role" data-rk-bd39f1="">{role}</span></span>
</figcaption>
</figure>
<div className="tf__side" data-rk-bd39f1="">
<dl className="tf__metrics" data-rk-bd39f1="">
{metrics.map((mt, __i: number) => (
<div key={__i} className="tf__metric" data-rk-bd39f1="">
<dt data-rk-bd39f1="">{mt.label}</dt>
<dd data-rk-bd39f1="">{mt.value}</dd>
</div>
))}
</dl>
{link && (
<a className="tf__link" href={link.href} data-rk-bd39f1="">
{link.label}
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" aria-hidden="true" data-rk-bd39f1=""><path d="M5 12h14M13 6l6 6-6 6" data-rk-bd39f1="" /></svg>
</a>
)}
</div>
</div>
</section>
</div>
</>
);
}
export default TestimonialFeatured;TestimonialFeatured.css
/* TestimonialFeatured — ported from astro-component-kit (sections/TestimonialFeatured.astro) */
.cq-testimonial-featured-cq:where([data-rk-bd39f1]) { container-type: inline-size; }
.tf:where([data-rk-bd39f1]) {
--tf-py: 5.5rem;
padding: var(--tf-py) var(--sp-6, 1.5rem);
background: var(--c-bg, #050505);
}
.tf--sm:where([data-rk-bd39f1]) { --tf-py: 3.5rem; }
.tf--lg:where([data-rk-bd39f1]) { --tf-py: 7.5rem; }
.tf__inner:where([data-rk-bd39f1]) { max-width: 1120px; margin: 0 auto; display: grid; grid-template-columns: 1.6fr 1fr; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
.tf--card:where([data-rk-bd39f1]) .tf__inner:where([data-rk-bd39f1]) {
padding: clamp(2rem, 5vw, 3.5rem);
border-radius: var(--r-xl, 28px);
background: radial-gradient(circle at 0% 0%, var(--c-primary-glow, color-mix(in srgb, var(--c-primary, #b8860b) 14%, transparent)), transparent 55%), rgb(var(--ink-rgb, 255 255 255) / 0.025);
border: 1px solid var(--c-border, rgb(var(--ink-rgb, 255 255 255) / 0.08));
}
.tf--centered:where([data-rk-bd39f1]) .tf__inner:where([data-rk-bd39f1]) { grid-template-columns: 1fr; text-align: center; max-width: 860px; }
.tf--centered:where([data-rk-bd39f1]) .tf__author:where([data-rk-bd39f1]), .tf--centered:where([data-rk-bd39f1]) .tf__company:where([data-rk-bd39f1]) { justify-content: center; }
.tf--centered:where([data-rk-bd39f1]) .tf__mark:where([data-rk-bd39f1]) { margin-inline: auto; }
.tf__figure:where([data-rk-bd39f1]) { margin: 0; }
.tf__company:where([data-rk-bd39f1]) { display: flex; align-items: center; gap: 0.5rem; margin: 0 0 2rem; font-size: 1.125rem; font-weight: 750; letter-spacing: -0.02em; color: var(--c-text-1, #fff); }
.tf__mark:where([data-rk-bd39f1]) { display: block; color: var(--c-primary-light, #d4a017); opacity: 0.8; margin-bottom: 1.25rem; }
.tf__quote:where([data-rk-bd39f1]) { margin: 0 0 2rem; }
.tf__quote:where([data-rk-bd39f1]) p:where([data-rk-bd39f1]) { margin: 0; font-size: clamp(1.35rem, 2.6vw, 1.875rem); font-weight: 550; line-height: 1.4; letter-spacing: -0.015em; color: var(--c-text-1, #fff); text-wrap: pretty; }
.tf__author:where([data-rk-bd39f1]) { display: flex; align-items: center; gap: 0.85rem; }
.tf__author:where([data-rk-bd39f1]) strong:where([data-rk-bd39f1]) { display: block; color: var(--c-text-1, #fff); }
.tf__role:where([data-rk-bd39f1]) { display: block; font-size: 0.875rem; color: var(--c-text-2, #a3a3a3); }
.tf__avatar:where([data-rk-bd39f1]) { display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; background: linear-gradient(135deg, var(--chart-7, #9085e9), var(--chart-1, #3987e5)); color: #fff; font-weight: 700; }
.tf__side:where([data-rk-bd39f1]) { display: grid; gap: 1.5rem; }
.tf__metrics:where([data-rk-bd39f1]) { margin: 0; display: grid; gap: 1px; border-radius: var(--r-lg, 20px); overflow: hidden; background: rgb(var(--ink-rgb, 255 255 255) / 0.07); }
.tf--centered:where([data-rk-bd39f1]) .tf__metrics:where([data-rk-bd39f1]) { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.tf__metric:where([data-rk-bd39f1]) { display: flex; flex-direction: column-reverse; gap: 0.25rem; padding: 1.25rem 1.5rem; background: var(--c-bg-1, #0a0a0a); }
.tf__metric:where([data-rk-bd39f1]) dt:where([data-rk-bd39f1]) { font-size: 0.875rem; color: var(--c-text-2, #a3a3a3); }
.tf__metric:where([data-rk-bd39f1]) dd:where([data-rk-bd39f1]) { margin: 0; font-size: 2rem; font-weight: 800; letter-spacing: -0.03em; color: var(--c-text-1, #fff); font-variant-numeric: tabular-nums; }
.tf__link:where([data-rk-bd39f1]) { display: inline-flex; align-items: center; gap: 0.45rem; min-height: 44px; font-weight: 650; color: var(--c-primary-light, #d4a017); text-decoration: none; }
.tf--centered:where([data-rk-bd39f1]) .tf__link:where([data-rk-bd39f1]) { justify-self: center; }
.tf__link:where([data-rk-bd39f1]) svg:where([data-rk-bd39f1]) { transition: transform 0.2s ease; }
.tf__link:hover:where([data-rk-bd39f1]) svg:where([data-rk-bd39f1]) { transform: translateX(3px); }
.tf__link:focus-visible:where([data-rk-bd39f1]) { outline: 2px solid var(--c-primary-light, #d4a017); outline-offset: 2px; border-radius: 4px; }
@container (max-width: 820px) { .tf__inner:where([data-rk-bd39f1]) { grid-template-columns: 1fr; } }