import type { CSSProperties } from "react"; import type { DividerBlockProps } from "@/features/editor/state/editorStore"; export interface DividerEscapers { escapeAttr: (value: string) => string; } export interface DividerExportTokens { style: string; } export const computeDividerExportTokens = ( props: DividerBlockProps, escapers: DividerEscapers, ): DividerExportTokens => { const { escapeAttr } = escapers; const thickness = props.thickness === "medium" ? "2px" : "1px"; const colorRaw = typeof props.colorHex === "string" ? props.colorHex.trim() : ""; const color = colorRaw !== "" ? colorRaw : "#475569"; const marginY = typeof props.marginYPx === "number" && props.marginYPx > 0 ? props.marginYPx : 16; const marginEm = pxToEm(marginY); const widthMode = props.widthMode ?? "full"; const align = props.align ?? "left"; const styleParts: string[] = []; styleParts.push("border:0"); styleParts.push(`border-bottom:${thickness} solid ${escapeAttr(color)}`); styleParts.push(`margin:${marginEm} 0`); if (widthMode === "auto") { styleParts.push("width:50%"); } else if (widthMode === "fixed") { const widthPx = typeof props.widthPx === "number" && props.widthPx > 0 ? props.widthPx : 320; styleParts.push(`width:${pxToEm(widthPx)}`); } if (widthMode === "auto" || widthMode === "fixed") { if (align === "center") { styleParts.push("margin-left:auto"); styleParts.push("margin-right:auto"); } else if (align === "right") { styleParts.push("margin-left:auto"); styleParts.push("margin-right:0"); } } const style = `${styleParts.join(";")};`; return { style }; }; export interface DividerEditorTokens { thicknessClass: string; innerWidthClass: string; widthPx?: number; borderColor: string; marginPx: number; } export const computeDividerEditorTokens = (props: DividerBlockProps): DividerEditorTokens => { const thicknessClass = props.thickness === "medium" ? "border-t-2" : "border-t"; const colorRaw = typeof props.colorHex === "string" ? props.colorHex.trim() : ""; const borderColor = colorRaw !== "" ? colorRaw : "#475569"; const widthMode = props.widthMode ?? "full"; let innerWidthClass = "w-full"; let widthPx: number | undefined; if (widthMode === "auto") { innerWidthClass = "w-1/2"; } else if (widthMode === "fixed") { innerWidthClass = ""; if (typeof props.widthPx === "number" && props.widthPx > 0) { widthPx = props.widthPx; } else { widthPx = 320; } } const marginPx = typeof props.marginYPx === "number" ? props.marginYPx : props.marginY === "sm" ? 8 : props.marginY === "lg" ? 24 : 16; return { thicknessClass, innerWidthClass, widthPx, borderColor, marginPx, }; }; export interface DividerPublicTokens { alignClass: string; thicknessClass: string; innerWidthClass: string; wrapperMarginEm: string; innerStyle: CSSProperties; lineStyle: CSSProperties; } const pxToEm = (px: number, base = 16) => `${px / base}em`; export const computeDividerPublicTokens = (props: DividerBlockProps): DividerPublicTokens => { const alignClass = props.align === "center" ? "items-center" : props.align === "right" ? "items-end" : "items-start"; const thicknessClass = props.thickness === "medium" ? "h-[2px]" : "h-px"; const marginPx = typeof props.marginYPx === "number" ? props.marginYPx : props.marginY === "sm" ? 8 : props.marginY === "lg" ? 24 : 16; const wrapperMarginEm = pxToEm(marginPx); const colorRaw = typeof props.colorHex === "string" ? props.colorHex.trim() : ""; const backgroundColor = colorRaw !== "" ? colorRaw : "#475569"; const widthMode = props.widthMode ?? "full"; const innerStyle: CSSProperties = {}; let innerWidthClass = "w-full"; const lineStyle: CSSProperties = { backgroundColor, }; if (widthMode === "auto") { innerWidthClass = "w-1/2"; } else if (widthMode === "fixed") { innerWidthClass = ""; innerStyle.width = "auto"; if (typeof props.widthPx === "number" && props.widthPx > 0) { lineStyle.width = pxToEm(props.widthPx); } else { lineStyle.width = pxToEm(320); } } return { alignClass, thicknessClass, innerWidthClass, wrapperMarginEm, innerStyle, lineStyle, }; };