Skip to content

Commit 6cc415c

Browse files
committed
Update index.jsx
1 parent eed989d commit 6cc415c

File tree

1 file changed

+92
-89
lines changed

1 file changed

+92
-89
lines changed

src/index.jsx

Lines changed: 92 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint-disable no-labels */
22
import React, { useState, useEffect, useRef } from 'react'
3+
import Chip from './Chip.jsx'
34
import CloseIcon from './CloseIcon.jsx'
45
import DownIcon from './DownIcon.jsx'
56
import Options from './Options'
@@ -9,7 +10,6 @@ import useComponentVisible from './useComponentVisible.jsx'
910
MultiSelect.defaultProps = {
1011
clearable: true,
1112
downArrow: true,
12-
width: 300,
1313
singleSelect: false,
1414
jsonValue: false,
1515
defaultValue: '',
@@ -20,7 +20,7 @@ MultiSelect.defaultProps = {
2020
limit: null,
2121
emptyDataLabel: 'No Data Found',
2222
placeholder: 'Select...',
23-
onChange: () => { },
23+
onChange: () => {},
2424
options: [
2525
{
2626
label: 'Empty',
@@ -29,12 +29,12 @@ MultiSelect.defaultProps = {
2929
style: { textAlign: 'center' }
3030
}
3131
],
32-
customValue: false
32+
customValue: false,
33+
chipAlternateText: 'Item Selected'
3334
}
3435

3536
function MultiSelect({
3637
options: userOptions,
37-
width,
3838
downArrowIcon,
3939
closeIcon,
4040
clearable,
@@ -53,17 +53,27 @@ function MultiSelect({
5353
disabled,
5454
limit,
5555
emptyDataLabel,
56-
customValue
56+
customValue,
57+
onMenuOpen,
58+
onMenuClose,
59+
chipAlternateText
5760
}) {
5861
const [value, setValue] = useState([])
5962
const [options, setOptions] = useState(userOptions || [])
6063
const [search, setSearch] = useState(null)
6164
const inputFld = useRef(null)
6265
const {
63-
ref,
66+
ref: componentRef,
6467
isComponentVisible: menuOpen,
6568
setIsComponentVisible: setMenuOpen
66-
} = useComponentVisible(false)
69+
} = useComponentVisible({
70+
initialIsVisible: false,
71+
onClickOutside: onMenuClose
72+
})
73+
74+
const calculatedWidth = `calc(100% - ${
75+
clearable && downArrow ? 60 : downArrow || clearable ? 40 : 5
76+
}px)`
6777

6878
const getValueObjFromOptios = (defaultValue, options) => {
6979
if (!defaultValue) return []
@@ -124,6 +134,7 @@ function MultiSelect({
124134
setOptions([...options, ...customValuesGroup])
125135
return [...searchedOptions, ...extraValues]
126136
}
137+
127138
useEffect(() => {
128139
setOptions(userOptions)
129140
}, [userOptions])
@@ -316,6 +327,18 @@ function MultiSelect({
316327
}
317328
}
318329

330+
const notClickableItem = (target) => {
331+
if (
332+
target.hasAttribute('clickable') ||
333+
target.parentNode.hasAttribute('clickable') ||
334+
target.parentNode.parentNode.hasAttribute('clickable') ||
335+
target.parentNode.parentNode.parentNode.hasAttribute('clickable')
336+
) {
337+
return false
338+
}
339+
return true
340+
}
341+
319342
const checkIsDropdownHandle = (target) => {
320343
if (
321344
target.hasAttribute('dropdown-handle') ||
@@ -326,116 +349,95 @@ function MultiSelect({
326349
}
327350
}
328351

352+
const focusSearchInput = () => {
353+
if (inputFld.current) {
354+
inputFld.current.focus()
355+
}
356+
}
357+
329358
const openMenu = ({ target }) => {
330-
if (checkIsDropdownHandle(target)) {
331-
setMenuOpen(!menuOpen)
332-
} else {
333-
setMenuOpen(true)
359+
if (notClickableItem(target)) {
360+
if (checkIsDropdownHandle(target)) {
361+
if (!menuOpen) {
362+
setMenuOpen(true)
363+
onMenuOpen()
364+
focusSearchInput()
365+
} else {
366+
setMenuOpen(false)
367+
onMenuClose()
368+
}
369+
} else {
370+
setMenuOpen(true)
371+
onMenuOpen()
372+
focusSearchInput()
373+
}
334374
}
335375
}
336376

337-
const showChipText = (opt) => {
338-
if (typeof opt.label === 'object') {
339-
return opt?.title || opt.value
377+
const showLabel = (optionObj) => {
378+
console.log(optionObj)
379+
if (typeof optionObj.label === 'object') {
380+
return optionObj?.title || optionObj.value
340381
} else {
341-
return opt.label
382+
return optionObj.label
383+
}
384+
}
385+
386+
const getActiveClass = () => {
387+
const el = componentRef.current
388+
var rect = el.getBoundingClientRect()
389+
if (window.innerHeight - (rect.top + el.clientHeight) < 200) {
390+
return 'msl-active-up'
342391
}
392+
return 'msl-active'
343393
}
344394

345395
return (
346396
<div
347-
ref={ref}
397+
ref={componentRef}
348398
{...attr}
349399
onClick={openMenu}
350400
tabIndex='0'
351401
onKeyPress={openMenu}
352-
style={{ ...style, width }}
353-
className={`msl-wrp msl-vars ${className} ${disabled ? 'msl-disabled' : ''
354-
}`}
402+
style={{ ...style }}
403+
className={`msl-wrp msl-vars ${className} ${
404+
disabled ? 'msl-disabled' : ''
405+
}`}
355406
>
356407
<input name={name} type='hidden' value={value?.map((itm) => itm.value)} />
357-
<div data-msl className={`msl ${menuOpen ? 'msl-active' : ''} `}>
408+
<div data-msl className={`msl ${menuOpen && getActiveClass()} `}>
358409
<div
359410
data-msl
360411
className='msl-input-wrp'
361-
style={{
362-
width: `calc(100% - ${clearable && downArrow
363-
? '60px'
364-
: downArrow || clearable
365-
? '40px'
366-
: '5px'
367-
}`
368-
}}
412+
style={{ width: calculatedWidth }}
369413
>
370414
{!singleSelect &&
371415
!disableChip &&
372416
value.map((val, i) => (
373-
<div key={`msl-chip-${i + 11}`} className='msl-chip'>
374-
{showChipText(val)}
375-
<div
376-
role='button'
377-
aria-label='delete-value'
378-
onClick={() => deleteValue(i)}
379-
onKeyPress={() => deleteValue(i)}
380-
tabIndex='0'
381-
className='msl-btn msl-chip-delete msl-flx'
382-
>
383-
<CloseIcon />
384-
</div>
385-
<span />
386-
</div>
417+
<Chip
418+
key={`msl-chip-${i + 11}`}
419+
value={val}
420+
deleteAction={() => deleteValue(i)}
421+
/>
387422
))}
388-
{!singleSelect && disableChip && value.length === 1 ? (
423+
{!singleSelect && disableChip && value.length > 0 && (
389424
<span
390425
className='msl-single-value'
391426
data-msl
392-
style={{
393-
width:
394-
width -
395-
(clearable && downArrow
396-
? 60
397-
: downArrow || clearable
398-
? 40
399-
: 5)
400-
}}
427+
style={{ width: calculatedWidth }}
401428
>
402-
{value[0].label}d
429+
{value.length === 1
430+
? showLabel(value[0])
431+
: `${value.length} ${chipAlternateText}`}
403432
</span>
404-
) : (
405-
disableChip &&
406-
value.length > 1 && (
407-
<span
408-
className='msl-single-value'
409-
data-msl
410-
style={{
411-
width:
412-
width -
413-
(clearable && downArrow
414-
? 60
415-
: downArrow || clearable
416-
? 40
417-
: 5)
418-
}}
419-
>
420-
{value.length} Selected
421-
</span>
422-
)
423-
)}
433+
)}
424434
{singleSelect && value.length === 1 && (
425435
<span
426436
className='msl-single-value'
427437
data-msl
428-
style={{
429-
width:
430-
width -
431-
(clearable && downArrow
432-
? 60
433-
: downArrow || clearable
434-
? 40
435-
: 5)
436-
}}
438+
style={{ width: calculatedWidth }}
437439
>
438-
{value[0].label}
440+
{showLabel(value[0])}
439441
</span>
440442
)}
441443
{showSearchOption() && (
@@ -454,6 +456,7 @@ function MultiSelect({
454456
{clearable && value.length > 0 && (
455457
<div
456458
role='button'
459+
clickable='true'
457460
aria-label='close-menu'
458461
onClick={clearValue}
459462
onKeyPress={clearValue}
@@ -503,12 +506,12 @@ function MultiSelect({
503506
}}
504507
/>
505508
) : (
506-
((search && !search.length) || (options && !options.length)) && (
507-
<option className='msl-option msl-option-disable'>
508-
{emptyDataLabel}
509-
</option>
510-
)
511-
)}
509+
((search && !search.length) || (options && !options.length)) && (
510+
<option className='msl-option msl-option-disable'>
511+
{emptyDataLabel}
512+
</option>
513+
)
514+
)}
512515
</div>
513516
</div>
514517
)

0 commit comments

Comments
 (0)