컴포넌트
Spinner
진행률을 알 수 없는 작업의 처리 상태를 표시합니다.
설치
pnpm dlx ply-ui add spinner사용법
size는 sm(16px), md(20px), lg(28px)입니다. label로 스크린 리더가 읽을 작업 이름을 지정합니다. 화면에는 원형 표시만 나타납니다.
주변에 같은 의미의 텍스트가 있다면 aria-hidden="true"로 중복 안내를 막습니다. 모션 줄이기를 설정한 환경에서는 회전하지 않습니다.
버튼 안의 로딩은 Button loading을 사용합니다. 퍼센트를 알 수 있는 작업은 Progress를 사용합니다.
속성
속성
타입
구현 코드
components/ui/spinner.tsx
import type { ComponentProps } from "react";
import { cx } from "../../lib/cx";
import "./spinner.css";
export type SpinnerProps = Omit<ComponentProps<"span">, "children"> & {
/** 표시 크기입니다. @defaultValue "md" */
size?: "sm" | "md" | "lg";
/** 스크린 리더가 읽을 진행 상태입니다. @defaultValue "처리 중" */
label?: string;
};
/** 진행률을 모르는 짧은 작업에 사용합니다. 진행률이 있으면 Progress를 사용합니다. */
export function Spinner({
size = "md",
label = "처리 중",
className,
...props
}: SpinnerProps) {
return (
<span
role="status"
aria-label={label}
{...props}
data-size={size}
className={cx("rbx-spinner", className)}
/>
);
}
components/ui/spinner.css
@layer theme, base, components, utilities;
@layer components.ply-base, components.ply;
@layer components.ply {
.rbx-spinner {
display: inline-block;
flex-shrink: 0;
width: 20px;
height: 20px;
border: 2px solid currentColor;
border-inline-end-color: transparent;
border-radius: 50%;
vertical-align: middle;
animation: rbx-spinner-rotate 800ms linear infinite;
}
.rbx-spinner[data-size="sm"] {
width: 16px;
height: 16px;
}
.rbx-spinner[data-size="lg"] {
width: 28px;
height: 28px;
border-width: 3px;
}
@keyframes rbx-spinner-rotate {
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: reduce) {
.rbx-spinner {
animation: none;
}
}
}