Skip to content

Commit ba1a20e

Browse files
committed
merge parent pr onesine#69 and onesine#56
1 parent c187e4e commit ba1a20e

File tree

3 files changed

+47
-7
lines changed

3 files changed

+47
-7
lines changed

pages/index.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ const SELECT_OPTIONS = [
5959
"isMultiple",
6060
"isDisabled",
6161
"loading",
62-
"isGroupOption"
63-
];
62+
"isGroupOption",
63+
"closeOnSelect"];
6464

6565
const printAlertContent = (element, value) => {
6666
const printText = (text, value) =>
@@ -79,6 +79,8 @@ const printAlertContent = (element, value) => {
7979
return printText("A loader appears on the field", value);
8080
case "isGroupOption":
8181
return printText("The options of the select field are grouped", value);
82+
case "closeOnSelect":
83+
return printText("Close dropdown every time an option is selected", value);
8284
default:
8385
return null;
8486
}
@@ -91,6 +93,7 @@ const Home = () => {
9193
const [value, setValue] = useState(null);
9294
const [isClearable, setIsClearable] = useState(false);
9395
const [isMultiple, setIsMultiple] = useState(false);
96+
const [closeOnSelect, setCloseOnSelect] = useState(false);
9497
const [isSearchable, setIsSearchable] = useState(false);
9598
const [isDisabled, setIsDisabled] = useState(false);
9699
const [isGroupOption, setIsGroupOption] = useState(false);
@@ -139,6 +142,10 @@ const Home = () => {
139142
}
140143
if (action === "get") return isMultiple;
141144
break;
145+
case "closeOnSelect":
146+
if (action === "set") setCloseOnSelect(valueData);
147+
if (action === "get") return closeOnSelect;
148+
break;
142149
case "isDisabled":
143150
if (action === "set") setIsDisabled(valueData);
144151
if (action === "get") return isDisabled;
@@ -158,7 +165,16 @@ const Home = () => {
158165
break;
159166
}
160167
},
161-
[isClearable, isDisabled, isGroupOption, isMultiple, isSearchable, loading, value]
168+
[
169+
isClearable,
170+
isDisabled,
171+
isGroupOption,
172+
isMultiple,
173+
closeOnSelect,
174+
isSearchable,
175+
loading,
176+
value
177+
]
162178
);
163179

164180
const handleCheck = useCallback(
@@ -239,6 +255,7 @@ const Home = () => {
239255
isClearable={isClearable}
240256
isSearchable={isSearchable}
241257
isMultiple={isMultiple}
258+
closeOnSelect={closeOnSelect}
242259
/*formatGroupLabel={(data) => (
243260
<div className={`py-2 text-xs flex items-center justify-between`}>
244261
<span className="font-bold">{data.label}</span>
@@ -282,6 +299,7 @@ const Home = () => {
282299
{printAlertContent("isDisabled", isDisabled)}
283300
{printAlertContent("loading", loading)}
284301
{printAlertContent("isGroupOption", isGroupOption)}
302+
{printAlertContent("closeOnSelect", closeOnSelect)}
285303
</Alert>
286304
</div>
287305
)}

src/components/Select.tsx

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@ const Select: React.FC<SelectProps> = ({
2727
primaryColor = DEFAULT_THEME,
2828
formatGroupLabel = null,
2929
formatOptionLabel = null,
30-
classNames
30+
classNames,
31+
scrollableContainer = null,
32+
closeOnSelect = false
3133
}) => {
3234
const [open, setOpen] = useState<boolean>(menuIsOpen);
3335
const [list, setList] = useState<ListOption>(options);
3436
const [inputValue, setInputValue] = useState<string>("");
3537
const ref = useRef<HTMLDivElement>(null);
3638
const searchBoxRef = useRef<HTMLInputElement>(null);
39+
const [showOptionAboveTheSelect, setShowOptionAboveTheSelect] = useState<boolean>(false);
3740

3841
useEffect(() => {
3942
const formatItem = (item: Option) => {
@@ -95,7 +98,7 @@ const Select: React.FC<SelectProps> = ({
9598
const handleValueChange = useCallback(
9699
(selected: Option) => {
97100
function update() {
98-
if (!isMultiple && !Array.isArray(value)) {
101+
if ((!isMultiple && !Array.isArray(value)) || closeOnSelect) {
99102
closeDropDown();
100103
onChange(selected);
101104
}
@@ -166,6 +169,22 @@ const Select: React.FC<SelectProps> = ({
166169
[classNames, isDisabled]
167170
);
168171

172+
const handleScroll = useCallback(() => {
173+
if (ref.current) {
174+
const { top } = ref.current.getBoundingClientRect();
175+
// check if the component is on the bottom half of the page or on the top half
176+
setShowOptionAboveTheSelect(top > window.innerHeight / 2);
177+
}
178+
}, [ref]);
179+
180+
useEffect(handleScroll, [ref]);
181+
182+
useEffect(() => {
183+
const _scrollableContainer = scrollableContainer || window.document;
184+
_scrollableContainer.addEventListener('scroll', handleScroll);
185+
return () => _scrollableContainer.removeEventListener('scroll', handleScroll);
186+
}, [scrollableContainer]);
187+
169188
return (
170189
<SelectProvider
171190
otherData={{
@@ -266,9 +285,10 @@ const Select: React.FC<SelectProps> = ({
266285
{open && !isDisabled && (
267286
<div
268287
className={
269-
classNames?.menu
288+
`${classNames?.menu
270289
? classNames.menu
271-
: "absolute z-10 w-full bg-white shadow-lg border rounded py-1 mt-1.5 text-sm text-gray-700"
290+
: "absolute z-10 w-full bg-white shadow-lg border rounded py-1 mt-1.5 text-sm text-gray-700"}
291+
${showOptionAboveTheSelect ? 'top-auto bottom-[44px]' : ''}`
272292
}
273293
>
274294
{isSearchable && (

src/components/type.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,6 @@ export interface SelectProps {
5252
formatGroupLabel?: ((data: GroupOption) => JSX.Element) | null;
5353
formatOptionLabel?: ((data: Option) => JSX.Element) | null;
5454
classNames?: ClassNames;
55+
scrollableContainer?: HTMLElement | null;
56+
closeOnSelect?: boolean;
5557
}

0 commit comments

Comments
 (0)