forked from 77media/video-flow
87 lines
2.8 KiB
TypeScript
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;
|
|
|
|
|