x
This commit is contained in:
1 parent
b641acbeb7
commit
e349ef5b84
14 files changed
+720
-558
No files matched your search
@@ -7,6 +7,7 @@ import {
|
||||
Smartphone,
|
||||
Trash2,
|
||||
} from 'lucide-react'
|
||||
import ContentPositionPicker from '../page-builder/ContentPositionPicker'
|
||||
|
||||
type CategoryHeroCarouselBlockFormProps = {
|
||||
payload: Record<string, unknown>
|
||||
@@ -32,6 +33,8 @@ const createSlide = (): SlidePayload => ({
|
||||
subtitle: {},
|
||||
buttonText: {},
|
||||
focalPoint: { x: '50%', y: '50%' },
|
||||
buttonPosition: 'bottom-left',
|
||||
mobileButtonPosition: '',
|
||||
})
|
||||
|
||||
const getSlides = (payload: Record<string, unknown>): SlidePayload[] =>
|
||||
@@ -253,6 +256,17 @@ export default function CategoryHeroCarouselBlockForm({
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Slide Button & Content Position */}
|
||||
<ContentPositionPicker
|
||||
compact
|
||||
defaultDesktop="bottom-left"
|
||||
desktopPosition={getString(slide.buttonPosition, 'bottom-left')}
|
||||
mobilePosition={getString(slide.mobileButtonPosition) || undefined}
|
||||
onChangeDesktop={(pos) => updateSlide(slideIndex, { buttonPosition: pos })}
|
||||
onChangeMobile={(pos) => updateSlide(slideIndex, { mobileButtonPosition: pos || '' })}
|
||||
title="ตำแหน่งปุ่ม & ข้อความของสไลด์นี้ (Slide Content Position)"
|
||||
/>
|
||||
</article>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { UploadCloud, Image as ImageIcon } from 'lucide-react';
|
||||
import { type PageSection } from '@homaroma/types';
|
||||
import FocalPointPicker from './FocalPointPicker';
|
||||
import ContentPositionPicker from './ContentPositionPicker';
|
||||
|
||||
interface BannerFormProps {
|
||||
editingSection: Partial<PageSection>;
|
||||
@@ -97,6 +98,16 @@ export default function BannerForm({
|
||||
className="admin-input w-full resize-none"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-2">
|
||||
<ContentPositionPicker
|
||||
defaultDesktop="center-left"
|
||||
desktopPosition={editingSection.payload?.buttonPosition || 'center-left'}
|
||||
mobilePosition={editingSection.payload?.mobileButtonPosition}
|
||||
onChangeDesktop={(pos) => updatePayloadValue('buttonPosition', pos)}
|
||||
onChangeMobile={(pos) => updatePayloadValue('mobileButtonPosition', pos)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
import { Monitor, Smartphone, RotateCcw } from 'lucide-react';
|
||||
|
||||
export const GRID_POSITIONS = [
|
||||
{ id: 'top-left', label: 'Top Left (บนซ้าย)', short: 'TL', icon: '↖' },
|
||||
{ id: 'top-center', label: 'Top Center (บนกลาง)', short: 'TC', icon: '↑' },
|
||||
{ id: 'top-right', label: 'Top Right (บนขวา)', short: 'TR', icon: '↗' },
|
||||
{ id: 'center-left', label: 'Center Left (กลางซ้าย)', short: 'CL', icon: '←' },
|
||||
{ id: 'center', label: 'Center (กึ่งกลาง)', short: 'C', icon: '•' },
|
||||
{ id: 'center-right', label: 'Center Right (กลางขวา)', short: 'CR', icon: '→' },
|
||||
{ id: 'bottom-left', label: 'Bottom Left (ล่างซ้าย)', short: 'BL', icon: '↙' },
|
||||
{ id: 'bottom-center', label: 'Bottom Center (ล่างกลาง)', short: 'BC', icon: '↓' },
|
||||
{ id: 'bottom-right', label: 'Bottom Right (ล่างขวา)', short: 'BR', icon: '↘' },
|
||||
];
|
||||
|
||||
export interface ContentPositionPickerProps {
|
||||
desktopPosition?: string;
|
||||
mobilePosition?: string;
|
||||
defaultDesktop?: string;
|
||||
onChangeDesktop: (position: string) => void;
|
||||
onChangeMobile: (position: string | undefined) => void;
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
compact?: boolean;
|
||||
}
|
||||
|
||||
export default function ContentPositionPicker({
|
||||
desktopPosition,
|
||||
mobilePosition,
|
||||
defaultDesktop = 'center',
|
||||
onChangeDesktop,
|
||||
onChangeMobile,
|
||||
title = 'ตำแหน่งปุ่ม & เนื้อหา (Button & Content Position)',
|
||||
subtitle = 'สามารถแยกตำแหน่งระหว่าง Desktop (PC) และ Mobile (มือถือ) ได้อิสระ',
|
||||
compact = false,
|
||||
}: ContentPositionPickerProps) {
|
||||
const effectiveDesktop = desktopPosition || defaultDesktop;
|
||||
const currentMobilePos = mobilePosition || effectiveDesktop;
|
||||
|
||||
return (
|
||||
<div className={`space-y-3 ${compact ? 'p-3 bg-night-950/60 rounded-xl border border-white/5' : 'pt-2'}`}>
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-1 border-b border-white/5 pb-2">
|
||||
<div>
|
||||
<label className="text-[11px] uppercase font-bold tracking-widest text-slate-300">
|
||||
{title}
|
||||
</label>
|
||||
{subtitle && (
|
||||
<p className="text-[11px] text-slate-400 mt-0.5">
|
||||
{subtitle}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={`grid grid-cols-1 ${compact ? 'gap-3 sm:grid-cols-2' : 'lg:grid-cols-2 gap-4'}`}>
|
||||
{/* Desktop (PC) */}
|
||||
<div className="bg-night-950/40 border border-white/5 p-3.5 rounded-2xl space-y-2.5">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="flex items-center gap-2 text-xs font-bold text-white uppercase tracking-wider">
|
||||
<Monitor className="w-4 h-4 text-cyan-glow" />
|
||||
Desktop (PC)
|
||||
</span>
|
||||
<span className="px-2 py-0.5 rounded-md bg-cyan-glow/10 text-cyan-glow font-mono font-bold text-[10px] border border-cyan-glow/20">
|
||||
{effectiveDesktop}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="grid grid-cols-3 gap-1.5 p-1.5 bg-night-900 border border-white/10 rounded-xl w-28 h-28 shrink-0 shadow-inner">
|
||||
{GRID_POSITIONS.map((pos) => {
|
||||
const isSelected = effectiveDesktop === pos.id;
|
||||
return (
|
||||
<button
|
||||
key={pos.id}
|
||||
type="button"
|
||||
onClick={() => onChangeDesktop(pos.id)}
|
||||
className={`flex flex-col items-center justify-center rounded-lg transition-all cursor-pointer ${
|
||||
isSelected
|
||||
? 'bg-cyan-glow text-night-950 font-black shadow-md shadow-cyan-glow/20 scale-105 ring-1 ring-white/30'
|
||||
: 'bg-white/5 hover:bg-white/10 text-slate-400 hover:text-white'
|
||||
}`}
|
||||
title={`Desktop: ${pos.label}`}
|
||||
>
|
||||
<span className="text-xs leading-none">{pos.icon}</span>
|
||||
<span className="text-[7px] font-mono mt-0.5">{pos.short}</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<p className="text-[10px] text-slate-400 leading-relaxed">
|
||||
ตำแหน่งแสดงบนหน้าจอคอมพิวเตอร์ / จอกว้าง (≥ 768px)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile (Smartphone) */}
|
||||
<div className="bg-night-950/40 border border-white/5 p-3.5 rounded-2xl space-y-2.5">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="flex items-center gap-2 text-xs font-bold text-white uppercase tracking-wider">
|
||||
<Smartphone className="w-4 h-4 text-pop-pink" />
|
||||
Mobile (มือถือ)
|
||||
</span>
|
||||
<div className="flex items-center gap-1.5">
|
||||
{mobilePosition && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onChangeMobile(undefined)}
|
||||
className="flex items-center gap-1 text-[10px] text-slate-400 hover:text-white px-2 py-0.5 rounded bg-white/5 hover:bg-white/10 border border-white/10 transition-colors cursor-pointer"
|
||||
title="รีเซ็ตให้เหมือน Desktop"
|
||||
>
|
||||
<RotateCcw className="w-3 h-3" />
|
||||
ตาม PC
|
||||
</button>
|
||||
)}
|
||||
<span className="px-2 py-0.5 rounded-md bg-pop-pink/10 text-pop-pink font-mono font-bold text-[10px] border border-pop-pink/20">
|
||||
{mobilePosition || `${effectiveDesktop} (ตาม PC)`}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="grid grid-cols-3 gap-1.5 p-1.5 bg-night-900 border border-white/10 rounded-xl w-28 h-28 shrink-0 shadow-inner">
|
||||
{GRID_POSITIONS.map((pos) => {
|
||||
const isSelected = currentMobilePos === pos.id;
|
||||
const isExplicit = mobilePosition === pos.id;
|
||||
return (
|
||||
<button
|
||||
key={pos.id}
|
||||
type="button"
|
||||
onClick={() => onChangeMobile(pos.id)}
|
||||
className={`flex flex-col items-center justify-center rounded-lg transition-all cursor-pointer ${
|
||||
isSelected
|
||||
? isExplicit
|
||||
? 'bg-pop-pink text-white font-black shadow-md shadow-pop-pink/20 scale-105 ring-1 ring-white/30'
|
||||
: 'bg-pop-pink/40 text-white font-bold ring-1 ring-pop-pink/40'
|
||||
: 'bg-white/5 hover:bg-white/10 text-slate-400 hover:text-white'
|
||||
}`}
|
||||
title={`Mobile: ${pos.label}`}
|
||||
>
|
||||
<span className="text-xs leading-none">{pos.icon}</span>
|
||||
<span className="text-[7px] font-mono mt-0.5">{pos.short}</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<p className="text-[10px] text-slate-400 leading-relaxed">
|
||||
ตำแหน่งแสดงบนโทรศัพท์มือถือ (หากไม่เลือก จะใช้ตาม Desktop)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Plus, Trash2, UploadCloud, Image as ImageIcon, Sliders } from 'lucide-react';
|
||||
import { type PageSection } from '@homaroma/types';
|
||||
import ContentPositionPicker from './ContentPositionPicker';
|
||||
|
||||
interface HeroCarouselFormProps {
|
||||
editingSection: Partial<PageSection>;
|
||||
@@ -318,7 +319,7 @@ export default function HeroCarouselForm({
|
||||
</div>
|
||||
|
||||
{/* Accessibility Alt & Optional Overlay Text */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3 pt-2 border-t border-white/5">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-3 pt-2 border-t border-white/5">
|
||||
<div className="space-y-1">
|
||||
<label className="text-[10px] uppercase font-bold tracking-widest text-slate-400">
|
||||
Alt Text
|
||||
@@ -357,7 +358,31 @@ export default function HeroCarouselForm({
|
||||
className="admin-input w-full text-xs"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
<label className="text-[10px] uppercase font-bold tracking-widest text-slate-400">
|
||||
Button Text (Optional)
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={getLocalizedSlideValue(slide, 'buttonText')}
|
||||
onChange={(e) => updateLocalizedSlideValue(idx, 'buttonText', e.target.value)}
|
||||
placeholder="e.g. Shop Now"
|
||||
className="admin-input w-full text-xs"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Slide Button & Content Position */}
|
||||
<ContentPositionPicker
|
||||
compact
|
||||
defaultDesktop="bottom-left"
|
||||
desktopPosition={slide.buttonPosition}
|
||||
mobilePosition={slide.mobileButtonPosition}
|
||||
onChangeDesktop={(pos) => updateSlidePayloadValue(idx, 'buttonPosition', pos)}
|
||||
onChangeMobile={(pos) => updateSlidePayloadValue(idx, 'mobileButtonPosition', pos || '')}
|
||||
title="ตำแหน่งปุ่ม & ข้อความของสไลด์นี้ (Slide Content Position)"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { UploadCloud, Image as ImageIcon, Monitor, Smartphone, RotateCcw, Layers, Sliders } from 'lucide-react';
|
||||
import { UploadCloud, Image as ImageIcon, Layers, Sliders } from 'lucide-react';
|
||||
import { type PageSection } from '@homaroma/types';
|
||||
import FocalPointPicker from './FocalPointPicker';
|
||||
import ContentPositionPicker from './ContentPositionPicker';
|
||||
|
||||
interface HeroFormProps {
|
||||
editingSection: Partial<PageSection>;
|
||||
@@ -12,18 +13,6 @@ interface HeroFormProps {
|
||||
setIsMediaModalOpen: (open: boolean) => void;
|
||||
}
|
||||
|
||||
const GRID_POSITIONS = [
|
||||
{ id: 'top-left', label: 'Top Left (บนซ้าย)', short: 'TL', icon: '↖' },
|
||||
{ id: 'top-center', label: 'Top Center (บนกลาง)', short: 'TC', icon: '↑' },
|
||||
{ id: 'top-right', label: 'Top Right (บนขวา)', short: 'TR', icon: '↗' },
|
||||
{ id: 'center-left', label: 'Center Left (กลางซ้าย)', short: 'CL', icon: '←' },
|
||||
{ id: 'center', label: 'Center (กึ่งกลาง)', short: 'C', icon: '•' },
|
||||
{ id: 'center-right', label: 'Center Right (กลางขวา)', short: 'CR', icon: '→' },
|
||||
{ id: 'bottom-left', label: 'Bottom Left (ล่างซ้าย)', short: 'BL', icon: '↙' },
|
||||
{ id: 'bottom-center', label: 'Bottom Center (ล่างกลาง)', short: 'BC', icon: '↓' },
|
||||
{ id: 'bottom-right', label: 'Bottom Right (ล่างขวา)', short: 'BR', icon: '↘' },
|
||||
];
|
||||
|
||||
const OVERLAY_PRESETS = [
|
||||
{ label: 'None (0%)', value: 0 },
|
||||
{ label: 'Light (25%)', value: 25 },
|
||||
@@ -237,116 +226,13 @@ export default function HeroForm({
|
||||
</div>
|
||||
|
||||
{/* 9-Box Grid Button Position Selector (Desktop & Mobile) */}
|
||||
<div className="md:col-span-2 space-y-4 pt-2">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-2 border-b border-white/5 pb-2">
|
||||
<div>
|
||||
<label className="text-[11px] uppercase font-bold tracking-widest text-slate-300">
|
||||
ตำแหน่งปุ่ม & เนื้อหา (Button & Content Position)
|
||||
</label>
|
||||
<p className="text-[11px] text-slate-400 mt-0.5">
|
||||
สามารถแยกตำแหน่งระหว่าง <strong>Desktop (PC)</strong> และ <strong>Mobile (มือถือ)</strong> ได้อิสระ
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
{/* Desktop (PC) */}
|
||||
<div className="bg-night-950/40 border border-white/5 p-4 rounded-2xl space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="flex items-center gap-2 text-xs font-bold text-white uppercase tracking-wider">
|
||||
<Monitor className="w-4 h-4 text-cyan-glow" />
|
||||
Desktop (PC)
|
||||
</span>
|
||||
<span className="px-2 py-0.5 rounded-md bg-cyan-glow/10 text-cyan-glow font-mono font-bold text-[10px] border border-cyan-glow/20">
|
||||
{editingSection.payload?.buttonPosition || 'center'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="grid grid-cols-3 gap-1.5 p-1.5 bg-night-900 border border-white/10 rounded-xl w-32 h-32 shrink-0 shadow-inner">
|
||||
{GRID_POSITIONS.map((pos) => {
|
||||
const isSelected = (editingSection.payload?.buttonPosition || 'center') === pos.id;
|
||||
return (
|
||||
<button
|
||||
key={pos.id}
|
||||
type="button"
|
||||
onClick={() => updatePayloadValue('buttonPosition', pos.id)}
|
||||
className={`flex flex-col items-center justify-center rounded-lg transition-all cursor-pointer ${
|
||||
isSelected
|
||||
? 'bg-cyan-glow text-night-950 font-black shadow-md shadow-cyan-glow/20 scale-105 ring-1 ring-white/30'
|
||||
: 'bg-white/5 hover:bg-white/10 text-slate-400 hover:text-white'
|
||||
}`}
|
||||
title={`Desktop: ${pos.label}`}
|
||||
>
|
||||
<span className="text-xs leading-none">{pos.icon}</span>
|
||||
<span className="text-[7px] font-mono mt-0.5">{pos.short}</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<p className="text-[11px] text-slate-400 leading-relaxed">
|
||||
ตำแหน่งที่จะแสดงเมื่อเปิดบนหน้าจอคอมพิวเตอร์ / จอกว้าง (ขนาด ≥ 768px)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile (Smartphone) */}
|
||||
<div className="bg-night-950/40 border border-white/5 p-4 rounded-2xl space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="flex items-center gap-2 text-xs font-bold text-white uppercase tracking-wider">
|
||||
<Smartphone className="w-4 h-4 text-pop-pink" />
|
||||
Mobile (มือถือ)
|
||||
</span>
|
||||
<div className="flex items-center gap-1.5">
|
||||
{editingSection.payload?.mobileButtonPosition && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => updatePayloadValue('mobileButtonPosition', undefined)}
|
||||
className="flex items-center gap-1 text-[10px] text-slate-400 hover:text-white px-2 py-0.5 rounded bg-white/5 hover:bg-white/10 border border-white/10 transition-colors"
|
||||
title="รีเซ็ตให้เหมือน Desktop"
|
||||
>
|
||||
<RotateCcw className="w-3 h-3" />
|
||||
ตาม PC
|
||||
</button>
|
||||
)}
|
||||
<span className="px-2 py-0.5 rounded-md bg-pop-pink/10 text-pop-pink font-mono font-bold text-[10px] border border-pop-pink/20">
|
||||
{editingSection.payload?.mobileButtonPosition || `${editingSection.payload?.buttonPosition || 'center'} (ตาม PC)`}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="grid grid-cols-3 gap-1.5 p-1.5 bg-night-900 border border-white/10 rounded-xl w-32 h-32 shrink-0 shadow-inner">
|
||||
{GRID_POSITIONS.map((pos) => {
|
||||
const currentMobilePos = editingSection.payload?.mobileButtonPosition || editingSection.payload?.buttonPosition || 'center';
|
||||
const isSelected = currentMobilePos === pos.id;
|
||||
const isExplicit = editingSection.payload?.mobileButtonPosition === pos.id;
|
||||
return (
|
||||
<button
|
||||
key={pos.id}
|
||||
type="button"
|
||||
onClick={() => updatePayloadValue('mobileButtonPosition', pos.id)}
|
||||
className={`flex flex-col items-center justify-center rounded-lg transition-all cursor-pointer ${
|
||||
isSelected
|
||||
? isExplicit
|
||||
? 'bg-pop-pink text-white font-black shadow-md shadow-pop-pink/20 scale-105 ring-1 ring-white/30'
|
||||
: 'bg-pop-pink/40 text-white font-bold ring-1 ring-pop-pink/40'
|
||||
: 'bg-white/5 hover:bg-white/10 text-slate-400 hover:text-white'
|
||||
}`}
|
||||
title={`Mobile: ${pos.label}`}
|
||||
>
|
||||
<span className="text-xs leading-none">{pos.icon}</span>
|
||||
<span className="text-[7px] font-mono mt-0.5">{pos.short}</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<p className="text-[11px] text-slate-400 leading-relaxed">
|
||||
ตำแหน่งที่จะแสดงเมื่อเปิดบนโทรศัพท์มือถือ (หากไม่เลือก จะใช้ตาม Desktop อัตโนมัติ)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="md:col-span-2">
|
||||
<ContentPositionPicker
|
||||
desktopPosition={editingSection.payload?.buttonPosition}
|
||||
mobilePosition={editingSection.payload?.mobileButtonPosition}
|
||||
onChangeDesktop={(pos) => updatePayloadValue('buttonPosition', pos)}
|
||||
onChangeMobile={(pos) => updatePayloadValue('mobileButtonPosition', pos)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { UploadCloud, Image as ImageIcon, Video } from 'lucide-react';
|
||||
import { type PageSection } from '@homaroma/types';
|
||||
import ContentPositionPicker from './ContentPositionPicker';
|
||||
|
||||
interface HeroVideoFormProps {
|
||||
editingSection: Partial<PageSection>;
|
||||
@@ -291,6 +292,14 @@ export default function HeroVideoForm({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Button & Content Position (9-Box Grid for Desktop & Mobile) */}
|
||||
<ContentPositionPicker
|
||||
desktopPosition={payload.buttonPosition}
|
||||
mobilePosition={payload.mobileButtonPosition}
|
||||
onChangeDesktop={(pos) => updatePayloadValue('buttonPosition', pos)}
|
||||
onChangeMobile={(pos) => updatePayloadValue('mobileButtonPosition', pos)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Smartphone,
|
||||
Trash2,
|
||||
} from 'lucide-react'
|
||||
import ContentPositionPicker from '../page-builder/ContentPositionPicker'
|
||||
|
||||
type ProductHeroCarouselBlockFormProps = {
|
||||
payload: Record<string, unknown>
|
||||
@@ -32,6 +33,8 @@ const createSlide = (): SlidePayload => ({
|
||||
subtitle: {},
|
||||
buttonText: {},
|
||||
focalPoint: { x: '50%', y: '50%' },
|
||||
buttonPosition: 'bottom-left',
|
||||
mobileButtonPosition: '',
|
||||
})
|
||||
|
||||
const getSlides = (payload: Record<string, unknown>): SlidePayload[] =>
|
||||
@@ -253,6 +256,17 @@ export default function ProductHeroCarouselBlockForm({
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Slide Button & Content Position */}
|
||||
<ContentPositionPicker
|
||||
compact
|
||||
defaultDesktop="bottom-left"
|
||||
desktopPosition={getString(slide.buttonPosition, 'bottom-left')}
|
||||
mobilePosition={getString(slide.mobileButtonPosition) || undefined}
|
||||
onChangeDesktop={(pos) => updateSlide(slideIndex, { buttonPosition: pos })}
|
||||
onChangeMobile={(pos) => updateSlide(slideIndex, { mobileButtonPosition: pos || '' })}
|
||||
title="ตำแหน่งปุ่ม & ข้อความของสไลด์นี้ (Slide Content Position)"
|
||||
/>
|
||||
</article>
|
||||
)
|
||||
})}
|
||||
|
||||
Reference in new issue
Block a user