/* eslint-disable no-nested-ternary */
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
import React, { useState, useRef } from 'react';

import { $TsFixMe, $TsFixMeFunc } from 'src/types/tsfix';
import styles from './Select.module.scss';
import { SelectContext, useSelectContext } from './selectContext';
import useOnClickOutside from '../../hooks/useOnClickOutside';
import LinearGradientContainer, {
  Color,
} from '../LinearGradientContainer/LinearGradientContainer';

const classNames = require('classnames');

type OptionSelectProps = {
  text: React.ReactNode;
  value: string;
  img?: React.ReactNode;
  bgrImg?: boolean;
};

export function OptionSelect({ text, img, bgrImg, value }: OptionSelectProps) {
  const { changeSelectedOption } = useSelectContext();
  return (
    <div
      className={styles.listItem}
      onClick={() => changeSelectedOption(value)}
    >
      {(bgrImg || img) && (
        <div
          className={styles.bgrImg}
          style={bgrImg ? { boxShadow: 'none', background: 'transparent' } : {}}
        >
          {img}
        </div>
      )}
      <div>{text || '-'}</div>
    </div>
  );
}

export type SelectOption = {
  text: string | JSX.Element;
  value: string;
  img?: React.ReactNode;
};

type SelectProps = {
  valueSelect: $TsFixMe;
  onChangeSelect: $TsFixMeFunc;
  children?: React.ReactNode;
  width?: string;
  disabled?: boolean;
  options?: SelectOption[];
  currentValue: React.ReactNode;
  color?: Color;
  title?: string;
  small?: boolean;
};

function Select({
  valueSelect,
  onChangeSelect,
  children,
  width,
  disabled,
  options,
  currentValue,
  small,
  color = Color.Yellow,
  title,
}: SelectProps) {
  const selectContainerRef = useRef(null);
  const [isOpen, setIsOpen] = useState(false);
  const toggling = () => {
    if (!disabled) {
      setIsOpen((item) => !item);
    }
  };

  const clickOutsideHandler = () => setIsOpen(false);

  const updateSelectedOption = (value: SelectOption['value']) => {
    if (value === currentValue?.value) {
      return;
    }

    onChangeSelect && onChangeSelect(value);
    setIsOpen(false);
  };

  useOnClickOutside(selectContainerRef, clickOutsideHandler);

  function renderTitle() {
    let value = currentValue;
    if (valueSelect !== undefined && options) {
      const item = options.find((item) => item.value === valueSelect);

      if (item) {
        value = (
          <>
            {item.img} {item.text}
          </>
        );
      }
    }

    return value;
  }

  return (
    <SelectContext.Provider
      // eslint-disable-next-line react/jsx-no-constructed-context-values
      value={{
        selectedOption: valueSelect,
        changeSelectedOption: updateSelectedOption,
      }}
    >
      <div
        style={{ width: width || '120px' }}
        className={classNames(styles.dropDown, { [styles.small]: small })}
        ref={selectContainerRef}
      >
        <div className={styles.dropDownContainer}>
          <button
            type="button"
            onClick={toggling}
            className={styles.dropDownContainerHeader}
          >
            <LinearGradientContainer
              active={isOpen}
              color={color}
              title={title}
            >
              <span className={styles.dropDownHeader}>{renderTitle()}</span>
            </LinearGradientContainer>
          </button>
          {isOpen && (
            <div className={styles.dropDownListContainer}>
              <div className={styles.dropDownList}>
                {/* {placeholder && (
                  <OptionSelect text={placeholder} value={null} />
                )} */}
                {options
                  ? options.map((option) => {
                      const { value, text, img } = option;
                      return (
                        <OptionSelect
                          key={value}
                          text={text}
                          value={value}
                          img={img}
                        />
                      );
                    })
                  : children}
              </div>

              <div
                className={classNames(
                  styles.ListContainer,
                  styles.dropDownBottomLine
                )}
              />
            </div>
          )}
        </div>
      </div>
    </SelectContext.Provider>
  );
}

export default Select;

Synonyms

