fixed buttons styles
This commit is contained in:
parent
fba1857e1b
commit
22fe0cd50f
@ -460,16 +460,20 @@ export default function RuntimePresentation({
|
|||||||
element.type === 'navigation_prev'
|
element.type === 'navigation_prev'
|
||||||
) {
|
) {
|
||||||
if (element.iconUrl) {
|
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 (
|
return (
|
||||||
<div className='relative w-full h-full min-w-[40px] min-h-[40px]'>
|
<img
|
||||||
<Image
|
src={resolveAssetPlaybackUrl(element.iconUrl)}
|
||||||
src={resolveAssetPlaybackUrl(element.iconUrl)}
|
alt='Navigation'
|
||||||
alt='Navigation'
|
style={imgStyle}
|
||||||
fill
|
draggable={false}
|
||||||
className='object-contain'
|
/>
|
||||||
unoptimized
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -70,10 +70,13 @@ export const ELEMENT_STYLE_PROPS = [
|
|||||||
const NUMERIC_PROPS = ['opacity', 'zIndex'] as const;
|
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 => {
|
const getTrimmedValue = (value: unknown): string => {
|
||||||
if (value === null || value === undefined) return '';
|
if (value === null || value === undefined) return '';
|
||||||
|
// Preserve 0 as '0' - explicit zero should be applied
|
||||||
|
if (value === 0) return '0';
|
||||||
return String(value).trim();
|
return String(value).trim();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,7 @@ import { logger } from '../lib/logger';
|
|||||||
import { resolveAssetPlaybackUrl } from '../lib/assetUrl';
|
import { resolveAssetPlaybackUrl } from '../lib/assetUrl';
|
||||||
import { parseJsonObject } from '../lib/parseJson';
|
import { parseJsonObject } from '../lib/parseJson';
|
||||||
import { waitForPageImages } from '../lib/imagePreDecode';
|
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 { PreloadPageLink, PreloadElement } from '../types/preload';
|
||||||
import type {
|
import type {
|
||||||
CanvasElementType,
|
CanvasElementType,
|
||||||
@ -418,6 +418,23 @@ const mergeElementWithDefaults = (
|
|||||||
yPercent: element.yPercent ?? defaults.yPercent ?? 50,
|
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.xPercent = clamp(Number(merged.xPercent ?? element.xPercent), 0, 100);
|
||||||
merged.yPercent = clamp(Number(merged.yPercent ?? element.yPercent), 0, 100);
|
merged.yPercent = clamp(Number(merged.yPercent ?? element.yPercent), 0, 100);
|
||||||
merged.appearDelaySec = normalizeAppearDelaySec(merged.appearDelaySec);
|
merged.appearDelaySec = normalizeAppearDelaySec(merged.appearDelaySec);
|
||||||
@ -2089,17 +2106,20 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
|
|||||||
const fallbackNavLabel = getNavigationButtonLabel(element.type);
|
const fallbackNavLabel = getNavigationButtonLabel(element.type);
|
||||||
const navigationLabel = element.navLabel?.trim() || fallbackNavLabel;
|
const navigationLabel = element.navLabel?.trim() || fallbackNavLabel;
|
||||||
if (element.iconUrl) {
|
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 (
|
return (
|
||||||
<div className='relative min-w-[60px] min-h-[60px] w-full h-full'>
|
<img
|
||||||
<NextImage
|
src={resolveAssetPlaybackUrl(element.iconUrl)}
|
||||||
src={resolveAssetPlaybackUrl(element.iconUrl)}
|
alt='Navigation icon'
|
||||||
alt='Navigation icon'
|
style={imgStyle}
|
||||||
fill
|
draggable={false}
|
||||||
sizes='100vw'
|
/>
|
||||||
className='object-contain'
|
|
||||||
draggable={false}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user