Skip to content

Commit

Permalink
Refactor(lib-components): restyling of dropdown button
Browse files Browse the repository at this point in the history
  • Loading branch information
emielvanseveren committed Dec 29, 2024
1 parent 9111973 commit c05ea96
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 53 deletions.
42 changes: 21 additions & 21 deletions packages/lib-components/src/components/actions/Button/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,20 @@ export const Default = styled.button<{
font-weight: 600;
white-space: nowrap;
color: ${({ theme, color }) => {
switch (color) {
case 'white':
return theme.colors.primary;
case 'background':
return theme.colors.text;
default:
return 'white';
}
}};
switch (color) {
case 'white':
return theme.colors.primary;
case 'background':
return theme.colors.text;
default:
return 'white';
}
}};
margin-left: ${({ icon, isLoading, iconPosition }): string =>
iconPosition === 'left' && (icon || isLoading) ? '10px' : '0px'};
iconPosition === 'left' && (icon || isLoading) ? '10px' : '0px'};
margin-right: ${({ icon, isLoading, iconPosition }): string =>
iconPosition === 'right' && (icon || isLoading) ? '10px' : '0px'};
iconPosition === 'right' && (icon || isLoading) ? '10px' : '0px'};
}
&:disabled {
Expand All @@ -62,15 +62,15 @@ export const Default = styled.button<{
display: ${({ icon, isLoading }): string => (icon || isLoading ? 'block' : 'none')};
cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')};
fill: ${({ theme, color }) => {
switch (color) {
case 'white':
return theme.colors.primary;
case 'background':
return theme.colors.text;
default:
return 'white';
}
}};
switch (color) {
case 'white':
return theme.colors.primary;
case 'background':
return theme.colors.text;
default:
return 'white';
}
}};
stroke: white;
}
Expand Down Expand Up @@ -103,7 +103,7 @@ export const Default = styled.button<{
}}
`;

export const Outline = styled(Default)<{ color: ButtonColor }>`
export const Outline = styled(Default) <{ color: ButtonColor }>`
background: transparent;
border: 0.1rem solid ${({ theme, color }): string => theme.colors[color]};
span {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { MdChevronRight as ArrowIcon } from 'react-icons/md';
import { ActionMenu } from '../../../components';
import { styled } from '../../../styled';
import { useFloating } from '@floating-ui/react';
import { shade } from 'polished';
import { ButtonColor } from '../Button/style';

const Arrow = styled(ArrowIcon)`
transform: rotate(90deg);
Expand All @@ -12,48 +14,44 @@ const Arrow = styled(ArrowIcon)`

const Wrapper = styled.div``;

const DropdownActionContainer = styled.div<{ isVisible: boolean }>`
const DropdownActionContainer = styled.div<{ color: ButtonColor }>`
font-weight: 500;
display: flex;
align-items: center;
padding: ${({ theme }) => `${theme.spacing['0_5']} 0`};
justify-content: center;
cursor: pointer;
width: 3.2rem;
border: .1rem solid ${({ theme, isVisible }) => (isVisible ? theme.colors.primary : theme.colors.backgroundAccent)}};
background: ${({ theme, color }) => shade(0.5, theme.colors[color])};
border: .1rem solid ${({ theme, color }) => theme.colors[color === 'background' ? 'backgroundAccent' : color]}};
border-top-right-radius: ${({ theme }) => theme.borderRadius.small}};
border-bottom-right-radius: ${({ theme }) => theme.borderRadius.small}};
&:hover {
border-color:${({ theme }) => theme.colors.primary};
svg {
fill: ${({ theme }) => theme.colors.primary};
}
svg {
fill: ${({ theme }) => theme.colors.text};
}
&:active {
background-color: transparent;
}
`;

