Типографикаtypographycurvedpathsvgheading
Curved Path Heading
Изогнутый по дуге SVG-заголовок для круглых печатей, значков и бейджей.
Живое превью
✦
Использование
Скопируйте и вставьте этот код в ваш React-компонент:
tsx
import { CurvedPathHeading } from 'react-component-kit-ui/typography';
<CurvedPathHeading text="PREMIUM ASTRO UI LIBRARY • " radius={120} />Ручная установка
Если вы не используете пакет npm, создайте файл и вставьте следующий код: src/components/CurvedPathHeading.tsx + CurvedPathHeading.css:
CurvedPathHeading.tsx
'use client';
import type { CSSProperties } from 'react';
import './CurvedPathHeading.css';
/** class:list → className */
function cx(...args: unknown[]): string {
const out: string[] = [];
const walk = (v: unknown) => {
if (!v) return;
if (typeof v === 'string' || typeof v === 'number') out.push(String(v));
else if (Array.isArray(v)) v.forEach(walk);
else if (typeof v === 'object') for (const [k, on] of Object.entries(v as Record<string, unknown>)) if (on) out.push(k);
};
args.forEach(walk);
return out.join(' ');
}
/** "a: b; --c: d" → style object */
function st(css: string | undefined): CSSProperties {
const o: Record<string, string> = {};
for (const decl of String(css ?? '').split(';')) {
const i = decl.indexOf(':');
if (i < 0) continue;
const k = decl.slice(0, i).trim();
if (k) o[k.startsWith('--') ? k : k.replace(/-([a-z])/g, (_, c) => c.toUpperCase())] = decl.slice(i + 1).trim();
}
return o as CSSProperties;
}
/**
* CurvedPathHeading — Typographic heading flowing along an SVG circular or arched trajectory.
*
* @param {string} text - Headline text content. Default is 'ASTRO COMPONENTS KIT • ZERO RUNTIME DEPENDENCIES •'.
* @param {number} size - Pixel container diameter. Default is 260.
* @param {boolean} animate - Whether the badge rotates continuously. Default is true.
*/
export interface CurvedPathHeadingProps {
text?: string;
size?: number;
animate?: boolean;
}
export function CurvedPathHeading({
text = 'ASTRO COMPONENTS KIT • ZERO RUNTIME • PURE CSS •',
size = 260,
animate = true,
}: CurvedPathHeadingProps) {
const pathId = `curve-path-${Math.random().toString(36).substring(2, 8)}`;
return (
<>
<div className={cx(['curved-heading', { 'is-animated': animate }])} style={st(`--curved-size: ${size}px;`)} data-rk-03862f="">
<svg viewBox="0 0 300 300" width={size} height={size} data-rk-03862f="">
<defs data-rk-03862f="">
<path id={pathId} d="M 150, 150 m -110, 0 a 110,110 0 1,1 220,0 a 110,110 0 1,1 -220,0" data-rk-03862f="" />
</defs>
<text className="curved-heading__text" data-rk-03862f="">
<textPath href={`#${pathId}`} startOffset="0%" data-rk-03862f="">
{text}
</textPath>
</text>
</svg>
<div className="curved-heading__core" data-rk-03862f="">✦</div>
</div>
</>
);
}
export default CurvedPathHeading;CurvedPathHeading.css
/* CurvedPathHeading — ported from astro-component-kit (typography/CurvedPathHeading.astro) */
.curved-heading:where([data-rk-03862f]) {
position: relative;
width: var(--curved-size);
height: var(--curved-size);
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--font-sans, system-ui, sans-serif);
user-select: none;
}
.curved-heading.is-animated:where([data-rk-03862f]) svg:where([data-rk-03862f]) {
animation: curved-path-heading-curved-spin 20s linear infinite;
}
.curved-heading__text:where([data-rk-03862f]) {
font-size: 13.5px;
font-weight: 800;
letter-spacing: 0.18em;
text-transform: uppercase;
fill: var(--c-primary-light, #d4a017);
}
.curved-heading__core:where([data-rk-03862f]) {
position: absolute;
width: 48px;
height: 48px;
border-radius: 50%;
background: rgba(184, 134, 11, 0.12);
border: 1px solid rgba(184, 134, 11, 0.3);
color: var(--c-accent, #fef3c7);
display: grid;
place-items: center;
font-size: 1.2rem;
}
@keyframes curved-path-heading-curved-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
.curved-heading.is-animated:where([data-rk-03862f]) svg:where([data-rk-03862f]) { animation: none; }
}Краткая информация
- Категория
- Типографика
- Имя файла
CurvedPathHeading.tsx- Зависимости
- Нет — чистый React + CSS
- Теги
- typographycurvedpathsvgheading