(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 ...props
}: ComponentPropsWithRef<typeof TextStyled>) => { }: ComponentPropsWithRef<typeof TextStyled>) => {
return ( return (
<TextStyled <TextStyled as="span" $theme="greyscale" $variation="text" {...props} />
as="span"
$theme="greyscale"
$variation="text"
{...props}
></TextStyled>
); );
}; };

View File

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

View File

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

View File

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

View File

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