Input Option คือ view ที่ใช้ไอคอน Option ในการกดเพื่อแสดงเมนูให้เลือก
import { useState } from "react";
import styled from "styled-components";
import useOutsideClick from "../../util/useOutsideClick";
import IconOption from "../element/icon/IconOption";
export default function InputOption({
onChange,
dataList, //[{text:'All',value:'all'}] or //['all','none']
width = 200,
maxHeight = 200,
className,
style,
optionColor = "var(--txt-normal)",
textTransform = "capitalize",
borderRadius = "8px",
}) {
const outerRef = useOutsideClick(() => setIsFocus(false));
const [isFocus, setIsFocus] = useState(false);
const [listPosition, setListPosition] = useState();
const handleOnChange = (item) => {
setIsFocus(false);
if (onChange) {
onChange(item.value || item || "");
}
};
const handleClickDropdown = (e) => {
setIsFocus((prev) => !prev);
const globalMousePos = { y: e.clientY || 0, x: e.clientX || 0 };
const windowSize = {
height: e.view.innerHeight || 0,
width: e.view.innerWidth || 0,
};
let tmpPosition;
//vertical axis
if (globalMousePos.y + maxHeight < windowSize.height) {
tmpPosition = {
...listPosition,
top: outerRef.current.clientHeight + dropDownGap,
bottom: null,
};
} else {
tmpPosition = {
...listPosition,
bottom: outerRef.current.clientHeight + dropDownGap,
top: null,
};
}
//horizontal axis
if (globalMousePos?.x + width > windowSize.width) {
tmpPosition = { ...tmpPosition, left: null, right: 5 };
} else if (globalMousePos?.x - width <= 0) {
tmpPosition = { ...tmpPosition, left: 5, right: null };
} else {
tmpPosition = {
...tmpPosition,
left: -(width / 2 + -outerRef.current.clientWidth / 2),
right: null,
};
}
setListPosition(tmpPosition);
};
return (
<Styled
className={className}
style={style}
$width={width}
$maxHeight={maxHeight}
$borderRadius={borderRadius}
$listPosition={listPosition}
$textTransform={textTransform}
>
<div ref={outerRef} className={"dropdown-inner"}>
<div className="option-wrap">
<div className="selected-wrp" onClick={handleClickDropdown}>
<IconOption isVertical color={optionColor} />
</div>
</div>
{isFocus && dataList && (
<ul className="list">
{dataList.map((item, index) => (
<li
className="item-li"
key={"item-" + index}
onClick={() => handleOnChange(item)}
>
{item?.text || item || ""}
</li>
))}
</ul>
)}
</div>
</Styled>
);
}
const Styled = styled.div`
position: relative;
display: inline-flex;
small {
margin-bottom: 5px;
font-weight: bold;
display: block;
}
.place-item {
color: var(--txt-normal-soft);
}
.dropdown-inner {
position: relative;
display: inline-flex;
flex-direction: column;
user-select: none;
cursor: pointer;
.list {
position: absolute;
margin: 0;
background-color: var(--surface);
min-width: 200px;
width: ${({ $width }) => $width + "px"};
max-height: ${({ $maxHeight }) => $maxHeight + "px"};
z-index: 999;
list-style: none;
border-radius: ${({ $borderRadius }) => $borderRadius};
padding: 0;
top: ${({ $listPosition }) =>
$listPosition?.top ? $listPosition.top + "px" : null};
bottom: ${({ $listPosition }) =>
$listPosition?.bottom ? $listPosition.bottom + "px" : null};
left: ${({ $listPosition }) =>
$listPosition?.left ? $listPosition.left + "px" : null};
right: ${({ $listPosition }) =>
$listPosition?.right ? $listPosition.right + "px" : null};
overflow-y: auto;
&::-webkit-scrollbar {
width: 10px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
}
&::-webkit-scrollbar-thumb {
background: #888;
border-radius: 20px;
}
}
.list li {
padding: 10px 12px;
text-transform: ${({ $textTransform }) => $textTransform};
display: flex;
}
.selected-wrp {
position: relative;
padding: 12px;
}
}
`;
import InputOption from "../../example/InputOption";
export default function TestView() {
return (
<div className="test-view">
<InputOption
onChange={(e) => console.log(e)}
dataList={[
{ value: "option 1", text: "Option 1" },
{ value: "option 2", text: "Option 2" },
{ value: "option 3", text: "Option 3" },
{ value: "option 4", text: "Option 4" },
{ value: "option 5", text: "Option 5" },
]}
/>
</div>
);
}
Property | Description | Type | Default |
---|---|---|---|
onChange | ฟังก์ชันจะทำงานเมื่อมีการเปลี่ยนแปลง | function | |
dataList | ชุดข้อมูลภายใน view | array | |
width | ความกว้างของเมนู | number | 200 |
maxHeight | ความสูงมากที่สุดของเมนู | number | 200 |
className | คุณลักษณะเฉพาะของ view | string | |
style | inline style | CSSProperties | |
optionColor | สีของไอคอน Option | string | "var(--txt-normal)" |
textTransform | ลักษณะของตัวอักษรในเมนู | string | "capitalize" |
borderRadius | ความโค้งมนของเมนู | string | "8px" |