KO
베타 번역

@core / blocks

1.0.0 ▾
인증됨MIT
GitHub

페이지 블록: 접근성 갖춘 15개 섹션(히어로, 가격, JSON-LD FAQ 등), 관리자 편집기, 확장 가능한 등록

코드파일 25개컨텍스트약 681토큰검사 통과

.genpmignore 적용 후 주입될 정확한 트리입니다. 고정 대상:

src/lib/blocks/render.ts읽기 전용 · a255d6d
// Render de una lista de bloques. Sin condicionales por tipo: cada bloque se pinta con el componente de su definición.
import { createElement as h, Fragment, type ReactNode } from 'react';
import type { ResolvedImage } from '../rich-text/index.ts';
import type { BlockContext, BlockInstance, BlockRegistry } from './define.ts';

const dev = () => typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';

export type RenderBlocksProps = {
  blocks: BlockInstance[] | null | undefined;
  registry: BlockRegistry;
  /** Imágenes de @core/media ya resueltas (`await loadBlockMedia(blocks, registry)`). */
  media?: Record<string, ResolvedImage>;
  /** `true` si la página ya tiene su `h1` fuera de los bloques: ningún bloque usará `h1`. */
  hasPageTitle?: boolean;
  /** Nivel de encabezado de los bloques (2 por defecto). */
  level?: 2 | 3 | 4;
  embeds?: 'link' | 'iframe';
  siteHost?: string;
  renderForm?: (formKey: string) => ReactNode;
  /** Aviso para bloques desconocidos o inválidos (por defecto `console.warn` solo en desarrollo). */
  onSkip?: (block: BlockInstance, reason: 'unknown' | 'invalid') => void;
};

/** `<RenderBlocks blocks={page.data.blocks} registry={blocks} media={media} />` */
export function RenderBlocks(p: RenderBlocksProps): ReactNode {
  const image = (id: unknown): ResolvedImage | null => (typeof id === 'string' && p.media?.[id]) || null;
  const skip = p.onSkip ?? ((b, reason) => dev() && console.warn(`[blocks] skipped ${reason} block "${b.type}" (${b.id})`));
  let titleUsed = !!p.hasPageTitle;
  let first = true;
  const out: ReactNode[] = [];
  for (const b of p.blocks ?? []) {
    if (b.hidden) continue;
    const def = p.registry.get(b.type);
    if (!def) {
      skip(b, 'unknown');
      continue;
    }
    const parsed = def.schema.safeParse(b.data);
    if (!parsed.success) {
      skip(b, 'invalid');
      continue;
    }
    const isTitle = !titleUsed && !!def.pageTitle?.(parsed.data);
    if (isTitle) titleUsed = true;
    const ctx: BlockContext = {
      id: `b-${b.id.replace(/[^\w-]/g, '')}`,
      level: isTitle ? 1 : (p.level ?? 2),
      image,
      embeds: p.embeds ?? 'link',
      first,
      ...(p.siteHost && { siteHost: p.siteHost }),
      ...(p.renderForm && { renderForm: p.renderForm }),
    };
    first = false;
    out.push(h(Fragment, { key: b.id }, h(def.Component, { data: parsed.data, ctx })));
  }
  return h(Fragment, null, ...out);
}

@core/blocks 신고

패키지를 신고하려면 GitHub로 로그인하세요.