Tarjeta de entrada perforada
Entrada editorial con talón perforado, fecha, código y acción; el código de barras es una muestra decorativa.
DSN-024Entrada de muestra
Código completo
Es exactamente el archivo que se descarga. Cópialo a tu proyecto y úsalo.
"use client";
import { type CSSProperties } from "react";
/** Tarjeta de entrada perforada. React + TypeScript, sin dependencias. Personaliza con variables --gcxk-*. */
export type TarjetaTicketProps = {
title?: string;
date?: string;
location?: string;
code?: string;
href?: string;
className?: string;
style?: CSSProperties;
};
const CSS = `
.gcxk-root { box-sizing: border-box; min-width: 0; max-width: 100%; color: var(--gcxk-fg, #202421); font: 400 15px/1.5 ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
.gcxk-root *, .gcxk-root *::before, .gcxk-root *::after { box-sizing: border-box; }
.gcxk-root button, .gcxk-root input, .gcxk-root textarea, .gcxk-root select { font: inherit; }
.gcxk-root button, .gcxk-root a { -webkit-tap-highlight-color: transparent; }
.gcxk-root :focus-visible { outline: 2px solid var(--gcxk-accent, #25724b); outline-offset: 4px; }
.gcxk-root ::selection { background: var(--gcxk-accent, #25724b); color: #fff; }
.gcxk-root button:disabled { opacity: .5; cursor: not-allowed; }
.gcxk-root svg { flex-shrink: 0; }
@media (prefers-reduced-motion: reduce) { .gcxk-root *, .gcxk-root *::before, .gcxk-root *::after { animation: none !important; transition-duration: .01ms !important; scroll-behavior: auto !important; } }
.gcxk-root { width: 480px; background: var(--gcxk-bg, #f8eecc); display: grid; grid-template-columns: 1fr 110px; border-radius: 14px; box-shadow: 0 12px 30px #452d1b18; overflow: hidden; }
.gcxk-main { padding: 28px; min-width: 0; }
.gcxk-date { font-size: 11px; letter-spacing: .08em; font-variant-numeric: tabular-nums; }
.gcxk-root h3 { font-size: 29px; line-height: 1.1; letter-spacing: -.025em; font-weight: 650; margin: 22px 0 12px; }
.gcxk-root p { margin: 0 0 26px; color: #695c38; font-size: 13px; }
.gcxk-root a { display: inline-flex; align-items: center; gap: 12px; color: #343026; text-underline-offset: 5px; font-size: 13px; font-weight: 600; }
.gcxk-root a svg { transition: transform .25s; }
.gcxk-root a:hover svg { transform: translateX(4px); }
.gcxk-stub { padding: 24px 14px; border-left: 1px dashed #a59263; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 14px; }
.gcxk-bars { display: flex; height: 65px; gap: 2px; }
.gcxk-bars i { background: #3d3728; }
.gcxk-stub span { font: 11px ui-monospace, monospace; }
.gcxk-stub small { color: #655936; font-size: 10px; text-align: center; }
@media(max-width:360px) { .gcxk-root { grid-template-columns:1fr 80px; }
.gcxk-main { padding:20px; }
.gcxk-root h3 { font-size:24px; }
.gcxk-bars { gap:1px; } }`;
export function TarjetaTicket({
title = "Diseño en movimiento",
date = "24 OCT · 18:00",
location = "Sesión online",
code = "DSN-024",
href = "#reservar",
className = "",
style,
}: TarjetaTicketProps) {
return (
<article className={`gcxk-root ${className}`} style={style}>
<style>{CSS}</style>
<div className="gcxk-main">
<span className="gcxk-date">{date}</span>
<h3>{title}</h3>
<p>{location}</p>
<a href={href}>
Reservar mi lugar
<svg
viewBox="0 0 24 24"
width="18"
height="18"
fill="none"
stroke="currentColor"
strokeWidth="1.6"
aria-hidden="true"
>
<path d="M5 12h14m-6-6 6 6-6 6" />
</svg>
</a>
</div>
<div className="gcxk-stub">
<div className="gcxk-bars" aria-hidden="true">
{Array.from({ length: 24 }, (_, i) => (
<i key={i} style={{ width: i % 3 === 0 ? 3 : 1 }} />
))}
</div>
<span>{code}</span>
<small>Entrada de muestra</small>
</div>
</article>
);
}
Úsalo en tu proyecto
Instálalo con la CLI de shadcn.
npx shadcn@latest add https://www.gassierconsulting.com/r/tarjeta-ticketEjemplo de uso de Tarjeta de entrada perforada
Después de copiar tarjeta-ticket.tsx a tu proyecto, impórtalo y colócalo donde lo necesites.
import { TarjetaTicket } from "./tarjeta-ticket";
export default function Ejemplo() {
return <TarjetaTicket title="Ejemplo" />;
}Propiedades de TarjetaTicket
TarjetaTicket acepta 7 propiedades: todas son opcionales y tienen un valor por defecto, así que funciona sin configurar nada.
| Propiedad | Tipo | Descripción |
|---|---|---|
title? | string | Opcional. |
date? | string | Opcional. |
location? | string | Opcional. |
code? | string | Opcional. |
href? | string | Opcional. |
className? | string | Opcional. |
style? | CSSProperties | Opcional. |
Personaliza Tarjeta de entrada perforada con variables CSS
Define estas variables en el contenedor o en tu hoja de estilos para cambiar los colores sin tocar el componente. Si no las defines, se usa el valor por defecto.
| Variable | Valor por defecto |
|---|---|
--gcxk-fg | #202421 |
--gcxk-accent | #25724b |
--gcxk-bg | #f8eecc |
Accesibilidad y rendimiento
El archivo tiene 87 líneas (4 KB) y no necesita @keyframes. Esto es lo que hace Tarjeta de entrada perforada por quien lo usa:
- Detecta prefers-reduced-motion y baja o quita el movimiento cuando la persona lo pide.
- Muestra un anillo de foco visible al navegar con teclado (:focus-visible).
- Expone su estado a tecnologías de apoyo con atributos aria-*.
- Es un componente de cliente de Next.js: incluye la directiva "use client".