This commit is contained in:
dev.daminik00 2025-10-21 21:20:35 +02:00
parent 30875ef4a7
commit 653b15e09c
8 changed files with 84 additions and 6 deletions

View File

@ -357,6 +357,7 @@ function ActionButtonControls({
const buttonText = value?.text || "";
const cornerRadius = value?.cornerRadius;
const showPrivacyTermsConsent = value?.showPrivacyTermsConsent ?? false;
const showGradientBlur = value?.showGradientBlur ?? true;
const handleToggle = (enabled: boolean) => {
if (enabled) {
@ -435,6 +436,29 @@ function ActionButtonControls({
}
};
const handleGradientBlurToggle = (checked: boolean) => {
// Работает даже когда кнопка отключена (для LIST экранов)
const newValue = {
...value,
// Если checked = true (дефолт), не сохраняем поле
// Если checked = false, сохраняем явно
showGradientBlur: checked ? undefined : false,
};
// Убираем undefined поля для чистоты
if (
!newValue.text &&
!newValue.cornerRadius &&
newValue.show !== false &&
!newValue.showPrivacyTermsConsent &&
newValue.showGradientBlur !== false
) {
onChange(undefined);
} else {
onChange(newValue);
}
};
return (
<div className="space-y-3">
<label className="flex items-center gap-2 text-sm">
@ -489,6 +513,25 @@ function ActionButtonControls({
</label>
</div>
)}
{/* Gradient Blur - доступен даже когда кнопка отключена */}
<div className="rounded-lg border border-border/60 bg-muted/20 p-3">
<label className="flex items-center gap-2 text-sm">
<input
type="checkbox"
checked={showGradientBlur}
onChange={(event) =>
handleGradientBlurToggle(event.target.checked)
}
/>
<span>
Показывать gradient blur{" "}
{!isEnabled && (
<span className="text-muted-foreground">(работает даже без кнопки)</span>
)}
</span>
</label>
</div>
</div>
);
}

View File

@ -20,6 +20,7 @@ export interface ListTemplateProps {
skipCheckChanges?: boolean
) => void;
actionButtonProps?: ActionButtonProps;
showGradientBlur?: boolean;
canGoBack: boolean;
onBack: () => void;
screenProgress?: { current: number; total: number };
@ -37,6 +38,7 @@ export function ListTemplate({
selectedOptionIds,
onSelectionChange,
actionButtonProps,
showGradientBlur,
canGoBack,
onBack,
screenProgress,
@ -119,6 +121,7 @@ export function ListTemplate({
{
preset: "left",
actionButton: actionButtonOptions,
showGradientBlur,
}
);

View File

@ -56,6 +56,7 @@ interface TemplateLayoutProps {
disabled: boolean;
onClick: () => void;
};
showGradientBlur?: boolean;
// Дополнительные props для BottomActionButton
childrenAboveButton?: React.ReactNode;
@ -96,6 +97,7 @@ export function TemplateLayout({
size: "lg",
},
actionButtonOptions,
showGradientBlur,
childrenAboveButton,
childrenUnderButton,
childrenAboveTitle,
@ -124,6 +126,12 @@ export function TemplateLayout({
screen,
actionButtonOptions,
})
: showGradientBlur
? // Если нет кнопки, но нужен blur (для LIST экранов)
{
actionButtonProps: undefined,
showGradientBlur: true,
}
: undefined;
// 🎯 Автоматически создаем PrivacyTermsConsent с фиксированными настройками

View File

@ -16,7 +16,7 @@ const buttonVariants = cva(
"pl-[26px] pr-[18px] py-[18px]",
"transition-[background-color,border-color,color]",
"duration-200",
"disabled:opacity-30",
"disabled:opacity-20",
"border-2",
"[-webkit-tap-highlight-color:transparent]",
"[transform:translateZ(0)]"
@ -78,7 +78,7 @@ function MainButton({
<Label
data-disabled={disabled}
className={cn(
disabled && "pointer-events-none opacity-30 cursor-not-allowed"
disabled && "pointer-events-none opacity-20 cursor-not-allowed"
)}
>
{emoji && <span className="text-[40px]">{Array.from(emoji)[0]}</span>}

View File

@ -46,6 +46,7 @@ const BottomActionButton = forwardRef<HTMLDivElement, BottomActionButtonProps>(
const hasExtra =
Boolean(childrenAboveButton) || Boolean(childrenUnderButton);
const hasContent = hasButton || hasExtra;
const shouldRender = hasContent || showGradientBlur;
useEffect(() => {
if (!syncCssVar || typeof window === "undefined" || !hasContent) return;
@ -72,8 +73,8 @@ const BottomActionButton = forwardRef<HTMLDivElement, BottomActionButtonProps>(
}
}, [syncCssVar, hasContent]);
// Ничего не рендерим, если нет контента
if (!hasContent) return null;
// Ничего не рендерим, если нет контента И не нужен blur
if (!shouldRender) return null;
return (
<div

View File

@ -172,8 +172,20 @@ export function buildBottomActionButtonProps(
options: BuildActionButtonOptions,
buttonDef?: BottomActionButtonDefinition
): BottomActionButtonProps | undefined {
// Если кнопка отключена (show: false) - не показывать ничего
// Если кнопка отключена (show: false)
if (buttonDef?.show === false) {
// Проверяем нужен ли blur (для LIST экранов)
const shouldShowBlur = buttonDef?.showGradientBlur ?? false;
if (shouldShowBlur) {
// Показать только blur без кнопки
return {
actionButtonProps: undefined,
showGradientBlur: true,
};
}
// Не показывать ничего
return undefined;
}
@ -182,7 +194,7 @@ export function buildBottomActionButtonProps(
return {
actionButtonProps,
showGradientBlur: true, // Градиент всегда включен (как требовалось)
showGradientBlur: buttonDef?.showGradientBlur ?? true, // Градиент по умолчанию включен
};
}

View File

@ -205,6 +205,9 @@ const TEMPLATE_REGISTRY: Record<
const actionDisabled = hasActionButton && isSelectionEmpty;
// Для LIST экранов всегда показываем blur (даже без кнопки)
const showGradientBlur = bottomActionButton?.showGradientBlur ?? true;
return (
<ListTemplate
screen={listScreen}
@ -219,6 +222,7 @@ const TEMPLATE_REGISTRY: Record<
}
: undefined
}
showGradientBlur={showGradientBlur}
canGoBack={canGoBack}
onBack={onBack}
screenProgress={screenProgress}

View File

@ -64,6 +64,11 @@ export interface CreateTemplateLayoutOptions {
* Контент под кнопкой (privacy banner, дополнительные элементы)
*/
childrenUnderButton?: React.ReactNode;
/**
* Управление отображением gradient blur (для LIST экранов без кнопки)
*/
showGradientBlur?: boolean;
}
/**
@ -126,5 +131,7 @@ export function createTemplateLayoutProps(
childrenAboveTitle: options?.childrenAboveTitle,
childrenAboveButton: options?.childrenAboveButton,
childrenUnderButton: options?.childrenUnderButton,
// Управление gradient blur
showGradientBlur: options?.showGradientBlur,
};
}