feat(mobile): add multiline text with Enter, per-text independent font selection and font size controls

This commit is contained in:
AyrisAI
2026-08-21 00:55:44 +03:00
parent b72846bd91
commit 2530ab4005
8 changed files with 1522 additions and 1608 deletions
@@ -0,0 +1,133 @@
import React from "react";
import { Text as SvgText, type SvgProps } from "react-native-svg";
import QrTemplate1 from "./QrTemplateLumiere";
import QrTemplate2 from "./QrTemplate2";
import QrTemplate3 from "./QrTemplate3";
import QrTemplate4 from "./QrTemplate4";
import QrTemplate5 from "./QrTemplate5";
export interface TextItemConfig {
text: string;
fontSize?: number;
fontId?: string;
visible?: boolean;
}
export interface QrCustomFields {
restaurantName: TextItemConfig;
subtitle: TextItemConfig;
tableNo: TextItemConfig;
ctaText: TextItemConfig;
wifiText: TextItemConfig;
socialText: TextItemConfig;
}
export interface QrTemplateProps extends SvgProps {
qrBase64?: string;
fields?: Partial<QrCustomFields>;
}
// Türkçe karakterleri (İ, ı, Ş, ş, Ğ, ğ, Ü, ü, Ö, ö, Ç, ç) eksiksiz destekleyen sistem fontları
export const FONT_OPTIONS = [
{
id: "sans",
label: "Modern Sans",
fontFamily: "System, -apple-system, Roboto, 'Helvetica Neue', Arial, sans-serif",
},
{
id: "serif",
label: "Zarif Serif",
fontFamily: "Georgia, 'Times New Roman', serif",
},
{
id: "times",
label: "Klasik (Times)",
fontFamily: "'Times New Roman', Times, Georgia, serif",
},
{
id: "palatino",
label: "Lüks Palatino",
fontFamily: "Palatino, 'Palatino Linotype', Georgia, serif",
},
{
id: "trebuchet",
label: "Dinamik",
fontFamily: "'Trebuchet MS', 'Segoe UI', Arial, sans-serif",
},
];
export function getFontFamily(fontId?: string, defaultFamily = "Georgia, serif"): string {
if (!fontId) return defaultFamily;
const found = FONT_OPTIONS.find((f) => f.id === fontId);
return found ? found.fontFamily : defaultFamily;
}
// Çok satırlı (Enter / \n) metinleri SVG içinde alt alta kusursuz render eden yardımcı fonksiyon
export function renderSvgLines({
text,
x,
y,
lineHeight,
fill,
fontFamily,
fontSize,
fontWeight = "normal",
letterSpacing,
textAnchor = "middle",
}: {
text?: string;
x: number;
y: number;
lineHeight?: number;
fill?: string;
fontFamily?: string;
fontSize?: number;
fontWeight?: string | number;
letterSpacing?: number;
textAnchor?: "middle" | "start" | "end";
}) {
if (!text) return null;
const lines = text.split("\n");
const computedLineHeight = lineHeight || (fontSize ? fontSize * 1.25 : 18);
return (
<>
{lines.map((line, idx) => (
<SvgText
key={idx}
x={x}
y={y + idx * computedLineHeight}
fill={fill}
fontFamily={fontFamily}
fontSize={fontSize}
fontWeight={fontWeight}
letterSpacing={letterSpacing}
textAnchor={textAnchor}
>
{line}
</SvgText>
))}
</>
);
}
// Yeni component eklemek için buraya import edip COMPONENT_TEMPLATES'e kaydet
export const COMPONENT_TEMPLATES: Record<
string,
React.FC<QrTemplateProps>
> = {
"qr-1": QrTemplate1,
"qr-2": QrTemplate2,
"qr-3": QrTemplate3,
"qr-4": QrTemplate4,
"qr-5": QrTemplate5,
};
// Her template'in aspect ratio'su (width/height)
export const TEMPLATE_ASPECT_RATIOS: Record<string, number> = {
"qr-1": 1, // 600x600 = 1:1
"qr-2": 400 / 650, // 400x650 = standart kart
"qr-3": 400 / 650, // 400x650 = standart kart
"qr-4": 400 / 580, // 400x580 = zarif altın çerçeve
"qr-5": 380 / 500, // 380x500 = PNG arka planlı modern kart
};