mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 74b91ee277 | |||
| 756cccf85c |
@@ -1,4 +1,4 @@
|
|||||||
import { forwardRef, LegacyRef, useImperativeHandle, useRef, useState } from "react";
|
import { forwardRef, LegacyRef, useEffect, useImperativeHandle, useRef, useState } from "react";
|
||||||
import { BsmIconType, BsmIcon } from "../svgs/bsm-icon.component";
|
import { BsmIconType, BsmIcon } from "../svgs/bsm-icon.component";
|
||||||
import { BsmButton, BsmButtonType } from "./bsm-button.component";
|
import { BsmButton, BsmButtonType } from "./bsm-button.component";
|
||||||
import { useTranslation } from "renderer/hooks/use-translation.hook";
|
import { useTranslation } from "renderer/hooks/use-translation.hook";
|
||||||
@@ -32,14 +32,25 @@ type Props = {
|
|||||||
children?: JSX.Element;
|
children?: JSX.Element;
|
||||||
text?: string;
|
text?: string;
|
||||||
textClassName?: string;
|
textClassName?: string;
|
||||||
|
maxVisibleItems?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const BsmDropdownButton = forwardRef(({ className, classNames, buttonColor, items, align, withBar = true, icon = "settings", buttonClassName, menuTranslationY, children, text, textClassName }: Props, fowardRed) => {
|
export const BsmDropdownButton = forwardRef(({ className, classNames, buttonColor, items, align, withBar = true, icon = "settings", buttonClassName, menuTranslationY, children, text, textClassName, maxVisibleItems }: Props, fowardRed) => {
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
const t = useTranslation();
|
const t = useTranslation();
|
||||||
const ref = useRef(fowardRed);
|
const ref = useRef(fowardRed);
|
||||||
useClickOutside(ref, () => setExpanded(false));
|
useClickOutside(ref, () => setExpanded(false));
|
||||||
|
|
||||||
|
const itemRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const [itemHeight, setItemHeight] = useState<number>();
|
||||||
|
const maxHeight = itemHeight && maxVisibleItems ? itemHeight * maxVisibleItems + 8 : undefined;
|
||||||
|
useEffect(() => {
|
||||||
|
if (itemRef.current) {
|
||||||
|
setItemHeight(itemRef.current.offsetHeight);
|
||||||
|
}
|
||||||
|
}, [items]);
|
||||||
|
|
||||||
useImperativeHandle(
|
useImperativeHandle(
|
||||||
fowardRed,
|
fowardRed,
|
||||||
() => ({
|
() => ({
|
||||||
@@ -73,13 +84,13 @@ export const BsmDropdownButton = forwardRef(({ className, classNames, buttonColo
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref as unknown as LegacyRef<HTMLDivElement>} className={cn(className, classNames?.mainContainer)}>
|
<div ref={ref as unknown as LegacyRef<HTMLDivElement>} className={cn(className, classNames?.mainContainer)} >
|
||||||
<BsmButton onClick={() => setExpanded(!expanded)} className={cn(buttonClassName ?? defaultButtonClassName, classNames?.button)} icon={icon} active={expanded} textClassName={textClassName} onClickOutside={handleClickOutside} withBar={withBar} text={text} typeColor={buttonColor} iconClassName={classNames?.iconClassName}/>
|
<BsmButton onClick={() => setExpanded(!expanded)} className={cn(buttonClassName ?? defaultButtonClassName, classNames?.button)} icon={icon} active={expanded} textClassName={textClassName} onClickOutside={handleClickOutside} withBar={withBar} text={text} typeColor={buttonColor} iconClassName={classNames?.iconClassName}/>
|
||||||
<div className={cn(`py-1 w-fit absolute cursor-pointer top-[calc(100%-4px)] rounded-md bg-inherit text-sm text-gray-800 dark:text-gray-200 shadow-md shadow-black transition-[scale] duration-150 ease-in-out ${alignClass}`, classNames?.itemsContainer)} style={{ scale: expanded ? "1" : "0", translate: `0 ${menuTranslationY}` }}>
|
<div className={cn(`py-1 w-fit absolute cursor-pointer top-[calc(100%-4px)] rounded-md bg-inherit text-sm text-gray-800 dark:text-gray-200 shadow-md shadow-black transition-[scale] duration-150 ease-in-out ${alignClass} overflow-y-auto scrollbar-thin `, classNames?.itemsContainer)} style={{ scale: expanded ? "1" : "0", translate: `0 ${menuTranslationY}`, maxHeight}}>
|
||||||
{items?.map(
|
{items?.map(
|
||||||
i =>
|
(i, index) =>
|
||||||
i && (
|
i && (
|
||||||
<div key={crypto.randomUUID()} onClick={() => { setExpanded(() => false); i.onClick?.()}} className="flex w-full px-3 py-2 hover:backdrop-brightness-150">
|
<div ref={index === 0 ? itemRef : undefined} key={crypto.randomUUID()} onClick={() => { setExpanded(() => false); i.onClick?.()}} className="flex w-full px-3 py-2 hover:backdrop-brightness-150">
|
||||||
{i.icon && <BsmIcon icon={i.icon} className="h-5 w-5 mr-1 text-inherit" />}
|
{i.icon && <BsmIcon icon={i.icon} className="h-5 w-5 mr-1 text-inherit" />}
|
||||||
<span className="w-max">{t(i.text)}</span>
|
<span className="w-max">{t(i.text)}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ export function useClickOutside(ref: MutableRefObject<any>, handler: ComponentPr
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("click", handleClickOutside);
|
document.addEventListener("mousedown", handleClickOutside);
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener("click", handleClickOutside);
|
document.removeEventListener("mousedown", handleClickOutside);
|
||||||
};
|
};
|
||||||
}, [ref]);
|
}, [ref]);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user