(app-desk) component BoxButton

We often need unstyled button to wrap around some content,
we were using Cunningham's button for this purpose,
but it is not the best choice as lot of style is applied
to their buttons.
This component is a simple wrapper around the button
element with all the Box functionalities. Usefull
for wrapping icons by example.
This commit is contained in:
Anthony LC
2024-03-06 11:28:27 +01:00
committed by Anthony LC
parent 7d65de1938
commit 8b014e289a
6 changed files with 74 additions and 71 deletions

View File

@@ -0,0 +1,41 @@
import { ComponentPropsWithRef, forwardRef } from 'react';
import { Box, BoxType } from './Box';
export type BoxButtonType = ComponentPropsWithRef<typeof BoxButton>;
/**
* Styleless button that extends the Box component.
* Good to wrap around SVGs or other elements that need to be clickable.
* @param props - @see BoxType props
* @param ref
* @see Box
* @example
* ```tsx
* <BoxButton $radius="100%" aria-label="My button" onClick={() => console.log('clicked')}>
* Click me
* </BoxButton>
* ```
*/
const BoxButton = forwardRef<HTMLDivElement, BoxType>(
({ $css, ...props }, ref) => {
return (
<Box
ref={ref}
as="button"
$background="none"
$css={`
cursor: pointer;
border: none;
outline: none;
transition: all 0.2s ease-in-out;
${$css || ''}
`}
{...props}
/>
);
},
);
BoxButton.displayName = 'BoxButton';
export { BoxButton };

View File

@@ -55,11 +55,6 @@ export const Text = ({
...props
}: ComponentPropsWithRef<typeof TextStyled>) => {
return (
<TextStyled
as="span"
$theme="greyscale"
$variation="text"
{...props}
></TextStyled>
<TextStyled as="span" $theme="greyscale" $variation="text" {...props} />
);
};

View File

@@ -1,4 +1,5 @@
export * from './Box';
export * from './BoxButton';
export * from './Card';
export * from './DropButton';
export * from './Link';

View File

@@ -1,10 +1,9 @@
import { Button } from '@openfun/cunningham-react';
import Image from 'next/image';
import React from 'react';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
import { Box, Text } from '@/components/';
import { Box, BoxButton, Text } from '@/components/';
import { LanguagePicker } from '../language/';
@@ -90,12 +89,9 @@ export const Header = () => {
alt={t(`Profile picture`)}
/>
</Box>
<Button
aria-label={t('Access to the cells menu')}
icon={<Image priority src={IconCells} alt={t('Cells icon')} />}
color="tertiary"
className="c__button-no-bg p-0 m-0"
/>
<BoxButton aria-label={t('Access to the cells menu')}>
<Image priority src={IconCells} alt={t('Cells icon')} />
</BoxButton>
</Box>
</Box>
</Box>

View File

@@ -1,9 +1,8 @@
import { Button } from '@openfun/cunningham-react';
import { usePathname } from 'next/navigation';
import React, { useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Box, StyledLink } from '@/components';
import { Box, BoxButton, StyledLink } from '@/components';
import { useCunninghamTheme } from '@/cunningham';
import { SVGComponent } from '@/types/components';
@@ -57,23 +56,15 @@ const MenuItem = ({ Icon, label, href }: MenuItemProps) => {
$background={background}
$radius="10px"
>
<Button
aria-label={t(`{{label}} button`, { label })}
icon={
<Box $color={color}>
<Icon
width="2.375rem"
aria-label={t(`{{label}} icon`, { label })}
style={{
transition: 'color 0.2s ease-in-out',
}}
/>
</Box>
}
color="tertiary"
className="c__button-no-bg p-0 m-0"
style={{ flexDirection: 'column', gap: '0' }}
/>
<BoxButton aria-label={t(`{{label}} button`, { label })} $color={color}>
<Icon
width="2.375rem"
aria-label={t(`{{label}} icon`, { label })}
style={{
transition: 'color 0.2s ease-in-out',
}}
/>
</BoxButton>
</Box>
{isTooltipOpen && (
<Tooltip

View File

@@ -1,33 +1,13 @@
import { Button } from '@openfun/cunningham-react';
import React, { CSSProperties } from 'react';
import React from 'react';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
import { Box, StyledLink } from '@/components';
import { Box, BoxButton, StyledLink } from '@/components';
import { useCunninghamTheme } from '@/cunningham';
import { TeamsOrdering } from '@/features/teams/api/';
import IconAdd from '@/features/teams/assets/icon-add.svg';
import IconSort from '@/features/teams/assets/icon-sort.svg';
import { useTeamStore } from '@/features/teams/store/useTeamsStore';
const ButtonSort = styled(Button)<{
$background: CSSProperties['background'];
$color: CSSProperties['color'];
}>`
&.c__button {
svg {
background-color: transparent;
transition: all 0.3s;
}
&.c__button--active svg {
background-color: ${({ $background }) => $background};
border-radius: 10rem;
color: ${({ $color }) => $color};
}
}
`;
export const PanelActions = () => {
const { t } = useTranslation();
const { changeOrdering, ordering } = useTeamStore();
@@ -47,27 +27,26 @@ export const PanelActions = () => {
}
`}
>
<ButtonSort
<BoxButton
aria-label={t('Sort the teams')}
icon={
<IconSort width={30} height={30} aria-label={t('Sort teams icon')} />
}
color="tertiary"
className="c__button-no-bg p-0 m-0"
onClick={changeOrdering}
active={ordering === TeamsOrdering.BY_CREATED_ON}
$background={colorsTokens()['primary-200']}
$radius="100%"
$background={
ordering === TeamsOrdering.BY_CREATED_ON
? colorsTokens()['primary-200']
: 'transparent'
}
$color={colorsTokens()['primary-600']}
/>
>
<IconSort width={30} height={30} aria-label={t('Sort teams icon')} />
</BoxButton>
<StyledLink href="/teams/create">
<Button
<BoxButton
aria-label={t('Add a team')}
icon={
<IconAdd width={30} height={30} aria-label={t('Add team icon')} />
}
color="tertiary"
className="c__button-no-bg p-0 m-0"
/>
$color={colorsTokens()['primary-600']}
>
<IconAdd width={30} height={30} aria-label={t('Add team icon')} />
</BoxButton>
</StyledLink>
</Box>
);