cyb/src/index.tsx
pussy-ts/src/index.tsx
bostrom.network/src/pages/Index.tsx
pussy-landing/src/pages/index.tsx
pussy.meme/src/pages/index.tsx
pussy-ts/src/containers/txs/index.tsx
pussy-ts/src/containers/mint/index.tsx
cyb/src/containers/mint/index.tsx
pussy-ts/src/components/ButtonSwap/index.tsx
pussy-ts/src/components/denom/index.tsx
cyb/src/containers/Objects/index.tsx
cyb/src/components/btnGrd/index.tsx
cyb/src/components/actionBar/index.tsx
pussy-ts/src/components/BandwidthBar/index.tsx
cyb/src/components/Select/index.tsx
pussy-ts/src/containers/portal/index.tsx
pussy-ts/src/components/btnGrd/index.tsx
cyb/src/components/TextMarkdown/index.tsx
cyb/src/containers/energy/index.tsx
pussy-ts/src/components/MainContainer/index.tsx
pussy-ts/src/components/actionBar/index.tsx
cyb/src/containers/portal/index.tsx
cyb/src/components/ButtonSwap/index.tsx
cyb/src/containers/nebula/index.tsx
pussy-ts/src/components/DonutChart/index.tsx
cyb/src/components/DonutChart/index.tsx
pussy-ts/src/containers/nebula/index.tsx
cyb/src/components/BandwidthBar/index.tsx
pussy-ts/src/containers/energy/index.tsx
cyb/src/components/denom/index.tsx
cyb/src/containers/sigma/index.tsx
cyb/src/components/Input/index.tsx
pussy-ts/src/containers/sigma/index.tsx
pussy-ts/src/containers/taverna/index.tsx
pussy-ts/src/components/Input/index.tsx
cyb/src/containers/blok/index.tsx
cyb/src/components/PDF/index.tsx
cyb/src/containers/txs/index.tsx
cyb/src/containers/taverna/index.tsx
cyb/src/components/MainContainer/index.tsx
pussy-ts/src/components/TextMarkdown/index.tsx
pussy-ts/src/components/PDF/index.tsx
cyb/src/containers/portal/citizenship/index.tsx
pussy-landing/src/components/xp/btnGrd/index.tsx
cyb/src/containers/portal/pasport/index.tsx
pussy-landing/src/components/xp/stars/index.tsx
cyb/src/components/buttons/ButtonIcon/index.tsx
cyb/src/containers/wasm/codes/index.tsx
pussy-ts/src/features/ipfs/Drive/index.tsx
pussy-ts/src/containers/portal/gift/index.tsx
pussy-ts/src/features/ipfs/ipfsSettings/index.tsx
pussy-ts/src/components/buttons/ButtonIcon/index.tsx
pussy-ts/src/containers/portal/release/index.tsx
cyb/src/containers/portal/release/index.tsx
cyb/src/features/ipfs/Drive/index.tsx
pussy-ts/src/containers/portal/pasport/index.tsx
cyb/src/features/ipfs/ipfsSettings/index.tsx
pussy-ts/src/containers/portal/citizenship/index.tsx
cyb/src/containers/portal/gift/index.tsx
cyb/src/components/contentIpfs/component/gateway/index.tsx
pussy-ts/src/containers/portal/components/ReleaseStatus/index.tsx
pussy-ts/src/components/contentIpfs/component/gateway/index.tsx
pussy-ts/src/containers/sigma/components/CardPassport/index.tsx
cyb/src/containers/sigma/components/CardPassport/index.tsx
cyb/src/components/contentIpfs/component/img/index.tsx
pussy-ts/src/components/contentIpfs/component/img/index.tsx
cyb/src/containers/portal/components/ActionBar/index.tsx
pussy-ts/src/components/contentIpfs/component/link/index.tsx
cyb/src/containers/portal/components/ReleaseStatus/index.tsx
cyb/src/containers/portal/components/stars/index.tsx
pussy-ts/src/containers/portal/components/stars/index.tsx
cyb/src/components/contentIpfs/component/link/index.tsx
pussy-ts/src/containers/sigma/components/cardUi/TitleCard/index.tsx
cyb/src/containers/sigma/components/cardUi/TitleCard/index.tsx
cyb/src/containers/sigma/components/cardUi/RowBalancesDetails/index.tsx
pussy-ts/src/containers/sigma/components/cardUi/RowBalancesDetails/index.tsx

Neighbours