video-flow-b/components/ChatInputBox/AspectRatioSelector.tsx
2025-09-20 16:33:57 +08:00

87 lines
2.8 KiB
TypeScript

"use client";
import { Dropdown } from "antd";
import { RectangleHorizontal, RectangleVertical } from "lucide-react";
import { AspectRatioOptions } from "./types";
export type AspectRatioValue =
| "VIDEO_ASPECT_RATIO_LANDSCAPE"
| "VIDEO_ASPECT_RATIO_PORTRAIT";
interface AspectRatioSelectorProps {
/** Current selected aspect ratio value */
value: AspectRatioValue;
/** Change handler when an option is selected */
onChange: (value: AspectRatioValue) => void;
/** Optional className to customize the trigger button */
className?: string;
/** Optional dropdown placement, defaults to top */
placement?: "top" | "bottom" | "topLeft" | "topRight" | "bottomLeft" | "bottomRight";
/** data-alt tag for analytics/testing */
dataAlt?: string;
}
/**
* A reusable aspect ratio selector (landscape/portrait) using Antd Dropdown.
* Shows an icon and label, and calls onChange when a new ratio is chosen.
* @param {AspectRatioValue} value - current selected value
* @param {(v: AspectRatioValue) => void} onChange - change handler
* @param {string} [className] - optional className for trigger button
* @param {string} [placement] - Dropdown placement, default is top
* @param {string} [dataAlt] - data-alt attribute for the trigger
* @returns {JSX.Element}
*/
export const AspectRatioSelector = ({
value,
onChange,
className,
placement = "top",
dataAlt = "config-aspect-ratio",
}: AspectRatioSelectorProps) => {
return (
<Dropdown
overlayClassName="aspect-dropdown"
menu={{
items: AspectRatioOptions.map((option) => ({
key: option.value,
label: (
<div
className={`flex items-center gap-2 px-2 py-2 ${
option.value === value ? "bg-white/[0.12] rounded-md" : ""
}`}
>
{option.value === "VIDEO_ASPECT_RATIO_LANDSCAPE" ? (
<RectangleHorizontal className="w-4 h-4" />
) : (
<RectangleVertical className="w-4 h-4" />
)}
<span className="text-sm text-white">{option.label}</span>
</div>
),
})),
onClick: ({ key }) => onChange(key as AspectRatioValue),
}}
trigger={["click"]}
placement={placement}
>
<button
data-alt={dataAlt}
className={`flex items-center gap-1 text-white/80 transition-all duration-200 px-2 py-2 ${className || ""}`}
>
{value === "VIDEO_ASPECT_RATIO_LANDSCAPE" ? (
<RectangleHorizontal className={"w-4 h-4"} />
) : (
<RectangleVertical className={"w-4 h-4"} />
)}
<span className="text-sm">
{value === "VIDEO_ASPECT_RATIO_LANDSCAPE" ? "16:9" : "9:16"}
</span>
</button>
</Dropdown>
);
};
export default AspectRatioSelector;