Enable Task creation (#688)

This commit is contained in:
Charles Bochet
2023-07-16 09:39:52 -07:00
committed by GitHub
parent 098cd038bd
commit 037628ab1d
126 changed files with 3032 additions and 253 deletions

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import styled from '@emotion/styled';
import { IconChevronDown } from '@/ui/icons/index';
@ -6,28 +6,55 @@ import { IconChevronDown } from '@/ui/icons/index';
type ButtonProps = React.ComponentProps<'button'>;
export type DropdownOptionType = {
key: string;
label: string;
icon: React.ReactNode;
};
type Props = {
type OwnProps = {
options: DropdownOptionType[];
selectedOptionKey?: string;
onSelection: (value: DropdownOptionType) => void;
} & ButtonProps;
const StyledButton = styled.button<ButtonProps>`
const StyledButton = styled.button<ButtonProps & { isOpen: boolean }>`
align-items: center;
background: ${({ theme }) => theme.background.tertiary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-bottom-left-radius: ${({ isOpen, theme }) =>
isOpen ? 0 : theme.border.radius.sm};
border-bottom-right-radius: ${({ isOpen, theme }) =>
isOpen ? 0 : theme.border.radius.sm};
border-top-left-radius: ${({ theme }) => theme.border.radius.sm};
border-top-right-radius: ${({ theme }) => theme.border.radius.sm};
color: ${({ theme }) => theme.font.color.secondary};
cursor: pointer;
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(1)} ${({ theme }) => theme.spacing(2)};
svg {
align-items: center;
display: flex;
height: 14px;
justify-content: center;
width: 14px;
}
`;
const StyledDropdownItem = styled.button<ButtonProps>`
align-items: center;
background: ${({ theme }) => theme.background.tertiary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
color: ${({ theme }) => theme.font.color.secondary};
cursor: pointer;
display: flex;
font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.medium};
gap: 8px;
height: 24px;
line-height: ${({ theme }) => theme.text.lineHeight.lg};
padding: 3px 8px;
gap: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(1)} ${({ theme }) => theme.spacing(2)};
svg {
align-items: center;
@ -45,17 +72,29 @@ const DropdownContainer = styled.div`
const DropdownMenu = styled.div`
display: flex;
flex-direction: column;
margin-top: -2px;
position: absolute;
width: 100%;
`;
export function DropdownButton({
options,
selectedOptionKey,
onSelection,
...buttonProps
}: Props) {
}: OwnProps) {
const [isOpen, setIsOpen] = useState(false);
const [selectedOption, setSelectedOption] = useState(options[0]);
const [selectedOption, setSelectedOption] = useState<
DropdownOptionType | undefined
>(undefined);
useEffect(() => {
if (selectedOptionKey) {
const option = options.find((option) => option.key === selectedOptionKey);
setSelectedOption(option);
} else {
setSelectedOption(options[0]);
}
}, [selectedOptionKey, options]);
if (!options.length) {
throw new Error('You must provide at least one option.');
@ -71,24 +110,35 @@ export function DropdownButton({
};
return (
<DropdownContainer>
<StyledButton onClick={() => setIsOpen(!isOpen)} {...buttonProps}>
{selectedOption.icon}
{selectedOption.label}
{options.length > 1 && <IconChevronDown />}
</StyledButton>
{isOpen && (
<DropdownMenu>
{options
.filter((option) => option.label !== selectedOption.label)
.map((option, index) => (
<StyledButton key={index} onClick={handleSelect(option)}>
{option.icon}
{option.label}
</StyledButton>
))}
</DropdownMenu>
<>
{selectedOption && (
<DropdownContainer>
<StyledButton
onClick={() => setIsOpen(!isOpen)}
{...buttonProps}
isOpen={isOpen}
>
{selectedOption.icon}
{selectedOption.label}
{options.length > 1 && <IconChevronDown />}
</StyledButton>
{isOpen && (
<DropdownMenu>
{options
.filter((option) => option.label !== selectedOption.label)
.map((option, index) => (
<StyledDropdownItem
key={index}
onClick={handleSelect(option)}
>
{option.icon}
{option.label}
</StyledDropdownItem>
))}
</DropdownMenu>
)}
</DropdownContainer>
)}
</DropdownContainer>
</>
);
}

View File

@ -5,7 +5,7 @@ const StyledPropertyBoxItem = styled.div`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
height: 32px;
padding: ${({ theme }) => theme.spacing(1)};
`;
const StyledIconContainer = styled.div`

View File

@ -1,7 +1,5 @@
import styled from '@emotion/styled';
import { Button } from '@/ui/components/buttons/Button';
import { RightDrawerTopBarCloseButton } from './RightDrawerTopBarCloseButton';
const StyledRightDrawerTopBar = styled.div`
@ -18,26 +16,14 @@ const StyledRightDrawerTopBar = styled.div`
padding-right: 8px;
`;
const StyledTopBarTitle = styled.div`
align-items: center;
font-weight: ${({ theme }) => theme.font.weight.medium};
margin-right: ${({ theme }) => theme.spacing(1)};
`;
type OwnProps = {
title?: string | null | undefined;
onSave?: () => void;
};
export function RightDrawerTopBar({ title, onSave }: OwnProps) {
function handleOnClick() {
onSave?.();
}
export function RightDrawerTopBar({ title }: OwnProps) {
return (
<StyledRightDrawerTopBar>
<RightDrawerTopBarCloseButton />
<StyledTopBarTitle>{title}</StyledTopBarTitle>
{onSave ? <Button title="Save" onClick={handleOnClick} /> : <div></div>}
</StyledRightDrawerTopBar>
);
}