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 (
+ }
+ onClick={onClick}
+ position={position}
+ size={size}
+ variant={variant}
+ />
+ );
})}
);
diff --git a/front/src/modules/ui/button/components/__stories__/FloatingIconButtonGroup.stories.tsx b/front/src/modules/ui/button/components/__stories__/FloatingIconButtonGroup.stories.tsx
index 485a828d1..55c7f757c 100644
--- a/front/src/modules/ui/button/components/__stories__/FloatingIconButtonGroup.stories.tsx
+++ b/front/src/modules/ui/button/components/__stories__/FloatingIconButtonGroup.stories.tsx
@@ -4,15 +4,22 @@ import { IconCheckbox, IconNotes, IconTimelineEvent } from '@/ui/icon';
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
-import {
- FloatingIconButton,
- FloatingIconButtonSize,
-} from '../FloatingIconButton';
+import { FloatingIconButtonSize } from '../FloatingIconButton';
import { FloatingIconButtonGroup } from '../FloatingIconButtonGroup';
const meta: Meta = {
title: 'UI/Button/FloatingIconButtonGroup',
component: FloatingIconButtonGroup,
+ args: {
+ iconButtons: [
+ { Icon: IconNotes },
+ { Icon: IconCheckbox },
+ { Icon: IconTimelineEvent },
+ ],
+ },
+ argTypes: {
+ iconButtons: { control: false },
+ },
};
export default meta;
@@ -21,29 +28,13 @@ type Story = StoryObj;
export const Default: Story = {
args: {
size: 'small',
- children: [
- } />,
- } />,
- } />,
- ],
- },
- argTypes: {
- children: { control: false },
},
decorators: [ComponentDecorator],
};
export const Catalog: Story = {
- args: {
- children: [
- } />,
- } />,
- } />,
- ],
- },
argTypes: {
size: { control: false },
- children: { control: false },
},
parameters: {
pseudo: { hover: ['.hover'], active: ['.pressed'], focus: ['.focus'] },
diff --git a/front/src/modules/ui/button/components/__stories__/IconButtonGroup.stories.tsx b/front/src/modules/ui/button/components/__stories__/IconButtonGroup.stories.tsx
index 0787b7bce..d163da2e4 100644
--- a/front/src/modules/ui/button/components/__stories__/IconButtonGroup.stories.tsx
+++ b/front/src/modules/ui/button/components/__stories__/IconButtonGroup.stories.tsx
@@ -4,7 +4,6 @@ import { IconCheckbox, IconNotes, IconTimelineEvent } from '@/ui/icon';
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
-import { Button } from '../Button';
import {
IconButtonAccent,
IconButtonSize,
@@ -15,6 +14,16 @@ import { IconButtonGroup } from '../IconButtonGroup';
const meta: Meta = {
title: 'UI/Button/IconButtonGroup',
component: IconButtonGroup,
+ args: {
+ iconButtons: [
+ { Icon: IconNotes },
+ { Icon: IconCheckbox },
+ { Icon: IconTimelineEvent },
+ ],
+ },
+ argTypes: {
+ iconButtons: { control: false },
+ },
};
export default meta;
@@ -25,31 +34,15 @@ export const Default: Story = {
size: 'small',
variant: 'primary',
accent: 'danger',
- children: [
- } />,
- } />,
- } />,
- ],
- },
- argTypes: {
- children: { control: false },
},
decorators: [ComponentDecorator],
};
export const Catalog: Story = {
- args: {
- children: [
- } />,
- } />,
- } />,
- ],
- },
argTypes: {
size: { control: false },
variant: { control: false },
accent: { control: false },
- children: { control: false },
},
parameters: {
catalog: {
diff --git a/front/src/modules/ui/menu-item/components/MenuItem.tsx b/front/src/modules/ui/menu-item/components/MenuItem.tsx
index 0ad2e593f..3ec1e9b26 100644
--- a/front/src/modules/ui/menu-item/components/MenuItem.tsx
+++ b/front/src/modules/ui/menu-item/components/MenuItem.tsx
@@ -1,7 +1,5 @@
-import { MouseEvent } from 'react';
-import { useTheme } from '@emotion/react';
+import type { MouseEvent } from 'react';
-import { FloatingIconButton } from '@/ui/button/components/FloatingIconButton';
import { FloatingIconButtonGroup } from '@/ui/button/components/FloatingIconButtonGroup';
import { IconComponent } from '@/ui/icon/types/IconComponent';
@@ -33,8 +31,6 @@ export function MenuItem({
testId,
onClick,
}: MenuItemProps) {
- const theme = useTheme();
-
const showIconButtons = Array.isArray(iconButtons) && iconButtons.length > 0;
return (
@@ -45,17 +41,7 @@ export function MenuItem({
accent={accent}
>
- {showIconButtons && (
-
- {iconButtons?.map(({ Icon, onClick }, index) => (
- }
- key={index}
- onClick={onClick}
- />
- ))}
-
- )}
+ {showIconButtons && }
);
}