본문으로 건너뛰기

인증 화면

로그인 · 가입 · 재설정 · 2단계 인증 · 초대 수락. 셸 없이 바닥 면 가운데에 카드 하나만 둡니다.

카드 하나에 할 일은 하나이고, 다음 단계는 같은 자리의 다음 카드로 바뀝니다. 오류는 계정이 있는지 드러내지 않는 한 문장으로 폼 위에 하나만 둡니다. AuthLayout 은 틀(로고 · 카드 · 카드 밖 줄)만 그리고 폼은 앱이 넣습니다. 칸 사이 줄(uyoo-auth-form) · 구분 글자(uyoo-auth-divider) · 라벨 줄 끝 링크(uyoo-auth-label-row)는 클래스로 씁니다.

import
import { AuthLayout, PasswordRules } from "@uyoolabs/ui/ui"; import { OtpField } from "@uyoolabs/ui/form";
쓰는 경우
셸 밖의 인증 화면(로그인 · 가입 · 비밀번호 재설정 · 2단계 인증 · 초대 수락 · OAuth 동의)에 씁니다. 비밀번호를 새로 정하는 칸에는 PasswordRules, 한 번 쓰는 코드에는 OtpField 를 둡니다.
쓰지 않는 경우
칸마다 빨간 경계로 '이메일이 없습니다'를 말하지 않습니다(계정 열거). 배경 일러스트 · 그라데이션 · 반투명 패널을 두지 않습니다. placeholder 로 라벨을 대신하지 않습니다. 코드 칸 여섯을 각각 input 으로 만들지 않습니다. 잠김을 빨강 오류로 말하지 않습니다. 셸 안 화면에서 h1 을 쓰지 않습니다(그곳은 브레드크럼이 이름입니다).
포커스
첫 포커스는 첫 빈 칸입니다. 다음 단계 카드로 바뀌면 앱이 그 카드 제목(tabIndex=-1)으로 옮깁니다. 오류 뒤에는 비밀번호 칸으로 옮깁니다.

AuthLayout

로고 · 카드(제목 h1 · 설명 · 본문 · 바닥 줄) · 카드 밖 줄.

uyoolabs

로그인

업무 계정으로 계속합니다.

이메일 또는 비밀번호가 맞지 않습니다.

또는 이메일로

계정이 없습니까? 가입

PasswordRules

칠 때마다 빈 원 → 체크. 제출 뒤 못 맞춘 규칙만 느낌표 + 오류 색입니다.

  • 10자 이상 — 충족
  • 글자와 숫자를 함께 — 충족
  • 이메일 · 이름이 들어가지 않게 — 아직
  • 10자 이상 — 충족
  • 글자와 숫자를 함께 — 충족
  • 이메일 · 이름이 들어가지 않게 — 맞지 않음

OtpField

숨은 input 하나 + 그리기만 하는 칸. 화면 낭독기는 칸 하나로 읽습니다(./form, radix 없음).

6자리
6자리

코드가 맞지 않습니다. 4번 더 시도할 수 있습니다.

6자리
6자리

단계가 바뀔 때

포커스는 새 카드의 제목으로.

제목은 탭 순서에 없지만 프로그램으로 포커스를 받습니다(링은 그리지 않습니다).

조립 규칙

P-Auth 보드의 규칙입니다.

