ilinxa
blockarticle-metasource: ok · hit
Article Meta
Icon-and-value metadata strip for article headers — author, date, read time, view count, or any custom pairs.
npx shadcn add "https://ui.ilinxa.com/r/article-meta.json"free
Where it goes
navbarblog-list
Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.
Dependencies
Bundle weight · lighticonslucide-react
Files4 · source cached 10/12/2026, 2:41:11 PM
src/registry/components/data/article-meta/article-meta.tsx
import { memo } from "react";
import { cn } from "@/lib/utils";
import { MetaItem } from "./parts/meta-item";
import type { ArticleMetaProps } from "./types";
const ALIGN_CLASS = {
start: "justify-start",
center: "justify-center",
end: "justify-end",
} as const;
function ArticleMetaInner(props: ArticleMetaProps) {
const {
items,
linkComponent = "a",
divider = false,
align = "start",
gapClass = "gap-6",
className,
itemClassName,
iconClassName,
} = props;
return (
<ul
role="list"
className={cn(
"flex flex-wrap items-center text-muted-foreground list-none",
gapClass,
ALIGN_CLASS[align],
divider && "pb-8 border-b border-border",
className
)}
>
{items.map((item) => (
<MetaItem
key={item.id}
item={item}
linkComponent={linkComponent}
itemClassName={itemClassName}
iconClassName={iconClassName}
/>
))}
</ul>
);
}
export const ArticleMeta = memo(ArticleMetaInner);
ArticleMeta.displayName = "ArticleMeta";
src/registry/components/data/article-meta/index.ts
export { ArticleMeta } from "./article-meta";
export type {
ArticleMetaProps,
ArticleMetaItem,
} from "./types";
src/registry/components/data/article-meta/types.ts
import type { ComponentType, ElementType, ReactNode } from "react";
export interface ArticleMetaItem {
id: string;
icon?: ComponentType<{ className?: string }>;
value: ReactNode;
href?: string;
ariaLabel?: string;
}
export interface ArticleMetaProps {
items: ReadonlyArray<ArticleMetaItem>;
linkComponent?: ElementType;
divider?: boolean;
align?: "start" | "center" | "end";
gapClass?: string;
className?: string;
itemClassName?: string;
iconClassName?: string;
}
src/registry/components/data/article-meta/parts/meta-item.tsx
import type { ElementType } from "react";
import { cn } from "@/lib/utils";
import type { ArticleMetaItem } from "../types";
interface MetaItemProps {
item: ArticleMetaItem;
linkComponent: ElementType;
itemClassName?: string;
iconClassName?: string;
}
export function MetaItem({
item,
linkComponent: LinkEl,
itemClassName,
iconClassName,
}: MetaItemProps) {
const Icon = item.icon;
const inner = (
<>
{Icon ? (
<Icon className={cn("w-4 h-4", iconClassName)} aria-hidden="true" />
) : null}
<span>{item.value}</span>
</>
);
return (
<li className={cn("flex items-center gap-2", itemClassName)}>
{item.href ? (
<LinkEl
href={item.href}
aria-label={item.ariaLabel}
className="inline-flex items-center gap-2 hover:text-foreground transition-colors rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
{inner}
</LinkEl>
) : item.ariaLabel ? (
<span aria-label={item.ariaLabel} className="inline-flex items-center gap-2">
{inner}
</span>
) : (
<span className="inline-flex items-center gap-2">{inner}</span>
)}
</li>
);
}