| Server IP : 121.121.20.254 / Your IP : 216.73.216.202 Web Server : Microsoft-IIS/10.0 System : Windows NT WEB-SERVER 10.0 build 20348 (Windows Server 2022) AMD64 User : IUSR ( 0) PHP Version : 8.3.28 Disable Function : NONE MySQL : ON | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/inetpub/wwwroot/OPENPOSFNB/wp-content/plugins/code-snippets-pro/js/components/common/ |
Upload File : |
import React, { useEffect, useState } from 'react'
import SelectBase from 'react-select'
import classnames from 'classnames'
import type { SelectGroup, SelectGroups, SelectOption } from '../../types/SelectOption'
import type { ActionMeta, Props, StylesConfig } from 'react-select'
const findSelectOptions = <T, >(groups?: SelectGroups<T>, currentValue?: T | T[]): SelectOption<T>[] => {
if (undefined === groups || undefined === currentValue) {
return []
}
const found: SelectOption<T>[] = []
for (const group of groups) {
for (const option of 'options' in group ? group.options : [group]) {
if (Array.isArray(currentValue)) {
if (currentValue.includes(option.value)) {
found.push(option)
}
} else {
if (currentValue === option.value) {
return [option]
}
}
}
}
return found
}
const getOptionValue = <T, >(option: SelectOption<T>): string => {
if (option.key) {
return 'string' === typeof option.key ? option.key : option.key.toString()
}
if ('string' === typeof option.value) {
return option.value
}
if ('number' === typeof option.value) {
return option.value.toString()
}
return JSON.stringify(option.value)
}
const buildSelectStyles = <T, IsMulti extends boolean>({
isDisabled
}: Pick<SelectProps<T, IsMulti>, 'isDisabled'>): StylesConfig<SelectOption<T>, IsMulti, SelectGroup<T>> => ({
menu: base => ({ ...base, zIndex: 9999 }),
menuPortal: base => ({ ...base, zIndex: 1000000 }),
control: base => ({ ...base, flexWrap: 'nowrap' }),
singleValue: base => ({ ...base, overflow: 'visible' }),
indicatorSeparator: () => ({ display: 'none' }),
multiValueLabel: base => isDisabled ? { ...base, padding: '3px 6px' } : base,
dropdownIndicator: base => isDisabled ? { display: 'none' } : base,
multiValueRemove: base => isDisabled ? { display: 'none' } : base
})
export interface SelectProps<T, IsMulti extends boolean> extends Props<SelectOption<T>, IsMulti, SelectGroup<T>> {
currentValue?: IsMulti extends true ? T[] : T
onSelect?: (selected: T | undefined, actionMeta: ActionMeta<SelectOption<T>>) => void
onSelectMulti?: (selected: T[], actionMeta: ActionMeta<SelectOption<T>>) => void
}
export const Select = <T, IsMulti extends boolean = false>({
options,
isMulti,
onChange,
onSelect,
className,
isDisabled,
currentValue,
onSelectMulti,
...selectProps
}: SelectProps<T, IsMulti>) => {
const [selectedOptions, setSelectedOptions] = useState<readonly SelectOption<T>[]>(
() => findSelectOptions(options, currentValue))
const menuPortalTarget = 'undefined' === typeof document ? undefined : document.body
useEffect(() => {
setSelectedOptions(findSelectOptions(options, currentValue))
}, [options, currentValue, isMulti])
return (
<SelectBase
styles={buildSelectStyles<T, IsMulti>({ isDisabled })}
value={isMulti ? selectedOptions : selectedOptions[0] ?? null}
isMulti={isMulti}
options={options}
className={classnames('code-snippets-select', className)}
isDisabled={isDisabled}
menuPortalTarget={menuPortalTarget}
menuPosition={'fixed'}
getOptionLabel={option => option.label}
getOptionValue={getOptionValue}
onChange={(selected, actionMeta) => {
onChange?.(selected, actionMeta)
if (null === selected) {
setSelectedOptions([])
onSelect?.(undefined, actionMeta)
} else if ('value' in selected) {
setSelectedOptions([selected])
onSelect?.(selected.value ?? undefined, actionMeta)
} else {
setSelectedOptions(selected)
onSelectMulti?.(selected.map(option => option.value), actionMeta)
}
}}
{...selectProps}
/>
)
}