250x250
반응형
arkhyeon
arkhyeon
arkhyeon
전체 방문자
오늘
어제
  • 분류 전체보기 (88)
    • Spring (5)
    • Java (4)
    • React (25)
      • TypeScript (6)
      • JavaScript (1)
      • Jest (9)
    • NEXT (8)
    • SQL (1)
    • React native (1)
    • CSS (3)
    • Web (1)
    • Git (3)
    • ETC (6)
    • 빅데이터DB (8)
    • Docker (4)
    • Tool (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • docker tomcat
  • react spring websocket
  • react loading
  • react
  • javasciprt websocket
  • WSS
  • node WebSocket
  • jest
  • react websocket
  • react typescript
  • react usetransition
  • javascript wss
  • websocket server
  • react19
  • websocket
  • kudu
  • usetransition
  • HIVE
  • react jest
  • Spring WebSocket

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
arkhyeon

arkhyeon

CSS

Input Radio Custom Css React Component

2024. 3. 6. 09:46
728x90
반응형

Accent-Color Demo

폼 컨트롤의 색상을 사용자 정의하고 서로 간의 시각적 구분을 향상시키는 데 도움이 될 수 있습니다. 내부의 배경색은 설정한 색의 대비로 결정되며 세세한 수정을 위해서는 새로 만들어야 합니다.

/** 전체 색상 변경
:root {
 accent-color: rgba(250, 15, 117);
}
*/

.radio {
  width: 40px;
  height: 40px;
  accent-color: dodgerblue;
}

.radio1 {
  width: 40px;
  height: 40px;
  accent-color: #ffc045;
}

.range {
  width: 200px;
  accent-color: lawngreen;
}

.progress {
  width: 200px;
  accent-color: coral;
}

 

 

CSS property: accent-color | Can I use... Support tables for HTML5, CSS3, etc

CSS property: accent-color Global usage 93.61% + 0% = 93.61% IE 6 - 10: Not supported11: Not supported Edge 12 - 92: Not supported93 - 121: Supported122: Supported Firefox 2 - 91: Not supported92 - 122: Supported123: Supported124 - 126: Supported Chrome 4

caniuse.com

현재 Chrome과 Edge의 최신 버전, 그리고 layout.css.accent-color.enabled 플래그를 활성화한 Firefox 브라우저를 지원하지만, IE는 지원하지 않습니다.

Radio React Component

import React, { useCallback } from 'react';
import styled from '@emotion/styled';
import { css } from '@emotion/react';

/**
 * @param {Number} param.value
 * 선택하고자 하는 값
 * 숫자 타입으로 인덱스 값으로 대상 분류한다고 가정
 * state로 관리하는 값이여야 함 (상태값)
 * default 값은 1
 * @param {Function} param.setValue
 * 선택 값을 바꾸는 함수
 * useState로 생성한 상태 관리 함수여야 함
 * default 값은 null
 * @param {Object [Array]} param.list
 * 선택할 수 있는 값들로 이루어진 배열
 * 각 객체는 value와 label 속성을 가지고 있음
 * default 값은 [{value: 1, label: 'test1'}, {value: 2, label: 'test2'}]
 * @param {String} param.text
 * 선택에 대한 제목
 * default 값은 '텍스트를 입력해주세요.'
 * @param {String} param.CheckColor
 * 체크 단락의 색
 * default 값은 'rgb(144, 202, 249)'
 * @param {String} param.hoverColor
 * 체크 단락에 마우스를 올렸을 때 생기는 원의 색
 * default 값은 '#eee'
 * @param {String} param.labelInSpacing
 * 한 라벨 내에서 체크 단락과 글씨와의 간격
 * default 값은 '4px'
 * @param {String} param.labelOutSpacing
 * 라벨 간의 간격
 * default 값은 '8px'
 * @param {String} param.type
 * Radio 컴포넌트의 형태 지정
 * 'fill' 체크 할 시, 동그라미로 표시(default)
 * 'border' 체크 할 시, 테두리가 굵어짐
 * @returns {JSX.Component} Radio Component
 */

function Radio({
  value = 1,
  setValue = null,
  list = [
    { value: 1, label: 'test1' },
    { value: 2, label: 'test2' },
  ],
  checkColor = 'rgb(144, 202, 249)',
  hoverColor = '#eee',
  labelInSpacing = '4px',
  labelOutSpacing = '8px',
  type = 'border',
  disabled = false,
}) {
  const handleValue = useCallback(
    value => {
      if (disabled) {
        return;
      }
      setValue(value);
    },
    [setValue],
  );

  const renderOption = useCallback(() => {
    return (
      <OptionWrapper>
        {list.map((el, idx) => (
          <Label
            key={`label-${el.value}`}
            onClick={() => handleValue(el.value)}
            labelOutSpacing={labelOutSpacing}
          >
            <CheckWrapper
              checkColor={checkColor}
              labelInSpacing={labelInSpacing}
              hoverColor={hoverColor}
              type={type}
              value={el.value}
              checked={value === el.value}
              idx={idx}
            >
              <Check
                value={el.value}
                checked={value === el.value}
                checkColor={checkColor}
                type={type}
              />
            </CheckWrapper>
            <div>{el.label}</div>
          </Label>
        ))}
      </OptionWrapper>
    );
  }, [handleValue, hoverColor, labelInSpacing, labelOutSpacing, list, value, type, checkColor]);

  return renderOption();
}

const OptionWrapper = styled.div`
  display: flex;
  gap: 10px;
`;

const CheckWrapper = styled.div`
  position: relative;
  border-radius: 50%;
  width: 16px;
  height: 16px;
  background: transparent;
  display: flex;
  align-items: center;

  :hover {
    background: ${({ hoverColor }) => hoverColor};
  }

  ::before {
    content: '';
    position: absolute;
    border: ${({ checkColor }) => `2px solid ${checkColor}`};
    background: white;
    width: 12px;
    height: 12px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    ${({ type, checked, checkColor }) => {
      if (type === 'border' && checked) {
        return css`
          border: 2px solid ${checkColor};
          background: ${checkColor};
        `;
      }

      if (type === 'border') {
        return css`
          border: 2px solid #d2d2d2;
        `;
      }
    }};
  }
`;

const Check = styled.div`
  position: absolute;
  width: 8px;
  height: 8px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;

  background: ${({ checked, checkColor, type }) => {
    if (checked && type === 'border') {
      return 'white';
    }

    if (checked) {
      return checkColor;
    }
    return 'transparent';
  }};

  transition: 0.2s;
`;

const Label = styled.label`
  display: flex;
  align-items: center;
  cursor: pointer;
  gap: 6px;

  & > div {
    font-size: 13px;
  }
`;

export default Radio;
728x90
반응형

'CSS' 카테고리의 다른 글

Module CSS Use Mixin Include SCSS  (0) 2024.05.30
React Light/Dark Theme switch  (0) 2024.04.03
    'CSS' 카테고리의 다른 글
    • Module CSS Use Mixin Include SCSS
    • React Light/Dark Theme switch
    arkhyeon
    arkhyeon

    티스토리툴바