switch 구성요소 빌드

반응형 및 액세스 가능한 스위치 구성요소를 빌드하는 방법에 관한 기본 개요

이 게시물에서는 스위치 구성 요소를 빌드하는 방법에 대한 생각을 공유하고자 합니다. 데모 사용해 보기

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph> 데모

동영상을 선호한다면 이 게시물의 YouTube 버전을 참고하세요.

개요

스위치는 체크박스와 유사하게 작동합니다. 불리언 켜기/끄기 상태를 명시적으로 나타냅니다.

이 데모는 대부분의 작업에 <input type="checkbox" role="switch">를 사용합니다. CSS 또는 JavaScript가 필요하지 않다는 장점이 있습니다. 액세스할 수 있습니다 CSS 로드로 오른쪽에서 왼쪽 지원 언어, 카테고리, 애니메이션 등이 있습니다. JavaScript를 로드하면 전환 만들 수 있습니다.

맞춤 속성

다음 변수는 스위치의 다양한 부분과 스위치의 다양한 부분을 나타냅니다. 있습니다. 최상위 클래스인 .gui-switch에는 사용되는 맞춤 속성이 포함되어 있습니다. 구성요소 하위 요소 전체에 걸쳐, 그리고 중앙 집중화된 맞춤설정할 수 있습니다.

추적

길이 (--track-size), 패딩 및 두 가지 색상:

.gui-switch {
  --track-size: calc(var(--thumb-size) * 2);
  --track-padding: 2px;

  --track-inactive: hsl(80 0% 80%);
  --track-active: hsl(80 60% 45%);

  --track-color-inactive: var(--track-inactive);
  --track-color-active: var(--track-active);

  @media (prefers-color-scheme: dark) {
    --track-inactive: hsl(80 0% 35%);
    --track-active: hsl(80 60% 60%);
  }
}

미리보기

크기, 배경 색상 및 상호작용 강조 색상은 다음과 같습니다.

.gui-switch {
  --thumb-size: 2rem;
  --thumb: hsl(0 0% 100%);
  --thumb-highlight: hsl(0 0% 0% / 25%);

  --thumb-color: var(--thumb);
  --thumb-color-highlight: var(--thumb-highlight);

  @media (prefers-color-scheme: dark) {
    --thumb: hsl(0 0% 5%);
    --thumb-highlight: hsl(0 0% 100% / 25%);
  }
}

움직임 감소

명확한 별칭을 추가하고 반복을 줄이기 위해 낮은 모션을 선호하는 사용자 맞춤 속성에 넣을 수 있는 PostCSS. 이 초안을 기반으로 하는 플러그인 미디어 쿼리의 사양 5:

@custom-media --motionOK (prefers-reduced-motion: no-preference);

마크업

<input type="checkbox" role="switch"> 요소를 <label>, 체크박스와 라벨 연결을 피하기 위해 관계를 번들로 묶음 사용자가 레이블과 상호작용하여 원하는 지점의 결과를 확인할 수 있도록 입력을 전환합니다.

가
라벨이 지정되지 않은 자연스러운 라벨 및 체크박스를 선택합니다.

<label for="switch" class="gui-switch">
  Label text
  <input type="checkbox" role="switch" id="switch">
</label>

<input type="checkbox">APIstate입니다. 이 브라우저는 checked 드림 속성 및 입력 이벤트 예를 들면 oninput, onchanged 등이 있습니다.

레이아웃

Flexbox gridcustom 속성이 할 수 있습니다. 가치를 중앙 집중화하고 모호한 계산이나 영역으로 변환하거나 작은 맞춤 속성도 사용 설정할 수 있습니다 간편한 구성요소 맞춤설정을 위한 API.

.gui-switch

스위치의 최상위 레이아웃은 Flexbox입니다. .gui-switch 클래스에는 다음이 포함됩니다. 자식이 계산을 위해 사용하는 비공개 및 공개 커스텀 속성 있습니다.

가로 라벨 및 스위치를 오버레이하여 레이아웃을 표시하는 Flexbox DevTools
배포됩니다.

.gui-switch {
  display: flex;
  align-items: center;
  gap: 2ch;
  justify-content: space-between;
}

Flexbox 레이아웃을 확장하고 수정하는 것은 Flexbox 레이아웃을 변경하는 것과 같습니다. 예를 들어 스위치 위 또는 아래에 라벨을 넣거나 flex-direction:

