memos/web/src/components/kit/Selector.tsx
Ajay Kumbhare 1780225da5
feat: add typeScript support to enforce valid translation keys (#1954)
* #1952 Fix incorrect localization key for sign-up failure message

* feat: add typeScript support to enforce valid translation keys

* feat: add typeScript support to enforce valid translation keys

* fix lint errors

* fix lint error
2023-07-15 10:27:37 +08:00

114 lines
3.0 KiB
TypeScript

import { Tooltip } from "@mui/joy";
import { memo, useEffect, useRef } from "react";
import { useTranslate } from "@/utils/i18n";
import useToggle from "@/hooks/useToggle";
import Icon from "../Icon";
import "@/less/common/selector.less";
interface SelectorItem {
text: string;
value: string;
}
interface Props {
className?: string;
value: string;
dataSource: SelectorItem[];
handleValueChanged?: (value: string) => void;
disabled?: boolean;
tooltipTitle?: string;
}
const nullItem = {
text: "common.select" as const,
value: "",
};
const Selector: React.FC<Props> = (props: Props) => {
const { className, dataSource, handleValueChanged, value, disabled, tooltipTitle } = props;
const t = useTranslate();
const [showSelector, toggleSelectorStatus] = useToggle(false);
const selectorElRef = useRef<HTMLDivElement>(null);
let currentItem = { text: t(nullItem.text), value: nullItem.value };
for (const d of dataSource) {
if (d.value === value) {
currentItem = d;
break;
}
}
useEffect(() => {
if (showSelector) {
const handleClickOutside = (event: MouseEvent) => {
if (!selectorElRef.current?.contains(event.target as Node)) {
toggleSelectorStatus(false);
}
};
window.addEventListener("click", handleClickOutside, {
capture: true,
once: true,
});
}
}, [showSelector]);
const handleItemClick = (item: SelectorItem) => {
if (handleValueChanged) {
handleValueChanged(item.value);
}
toggleSelectorStatus(false);
};
const handleCurrentValueClick = (event: React.MouseEvent) => {
if (disabled) return;
event.stopPropagation();
toggleSelectorStatus();
};
return (
<Tooltip title={tooltipTitle} hidden={!disabled}>
<div className={`selector-wrapper ${className ?? ""} `} ref={selectorElRef}>
<div
className={`current-value-container ${showSelector ? "active" : ""} ${disabled && "selector-disabled"}`}
onClick={handleCurrentValueClick}
>
{disabled && (
<span className="lock-text">
<Icon.Lock className="icon-img" />
</span>
)}
<span className="value-text">{currentItem.text}</span>
{!disabled && (
<span className="arrow-text">
<Icon.ChevronDown className="icon-img" />
</span>
)}
</div>
<div className={`items-wrapper ${showSelector ? "" : "!hidden"}`}>
{dataSource.length > 0 ? (
dataSource.map((d) => {
return (
<div
className={`item-container ${d.value === value ? "selected" : ""}`}
key={d.value}
onClick={() => {
handleItemClick(d);
}}
>
{d.text}
</div>
);
})
) : (
<p className="tip-text">{t("common.null")}</p>
)}
</div>
</div>
</Tooltip>
);
};
export default memo(Selector);