import React, { useState } from 'react'; import { FloatingActionButton } from '../FloatingActionButton/FloatingActionButton'; import { PlusIcon, TimesIcon } from '../../icons'; // FIX: Stack and Text are not exported from core. They are imported separately. import { useStyles, useTheme } from '../../core'; import { useClickOutside } from '../../core/hooks/useInteractions'; import { Stack } from '../Stack/Stack'; import { Text } from '../Text/Text'; interface SpeedDialAction { icon: React.ElementType; label: string; onClick: () => void; } interface SpeedDialProps { actions: SpeedDialAction[]; position?: { bottom?: string; right?: string; top?: string; left?: string }; } export const SpeedDial: React.FC = ({ actions, position = { bottom: '2rem', right: '2rem' } }) => { const [isOpen, setIsOpen] = useState(false); const { theme } = useTheme(); const createStyle = useStyles('speed-dial'); const containerRef = useClickOutside(() => setIsOpen(false)); const containerClass = createStyle({ position: 'fixed', ...position, zIndex: 45, display: 'flex', flexDirection: 'column-reverse', alignItems: 'center', gap: '1rem', }); const actionClass = (index: number) => createStyle({ display: 'flex', alignItems: 'center', gap: '1rem', transition: `all 0.3s ease ${index * 0.05}s`, opacity: isOpen ? 1 : 0, transform: isOpen ? 'translateY(0)' : 'translateY(10px)', }); const labelClass = createStyle({ backgroundColor: theme.colors.backgroundSecondary, color: theme.colors.text, padding: '0.25rem 0.75rem', borderRadius: '4px', boxShadow: '0 2px 8px rgba(0,0,0,0.3)', whiteSpace: 'nowrap', }); return (
setIsOpen(!isOpen)} /> {actions.map((action, index) => (
{/* FIX: Use theme value for font size instead of shorthand string. */} {action.label}
{ action.onClick(); setIsOpen(false); }} size="small" // We use relative positioning here because the parent is fixed position={{ }} style={{ position: 'relative' }} />
))}
); };