버튼
사용자가 동작을 실행하는 요소입니다. Button · IconButton 컴포넌트와, 같은 모양을 문자열로 주는 클래스 상수를 함께 제공합니다.
버튼은 키캡입니다. 오른쪽 아래로 2px 두께가 있고, 손을 올리면 1px 솟고, 누르면 두께만큼 대각으로 가라앉습니다. 빛은 왼쪽 위 하나라 두께는 늘 오른쪽 아래로 떨어집니다. ghost 와 link 는 솟지 않습니다.
primary 는 같은 색의 진한 옆면과 위가 7% 밝은 아주 약한 볼록면입니다. hover 에 색을 밝히면 흰 글자 대비가 4.5:1 아래로 떨어지므로 색은 그대로 두고 솟는 것으로만 말합니다. secondary 는 컨트롤 경계(3:1)가 있는 흰 키캡, danger 는 빨간 키캡입니다.
포커스 링은 2px 이고 3px 띄워 두께 바깥에 그립니다. 비활성은 투명도를 낮추지 않고 두께 없는 파인 면과 흐린 글자로 바꿉니다. 컴포넌트와 클래스 상수는 같은 buttonVariants 에서 나와 <Button variant="primary"> 와 <button className={primaryButtonClass}> 는 모양이 같습니다.
- import
- import { Button, IconButton, buttonVariants } from "@uyoolabs/ui/ui";
- 쓰는 경우
- 저장 · 확정 같은 주요 동작은 primary 를 한 화면에 하나만 씁니다. 보관 · 나가기처럼 되돌릴 수 있는 보조 동작은 secondary(기본값), 툴바 · 표 안 · 비중이 낮은 동작은 ghost, 되돌릴 수 없는 동작을 확인하는 자리에는 danger, 글 사이의 가벼운 동작은 link 를 씁니다.
- 쓰지 않는 경우
- 보관 · 나가기처럼 되돌릴 수 있는 동작에 danger 를 쓰지 않습니다(빨강은 오류와 되돌릴 수 없는 동작에만). 페이지 이동에 button 을 쓰지 않고 asChild 로 링크에 입힙니다. 목록을 거르는 전환에는 TabNav, 목록 항목 전체를 링크로 만들 때는 rowClass 를 씁니다.
Button
variant 로 종류를, size 로 크기를 고릅니다. type 기본값은 button 이라 폼 안에서 저절로 제출되지 않습니다.
아이콘 · 불러오는 중
아이콘만 있는 버튼은 IconButton 을 쓰고 label 을 반드시 줍니다. label 이 스크린 리더가 읽는 이름이 됩니다.
눌린 상태 · 묶음
툴바에서 고른 도구는 aria-pressed 로 눌린 면에 고정합니다. 함께 놓이는 버튼은 묶음 클래스로 간격을 맞춥니다.
asChild
페이지 이동은 button 이 아니라 링크입니다. 링크에 버튼 모양을 입힐 때 asChild 를 씁니다.
키보드
| 키 | 동작 |
|---|---|
| Enter | 누릅니다. 네이티브 button 이 처리하므로 따로 코드를 두지 않습니다. |
| Space | 누릅니다. 누르고 있는 동안 :active 라 키캡이 가라앉은 모양으로 보입니다. |
| Tab | 다음 버튼으로 옮깁니다. 불러오는 중인 버튼도 포커스를 받습니다(aria-disabled). disabled 버튼은 건너뜁니다. |
props
소스의 타입과 JSDoc 에서 생성한 표입니다. 컴포넌트를 고치면 pnpm gen 으로 다시 만듭니다.
Button
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| variant | "primary" | "secondary" | "ghost" | "danger" | "link" | "secondary" | 기본값 secondary. primary 는 한 화면에 하나만 둔다 |
| size | "sm" | "md" | "lg" | "md" | sm 28 · md(기본) · lg 44(터치 · 모바일) |
| icon | ReactNode | — | 라벨 앞 아이콘. 장식이라 aria-hidden 으로 감싼다 |
| iconEnd | ReactNode | — | 라벨 뒤 아이콘(화살표 · 바깥 링크 표시) |
| loading | boolean | false | 불러오는 중. 앞 아이콘 자리에 스피너를 두고 aria-busy 를 단다. 클릭은 막지만 disabled 를 쓰지 않아 포커스가 남는다. disabled 를 쓰면 누른 버튼에서 포커스가 body 로 튀어 키보드 사용자가 위치를 잃는다 |
| asChild | boolean | false | 자식 요소(라우터 링크 · a)에 버튼 클래스와 동작을 입힌다. 자식은 요소 하나여야 한다 |
이 밖에 <button> props를 그대로 받습니다. 기본값을 바꾼 것은 type="button" 입니다.
IconButton
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| variant | "primary" | "secondary" | "ghost" | "danger" | "ghost" | 기본값 ghost. 툴바 · 표 행의 아이콘 버튼은 면 없이 hover 에만 배경이 생긴다 |
| size | "sm" | "md" | "lg" | "md" | sm 28 · md(기본) · lg 44(터치 · 모바일) |
| loading | boolean | — | 불러오는 중. 앞 아이콘 자리에 스피너를 두고 aria-busy 를 단다. 클릭은 막지만 disabled 를 쓰지 않아 포커스가 남는다. disabled 를 쓰면 누른 버튼에서 포커스가 body 로 튀어 키보드 사용자가 위치를 잃는다 |
| label필수 | string | — | 접근성 이름(aria-label). 아이콘만으로는 스크린 리더가 읽을 이름이 없어 반드시 받는다 |
| children필수 | ReactNode | — | 아이콘 하나 |
이 밖에 <button> props(aria-label 제외)를 그대로 받습니다.
클래스 상수
컴포넌트를 쓸 수 없는 자리(라우터 링크 · 메뉴 트리거 · 서버 폼)에 붙이는 클래스 API 입니다. v1 과 이름이 같고 값만 카톤 클래스로 바뀌었습니다.