세로 라벨 및 스위치를 오버레이하는 Flexbox DevTools

<label for="light-switch" class="gui-switch" style="flex-direction: column">
  Default
  <input type="checkbox" role="switch" id="light-switch">
</label>

추적

체크박스 입력은 일반 appearance: checkbox하고 자체 크기를 대신 제공합니다.

스위치 트랙을 오버레이하고 이름이 지정된 그리드 트랙을 표시하는 그리드 DevTools
&#39;track&#39;이라는 이름이 있는 영역.

.gui-switch > input {
  appearance: none;

  inline-size: var(--track-size);
  block-size: var(--thumb-size);
  padding: var(--track-padding);

  flex-shrink: 0;
  display: grid;
  align-items: center;
  grid: [track] 1fr / [track] 1fr;
}

이 트랙은 또한 하나의 엄지손가락을 작동할 수 있도록 하나씩 단일 셀 그리드 트랙 영역을 소유권 주장

미리보기

또한 appearance: none 스타일은 있습니다. 이 구성요소는 pseudo-element:checked 의사 클래스를 이 시각적 표시기를 교체할 수 있습니다.

thumb은 input[type="checkbox"]에 연결된 의사 요소 하위 요소입니다. 그리드 영역을 확보하여 트랙 아래가 아닌 위에 스택 track:

CSS 그리드 내에 배치된 pseudo-element thumb을 보여주는 DevTools

.gui-switch > input::before {
  content: "";
  grid-area: track;
  inline-size: var(--thumb-size);
  block-size: var(--thumb-size);
}
드림

스타일

맞춤 속성을 사용하면 색상에 맞게 조정되는 다목적 스위치 구성요소를 사용할 수 있습니다. 오른쪽에서 왼쪽으로 읽는 언어, 모션 환경설정을 지원합니다

스위치의 밝은 테마와 어두운 테마를 나란히 비교한
있습니다.

터치 상호작용 스타일

모바일에서는 브라우저가 탭 강조표시 및 텍스트 선택 기능을 라벨과 사용됩니다. 이는 광고 스타일 및 시각적 상호작용 피드백에 이 스위치는 필요하지 않습니다 CSS 몇 줄로 이러한 효과를 제거하고 나만의 cursor: pointer 스타일:

