fixed buttons styles

This commit is contained in:
Dmitri 2026-03-24 19:19:55 +04:00
parent fba1857e1b
commit 22fe0cd50f
3 changed files with 48 additions and 21 deletions

View File

@ -460,16 +460,20 @@ export default function RuntimePresentation({
element.type === 'navigation_prev'
) {
if (element.iconUrl) {
// Use img tag with flexible sizing - auto for dimensions not provided
const imgStyle: React.CSSProperties = {
width: element.width || 'auto',
height: element.height || 'auto',
objectFit: 'contain',
};
// eslint-disable-next-line @next/next/no-img-element
return (
<div className='relative w-full h-full min-w-[40px] min-h-[40px]'>
<Image
<img
src={resolveAssetPlaybackUrl(element.iconUrl)}
alt='Navigation'
fill
className='object-contain'
unoptimized
style={imgStyle}
draggable={false}
/>
</div>
);
}
return (

View File

@ -70,10 +70,13 @@ export const ELEMENT_STYLE_PROPS = [
const NUMERIC_PROPS = ['opacity', 'zIndex'] as const;
/**
* Get trimmed CSS value from unknown input
* Get trimmed CSS value from unknown input.
* Returns empty string for null/undefined, but preserves '0' for explicit zero values.
*/
const getTrimmedValue = (value: unknown): string => {
if (value === null || value === undefined) return '';
// Preserve 0 as '0' - explicit zero should be applied
if (value === 0) return '0';
return String(value).trim();
};

View File

@ -32,7 +32,7 @@ import { logger } from '../lib/logger';
import { resolveAssetPlaybackUrl } from '../lib/assetUrl';
import { parseJsonObject } from '../lib/parseJson';
import { waitForPageImages } from '../lib/imagePreDecode';
import { buildElementStyle } from '../lib/elementStyles';
import { buildElementStyle, ELEMENT_STYLE_PROPS } from '../lib/elementStyles';
import type { PreloadPageLink, PreloadElement } from '../types/preload';
import type {
CanvasElementType,
@ -418,6 +418,23 @@ const mergeElementWithDefaults = (
yPercent: element.yPercent ?? defaults.yPercent ?? 50,
};
// For style properties, use defaults if element has empty/null/undefined value
// This ensures DB defaults are applied when element has no explicit value
const elementRecord = element as unknown as Record<string, unknown>;
const defaultsRecord = defaults as unknown as Record<string, unknown>;
const mergedRecord = merged as unknown as Record<string, unknown>;
ELEMENT_STYLE_PROPS.forEach((prop) => {
const elementValue = elementRecord[prop];
const defaultValue = defaultsRecord[prop];
const elementIsEmpty =
elementValue === '' || elementValue === undefined || elementValue === null;
const defaultHasValue =
defaultValue !== undefined && defaultValue !== null && defaultValue !== '';
if (elementIsEmpty && defaultHasValue) {
mergedRecord[prop] = defaultValue;
}
});
merged.xPercent = clamp(Number(merged.xPercent ?? element.xPercent), 0, 100);
merged.yPercent = clamp(Number(merged.yPercent ?? element.yPercent), 0, 100);
merged.appearDelaySec = normalizeAppearDelaySec(merged.appearDelaySec);
@ -2089,17 +2106,20 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
const fallbackNavLabel = getNavigationButtonLabel(element.type);
const navigationLabel = element.navLabel?.trim() || fallbackNavLabel;
if (element.iconUrl) {
// Use img tag with flexible sizing - auto for dimensions not provided
const imgStyle: React.CSSProperties = {
width: element.width || 'auto',
height: element.height || 'auto',
objectFit: 'contain',
};
// eslint-disable-next-line @next/next/no-img-element
return (
<div className='relative min-w-[60px] min-h-[60px] w-full h-full'>
<NextImage
<img
src={resolveAssetPlaybackUrl(element.iconUrl)}
alt='Navigation icon'
fill
sizes='100vw'
className='object-contain'
style={imgStyle}
draggable={false}
/>
</div>
);
}