2022-02-28 07:56:54 +00:00
|
|
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
2022-02-02 13:18:15 +00:00
|
|
|
import PropTypes from "prop-types";
|
|
|
|
|
|
|
|
import IconButton from "../../icon-button";
|
2022-02-07 15:49:08 +00:00
|
|
|
import Tooltip from "../../tooltip";
|
2022-02-21 20:30:42 +00:00
|
|
|
import { useClickOutside } from "../../utils/useClickOutside.js";
|
2022-02-02 13:18:15 +00:00
|
|
|
|
|
|
|
import { DeleteIcon, WarningIcon } from "../svg";
|
2022-03-02 09:55:32 +00:00
|
|
|
import {
|
|
|
|
MAX_EMAIL_LENGTH,
|
|
|
|
MAX_EMAIL_LENGTH_WITH_DOTS,
|
|
|
|
sliceEmail,
|
|
|
|
} from "./helpers";
|
2022-02-02 13:18:15 +00:00
|
|
|
|
2022-02-07 15:49:08 +00:00
|
|
|
import {
|
|
|
|
StyledChip,
|
|
|
|
StyledChipInput,
|
|
|
|
StyledChipValue,
|
2022-03-01 11:53:57 +00:00
|
|
|
StyledContainer,
|
2022-03-06 19:35:31 +00:00
|
|
|
} from "../styled-emailchips.js";
|
2022-02-02 13:18:15 +00:00
|
|
|
|
|
|
|
const Chip = (props) => {
|
|
|
|
const {
|
|
|
|
value,
|
2022-02-07 15:49:08 +00:00
|
|
|
currentChip,
|
2022-02-02 13:18:15 +00:00
|
|
|
isSelected,
|
|
|
|
isValid,
|
2022-02-21 20:30:42 +00:00
|
|
|
invalidEmailText,
|
2022-03-01 11:53:57 +00:00
|
|
|
chipOverLimitText,
|
2022-02-02 13:18:15 +00:00
|
|
|
onDelete,
|
|
|
|
onDoubleClick,
|
|
|
|
onSaveNewChip,
|
|
|
|
onClick,
|
|
|
|
} = props;
|
|
|
|
|
2022-03-06 19:35:31 +00:00
|
|
|
function initNewValue() {
|
|
|
|
return value?.email === value?.name || value?.name === ""
|
|
|
|
? value?.email
|
|
|
|
: `"${value?.name}" <${value?.email}>`;
|
|
|
|
}
|
|
|
|
|
|
|
|
const [newValue, setNewValue] = useState(initNewValue());
|
2022-02-17 11:37:44 +00:00
|
|
|
const [chipWidth, setChipWidth] = useState(0);
|
2022-03-01 11:53:57 +00:00
|
|
|
const [isChipOverLimit, setIsChipOverLimit] = useState(false);
|
2022-02-07 15:49:08 +00:00
|
|
|
|
|
|
|
const tooltipRef = useRef(null);
|
2022-02-15 07:42:37 +00:00
|
|
|
const warningRef = useRef(null);
|
2022-02-17 11:37:44 +00:00
|
|
|
const chipRef = useRef(null);
|
2022-02-25 11:42:31 +00:00
|
|
|
const chipInputRef = useRef(null);
|
2022-02-07 15:49:08 +00:00
|
|
|
|
2022-02-18 10:27:07 +00:00
|
|
|
useEffect(() => {
|
|
|
|
setChipWidth(chipRef.current?.clientWidth);
|
|
|
|
}, [chipRef]);
|
|
|
|
|
2022-02-25 11:42:31 +00:00
|
|
|
useEffect(() => {
|
|
|
|
if (isSelected) {
|
|
|
|
chipRef.current?.scrollIntoView({ block: "end" });
|
|
|
|
}
|
|
|
|
}, [isSelected]);
|
|
|
|
|
2022-03-02 09:55:32 +00:00
|
|
|
useEffect(() => {
|
|
|
|
if (newValue.length > MAX_EMAIL_LENGTH) {
|
|
|
|
setIsChipOverLimit(true);
|
|
|
|
} else {
|
|
|
|
setIsChipOverLimit(false);
|
|
|
|
}
|
|
|
|
}, [newValue]);
|
|
|
|
|
2022-02-15 07:42:37 +00:00
|
|
|
useClickOutside(warningRef, () => tooltipRef.current.hideTooltip());
|
2022-02-25 11:42:31 +00:00
|
|
|
useClickOutside(
|
|
|
|
chipInputRef,
|
|
|
|
() => {
|
|
|
|
onSaveNewChip(value, newValue);
|
|
|
|
},
|
|
|
|
newValue
|
|
|
|
);
|
2022-02-02 13:18:15 +00:00
|
|
|
|
|
|
|
const onChange = (e) => {
|
2022-03-02 09:55:32 +00:00
|
|
|
if (
|
|
|
|
e.target.value.length <= MAX_EMAIL_LENGTH_WITH_DOTS ||
|
|
|
|
e.target.value.length < newValue.length
|
|
|
|
) {
|
2022-03-01 11:53:57 +00:00
|
|
|
setNewValue(e.target.value);
|
2022-03-02 09:55:32 +00:00
|
|
|
}
|
2022-02-02 13:18:15 +00:00
|
|
|
};
|
|
|
|
|
2022-02-03 11:57:50 +00:00
|
|
|
const onClickHandler = (e) => {
|
|
|
|
if (e.shiftKey) {
|
|
|
|
document.getSelection().removeAllRanges();
|
|
|
|
}
|
2022-02-17 11:37:44 +00:00
|
|
|
onClick(value, e.shiftKey);
|
2022-02-02 13:18:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const onDoubleClickHandler = () => {
|
|
|
|
onDoubleClick(value);
|
|
|
|
};
|
|
|
|
|
|
|
|
const onIconClick = () => {
|
|
|
|
onDelete(value);
|
|
|
|
};
|
|
|
|
|
2022-02-28 07:56:54 +00:00
|
|
|
const onInputKeyDown = useCallback(
|
|
|
|
(e) => {
|
|
|
|
const code = e.code;
|
2022-02-02 13:18:15 +00:00
|
|
|
|
2022-02-28 07:56:54 +00:00
|
|
|
switch (code) {
|
|
|
|
case "Enter":
|
|
|
|
case "NumpadEnter": {
|
|
|
|
onSaveNewChip(value, newValue);
|
2022-03-06 19:35:31 +00:00
|
|
|
setNewValue(sliceEmail(newValue).email);
|
2022-02-28 07:56:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case "Escape": {
|
2022-03-06 19:35:31 +00:00
|
|
|
setNewValue(initNewValue());
|
2022-02-28 07:56:54 +00:00
|
|
|
onDoubleClick(null);
|
|
|
|
return false;
|
|
|
|
}
|
2022-02-02 13:18:15 +00:00
|
|
|
}
|
2022-02-28 07:56:54 +00:00
|
|
|
},
|
|
|
|
[newValue]
|
|
|
|
);
|
2022-03-06 19:35:31 +00:00
|
|
|
if (value?.email === currentChip?.email) {
|
2022-02-02 13:18:15 +00:00
|
|
|
return (
|
2022-03-01 11:53:57 +00:00
|
|
|
<StyledContainer>
|
|
|
|
{isChipOverLimit && (
|
|
|
|
<Tooltip getContent={() => {}} id="input" effect="float" />
|
|
|
|
)}
|
|
|
|
<StyledChipInput
|
|
|
|
data-for="input"
|
|
|
|
data-tip={chipOverLimitText}
|
|
|
|
value={newValue}
|
|
|
|
forwardedRef={chipInputRef}
|
|
|
|
onChange={onChange}
|
|
|
|
onKeyDown={onInputKeyDown}
|
|
|
|
isAutoFocussed
|
|
|
|
withBorder={false}
|
2022-03-02 09:55:32 +00:00
|
|
|
maxLength={MAX_EMAIL_LENGTH_WITH_DOTS}
|
2022-03-01 11:53:57 +00:00
|
|
|
flexvalue={
|
2022-03-06 19:35:31 +00:00
|
|
|
value?.name !== value?.email ? "0 1 auto" : `0 0 ${chipWidth}px`
|
2022-03-01 11:53:57 +00:00
|
|
|
}
|
|
|
|
/>
|
|
|
|
</StyledContainer>
|
2022-02-02 13:18:15 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<StyledChip
|
|
|
|
isSelected={isSelected}
|
|
|
|
onDoubleClick={onDoubleClickHandler}
|
|
|
|
onClick={onClickHandler}
|
2022-02-08 13:41:29 +00:00
|
|
|
isValid={isValid}
|
2022-02-17 11:37:44 +00:00
|
|
|
ref={chipRef}
|
2022-02-02 13:18:15 +00:00
|
|
|
>
|
|
|
|
{!isValid && (
|
2022-02-15 07:42:37 +00:00
|
|
|
<div className="warning_icon_wrap" ref={warningRef}>
|
2022-02-07 15:49:08 +00:00
|
|
|
<IconButton
|
|
|
|
iconName={WarningIcon}
|
|
|
|
size={12}
|
|
|
|
className="warning_icon_wrap warning_icon "
|
|
|
|
data-for="group"
|
2022-02-14 10:48:52 +00:00
|
|
|
data-tip={invalidEmailText}
|
2022-02-07 15:49:08 +00:00
|
|
|
/>
|
|
|
|
<Tooltip
|
|
|
|
getContent={() => {}}
|
|
|
|
id="group"
|
|
|
|
reference={tooltipRef}
|
2022-02-08 13:41:29 +00:00
|
|
|
place={"top"}
|
2022-02-07 15:49:08 +00:00
|
|
|
/>
|
|
|
|
</div>
|
2022-02-02 13:18:15 +00:00
|
|
|
)}
|
2022-03-06 19:35:31 +00:00
|
|
|
<StyledChipValue>{value?.name || value?.email}</StyledChipValue>
|
2022-02-02 13:18:15 +00:00
|
|
|
<IconButton iconName={DeleteIcon} size={12} onClick={onIconClick} />
|
|
|
|
</StyledChip>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
Chip.propTypes = {
|
2022-02-07 15:49:08 +00:00
|
|
|
value: PropTypes.object,
|
2022-02-08 13:41:29 +00:00
|
|
|
currentChip: PropTypes.object,
|
2022-02-07 15:49:08 +00:00
|
|
|
isSelected: PropTypes.bool,
|
|
|
|
isValid: PropTypes.bool,
|
2022-02-14 10:48:52 +00:00
|
|
|
invalidEmailText: PropTypes.string,
|
2022-03-01 11:53:57 +00:00
|
|
|
chipOverLimitText: PropTypes.string,
|
2022-02-02 13:18:15 +00:00
|
|
|
onClick: PropTypes.func,
|
|
|
|
onDoubleClick: PropTypes.func,
|
|
|
|
onDelete: PropTypes.func,
|
|
|
|
onSaveNewChip: PropTypes.func,
|
|
|
|
};
|
|
|
|
|
|
|
|
export default Chip;
|