무엇규칙
자리셸 · 사이드바 · 상단 바 없음. main 하나 안에 로고(28) → 카드(폭 ≤ 400 · 안쪽 32 · 지붕 모서리) → 카드 밖 언어 · 도움말 줄. 480 미만은 카드가 화면을 채웁니다(두께 · 지붕 없음, 누르는 칸 lg 44).
제목 · 순서카드 제목이 화면 이름이고 h1 입니다(셸 밖 화면의 예외, 결정 #23). 공급자(SSO) → '또는 이메일로' → 칸 → 유지 체크 → 제출 → 카드 바닥 링크. 칸 이름은 늘 보이는 label 입니다.
오류 · 보안로그인 실패 · 재설정 요청 · 로그인 링크는 계정이 있는지 드러내지 않는 같은 문장입니다. 오류는 폼 위 Alert(bad) 하나, 비밀번호 칸을 비우고 포커스. 잠김은 warn(사람이 풀 수 있다, 결정 #25) + 풀리는 시각.
비밀번호autocomplete current-password · new-password. 붙여넣기 허용. 보기 토글은 aria-pressed + 눈 · 빗금 눈. 규칙은 aria-describedby 로 잇고 제출 뒤 못 맞춘 규칙만 오류입니다.
코드 칸OtpField 하나(inputmode=numeric · autocomplete=one-time-code). 셋씩 묶는 틈. 6자리를 붙여넣으면 채우고 바로 확인, 틀리면 여섯 칸 모두 오류 경계 + 값 전체 선택. 복구 코드는 mono 입력 하나(spellcheck · 자동 완성 끔).
보내는 중제출 버튼 loading(aria-busy · 폭 그대로). 두 번 보내지 않습니다. Enter 는 form 의 submit 하나로만 보냅니다(이름 칸의 한 · 일 조합 확정 Enter 는 브라우저가 submit 하지 않습니다).

키보드

키동작
TabSSO → 칸 → 라벨 줄 끝 링크 → 칸 → 유지 체크 → 제출 → 바닥 링크 순서입니다.
Enterform 의 submit 하나로만 보냅니다. 한 · 일 조합을 확정하는 Enter 는 보내지 않습니다(isComposing).
0–9코드 칸: 다음 칸으로 채웁니다. 6자리를 다 채우면 onComplete 로 바로 확인합니다.
Backspace코드 칸: 앞 칸을 지웁니다.
←→코드 칸: 고칠 자리로 옮깁니다(브라우저 기본 편집).
⌘V코드 칸: 붙여넣은 글에서 숫자만 받아 채우고 바로 확인합니다.
Space비밀번호 보기 토글(aria-pressed)을 켜고 끕니다.

props

소스의 타입과 JSDoc 에서 생성한 표입니다. 컴포넌트를 고치면 pnpm gen 으로 다시 만듭니다.

AuthLayout

prop타입기본값설명
title필수ReactNode—카드 제목 = 화면 이름(로그인 · 가입 · 2단계 인증). 셸 밖 화면이라 h1 이다(W2-5 결정 #23)
descriptionReactNode—제목 아래 한 줄(13 보조색)
titleAs"h1" | "h2""h1"제목 요소. 기본 h1. 문서 · 견본처럼 한 화면에 카드를 여럿 둘 때만 h2
titleIdstring—제목 요소의 id. 다음 단계 카드로 바뀐 뒤 앱이 이 제목으로 포커스를 옮긴다(tabIndex=-1)
logoReactNode—카드 위 로고 자리(28). 보통 ./brand 의 BrandLogo
mediaReactNode—제목 위 그림 한 칸(초대 수락의 워크스페이스 아바타 · 메일 보냄 아이콘)
align"start" | "center""start"머리를 가운데로 모은다(초대 수락처럼 media 가 주인공인 카드)
childrenReactNode—카드 본문. 보통 <form className="uyoo-auth-form">
footerReactNode—카드 바닥 줄(계정이 없습니까? 가입)
legalReactNode—카드 밖 줄(언어 · 도움말 · 개인정보 처리방침). 바닥 면 위라 링크는 TextLink
layout"center" | "fill""center"fill: 카드가 화면을 채운다(두께 · 지붕 없음). 480 미만에서는 저절로 이렇게 된다. 앱 안 웹뷰 · 미리보기에서 넓은 화면에도 채우고 싶을 때 준다
landmarkbooleantruefalse 면 바깥을 main 대신 div 로 그린다(문서 · 견본 안에 여러 장 둘 때). 기본 true
lang"ko" | "en" | "ja"—
labelsPartial<AuthLayoutLabels>—
classNamestring—

PasswordRules

prop타입기본값설명
rules필수readonly PasswordRule[]—
submittedbooleanfalse제출한 뒤. 못 맞춘 규칙만 오류로 보인다. 치는 동안에는 빨강을 쓰지 않는다(아직 오류가 아니다)
idstring—비밀번호 칸의 aria-describedby 가 가리킬 id
lang"ko" | "en" | "ja"—
labelsPartial<PasswordRulesLabels>—
classNamestring—

OtpField

prop타입기본값설명
lengthnumber6자릿수. 기본 6
valuestring—제어 값(숫자만, length 까지)
defaultValuestring—비제어 첫 값
onValueChange(value: string) => void—
onComplete(value: string) => void—length 를 다 채우면(붙여넣기 · 자동 채움 포함) 한 번 부른다. 앱이 바로 확인한다
invalidboolean—틀린 코드. 칸 모두 오류 경계 + 값 전체 선택(다시 치면 바뀐다). Field 의 aria-invalid 도 같은 뜻이다
busybooleanfalse확인하는 동안. 칸이 읽기 전용 면이 되고 aria-busy 다
groupSizenumber3이 자리마다 틈을 둔다(셋씩 묶어 읽기 쉽게). 0 이면 틈 없음. 기본 3
mode"numeric" | "alphanumeric""numeric"numeric(기본) · alphanumeric(영문 섞인 코드). 복구 코드는 이 칸이 아니라 mono 입력 하나로 받는다
lang"ko" | "en" | "ja"—
labelsPartial<OtpFieldLabels>—

이 밖에 <input> props(children · value · onChange · defaultValue · size · type · maxLength 제외)를 그대로 받습니다.