const CurrentAction = styled.div`
const CurrentAction = styled.div<{ color: ButtonColor }>`
padding: ${({ theme }) => `${theme.spacing['0_5']} ${theme.spacing[1]}`};
font-weight: 500;
cursor: pointer;
min-width: 10rem;
height: 100%;
color: ${({ theme }) => theme.colors.text};
border-top: 0.1rem solid ${({ theme }) => theme.colors.backgroundAccent};
border-left: 0.1rem solid ${({ theme }) => theme.colors.backgroundAccent};
border-bottom: 0.1rem solid ${({ theme }) => theme.colors.backgroundAccent};
background: ${({ theme, color }) => shade(0.5, theme.colors[color])};
border-top: 0.1rem solid ${({ theme, color }) => theme.colors[color === 'background' ? 'backgroundAccent' : color]};
border-left: 0.1rem solid ${({ theme, color }) => theme.colors[color === 'background' ? 'backgroundAccent' : color]};
border-bottom: 0.1rem solid ${({ theme, color }) => theme.colors[color === 'background' ? 'backgroundAccent' : color]};
border-top-left-radius: ${({ theme }) => theme.borderRadius.small};
border-bottom-left-radius: ${({ theme }) => theme.borderRadius.small};
text-align: center;
&:hover {
color: ${({ theme }) => theme.colors.primary};
border-color: ${({ theme }) => theme.colors.primary};
}
&:active {
background-color: transparent;
}
Expand All @@ -65,44 +63,43 @@ const Container = styled.div`
flex-wrap: wrap;
border-radius: ${({ theme }) => theme.borderRadius.large};
width: max-content;
&:hover ${DropdownActionContainer} {
border-left-color: ${({ theme }) => theme.colors.primary};
}
`;

export interface DropdownButtonProps {
children: ReactElement[];
color?: ButtonColor;
}

export const DropdownButton: FC<DropdownButtonProps> = ({ children }) => {
const [visible, setVisible] = useState<boolean>(false);
export const DropdownButton: FC<DropdownButtonProps> = ({ children, color = 'primary' }) => {
const [listVisible, setListVisible] = useState<boolean>(false);
const [selected, setSelected] = useState<number>(0);
const { x, y, refs, strategy } = useFloating();

const parentRef = useRef<HTMLDivElement>(null);

useOutsideAlerter(parentRef, () => {
setVisible(false);
setListVisible(false);
});

useEffect(() => {
setVisible(false);
setListVisible(false);
}, [selected]);

const handleSelectedActionClicked = () => {
setVisible(false);
setListVisible(false);
children[selected].props.onClick();
};

return (
<Wrapper ref={parentRef}>
<Container ref={refs.setReference}>
<CurrentAction onClick={handleSelectedActionClicked}>{children[selected].props.text}</CurrentAction>
<DropdownActionContainer onClick={() => setVisible(!visible)} isVisible={visible}>
<CurrentAction color={color} onClick={handleSelectedActionClicked}>
{children[selected].props.text}
</CurrentAction>
<DropdownActionContainer color={color} onClick={() => setListVisible(!listVisible)}>
<Arrow size={20} />
</DropdownActionContainer>
{visible && (
{listVisible && (
<ActionMenu selectedState={[selected, setSelected]} attributes={{ x, y, strategy }} ref={refs.setFloating}>
{children}
</ActionMenu>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface ActionMenuProps {

export const ActionMenu = forwardRef<HTMLUListElement, ActionMenuProps>(function ActionMenu(
{ attributes, children, selectedState, elevation = 4 },
ref,
ref
) {
const [selected, setSelected] = selectedState;

Expand All @@ -31,7 +31,12 @@ export const ActionMenu = forwardRef<HTMLUListElement, ActionMenuProps>(function
ref={ref}
>
{Children.map(children, (child: ReactElement<ActionProps>, idx) => (
<Item onClick={() => setSelected(idx)}>
<Item
onClick={() => {
if (child.props.disabled) return;
setSelected(idx);
}}
>
{child}
{selected === idx ? (
<div style={{ display: 'flex', alignItems: 'center' }}>
Expand All @@ -49,8 +54,8 @@ export const ActionMenu = forwardRef<HTMLUListElement, ActionMenuProps>(function
interface ActionProps {
onClick: () => unknown;
text: string;
// TODO: implement disabled when needed
disabled?: boolean;
}
export const Action: FC<PropsWithChildren<ActionProps>> = ({ children }) => {
export const Action: FC<PropsWithChildren<ActionProps>> = ({ children, disabled = false }) => {

Check failure on line 59 in packages/lib-components/src/components/other/ActionMenu/index.tsx

View workflow job for this annotation

GitHub Actions / Run Prettier and Commit Changes

'disabled' is assigned a value but never used. Allowed unused args must match /^_/u

Check failure on line 59 in packages/lib-components/src/components/other/ActionMenu/index.tsx

View workflow job for this annotation

GitHub Actions / e2e

'disabled' is assigned a value but never used. Allowed unused args must match /^_/u

Check failure on line 59 in packages/lib-components/src/components/other/ActionMenu/index.tsx

View workflow job for this annotation

GitHub Actions / node-ci (20)

'disabled' is assigned a value but never used. Allowed unused args must match /^_/u
return <div>{children}</div>;
};

0 comments on commit c05ea96

Please sign in to comment.