일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- graphql mutation error
- graphql
- apolloclient
- 홍대 카페 장쌤
- 도그존
- graphql 400
- 잠실새내
- 홍대 예술
- promise메서드
- 고르드
- 비동기배열
- 비동기배열처리방법
- 홍대 토라비
- 화이트해커를 위한 웹 해킹의 기술
- promise처리
- 지보싶 신촌점
- 예쁜술집 예술
- 금별맥주
- typescript
- 신촌 소문난집
- graphql with RN
- 앙버터마카롱
- useMutation error
- 잠실새내 도그존
- apollo react native
- 화이트 해커를 위한 웹 해킹의 기술
- graphql react native
- 운정 소바동
- graphql with reactnative
- 토라비
- Today
- Total
yehey's 공부 노트 \n ο(=•ω<=)ρ⌒☆
[Next js] input type='date' width 적용 이슈 본문
Issue
Input 컴포넌트를 styled-component로 커스텀하여 사용하는 중, input type='date'
를 사용하여 날짜를 선택할 수 있게 하려 했다.
데스크탑 웹에서 테스트 및 개발을 하고 있기 때문에 모바일로 확인해서 볼 기회가 없었는데, 최근 테스트를 하며 기대한 것과 다르게 input 의 width
가 설정해둔 100%가 아닌 특정 값으로 고정되어있었다. (테스트 기기는 아이폰 13pro, safari, chrome 모두 동일하게 출력됐다.)
100%로는 지정되지 않는데, 정확한 값을 넣으면 또 되고,,, 그치만 내가 원하는건 반응형으로 딱 절반 크기의 width가 될 수 있도록 하고 싶었다.
우선 같은 이슈를 가진 사람들은 어떻게 해결했는지 찾아본 결과..
https://github.com/mapbox/assembly/issues/540
display:block; width:100%
를 통해 해결할 수 있지만 type='date'
를 사용하지 않거나, type='date'
의 스타일링을 막는 방법이 있었다.display:block; width:100%
참고로 이건 내 케이스에서는 먹히지 않았다. 그래서 2가지 방법을 적용해봤다.
Solution 1 : prevent appearance
그리 권장하는 방법은 아니지만, 네이티브로 input type="date"
에 적용되어있는 스타일을 none으로 두고 리셋한다.
/* gloabl css file */
input[type="date"]{
appearance:none ;
-webkit-appearance: none;
-moz-appearance: none;
}
나는 global style을 정의하는 부분에 input type="date"
인 경우에만 appearance:none
을 추가해주었다.
원하는대로 input width 가 100%로 설정되었다.
Solution 2: react-datepicker 라이브러리 사용
input 태그를 스타일링 해서 사용하는 방법 외에 외부 datepicker 라이브러리를 설치, 사용하는 방법이다.
나는 react-datepicker
라이브러리를 사용했다.
npm install react-datepicker --save
//typescript 사용하는 경우 추가
npm install @types/react-datepicker --save
react-datepicker 도 내장된 input이 있지만 해당 부분을 inline 으로 처리해서 input은 보이지 않게 하고 datepick 부분만 뜨게 했다.
date pick 부분은 커스텀 버튼으로 컨트롤하도록!
interface IDatePickerButtonProps {
color?: string;
onChange: (date: Date, name: string) => void;
label?: string;
name: string;
selected: string;
}
function DatePickerButton({ label, name, onChange, selected, color = theme.color.WHITE }: IDatePickerButtonProps) {
const [isOpen, setIsOpen] = useState(false);
const handleChange = (date: Date) => {
setIsOpen(!isOpen);
onChange(date, name);
};
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
setIsOpen(!isOpen);
};
return (
<Wrapper>
{label && <Label>{label}</Label>}
<StyledButton color={color} onClick={handleClick}>
{selected}
</StyledButton>
{isOpen && (
<DateWrapper isOpen={isOpen} hasLabel={!!label}>
<ReactDatePicker name={name} locale={ko} onChange={handleChange} dateFormat="yyyy-MM-dd" inline />
</DateWrapper>
)}
</Wrapper>
);
}
export default DatePickerButton;
const Wrapper = styled.div`
display: flex;
flex-direction: column;
width: 100%;
position: relative;
z-index: 10;
`;
const Label = styled.label`
font-size: ${theme.font.fontSize[16]};
font-weight: ${theme.font.fontWeight.semibold};
color: ${theme.color.GREY[200]};
margin-bottom: 0.8rem;
width: 100%;
`;
const StyledButton = styled.button<{ color: string }>`
padding: 1.2rem;
width: 100%;
height: 4rem;
border-radius: 8px;
margin-bottom: 1.5rem;
font-size: ${theme.font.fontSize[14]};
font-weight: ${theme.font.fontWeight.regular};
color: ${theme.color.GREY[200]};
background-color: ${(props) => props.color};
border: none;
outline: none;
`;
const DateWrapper = styled.div<{ isOpen: boolean; hasLabel: boolean }>`
position: absolute;
top: ${(props) => (props.hasLabel ? '7rem' : '4.5rem')};
display: flex;
flex-direction: column;
width: 100%;
/* background-color: transparent; */
border-radius: 0.8rem;
box-shadow: 0px 1px 4px 0px ${theme.color.GREY[300]};
height: ${(props) => (props.isOpen ? 'none' : 0)};
max-height: ${(props) => (props.isOpen ? 'none' : 0)};
overflow: ${(props) => (props.isOpen ? 'visible' : 'hidden')};
z-index: 15;
@keyframes dropdown {
0% {
transform: translateY(-5%);
}
100% {
transform: translateY(0);
}
}
animation: dropdown 1s ease;
`;
IDatePickerButtonProps
가 ReactDatePickerProps
를 extend 하도록 할 수 있었지만 selected
,onChange
가 타입이 맞지 않아서 적용하지 않았다.
적용하면 달력 모양이 기본 내장 datepicker 와는 다르다. 저 부분도 수정할 수 있지만 아직 적용하지 않았다.
고민중인 부분은 열렸을 때 달력 스타일이 기본 input이 더 낫다는 생각..
react-datepicker는 달력이 너무 작다. 커스텀 하는 방법도 있지만 그래도 기본 input이 나아보이는...
그치만 appearance:none 을 함부로 줘도 되는가? 에 대한 고민은 떨칠 수 없다...
Error Review
간단한 해결방법과 적당한 해결방법을 찾았으니 둘 중 하나를 선택할 일만 남았다.
react-datepicker를 사용한다면 달력을 modal 처럼 portal로 띄워 구성하는 방법을 고려중이다. 달력 크기를 키워야 사용자가 날짜를 선택할 때 편하니까.
테스트의 중요성을 알았다. 사용할 기기, 다양한 기기에서 테스트를 해봐야 어떤 점을 생각해야하는 지 알게되는 것 같다.
참조
https://github.com/mapbox/assembly/issues/540
'적어보자 에러 일지' 카테고리의 다른 글
[Typescript] 'string' 형식의 식을 인덱스 형식에 사용할 수 없으므로 요소에 암시적으로 'any' 형식이 있습니다. (1) | 2023.12.27 |
---|---|
[Next js/Approuter] google material icon 사용하기 (0) | 2023.12.24 |
[Next js] AppRouter 프로젝트에 styled-component 적용하기 (0) | 2023.12.18 |
[BE/spring boot] JPA DTO 생성 (with. swagger request body) (0) | 2023.12.09 |
[ReactNative, RN, Graphql, Apollo Client] graphql mutation error (0) | 2021.11.19 |