File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
"use client";
import type { ReactNode, Ref } from "react";
import { cx } from "../../utils";
/** `outlined`는 시안 carousel-arrow(테두리+그림자), `plain`은 carousel-atomic(민짜)이다. */
export type FoxCarouselButtonType = "outlined" | "plain";
export type FoxCarouselButtonSize = "lg" | "md" | "sm";
export interface FoxCarouselButtonProps {
type?: FoxCarouselButtonType;
size?: FoxCarouselButtonSize;
/** 네이티브 `type` — prop의 `type`이 시각 계열을 쓰므로 분리했다. */
htmlType?: "button" | "submit" | "reset";
/** `currentColor`로 그린 SVG여야 상태별 색이 적용된다. 크기는 슬롯이 정한다. */
icon: ReactNode;
/** 글자가 보이지 않으므로 `aria-label`이 된다. 무엇을 하는 버튼인지 적는다. */
label: string;
disabled?: boolean;
/** 참이면 렌더하지 않는다(DOM에 남지 않는다). */
hidden?: boolean;
onAction?: () => void;
/** 배치 조정용. 모양이 달라야 하면 여기 말고 `type`을 추가한다. */
className?: string;
ref?: Ref<HTMLButtonElement>;
}
const TYPE_CLASS: Record<FoxCarouselButtonType, string> = {
outlined: "fox-carousel-button--outlined",
plain: "fox-carousel-button--plain",
};
const SIZE_CLASS: Record<FoxCarouselButtonSize, string> = {
lg: "fox-carousel-button--lg",
md: "fox-carousel-button--md",
sm: "fox-carousel-button--sm",
};
/**
* @fox 캐러셀 조작 버튼. 동그란 아이콘 버튼이고 상태를 갖지 않는다.
*
* 시안의 carousel-arrow와 carousel-atomic을 하나로 둔다 — 원형·흰 바탕·아이콘 하나까지
* 같고 테두리와 그림자 유무만 다르다. 그 차이가 `type`이다.
* 시안에 있는 조합은 outlined lg·md·sm과 plain md뿐이지만, 나머지도 같은 규칙으로 나온다.
*
* 아이콘은 호출부가 넘긴다(FoxIconButton과 같다). 시안이 쓰는 다섯 개는 `@fox/core/icons`의
* `FoxCaretLeftBoldIcon` · `FoxCaretRightBoldIcon` · `FoxPlayIcon` · `FoxPauseIcon` ·
* `FoxPlusIcon`이다.
*
* ⚠️ 스타일은 이 파일이 import하지 않는다 — 호스트 앱이 `@use "@fox/styles/components"`
* (또는 개별 파티셜)로 한 번 불러와야 한다.
*/
export function FoxCarouselButton({
type = "outlined",
size = "md",
htmlType = "button",
icon,
label,
disabled = false,
hidden = false,
onAction,
className,
ref,
}: FoxCarouselButtonProps) {
if (hidden) {
return null;
}
return (
<button
ref={ref}
type={htmlType}
className={cx("fox-carousel-button", TYPE_CLASS[type], SIZE_CLASS[size], className)}
aria-label={label}
disabled={disabled}
onClick={disabled ? undefined : onAction}
>
<span className="fox-carousel-button__icon" aria-hidden="true">
{icon}
</span>
</button>
);
}