✨(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:
41
src/frontend/apps/desk/src/components/BoxButton.tsx
Normal file
41
src/frontend/apps/desk/src/components/BoxButton.tsx
Normal 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 };
|
||||
@@ -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} />
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './Box';
|
||||
export * from './BoxButton';
|
||||
export * from './Card';
|
||||
export * from './DropButton';
|
||||
export * from './Link';
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user