/**
* External dependencies
*/
import Select from 'react-select';
import { isArray } from 'lodash';
import { COLORS } from '@nab/utils';
import type { Props as SelectProps, StylesConfig } from 'react-select';
/**
* Internal dependencies
*/
import './style.scss';
export const DEFAULT_STYLE: StylesConfig< unknown, boolean > = {
control: ( _, state ) => ( {
...getControlBorder( state ),
background: state.isDisabled
? COLORS.nabBackgroundLightGrey
: COLORS.nabBackgroundWhite,
boxShadow: undefined,
display: 'flex',
flexDirection: 'row',
fontSize: '13px',
height: ! state.isMulti ? '40px' : undefined,
margin: '0',
marginBottom: '1em',
padding: '0 6px 0 12px',
paddingLeft: state.isMulti ? '0' : undefined,
} ),
singleValue: ( style, state ) => ( {
...style,
color: state.isDisabled ? COLORS.nabTextLightGrey : COLORS.nabText,
} ),
input: ( style ) => ( {
...style,
marginTop: '-3px',
} ),
groupHeading: ( style ) => ( {
...style,
padding: '1em',
} ),
loadingIndicator: () => ( {
display: 'none',
} ),
indicatorSeparator: () => ( {
display: 'none',
} ),
dropdownIndicator: () => ( {
display: 'flex',
color: 'transparent',
width: '1.5em',
height: '100%',
background:
'url(\'data:image/svg+xml,\') center no-repeat',
} ),
menuPortal: ( style ) => {
const margin = 14;
const width = Math.min( document.body.clientWidth - 2 * margin, 300 );
const sl: unknown = isArray( style.left )
? style.left[ 0 ]
: style.left;
const styleLeft = numberify( sl );
const overflowX = Math.abs(
Math.min(
0,
document.body.clientWidth - ( styleLeft + width + 14 )
)
);
const left = styleLeft - overflowX;
return {
...style,
zIndex: '999999',
width,
left,
right: left + width - margin,
};
},
menu: ( style ) => ( {
...style,
borderRadius: 0,
} ),
option: ( style, state ) => ( {
...style,
...getOptionColor( state ),
padding: '0.5em 1em',
} ),
};
export function StylizedSelectControl< OptionType, IsMulti extends boolean >( {
className = '',
styles = {},
// eslint-disable-next-line @typescript-eslint/no-unused-vars
menuPortalTarget,
...props
}: SelectProps< OptionType, IsMulti > ): JSX.Element {
return (
);
}
// =======
// HELPERS
// =======
const getControlBorder = ( {
isDisabled,
isFocused,
}: Partial< {
isDisabled: boolean;
isFocused: boolean;
} > = {} ) => {
let color = COLORS.nabBorder;
if ( isFocused ) {
color = COLORS.wpComponentsColorAccent;
}
if ( isDisabled ) {
color = COLORS.nabBorderLighter;
}
return {
border: `1px solid ${ color }`,
borderRadius: '2px',
};
};
const getOptionColor = ( {
isSelected,
isFocused,
}: Partial< {
isSelected: boolean;
isFocused: boolean;
} > = {} ) => {
let color = COLORS.nabText;
let background = COLORS.nabBackgroundWhite;
if ( isSelected ) {
background = COLORS.nabBackgroundLightGrey;
}
if ( isFocused ) {
color = COLORS.nabBackgroundWhite;
background = COLORS.wpComponentsColorAccent;
}
return { background, color };
};
const numberify = ( x: unknown ): number => {
if ( 'number' === typeof x ) {
return x;
}
return 'string' === typeof x ? Number.parseInt( x ) || 0 : 0;
};