Skip to content

Commit e0f9774

Browse files
committed
feat(QYOG-162): 오프라인 리뷰 반영(select 태그 삭제), 선택된 값 상태관리 추가
1 parent 243a254 commit e0f9774

File tree

3 files changed

+79
-55
lines changed

3 files changed

+79
-55
lines changed

src/components/Design/SelectBox/SelectBox.stories.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ type Story = StoryObj<typeof meta>;
1010

1111
export const Primary: Story = {
1212
args: {
13-
options: ["12340", "한글", "English", "Aa10테스트"],
13+
options: [
14+
{ name: "1학년", value: "1" },
15+
{ name: "2학년", value: "2" },
16+
],
17+
18+
defaultName: "학년",
19+
isRequired: true,
1420
},
1521
};
1622

src/components/Design/SelectBox/SelectBox.tsx

+45-21
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,57 @@
44
* Copyright (c) 2024 Your Company
55
*/
66

7-
import { InputHTMLAttributes } from "react";
8-
9-
import { Theme } from "@emotion/react";
7+
import { useState, useRef } from "react";
108

119
import * as S from "./emotion";
1210

13-
interface ISelectBoxProps extends InputHTMLAttributes<HTMLInputElement> {
14-
backgroundColor?: keyof Theme["color"];
15-
typoColor?: keyof Theme["color"];
16-
typoSize?: keyof Theme["typography"];
17-
shape?: "square" | "round";
18-
options: string[];
19-
boxSize?: "xs" | "s" | "m" | "l" | "xl";
11+
interface OptionInterface {
12+
name: string;
13+
value: string;
14+
}
15+
interface SelectboxProps {
16+
options: OptionInterface[];
17+
defaultName: string;
18+
isRequired: boolean;
2019
}
2120

22-
export default function SelectBox(props: ISelectBoxProps) {
21+
export default function SelectBox({
22+
options,
23+
defaultName = "값을 선택하세요.",
24+
isRequired = false,
25+
}: SelectboxProps) {
26+
const [isOpen, setIsOpen] = useState<boolean>(false);
27+
const [selectedName, setSelectedName] = useState(defaultName);
28+
const [selectedIndex, setSelectedIndex] = useState<number>(-1);
29+
const [isChanged, setIsChanged] = useState<boolean>(false);
30+
31+
//마지막에 밖에다 빼줘야되는 정보
32+
// const returnOption:OptionInterface = options[selectedIndex]
33+
34+
function handleOnChangeOption(e: any) {
35+
setSelectedName(e.target.innerHTML);
36+
setSelectedIndex(e.target.id);
37+
setIsChanged(true);
38+
}
39+
2340
return (
24-
<div>
25-
<S.CommonStyledSelectField
26-
backgroundColor={props.backgroundColor}
27-
shape={props.shape}
28-
boxSize={props.boxSize}
29-
>
30-
{props.options.map((el, idx) => {
31-
return <S.CommonstyledOption key={idx}>{el}</S.CommonstyledOption>;
41+
<S.SelectBoxWrap
42+
onClick={() => setIsOpen(!isOpen)}
43+
verticalAlign="center"
44+
horizonAlign="center"
45+
>
46+
<label>{selectedName}</label>
47+
<S.OptionUl isShow={isOpen}>
48+
{options.map((option, idx) => {
49+
return (
50+
<li key={idx} id={String(idx)} onClick={handleOnChangeOption}>
51+
{option.name}
52+
</li>
53+
);
3254
})}
33-
</S.CommonStyledSelectField>
34-
</div>
55+
</S.OptionUl>
56+
57+
{!isChanged && isRequired ? <div>필수값입니다.</div> : <></>}
58+
</S.SelectBoxWrap>
3559
);
3660
}
+27-33
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,37 @@
11
/*
2-
* Created on Fri Feb 16 2024
2+
* Created on Sat June 15 2024
33
*
4-
* Copyright (c) 2024 Your Company
4+
* Copyright (c) 2023 Your Company
55
*/
66

7-
import { Row } from "@/components/Layouts";
8-
import { Theme } from "@emotion/react";
7+
import { Column } from "@/components/Layouts";
98
import styled from "@emotion/styled";
109

11-
export const CommonStyledSelectField = styled(Row.select)<{
12-
backgroundColor?: keyof Theme["color"];
13-
typoColor?: keyof Theme["color"];
14-
typoSize?: keyof Theme["typography"];
15-
shape?: "round" | "square";
16-
boxSize?: "xs" | "s" | "m" | "l" | "xl";
17-
}>`
18-
background-color: ${({ theme, backgroundColor }) =>
19-
theme.color[!backgroundColor ? "white" : backgroundColor]};
10+
export const SelectBoxWrap = styled(Column.div)`
11+
border: 1px solid red;
12+
position: relative;
13+
cursor: pointer;
2014
21-
border-radius: ${({ shape }) => (shape === "round" ? "16px" : "3px")};
22-
border: 1px solid #8f8f8f;
15+
&::before {
16+
content: "⌵";
17+
position: absolute;
18+
top: 1px;
19+
right: 8px;
20+
font-size: 20px;
21+
}
2322
24-
padding: ${({ boxSize }) => {
25-
switch (boxSize) {
26-
case "xl":
27-
return "8px 14px";
28-
case "l":
29-
return "6px 12px";
30-
case "m":
31-
return "4px 8px";
32-
case "s":
33-
return "2px 6px";
34-
case "xs":
35-
return "2px 4px";
36-
37-
default:
38-
return "4px 8px";
39-
}
40-
}};
23+
padding: 10px;
24+
/* 의논필요 */
25+
/* width: 200px;
26+
border-radius: 10px; */
4127
`;
4228

43-
export const CommonstyledOption = styled.option``;
29+
export const OptionUl = styled.ul<{ isShow: boolean }>`
30+
max-height: ${(props) => (props.isShow ? "none" : "0")};
31+
position: absolute;
32+
list-style: none;
33+
top: 18px;
34+
left: 0;
35+
overflow: hidden;
36+
padding: 0;
37+
`;

0 commit comments

Comments
 (0)