ugcinc 4.5.61 → 4.5.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -45,6 +45,7 @@ const react_1 = __importStar(require("react"));
|
|
|
45
45
|
const defaults_1 = require("../utils/defaults");
|
|
46
46
|
const fonts_1 = require("../utils/fonts");
|
|
47
47
|
const text_1 = require("../utils/text");
|
|
48
|
+
const emoji_1 = require("../utils/emoji");
|
|
48
49
|
/**
|
|
49
50
|
* Calculate the actual width for auto-width text AND the line breaks.
|
|
50
51
|
* Uses DOM-based measurement to ensure the same fonts are used as CSS rendering.
|
|
@@ -362,7 +363,9 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
362
363
|
paddingTop, paddingRight, paddingBottom, paddingLeft,
|
|
363
364
|
autoWidth, verticalAlign, hasStroke
|
|
364
365
|
]);
|
|
365
|
-
// Stroke underlay style
|
|
366
|
+
// Stroke underlay style — extended by strokeWidth on all sides so the
|
|
367
|
+
// dilated outline stays inside the div and doesn't clip at text edges.
|
|
368
|
+
// Extra padding compensates so text wraps identically to the fill layer.
|
|
366
369
|
const strokeTextStyle = (0, react_1.useMemo)(() => {
|
|
367
370
|
if (!hasStroke)
|
|
368
371
|
return undefined;
|
|
@@ -371,14 +374,30 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
371
374
|
color: strokeColor,
|
|
372
375
|
filter: `url(#${filterId})`,
|
|
373
376
|
position: 'absolute',
|
|
374
|
-
|
|
377
|
+
top: -strokeWidth,
|
|
378
|
+
left: -strokeWidth,
|
|
379
|
+
right: -strokeWidth,
|
|
380
|
+
bottom: -strokeWidth,
|
|
381
|
+
padding: `${paddingTop + strokeWidth}px ${paddingRight + strokeWidth}px ${paddingBottom + strokeWidth}px ${paddingLeft + strokeWidth}px`,
|
|
375
382
|
};
|
|
376
|
-
}, [hasStroke, textStyle, strokeColor, filterId]);
|
|
383
|
+
}, [hasStroke, textStyle, strokeColor, filterId, strokeWidth, paddingTop, paddingRight, paddingBottom, paddingLeft]);
|
|
377
384
|
// SVG filter for smooth text outline (avoids miter spikes from -webkit-text-stroke)
|
|
378
385
|
const strokePadPct = Math.max(50, Math.ceil((strokeWidth / fontSize) * 200));
|
|
379
386
|
const strokeFilterSvg = hasStroke ? ((0, jsx_runtime_1.jsx)("svg", { style: { position: 'absolute', width: 0, height: 0, overflow: 'hidden' }, "aria-hidden": "true", children: (0, jsx_runtime_1.jsx)("defs", { children: (0, jsx_runtime_1.jsxs)("filter", { id: filterId, x: `-${strokePadPct}%`, y: `-${strokePadPct}%`, width: `${100 + 2 * strokePadPct}%`, height: `${100 + 2 * strokePadPct}%`, children: [(0, jsx_runtime_1.jsx)("feMorphology", { in: "SourceAlpha", operator: "dilate", radius: strokeWidth, result: "dilated" }), (0, jsx_runtime_1.jsx)("feFlood", { floodColor: strokeColor, result: "color" }), (0, jsx_runtime_1.jsx)("feComposite", { in: "color", in2: "dilated", operator: "in" })] }) }) })) : null;
|
|
387
|
+
// Render text with emojis made invisible (opacity 0) so the stroke
|
|
388
|
+
// filter doesn't dilate around them. Emojis still occupy space to
|
|
389
|
+
// keep layout identical to the fill layer.
|
|
390
|
+
const renderStrokeText = (text) => {
|
|
391
|
+
const parts = (0, emoji_1.splitTextAndEmojis)(text);
|
|
392
|
+
if (parts.every(p => p.type === 'text'))
|
|
393
|
+
return text;
|
|
394
|
+
return parts.map((part, i) => part.type === 'emoji'
|
|
395
|
+
? (0, jsx_runtime_1.jsx)("span", { style: { opacity: 0 }, children: part.content }, i)
|
|
396
|
+
: (0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: part.content }, i));
|
|
397
|
+
};
|
|
380
398
|
if (autoWidth) {
|
|
381
399
|
const textContent = calculatedLines.map((line, index) => ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [line, index < calculatedLines.length - 1 && (0, jsx_runtime_1.jsx)("br", {})] }, index)));
|
|
400
|
+
const strokeContent = calculatedLines.map((line, index) => ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [renderStrokeText(line), index < calculatedLines.length - 1 && (0, jsx_runtime_1.jsx)("br", {})] }, index)));
|
|
382
401
|
if (backgroundColor) {
|
|
383
402
|
return ((0, jsx_runtime_1.jsx)("div", { style: positioningContainerStyle, children: (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
384
403
|
width: calculatedWidth,
|
|
@@ -386,10 +405,10 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
386
405
|
backgroundColor: (0, text_1.hexToRgba)(backgroundColor, backgroundOpacity),
|
|
387
406
|
borderRadius: borderRadiusStyle,
|
|
388
407
|
...(hasStroke && { position: 'relative' }),
|
|
389
|
-
}, children: [strokeFilterSvg, strokeTextStyle && (0, jsx_runtime_1.jsx)("div", { style: strokeTextStyle, "aria-hidden": "true", children:
|
|
408
|
+
}, children: [strokeFilterSvg, strokeTextStyle && (0, jsx_runtime_1.jsx)("div", { style: strokeTextStyle, "aria-hidden": "true", children: strokeContent }), (0, jsx_runtime_1.jsx)("div", { style: textStyle, children: textContent })] }) }));
|
|
390
409
|
}
|
|
391
|
-
return ((0, jsx_runtime_1.jsx)("div", { style: positioningContainerStyle, children: (0, jsx_runtime_1.jsxs)("div", { style: { width: calculatedWidth, maxWidth: width, ...(hasStroke && { position: 'relative' }) }, children: [strokeFilterSvg, strokeTextStyle && (0, jsx_runtime_1.jsx)("div", { style: strokeTextStyle, "aria-hidden": "true", children:
|
|
410
|
+
return ((0, jsx_runtime_1.jsx)("div", { style: positioningContainerStyle, children: (0, jsx_runtime_1.jsxs)("div", { style: { width: calculatedWidth, maxWidth: width, ...(hasStroke && { position: 'relative' }) }, children: [strokeFilterSvg, strokeTextStyle && (0, jsx_runtime_1.jsx)("div", { style: strokeTextStyle, "aria-hidden": "true", children: strokeContent }), (0, jsx_runtime_1.jsx)("div", { style: textStyle, children: textContent })] }) }));
|
|
392
411
|
}
|
|
393
|
-
return ((0, jsx_runtime_1.jsx)("div", { style: positioningContainerStyle, children: (0, jsx_runtime_1.jsxs)("div", { style: { ...backgroundBoxStyle, ...(hasStroke && { position: 'relative' }) }, children: [strokeFilterSvg, strokeTextStyle && (0, jsx_runtime_1.jsx)("div", { style: strokeTextStyle, "aria-hidden": "true", children: segment.text }), (0, jsx_runtime_1.jsx)("div", { style: textStyle, children: segment.text })] }) }));
|
|
412
|
+
return ((0, jsx_runtime_1.jsx)("div", { style: positioningContainerStyle, children: (0, jsx_runtime_1.jsxs)("div", { style: { ...backgroundBoxStyle, ...(hasStroke && { position: 'relative' }) }, children: [strokeFilterSvg, strokeTextStyle && (0, jsx_runtime_1.jsx)("div", { style: strokeTextStyle, "aria-hidden": "true", children: renderStrokeText(segment.text) }), (0, jsx_runtime_1.jsx)("div", { style: textStyle, children: segment.text })] }) }));
|
|
394
413
|
}
|
|
395
414
|
exports.default = TextElement;
|