All files / src/cascader Cascader.tsx

63.64% Statements 7/11
60% Branches 9/15
20% Functions 1/5
63.64% Lines 7/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93                          3x 3x                                       3x   3x 3x   3x                                                                                                       1x  
import React from "react";
import classNames from "classnames";
import { useDefaultValue } from "../form";
import { Popover } from "../popover";
import { Input } from "../input";
import { Icon } from "../icon";
import { useTranslation } from "../i18n";
import { CascaderProps } from "./CascaderProps";
import { CascaderBox, getOptions } from "./CascaderBox";
import { useDefault } from "../_util/use-default";
import { useConfig } from "../_util/config-context";
 
export function Cascader(props: CascaderProps) {
  const t = useTranslation();
  const { classPrefix } = useConfig();
  const {
    data,
    value,
    onChange,
    onLoad,
    disabled,
    changeOnSelect,
    className,
    style,
    placeholder = t.pleaseSelect,
    defaultOpen = false,
    open,
    onOpenChange = () => null,
    placement = "bottom-start",
    placementOffset = 5,
    closeOnScroll = true,
    escapeWithReference,
    overlayClassName,
    overlayStyle,
  } = useDefaultValue(props, []);
 
  const [isOpened, setIsOpened] = useDefault(open, defaultOpen, onOpenChange);
  const options = getOptions(data, value);
 
  return (
    <Popover
      trigger={disabled ? "empty" : "click"}
      visible={isOpened}
      onVisibleChange={setIsOpened}
      placement={placement || "bottom-start"}
      placementOffset={placementOffset}
      closeOnScroll={closeOnScroll}
      escapeWithReference={escapeWithReference}
      overlayClassName={overlayClassName}
      overlayStyle={overlayStyle}
      overlay={({ scheduleUpdate }) => {
        return (
          <CascaderBox
            data={data}
            value={value}
            onChange={onChange}
            onLoad={onLoad}
            onClose={() => setIsOpened(false)}
            changeOnSelect={changeOnSelect}
            scheduleUpdate={scheduleUpdate}
            classPrefix={classPrefix}
          />
        );
      }}
    >
      <div
        className={classNames(`${classPrefix}-cascader`, className)}
        style={style}
      >
        <div className={`${classPrefix}-cascader__input`}>
          <div className={`${classPrefix}-cascader__value`}>
            {options.map(
              ({ value, label } = { value: undefined, label: undefined }) => (
                <span key={value} className={`${classPrefix}-cascader__label`}>
                  {label || value}
                </span>
              )
            )}
          </div>
          <Input
            readonly
            autoComplete="off"
            placeholder={value.length ? "" : placeholder}
          />
        </div>
        <Icon type="arrowdown" />
      </div>
    </Popover>
  );
}
 
Cascader.defaultLabelAlign = "middle";