Avatar
사람이나 사물의 그림을 정해진 크기로 그립니다. 그림이 있으면 그림을, 없으면 이니셜이나 글리프, 실루엣을 대신 그리기 때문에 빈 상자가 되는 일이 없습니다.
import { Avatar } from 'neba';
<Avatar src="/people/jane.jpg" name="홍길동" />
<Avatar name="홍길동" />
<Avatar shape="square" variant="solid" color="info">N</Avatar>;Props
| Prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| src | string | — | 그림. 로딩되기 전까지, 그리고 실패하면 계속 fallback이 그려집니다 |
| srcSet | string | — | 다른 해상도의 후보 이미지. img의 srcSet 그대로 |
| alt | string | name | 그림의 대체 텍스트. 이름 옆에 놓인 아바타는 장식이므로 name도 없으면 빈 문자열이 됩니다 |
| name | string | — | 누구 또는 무엇인지. 그림의 이름이 되고, initials가 여기서 파생되며, screen reader는 이 문장을 대신 읽습니다 |
| initials | string | — | 이니셜을 직접 씁니다. 첫 단어와 마지막 단어의 첫 글자라는 규칙이 맞지 않는 이름일 때 |
| shape | 'circle' | 'square' | 'circle' | 크롭 모양. square는 모서리를 상자의 약 28%만큼 잘라 냅니다 |
| variant공통 | 'solid' | 'outline' | 'text' | 'text' | fallback 뒤 표면의 무게. 그림이 로딩되면 가장자리만 남고 보이지 않습니다 |
| size공통 | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | 그림이 그려지는 상자. 컨트롤 높이 사다리라서 옆에 놓인 Button과 높이가 맞습니다 |
| color공통 | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'primary' | 의미론적 색 역할. 임의 색상값은 받지 않습니다 |
| elevation공통 | 0 | 1 | 2 | 3 | 0 | 그림자 깊이. 0은 그림자 없음 |
| delay | number | — | fallback을 그리기까지 기다리는 시간(ms). 캐시된 그림 앞에서 이니셜이 번쩍이는 것을 막습니다 |
| imageProps | Omit<ComponentPropsWithoutRef<'img'>, 'src' | 'srcSet' | 'alt'> | — | img에 필요한 나머지 속성, loading, crossOrigin, referrerPolicy |
| onLoadingStatusChange | (status: 'idle' | 'loading' | 'loaded' | 'error') => void | — | 그림의 로딩 상태가 바뀔 때 호출됩니다 |
| children | ReactNode | — | 이니셜 대신 그릴 fallback. 아이콘, 로고, 이모지 하나 |
| transition공통 | NebaTransition | — | mount 시 한 번 실행되는 등장 애니메이션 (transition="fade"). 트리거나 반복이 필요하면 Animate* 컴포넌트로 감싸세요 |
나머지 <span> 속성은 모두 루트로 전달됩니다. <img>는 src, srcSet, alt를 직접 받고, 그 밖에 필요한 속성은 imageProps에 넣습니다.
공통 축(variant size color elevation)의 의미는 Prop 규약에 있습니다. density는 없습니다. 아바타에는 바꿀 여백이 없기 때문입니다.
예시
variant와 color
solid는 채운 원, outline은 테두리와 옅은 panel, 기본값인 text는 가장자리 없이 배경만 얇게 깔린 형태입니다. color는 여섯 가지 역할 색 중 하나를 고릅니다. 그림이 로딩되면 셋 다 가장자리만 남기고 보이지 않습니다.
size
컨트롤 높이 사다리를 그대로 씁니다. 22, 26, 32, 40, 48px이며, 그래서 같은 줄의 Button과 높이가 맞습니다. 이니셜은 줄이 아니라 상자를 기준으로 잡혀서 지름의 약 40%가 됩니다.
shape
기본 크롭은 circle입니다. square는 대신 모서리를 상자의 약 28%만큼 잘라 냅니다. 사각형 가장자리까지 그려진 로고나 저장소 아이콘은 원형으로 자르면 그 가장자리를 잃기 때문에, 이런 것에는 square가 맞습니다.
name과 initials
name은 세 가지 일을 합니다. 그림의 alt가 되고, 이니셜이 여기서 파생되며, screen reader는 이니셜 대신 이 문장을 읽습니다.
규칙은 첫 단어의 첫 글자와 마지막 단어의 첫 글자입니다. Jane Doe는 JD, jane miriam van doe도 JD, 홍길동은 홍이 됩니다. 분해된 악센트는 먼저 결합하므로 Ängela는 A가 아니라 Ä입니다. 규칙이 엉뚱한 글자를 고른다면 initials에 직접 씁니다.
children
children은 이니셜 대신 그릴 fallback입니다. 아이콘, 로고, 이모지 하나가 여기에 들어갑니다. 안에 있는 <svg>는 상자의 55% 크기로 맞춰집니다. children도 initials도 name도 없으면 실루엣을 그립니다.
셋 중 무엇이 보이는지는 그림의 로딩 상태가 정합니다. delay를 주면 fallback을 잠시 미룰 수 있어서 캐시된 그림 앞에서 이니셜이 번쩍이지 않고, 상태 자체는 onLoadingStatusChange로 읽습니다.
상태 표시
Avatar에는 상태 점이 없습니다. overlap="circle"을 준 Badge로 감싸면 됩니다. 원의 모서리가 bounding box보다 안쪽에 있는 만큼 표식을 더 당겨 줍니다.
접근성
JD는 소리 내어 읽으면 사람이 아니라 글자 두 개입니다.name을 주면 이니셜은 accessibility tree에서 빠지고 그 이름이 fallback의 accessible name이 됩니다.name도alt도 없으면<img>의alt는 빈 문자열이 되어 파일 이름이 읽히는 대신 건너뛰어집니다. 사람 이름 옆에 놓인 아바타에는 이쪽이 맞습니다. 그림이 그 사람을 가리키는 유일한 단서일 때만alt를 넘기세요.name없이children글리프만 있으면 accessible name이 생기지 않습니다. 글리프만으로 뜻이 전달되어야 한다면name을 주거나 감싼 요소에aria-label을 붙이세요.