.gui-switch {
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

이러한 스타일은 시각적 효과가 중요할 수 있으므로 이러한 스타일을 삭제하지 않는 것이 좋습니다. 상호작용 피드백에 대해 자세히 알아보세요. 맞춤 대안을 삭제하는 경우 반드시 다른 대안을 제공하세요.

추적

이 요소의 스타일은 주로 요소의 모양과 색상에 관한 것으로, 액세스됩니다. 상위 .gui-switch에서 다음을 통해 캐스케이드

맞춤 트랙 크기 및 색상이 포함된 스위치 변형

.gui-switch > input {
  appearance: none;
  border: none;
  outline-offset: 5px;
  box-sizing: content-box;

  padding: var(--track-padding);
  background: var(--track-color-inactive);
  inline-size: var(--track-size);
  block-size: var(--thumb-size);
  border-radius: var(--track-size);
}

스위치 트랙에 대한 다양한 맞춤설정 옵션은 4가지 맞춤 속성입니다. appearance: none가 추가되지 않으므로 border: none가 추가됩니다. 모든 브라우저에서 체크박스의 테두리를 삭제합니다.

미리보기

thumb 요소는 이미 오른쪽 track에 있지만 원 스타일이 필요합니다.

.gui-switch > input::before {
  background: var(--thumb-color);
  border-radius: 50%;
}

DevTools에 원 thumb 의사 요소가 강조 표시되어 있음

상호작용

맞춤 속성을 사용하여 마우스 오버가 표시되는 상호작용을 준비합니다. 강조 표시 및 엄지손가락 위치 변경입니다. 또한 사용자의 환경설정은 체크박스 선택을 강조표시 스타일을 설정할 수 있습니다.

.gui-switch > input::before {
  box-shadow: 0 0 0 var(--highlight-size) var(--thumb-color-highlight);

  @media (--motionOK) { & {
    transition:
      transform var(--thumb-transition-duration) ease,
      box-shadow .25s ease;
  }}
}

엄지손가락 위치

맞춤 속성은 썸네일을 배치하기 위한 단일 소스 메커니즘을 제공합니다. 확인할 수 있습니다. 우리가 사용할 수 있는 것은 트랙과 엄지 손가락의 크기입니다. 계산을 사용하여 thumb을 적절히 오프셋하고 트랙 내에서 그 사이를 유지합니다. 0%100%.

input 요소는 위치 변수 --thumb-position를 소유하고 thumb을 소유함 pseudo 요소는 이를 translateX 위치로 사용합니다.

.gui-switch > input {
  --thumb-position: 0%;
}

.gui-switch > input::before {
  transform: translateX(var(--thumb-position));
}

이제 CSS 및 의사 클래스에서 자유롭게 --thumb-position를 변경할 수 있습니다. 체크박스 요소에 제공됩니다. 앞서 이 요소에서 transition: transform var(--thumb-transition-duration) ease를 조건부로 설정했으므로 이러한 변경사항은 변경될 때 애니메이션이 표시될 수 있습니다.

/* positioned at the end of the track: track length - 100% (thumb width) */
.gui-switch > input:checked {
  --thumb-position: calc(var(--track-size) - 100%);
}

/* positioned in the center of the track: half the track - half the thumb */
.gui-switch > input:indeterminate {
  --thumb-position: calc(
    (var(--track-size) / 2) - (var(--thumb-size) / 2)
  );
}

저는 이 분리된 오케스트레이션이 효과적이라고 생각했습니다. thumb 요소는 하나의 스타일, 즉 translateX 위치에만 관련됩니다. 입력으로 복잡도와 계산에 집중할 수 있습니다.

업종

지원은 다음과 같이 회전을 추가하는 수정자 클래스 -vertical로 실행되었습니다. input 요소로 CSS 변환

3D로 회전된 요소는 구성요소의 전체 높이를 변경하지 않습니다. 이로 인해 블록 레이아웃이 발생할 수 있습니다. --track-size--track-padding 변수 에 필요한 최소 공간의 양 계산 예상대로 레이아웃에 흘러가는 세로 버튼

.gui-switch.-vertical {
  min-block-size: calc(var(--track-size) + calc(var(--track-padding) * 2));

  & > input {
    transform: rotate(-90deg);
  }
}

(RTL) 오른쪽에서 왼쪽으로

저는 CSS 친구인 Elad Schecter와 함께 프로토타입을 제작했습니다. 오른쪽에서 왼쪽으로 처리하는 CSS 변환을 사용하여 슬라이드 아웃 사이드 메뉴 표시 한 문장을 뒤집어서 변수의 값을 지정합니다. CSS에는 논리 속성 변환이 없으므로 절대 없을 수도 있습니다. Elad는 맞춤 속성 값을 사용해 백분율을 반전시켜 나만의 맞춤 위치를 한 곳에서 관리할 수 있습니다. 논리 변환에 사용됩니다. 이 스위치에서 같은 기법을 사용했고 효과가 좋았다고 생각함:

.gui-switch {
  --isLTR: 1;

  &:dir(rtl) {
    --isLTR: -1;
  }
}

--isLTR라는 맞춤 속성은 처음에 1의 값을 보유합니다. 즉, true입니다. 그런 다음 CSS를 사용하여 의사 클래스 :dir() 구성요소가 오른쪽에서 왼쪽 레이아웃 내에 있을 때 값은 -1로 설정됩니다.

변환 내 calc() 내에서 --isLTR를 사용하여 실행합니다.

.gui-switch.-vertical > input {
  transform: rotate(-90deg);
  transform: rotate(calc(90deg * var(--isLTR) * -1));
}

이제 수직 스위치의 회전이 반대쪽 위치를 감안합니다. 추가해야 합니다.

thumb 의사 요소의 translateX 변환도 다음과 같이 업데이트해야 합니다. 반대쪽 요구사항을 고려합니다.

.gui-switch > input:checked {
  --thumb-position: calc(var(--track-size) - 100%);
  --thumb-position: calc((var(--track-size) - 100%) * var(--isLTR));
}

.gui-switch > input:indeterminate {
  --thumb-position: calc(
    (var(--track-size) / 2) - (var(--thumb-size) / 2)
  );
  --thumb-position: calc(
   ((var(--track-size) / 2) - (var(--thumb-size) / 2))
    * var(--isLTR)
  );
}

이 접근 방식이 논리적 CSS와 같은 개념과 관련된 모든 요구사항을 해결할 수는 없지만 몇 가지를 제공하는데 DRY 원칙을 사용하여 사용할 수 있습니다

내장된 input[type="checkbox"]를 사용하지 않으면 완전할 수 없습니다. :checked, :disabled 등 다양한 상태를 처리합니다. :indeterminate:hover :focus은(는) 해당 오프셋에 대해서만 조정됩니다. 초점 링은 Firefox에서 훌륭하게 보였고 Safari

Firefox 및 Safari에서 스위치에 포커스가 있는 포커스 링의 스크린샷

선택됨

<label for="switch-checked" class="gui-switch">
  Default
  <input type="checkbox" role="switch" id="switch-checked" checked="true">
</label>

이 상태는 on 상태를 나타냅니다. 이 상태에서 입력 'track'은 배경은 활성 색상으로 설정되고 엄지손가락 위치는 ' end'라는 텍스트입니다.

.gui-switch > input:checked {
  background: var(--track-color-active);
  --thumb-position: calc((var(--track-size) - 100%) * var(--isLTR));
}

사용 중지됨

<label for="switch-disabled" class="gui-switch">
  Default
  <input type="checkbox" role="switch" id="switch-disabled" disabled="true">
</label>

:disabled 버튼은 시각적으로 다르게 보일 뿐만 아니라 상호작용 불변성은 브라우저에서 자유롭지만 appearance: none를 사용하기 때문에 시각적 상태에 스타일이 필요합니다.

.gui-switch > input:disabled {
  cursor: not-allowed;
  --thumb-color: transparent;

  &::before {
    cursor: not-allowed;
    box-shadow: inset 0 0 0 2px hsl(0 0% 100% / 50%);

    @media (prefers-color-scheme: dark) { & {
      box-shadow: inset 0 0 0 2px hsl(0 0% 0% / 50%);
    }}
  }
}

사용 중지됨, 선택됨, 선택 해제된 어두운 스타일의 스위치
있습니다.

이 상태는 사용 중지된 상태와 밝은 테마가 모두 적용된 어두운 테마와 밝은 테마가 필요하므로 까다롭습니다. 선택할 수 있습니다. 저는 이러한 주를 위해 스타일리시하게 미니멀한 스타일을 선택했습니다. 유지보수 부담을 줄일 수 있습니다

불확실

자주 잊혀지는 상태는 :indeterminate이며 체크박스가 아닌 경우 선택 또는 선택 해제되어 있습니다. 이곳은 재미난 상황이고, 친근하고 소박한 분위기를 자아냅니다. 좋음 불리언 상태가 상태 간에 부적절한 것일 수 있다는 것을 알립니다.

체크박스는 확실하지 않음으로 설정하기가 까다롭습니다. 자바스크립트만 설정할 수 있습니다.

<label for="switch-indeterminate" class="gui-switch">
  Indeterminate
  <input type="checkbox" role="switch" id="switch-indeterminate">
  <script>document.getElementById('switch-indeterminate').indeterminate = true</script>
</label>

다음에 트랙 thumb이 있는 미확정 상태
중간값으로 결정되지 않음을 나타냅니다.

제가 보기에는 이 주가 소박하고 호감이 넘치기 때문에 있습니다.

.gui-switch > input:indeterminate {
  --thumb-position: calc(
    calc(calc(var(--track-size) / 2) - calc(var(--thumb-size) / 2))
    * var(--isLTR)
  );
}

마우스 오버

마우스 오버 상호작용은 연결된 UI를 시각적으로 지원해야 하며 대화형 UI 방향을 제시합니다. 이 스위치는 라벨이나 입력에 마우스를 가져가면 반투명 고리가 표시됩니다. 이 마우스 오버 그러면 애니메이션이 대화형 thumb 요소를 향하는 방향을 제공합니다.

'하이라이트' 효과는 box-shadow로 실행됩니다. 사용 중지되지 않은 입력에 마우스를 가져가면 --highlight-size의 크기를 늘립니다. 사용자가 모션에 동의하면 box-shadow를 전환하여 성장하는 것을 확인하며 사용자가 모션에 문제가 없으면 강조표시가 즉시 표시됩니다.

.gui-switch > input::before {
  box-shadow: 0 0 0 var(--highlight-size) var(--thumb-color-highlight);

  @media (--motionOK) { & {
    transition:
      transform var(--thumb-transition-duration) ease,
      box-shadow .25s ease;
  }}
}

.gui-switch > input:not(:disabled):hover::before {
  --highlight-size: .5rem;
}

자바스크립트

제 생각에 스위치 인터페이스는 물리적 하드웨어를 에뮬레이션하려는 특히 트랙 안에 원이 있는 이런 종류의 인터페이스입니다. iOS의 정답 좌우로 끌 수 있어 매우 만족스럽습니다. 선택할 수 있습니다 반대로 드래그 동작이 아무 일도 일어나지 않습니다.

드래그 가능한 엄지손가락

thumb 의사 요소는 .gui-switch > input에서 위치를 수신합니다. 범위가 var(--thumb-position)인 경우, JavaScript는 다음 위치에 인라인 스타일 값을 제공할 수 있습니다. 엄지손가락 위치를 동적으로 업데이트하여 따라가는 것처럼 보이게 하는 입력 사용할 수 있습니다. 포인터가 해제되면 인라인 스타일을 제거하고 맞춤 속성을 사용하여 드래그가 꺼짐 또는 켜기에 가까웠는지 확인합니다. --thumb-position 이는 솔루션의 근간입니다. 포인터 이벤트 포인터 위치를 조건부로 추적하여 CSS 맞춤 속성을 수정합니다.

이 스크립트가 표시되기 전에 구성요소가 이미 100% 작동했습니다. 기존 동작을 유지하려면 상당한 작업이 필요합니다. 라벨을 클릭하여 입력을 전환할 수 있습니다. JavaScript는 다른 위치에 특성을 기존 기능의 비용을 줄일 수 있습니다

touch-action

드래그는 맞춤형 동작으로, touch-action 혜택. 이 스위치의 경우 가로 동작은 스크립트에 의해 처리되거나 수직 스위치로 캡처된 세로 동작이 있습니다. touch-action를 사용하면 처리할 동작을 브라우저에 알릴 수 있습니다. 이 요소를 사용하여 스크립트가 경쟁 없이 동작을 처리할 수 있습니다.

다음 CSS는 포인터 동작이 세로 동작을 처리하고 가로 동작으로는 아무 작업도 하지 않습니다. 다음과 같습니다.

.gui-switch > input {
  touch-action: pan-y;
}

원하는 결과는 화면 이동이나 스크롤도 하지 않는 가로 동작입니다. 있습니다. 포인터는 입력 내에서 수직으로 스크롤할 수 있고 가로 페이지는 맞춤 처리됩니다.

픽셀 값 스타일 유틸리티

설정 시 및 드래그 중에 다양한 계산된 숫자 값을 가져와야 합니다. 요소에서 추출해야 합니다. 다음 자바스크립트 함수는 계산된 픽셀 값을 반환합니다. CSS 속성이 있어야 합니다. 설정 스크립트에서 다음과 같이 사용됩니다. getStyle(checkbox, 'padding-left')

​​const getStyle = (element, prop) => {
  return parseInt(window.getComputedStyle(element).getPropertyValue(prop));
}

const getPseudoStyle = (element, prop) => {
  return parseInt(window.getComputedStyle(element, ':before').getPropertyValue(prop));
}

export {
  getStyle,
  getPseudoStyle,
}

window.getComputedStyle()가 두 번째 인수인 타겟 의사 요소를 허용하는 방식을 확인합니다. JavaScript가 의사 요소에서조차도 요소에서 너무 많은 값을 읽을 수 있다는 것은 꽤 훌륭합니다.

dragging

이 시점은 드래그 로직의 핵심 시점이며, 다음과 같은 몇 가지 사항이 있습니다. 를 삭제합니다.

const dragging = event => {
  if (!state.activethumb) return

  let {thumbsize, bounds, padding} = switches.get(state.activethumb.parentElement)
  let directionality = getStyle(state.activethumb, '--isLTR')

  let track = (directionality === -1)
    ? (state.activethumb.clientWidth * -1) + thumbsize + padding
    : 0

  let pos = Math.round(event.offsetX - thumbsize / 2)

  if (pos < bounds.lower) pos = 0
  if (pos > bounds.upper) pos = bounds.upper

  state.activethumb.style.setProperty('--thumb-position', `${track + pos}px`)
}

스크립트 주인공은 이 스크립트가 속한 작은 원 state.activethumb입니다. 위치를 지정할 수 있습니다. switches 객체는 Map()입니다. 여기서 키는 .gui-switch의 값이며 값은 스크립트를 효율적으로 실행합니다. 오른쪽에서 왼쪽으로는 동일한 맞춤 속성을 사용하여 처리됩니다. 해당 CSS가 --isLTR이며 이를 사용하여 로직을 반전시키고 RTL을 지원합니다. event.offsetX도 델타를 포함하므로 중요합니다. 값도 있습니다.

state.activethumb.style.setProperty('--thumb-position', `${track + pos}px`)

CSS의 마지막 줄은 thumb 요소에서 사용하는 맞춤 속성을 설정합니다. 이 그렇지 않으면 시간이 지남에 따라 값 할당이 전환되지만, 이전 포인터는 이벤트가 일시적으로 --thumb-transition-duration을(를) 0s(으)로 설정하여 느린 상호 작용이었을 것입니다

dragEnd

사용자가 스위치 바깥쪽으로 드래그한 후 놓을 수 있도록 하려면 등록이 필요한 전역 기간 이벤트:

window.addEventListener('pointerup', event => {
  if (!state.activethumb) return

  dragEnd(event)
})

저는 사용자가 느슨하게 드래그하고 인터페이스가 그것을 처리할 만큼 똑똑해야 합니다. 처리하는 데 그리 오래 걸리지 않았습니다. 개발 과정에서 신중한 고려가 필요했습니다. 프로세스입니다

const dragEnd = event => {
  if (!state.activethumb) return

  state.activethumb.checked = determineChecked()

  if (state.activethumb.indeterminate)
    state.activethumb.indeterminate = false

  state.activethumb.style.removeProperty('--thumb-transition-duration')
  state.activethumb.style.removeProperty('--thumb-position')
  state.activethumb.removeEventListener('pointermove', dragging)
  state.activethumb = null

  padRelease()
}

요소와의 상호작용이 완료되었으며, 입력 설정 시간이 확인됨 속성을 설정하고 모든 동작 이벤트를 삭제합니다. 체크박스가 state.activethumb.checked = determineChecked()

determineChecked()

dragEnd에서 호출하는 이 함수는 thumb 현재의 위치를 결정합니다. 트랙의 경계 내에 있으며 다음 값보다 크거나 같으면 true를 반환합니다. 트랙의 중간 지점에서:

const determineChecked = () => {
  let {bounds} = switches.get(state.activethumb.parentElement)

  let curpos =
    Math.abs(
      parseInt(
        state.activethumb.style.getPropertyValue('--thumb-position')))

  if (!curpos) {
    curpos = state.activethumb.checked
      ? bounds.lower
      : bounds.upper
  }

  return curpos >= bounds.middle
}

추가 생각

드래그 동작은 초기 HTML 구조로 인해 약간의 코드 부채를 야기했습니다. 특히 라벨에 입력을 래핑합니다. 상위 라벨 요소의 경우 입력 후 클릭 상호작용을 수신합니다. dragEnd 이벤트 발생 시 padRelease()이(가) 이상한 것으로 인식되었을 수 있습니다. 함수를 사용하세요.

const padRelease = () => {
  state.recentlyDragged = true

  setTimeout(_ => {
    state.recentlyDragged = false
  }, 300)
}

이는 선택 해제되어 나중에 클릭하게 하는 라벨을 고려하기 위함입니다. 사용자가 수행한 상호작용을 나타냅니다

다시 이 작업을 하려면 JavaScript로 DOM을 조정하는 것이 좋습니다. (예: 라벨 클릭 자체를 처리하는 요소를 만들기 위해) 내장된 동작으로 싸우지 않습니다.

이런 종류의 JavaScript는 제가 가장 쓰기 편하지 않기 때문에 직접 관리하고 싶지는 않습니다. 조건부 이벤트 버블링:

const preventBubbles = event => {
  if (state.recentlyDragged)
    event.preventDefault() && event.stopPropagation()
}

결론

이 작은 스위치 구성 요소가 모든 GUI 도전 과제 중 가장 많은 작업이 되었습니다. 되었습니다! 이제 제가 어떻게 했는지 알게 되셨으니 어떻게 하면 좋을까요?‽ 보상

접근방식을 다각화하고 웹에서 빌드하는 방법을 모두 알아보겠습니다. 데모를 만들고 링크를 트윗하여 추가하면 됩니다. 아래 커뮤니티 리믹스 섹션을 공유해 주세요

커뮤니티 리믹스

리소스

다음에서 .gui-switch 소스 코드 찾기 GitHub를 참고하세요.