summaryrefslogtreecommitdiff
path: root/src/components/toolbar/ToolbarItem.tsx
diff options
context:
space:
mode:
authorElizabeth Hunt <me@liz.coffee>2025-10-05 16:42:02 -0700
committerElizabeth Hunt <me@liz.coffee>2025-10-05 23:11:41 -0700
commitde43eb05d2e43ab31effce3dcca62ad91a556b26 (patch)
tree47a62b61bfc97dda639dea70627ecf3005ba7b02 /src/components/toolbar/ToolbarItem.tsx
parent35add63ec4dce39710095f17abd86777de9e5b49 (diff)
downloadansicolor-de43eb05d2e43ab31effce3dcca62ad91a556b26.tar.gz
ansicolor-de43eb05d2e43ab31effce3dcca62ad91a556b26.zip
Diffstat (limited to 'src/components/toolbar/ToolbarItem.tsx')
-rw-r--r--src/components/toolbar/ToolbarItem.tsx57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/components/toolbar/ToolbarItem.tsx b/src/components/toolbar/ToolbarItem.tsx
new file mode 100644
index 0000000..76bd615
--- /dev/null
+++ b/src/components/toolbar/ToolbarItem.tsx
@@ -0,0 +1,57 @@
+import React, { useState } from 'react';
+
+export interface ToolbarItemProps {
+ children: React.ReactNode;
+ renderContent?: (onClose: () => void) => React.ReactNode;
+ onClick?: () => void;
+ disabled?: boolean;
+}
+
+export const ToolbarItem: React.FC<ToolbarItemProps> = ({
+ children,
+ renderContent,
+ onClick,
+ disabled = false,
+}) => {
+ const [isOpen, setIsOpen] = useState(false);
+ const [isFading, setIsFading] = useState(false);
+
+ const handleClose = () => {
+ setIsFading(true);
+ setTimeout(() => {
+ setIsOpen(false);
+ setIsFading(false);
+ }, 200);
+ };
+
+ const handleToggle = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ if (disabled) return;
+
+ if (renderContent) {
+ if (isOpen) {
+ handleClose();
+ } else {
+ setIsOpen(true);
+ }
+ }
+
+ onClick?.();
+ };
+
+ return (
+ <div className={`toolbar-item ${disabled ? 'disabled' : ''}`} onClick={handleToggle}>
+ <div className='toolbar-item-content'>
+ {children}
+ </div>
+ {renderContent && isOpen && !disabled && (
+ <div
+ className={`toolbar-item-content-panel ${isFading ? 'fading' : ''}`}
+ onClick={(e) => e.stopPropagation()}
+ >
+ {renderContent(handleClose)}
+ </div>
+ )}
+ </div>
+ );
+};