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 buttonText = value?.text || "";
const cornerRadius = value?.cornerRadius; const cornerRadius = value?.cornerRadius;
const showPrivacyTermsConsent = value?.showPrivacyTermsConsent ?? false; const showPrivacyTermsConsent = value?.showPrivacyTermsConsent ?? false;
const showGradientBlur = value?.showGradientBlur ?? true;
const handleToggle = (enabled: boolean) => { const handleToggle = (enabled: boolean) => {
if (enabled) { 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 ( return (
<div className="space-y-3"> <div className="space-y-3">
<label className="flex items-center gap-2 text-sm"> <label className="flex items-center gap-2 text-sm">
@ -489,6 +513,25 @@ function ActionButtonControls({
</label> </label>
</div> </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> </div>
); );
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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