arch: move web folder into api & move api to top level

This commit is contained in:
Jordan Knott
2020-07-04 18:08:37 -05:00
parent eaffaa70df
commit e5d5e6da01
354 changed files with 20 additions and 1557 deletions

View File

@ -0,0 +1,19 @@
import React from 'react';
import { action } from '@storybook/addon-actions';
import AddList from '.';
export default {
component: AddList,
title: 'AddList',
parameters: {
backgrounds: [
{ name: 'gray', value: '#262c49', default: true },
{ name: 'white', value: '#ffffff' },
],
},
};
export const Default = () => {
return <AddList onSave={action('on save')} />;
};

View File

@ -0,0 +1,113 @@
import styled, { css } from 'styled-components';
import TextareaAutosize from 'react-autosize-textarea/lib';
import { mixin } from 'shared/utils/styles';
import Button from 'shared/components/Button';
export const Container = styled.div`
width: 272px;
margin: 0 4px;
height: 100%;
box-sizing: border-box;
display: inline-block;
vertical-align: top;
white-space: nowrap;
`;
export const Wrapper = styled.div<{ editorOpen: boolean }>`
display: inline-block;
background-color: hsla(0, 0%, 100%, 0.24);
cursor: pointer;
border-radius: 3px;
height: auto;
min-height: 32px;
padding: 4px;
transition: background 85ms ease-in, opacity 40ms ease-in, border-color 85ms ease-in;
width: 272px;
margin: 0 4px;
margin-right: 8px;
${props =>
!props.editorOpen &&
css`
&:hover {
background-color: hsla(0, 0%, 100%, 0.32);
}
`}
${props =>
props.editorOpen &&
css`
background-color: #10163a;
border-radius: 3px;
height: auto;
min-height: 32px;
padding: 8px;
transition: background 85ms ease-in, opacity 40ms ease-in, border-color 85ms ease-in;
`}
`;
export const AddListButton = styled(Button)`
padding: 6px 12px;
`;
export const Placeholder = styled.span`
color: #c2c6dc;
display: flex;
align-items: center;
padding: 6px 8px;
transition: color 85ms ease-in;
`;
export const AddIconWrapper = styled.div`
color: #fff;
margin-right: 6px;
`;
export const ListNameEditorWrapper = styled.div`
display: flex;
`;
export const ListNameEditor = styled(TextareaAutosize)`
background-color: ${props => mixin.lighten('#262c49', 0.05)};
border: none;
box-shadow: inset 0 0 0 2px #0079bf;
transition: margin 85ms ease-in, background 85ms ease-in;
line-height: 20px;
padding: 8px 12px;
font-family: 'Droid Sans';
overflow: hidden;
overflow-wrap: break-word;
resize: none;
height: 54px;
width: 100%;
border: none;
border-radius: 3px;
box-shadow: none;
margin-bottom: 4px;
max-height: 162px;
min-height: 54px;
font-size: 14px;
line-height: 20px;
color: #c2c6dc;
l &:focus {
background-color: ${props => mixin.lighten('#262c49', 0.05)};
}
`;
export const ListAddControls = styled.div`
height: 32px;
transition: margin 85ms ease-in, height 85ms ease-in;
overflow: hidden;
margin: 4px 0 0;
`;
export const CancelAdd = styled.div`
display: flex;
align-items: center;
justify-content: center;
height: 32px;
width: 32px;
cursor: pointer;
`;

View File

@ -0,0 +1,111 @@
import React, { useState, useRef, useEffect } from 'react';
import { Plus, Cross } from 'shared/icons';
import useOnOutsideClick from 'shared/hooks/onOutsideClick';
import Button from 'shared/components/Button';
import {
Container,
Wrapper,
Placeholder,
AddIconWrapper,
AddListButton,
ListNameEditor,
ListAddControls,
CancelAdd,
ListNameEditorWrapper,
} from './Styles';
type NameEditorProps = {
onSave: (listName: string) => void;
onCancel: () => void;
};
const NameEditor: React.FC<NameEditorProps> = ({ onSave, onCancel }) => {
const $editorRef = useRef<HTMLTextAreaElement>(null);
const [listName, setListName] = useState('');
useEffect(() => {
if ($editorRef && $editorRef.current) {
$editorRef.current.focus();
}
});
const onKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
e.preventDefault();
onSave(listName);
setListName('');
if ($editorRef && $editorRef.current) {
$editorRef.current.focus();
}
}
};
return (
<>
<ListNameEditorWrapper>
<ListNameEditor
ref={$editorRef}
onKeyDown={onKeyDown}
value={listName}
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => setListName(e.currentTarget.value)}
placeholder="Enter a title for this list..."
/>
</ListNameEditorWrapper>
<ListAddControls>
<AddListButton
variant="relief"
onClick={() => {
onSave(listName);
setListName('');
if ($editorRef && $editorRef.current) {
$editorRef.current.focus();
}
}}
>
Save
</AddListButton>
<CancelAdd onClick={() => onCancel()}>
<Cross width={16} height={16} />
</CancelAdd>
</ListAddControls>
</>
);
};
type AddListProps = {
onSave: (listName: string) => void;
};
const AddList: React.FC<AddListProps> = ({ onSave }) => {
const [editorOpen, setEditorOpen] = useState(false);
const $wrapperRef = useRef<HTMLDivElement>(null);
const onOutsideClick = () => {
setEditorOpen(false);
};
useOnOutsideClick($wrapperRef, editorOpen, onOutsideClick, null);
return (
<Container>
<Wrapper
ref={$wrapperRef}
editorOpen={editorOpen}
onClick={() => {
if (!editorOpen) {
setEditorOpen(true);
}
}}
>
{editorOpen ? (
<NameEditor onCancel={() => setEditorOpen(false)} onSave={onSave} />
) : (
<Placeholder>
<AddIconWrapper>
<Plus size={12} color="#c2c6dc" />
</AddIconWrapper>
Add another list
</Placeholder>
)}
</Wrapper>
</Container>
);
};
export default AddList;