diff --git a/front/src/modules/ui/button/components/FloatingIconButton.tsx b/front/src/modules/ui/button/components/FloatingIconButton.tsx index bb0db1879..74a299f4f 100644 --- a/front/src/modules/ui/button/components/FloatingIconButton.tsx +++ b/front/src/modules/ui/button/components/FloatingIconButton.tsx @@ -68,17 +68,24 @@ const StyledButton = styled.button< font-family: ${({ theme }) => theme.font.family}; font-weight: ${({ theme }) => theme.font.weight.regular}; gap: ${({ theme }) => theme.spacing(1)}; - height: ${({ size }) => (size === 'small' ? '24px' : '32px')}; justify-content: center; padding: 0; position: relative; transition: background 0.1s ease; white-space: nowrap; - width: ${({ size }) => (size === 'small' ? '24px' : '32px')}; + ${({ position, size }) => { + const sizeInPx = + (size === 'small' ? 24 : 32) - (position === 'standalone' ? 0 : 4); - &:hover .floating-icon-button-hovered { - display: flex; + return ` + height: ${sizeInPx}px; + width: ${sizeInPx}px; + `; + }} + + &:hover { + background: ${({ theme }) => theme.background.transparent.lighter}; } &:active { @@ -91,18 +98,6 @@ const StyledButton = styled.button< } `; -const StyledHover = styled.div` - background: ${({ theme }) => theme.background.transparent.lighter}; - border-radius: calc(${({ theme }) => theme.border.radius.sm} - 2px); - bottom: 2px; - box-sizing: border-box; - display: none; - left: 2px; - position: absolute; - right: 2px; - top: 2px; -`; - export function FloatingIconButton({ className, icon: initialIcon, @@ -135,7 +130,6 @@ export function FloatingIconButton({ position={position} onClick={onClick} > - {!disabled && } {icon} ); diff --git a/front/src/modules/ui/button/components/FloatingIconButtonGroup.tsx b/front/src/modules/ui/button/components/FloatingIconButtonGroup.tsx index f2b8a6a3d..e5206543b 100644 --- a/front/src/modules/ui/button/components/FloatingIconButtonGroup.tsx +++ b/front/src/modules/ui/button/components/FloatingIconButtonGroup.tsx @@ -1,59 +1,61 @@ -import React from 'react'; +import type { MouseEvent } from 'react'; +import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; +import type { IconComponent } from '@/ui/icon/types/IconComponent'; + import { + FloatingIconButton, FloatingIconButtonPosition, - FloatingIconButtonProps, + type FloatingIconButtonProps, } from './FloatingIconButton'; const StyledFloatingIconButtonGroupContainer = styled.div` backdrop-filter: blur(20px); - border-radius: ${({ theme }) => theme.border.radius.md}; + border-radius: ${({ theme }) => theme.border.radius.sm}; box-shadow: ${({ theme }) => `0px 2px 4px 0px ${theme.background.transparent.light}, 0px 0px 4px 0px ${theme.background.transparent.medium}`}; display: flex; + gap: 2px; + padding: 2px; `; export type FloatingIconButtonGroupProps = Pick< FloatingIconButtonProps, - 'size' | 'className' + 'className' | 'size' > & { - children: React.ReactNode[]; + iconButtons: { + Icon: IconComponent; + onClick?: (event: MouseEvent) => void; + }[]; }; export function FloatingIconButtonGroup({ - children, + iconButtons, size, }: FloatingIconButtonGroupProps) { + const theme = useTheme(); + return ( - {React.Children.map(children, (child, index) => { - let position: FloatingIconButtonPosition; + {iconButtons.map(({ Icon, onClick }, index) => { + const position: FloatingIconButtonPosition = + index === 0 + ? 'left' + : index === iconButtons.length - 1 + ? 'right' + : 'middle'; - if (index === 0) { - position = 'left'; - } else if (index === children.length - 1) { - position = 'right'; - } else { - position = 'middle'; - } - - const additionalProps: any = { - position, - size, - applyShadow: false, - applyBlur: false, - }; - - if (size) { - additionalProps.size = size; - } - - if (!React.isValidElement(child)) { - return null; - } - - return React.cloneElement(child, additionalProps); + return ( + } + onClick={onClick} + position={position} + size={size} + /> + ); })} ); diff --git a/front/src/modules/ui/button/components/IconButtonGroup.tsx b/front/src/modules/ui/button/components/IconButtonGroup.tsx index 8624d4633..0b31439f3 100644 --- a/front/src/modules/ui/button/components/IconButtonGroup.tsx +++ b/front/src/modules/ui/button/components/IconButtonGroup.tsx @@ -1,7 +1,11 @@ -import React from 'react'; +import type { MouseEvent } from 'react'; +import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { IconButtonPosition, IconButtonProps } from './IconButton'; +import type { IconComponent } from '@/ui/icon/types/IconComponent'; + +import { Button } from './Button'; +import { IconButtonPosition, type IconButtonProps } from './IconButton'; const StyledIconButtonGroupContainer = styled.div` border-radius: ${({ theme }) => theme.border.radius.md}; @@ -10,45 +14,42 @@ const StyledIconButtonGroupContainer = styled.div` export type IconButtonGroupProps = Pick< IconButtonProps, - 'variant' | 'size' | 'accent' + 'accent' | 'size' | 'variant' > & { - children: React.ReactElement[]; + iconButtons: { + Icon: IconComponent; + onClick?: (event: MouseEvent) => void; + }[]; }; export function IconButtonGroup({ - children, - variant, - size, accent, + iconButtons, + size, + variant, }: IconButtonGroupProps) { + const theme = useTheme(); + return ( - {React.Children.map(children, (child, index) => { - let position: IconButtonPosition; + {iconButtons.map(({ Icon, onClick }, index) => { + const position: IconButtonPosition = + index === 0 + ? 'left' + : index === iconButtons.length - 1 + ? 'right' + : 'middle'; - if (index === 0) { - position = 'left'; - } else if (index === children.length - 1) { - position = 'right'; - } else { - position = 'middle'; - } - - const additionalProps: any = { position }; - - if (variant) { - additionalProps.variant = variant; - } - - if (accent) { - additionalProps.accent = accent; - } - - if (size) { - additionalProps.size = size; - } - - return React.cloneElement(child, additionalProps); + return ( +