Switch
의 역할은 두 상태 간의 값을 전환할 수 있는 편리한 인터페이스로, 기본 체크박스 요소와 동일한 의미와 키보드 탐색 기능을 제공한다.
사용자가 checked와 not checked 사이를 전환할 수 있는 컨트롤이다.
button과 span으로 구성되어있는것은 사이트에서 제공한 예제이기 때문에 넘어간다.
switch
를 제작할때는 아래의 사항을 생각해야한다.
일단 checkbox
와는 기능적으로는 같다. 다만 checkbox는 선택됨과 선택 취소됨의 의미지만, switch는 켜짐과 꺼짐이라는 의미적인 상태 표현이 다르다. 이를 제외하고는 checkbox와 같다.
checkbox와 마찬가지로 aria-checked
라는 attribute를 선언하는것을 필수라고 정의하고 있다.
switch는 대화형 컨트롤이므로 초점을 맞출수 있고, 키보드로 엑세스를 할 수 있어야 한다.
개발자는 스위치가 토글될때 aria-checked
를 동적으로 변화 시켜줘야한다.
그래서
tabindex = 0
를 통해 포커스를 잡을 수 있도록 하였다.
type SwitchPropsWeControl =
| 'aria-checked'
| 'aria-describedby'
| 'aria-labelledby'
| 'role'
| 'tabIndex'
headlessui/switch.tsx at main · tailwindlabs/headlessui
we
와 their
이라는 지칭이 나오고 있는데, ourProps
가 컴포넌트 내부에서 정의되고 만들어지며, theirProps
는 외부에서 받아오는 props를 지칭하는것으로 보아, 이 라이브러리 내부에서 지칭하는 we
는 컴포넌트를 만드는 제작자, their
은 컴포넌트를 사용하는 사용자를 뜻하는것으로 보인다.
그러므로 SwitchPropsWeContorol
은 컴포넌트 내부에서 저 Prop들을 제작자가 알아서 컨트롤하게 만들어 놓은것이라고 추측할 수 있다.
let handleKeyUp = useEvent((event: ReactKeyboardEvent<HTMLButtonElement>) => {
if (event.key === Keys.Space) {
event.preventDefault()
toggle()
} else if (event.key === Keys.Enter) {
attemptSubmit(event.currentTarget)
}
})
Switch 컴포넌트를 Space bar로 누르는것과 Enter를 누르는것의 반응이 달랐다.
나는 Space Bar
와 Enter
의 역할이 어떻게 나누어지는지 호기심이 생겼다.
위 링크의 내용으로 본다면
Form
에서 사용했을때,
Space bar
는 선택이다. 마우스 클릭과도 비슷한 역할을 하는 것이고,
Enter
는 전송이다. 암묵적으로 Enter를 누르면 form tag의 첫번째 submit 버튼을 찾아서 submit을 실행한다.
이를 Implicit Submission
이라고 한다.
그래서 위의 컴포넌트는 이 Implicit Submission
을 위해서 Space bar
와 Enter
의 역할을 나누어서 처리를 한것으로 보여진다.
폼에는 일반적으로 제출(submit) 버튼이 있어 사용자가 버튼을 클릭하여 데이터를 서버로 제출한다.
그러나 몇 가지 경우에는 사용자가 버튼을 클릭하지 않고도 폼이 자동으로 제출되어야 할 수 있다.
이때 Implicit submission
이 사용된다.
Implicit submission은 특히 검색 폼 또는 로그인 폼 등과 같이 사용자가 빠르게 제출하고자 할 때 유용하다.
사용자가 필요한 정보를 입력한 후 Enter 키를 누르면 검색 결과를 표시하거나 로그인을 처리할 수 있다.
Implicit submission은 HTML 폼 요소와 관련이 있으며, 폼 요소에서 사용되는 일부 특정 요소에 대해서만 적용될 수 있다.
예를 들어, <input>
, <textarea>
, <select>
와 같은 일부 요소는 기본적으로 Implicit submission을 지원한다. 그러나 <button>
요소는 기본적으로 Implicit submission을 지원하지 않는다.
Implicit submission은 자바스크립트를 사용하여 커스터마이즈할 수도 있다.
이를 통해 사용자의 입력을 처리하고 폼을 동적으로 제출하는 방식을 구현할 수 있다.
그러나 이러한 자바스크립트 기반의 Implicit submission은 명시적인 사용자 동의 없이 폼을 제출하는 것에 대한 보안 및 사용자 경험적인 문제에 유의해야 한다.
primitives/Switch.tsx at main · radix-ui/primitives
Github 코드와 HTML 기준으로 Headless ui 에서 달라진 점을 중점으로 보면 좋을것 같다.
aria-hidden
과 tabindex= -1
로 해놓은것으로 봐서 유저에게서는 숨기고 내부 동작만 이용하도록 할려고 한것 같다.
button의 onClick 메소드에서는 stopPropagation
이 사용되어있는 것으로 보아 클릭 이벤트 확산을 막는 장치를 마련해두었다.
form에서만 input이 렌더링되게 사용된것으로 보아 form이 submit을 할 때 switch값과 동기화 해둔 input의 값을 가져가도록 의도한것으로 보인다.
대신 상태의 변경을 button
으로만 의존하고, headless ui 처럼 Implicit Submission에 대해 추가적인 처리가 되어있지 않았다.
그래서 space bar
를 누르든 enter
를 누르든 상태가 변하는 같은 동작이 이루어져 있었다.
알아본 결과 Implicit Submission의 처리가 필수는 아니였다. 제작자의 의도에 맞게 설정하면 된다.
사용자 의도의 명확성
Implicit submission은 사용자가 폼을 제출하는 의도를 명확하게 표현하지 않을 수 있다.
사용자가 Enter 키를 누를 때마다 폼이 자동으로 제출되면, 실수로 잘못된 데이터를 제출할 수도 있다.
명시적인 제출 버튼을 클릭하는 것은 사용자가 폼을 제출하기 위한 명확한 의도를 나타내는 방법이다.
사용자 경험
Implicit submission은 사용자에게 예상치 못한 동작을 유발할 수 있다.
사용자가 Enter 키를 누를 때마다 폼이 제출되면, 사용자가 입력을 완료하기 전에 실수로 폼을 제출할 수 있다.
또한, 사용자가 다른 목적으로 Enter 키를 사용하는 경우에도 예기치 않은 결과를 초래할 수 있다.
접근성
일부 사용자는 키보드 이용에 제한이 있는 경우가 있다. Implicit submission이 활성화되면, 이러한 사용자들이 폼을 작성하는 동안 Enter 키를 사용하기 어려울 수 있다. 명시적인 제출 버튼을 제공하면 이러한 사용자들도 폼을 제출할 수 있는 방법이 확실하게 제공된다.
보안
명시적인 제출 버튼을 클릭하지 않고 폼이 자동으로 제출되는 경우, 악의적인 사용자가 폼을 악용할 수 있는 가능성이 있다. 예를 들어, 폼 스팸이나 악성 스크립트를 사용하여 불필요한 데이터 제출 또는 공격을 시도할 수 있다. 명시적인 제출 버튼은 사용자가 폼 제출을 확인하고 필요한 경우에만 실행할 수 있도록 보안성을 강화하는 역할을 한다.
tabindex가 radix ui에는 정의가 안되있었다.
headless ui 같은 경우에는 Fragment나 태그와 스타일을 사용자가 직접 작성하기 때문에 tab에 의한 포커싱을 놓칠 가능성이 있다. 그래서 tabIndex를 의도적으로 정의를 해둔것 같다.
단 radix ui 같은 경우에는 기본적인 스타일로 적용되어있는 라이브러리기 때문에 button이라는 태그가 사용되는것이 강제되어있다고 말할수 있다. button 태그의 경우에는 기본적으로 tabindex=0이 디폴트값으로 되어있기 때문에 추가적인 정의가 필요없다라고 할 수 있다.
aria-hidden 같은 경우에는 접근성 트리에서 해당 요소와 해당요소의 모든 하위요소가 제거되고, 보조 기술 사용자의 경험을 향상 시킬수 있다.
StaticText는 다른 span 태그이다.
headless ui 의 접근성 트리에는 span 에 aria-hidden을 적어 놓은 덕분에 span에 해당하는 접근성 트리가 없다.
경우에는 span에 아무런 처리도 없기때문에 의미없는 접근성 트리의 가지가 하나 생겼다.
role="switch"
는 스위치 형태의 UI 요소를 정의하고 스크린 리더기 등 보조 기술이 해당 요소를 올바르게 인식할 수 있도록 도와준다.
role="switch"
를 사용하면 스크린 리더기, 보조 기술 또는 키보드 사용자와 같은 사용자들이 해당 스위치를 쉽게 찾아 사용할 수 있다. 이는 시각 장애인이나 기타 장애가 있는 사용자들이 웹 사이트를 동등하게 이용할 수 있도록 도와준다.role="switch"
를 사용하면 해당 요소가 스위치라는 역할을 수행한다는 것을 명확하게 나타낼 수 있다. 이는 스크린 리더기 사용자에게 요소의 의미와 상태를 이해하기 쉽게 만들어준다.role="switch"
를 사용하면 해당 상태를 표시할 수 있다. 이는 시각적인 표시만으로 상태를 파악하기 어려운 사용자들에게 도움을 준다.role="switch"
를 사용하면 키보드만을 사용하는 사용자들도 스위치를 쉽게 조작할 수 있다. 적절한 키보드 포커스 관리와 키보드 이벤트 처리를 통해 사용자가 스위치를 선택하고 상태를 변경할 수 있다.aria-checked
속성은 스위치, 체크박스, 라디오 버튼 등의 선택 가능한 요소의 선택 상태를 나타내는 데 사용된다.
aria-checked
속성은 선택 가능한 요소의 현재 선택 상태를 명확하게 나타내므로 시각 장애인, 인지 장애를 가진 사용자 또는 보조 기술 사용자가 해당 요소의 상태를 이해하고 조작할 수 있다.aria-checked
속성은 선택 가능한 요소의 상태를 표시한다. 이는 시각적으로 선택 상태를 파악하기 어려운 사용자들에게 도움준다. 예를 들어, 스위치가 "켜짐" 또는 "꺼짐" 상태를 나타내는 경우, aria-checked="true"
또는 aria-checked="false"
값을 사용하여 스위치의 상태를 알려줄 수 있다.aria-checked
속성을 사용하여 선택 가능한 요소의 상태를 사용자에게 알려준다. 이를 통해 스크린 리더기 사용자는 해당 요소의 선택 상태에 대한 정보를 들을 수 있다.aria-checked
속성은 키보드만을 사용하는 사용자들이 선택 가능한 요소를 조작할 때 유용하다. 키보드 포커스와 키보드 이벤트 처리를 통해 사용자가 요소의 선택 상태를 변경할 수 있다.tabindex
속성은 HTML 요소의 키보드 포커스 가능성 및 탐색 순서를 지정하는 데 사용된다.
tabindex
속성은 키보드 사용자들이 웹 페이지를 효율적으로 탐색하고 상호작용할 수 있도록 도와준다. 일반적으로 웹 페이지를 탐색할 때 "Tab" 키를 사용하여 요소 간에 이동할 수 있다. tabindex
속성을 설정하면 포커스 가능한 요소의 탐색 순서를 지정할 수 있다.tabindex
속성을 사용하면 키보드 포커스가 일반적으로 포커스를 받지 않는 요소들에게도 포커스를 부여할 수 있다. 이는 접근성 기능을 확장하고 보조 기술 사용자가 숨겨진 요소나 대화형이 아닌 요소들과 상호작용할 수 있도록 도와준다.tabindex
속성을 사용하여 요소의 탐색 순서를 조정하면 사용자가 웹 페이지를 이해하고 사용하는 데 도움이 될 수 있다. 일부 요소를 우선 순위로 설정하거나 관련 요소들을 그룹화하여 사용자 경험을 개선할 수 있다.tabindex
속성을 사용하여 특정 요소에 초기 포커스를 설정할 수 있다. 이는 웹 페이지에 접근했을 때 특정 요소에 자동으로 포커스를 설정하고 키보드를 통해 해당 요소를 제어할 수 있는 기능을 제공한다.tabindex
속성은 웹 페이지에서 양식 요소나 게시판의 탐색을 용이하게 만들 수 있다. 사용자가 키보드로 양식 필드를 순차적으로 탐색하고 제출 버튼 등에 쉽게 도달할 수 있다.aria-hidden
속성은 요소가 스크린 리더기 등의 보조 기술에 의해 인식되지 않아야 함을 나타낸다.
aria-hidden
속성을 사용하여 특정 요소를 스크린 리더기 사용자에게 숨길 수 있다. 이는 시각적으로만 표시되는 요소나 보조적인 정보를 제공하는 요소 등을 보조 기술 사용자에게 표시하지 않을 수 있도록 한다.aria-hidden
속성을 사용하여 보조 기술에 표시되지 않아야 하는 요소를 제외함으로써 사용자에게 필요한 정보만 제공할 수 있다. 이는 정보 과부하를 방지하고 사용자가 웹 페이지의 핵심적인 내용에 집중할 수 있도록 도와준다.aria-hidden
속성을 사용하여 상태가 변경되지 않은 요소를 숨김으로써 스크린 리더기 사용자에게 상태 변경에 대한 중복된 통지를 방지할 수 있다. 예를 들어, 동적으로 업데이트되는 영역의 중복된 텍스트 읽기를 피할 수 있다.aria-hidden
속성을 사용하여 시각적으로 보이는 요소에 대해 스크린 리더기에서는 읽히지 않도록 할 수 있다. 이는 시각적으로 보이는 스타일 요소에 대한 보조 기술 읽기를 방지하여 사용자 경험을 개선할 수 있다.headlessui/switch.tsx at main · tailwindlabs/headlessui
primitives/Switch.tsx at main · radix-ui/primitives
WAI-ARIA 바르게 사용하기 6부: menu role 바르게 사용하기