feat: UI create explore view skeleton (#197)

* wip: added header for explore view

* chore: add skeleton for explore view

* chore: add dropdown variation

* style: align dropdown list
This commit is contained in:
Camila Sosa Morales 2023-03-31 12:33:30 -03:00 committed by GitHub
parent f74c8bb569
commit c10c59ae24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 249 additions and 29 deletions

View File

@ -1,7 +1,6 @@
import { HashRouter, Route, Routes, Navigate } from 'react-router-dom';
import { themeGlobals } from '@/theme/globals';
import { ComponentsTest, CreateAP, Home, Mint } from './views';
import { MintTest } from './views/mint-test';
import { ComponentsTest, Home, Mint, Explore, CreateAP } from './views';
import { AppPage, ToastProvider } from './components';
export const App = () => {
@ -13,12 +12,12 @@ export const App = () => {
<AppPage>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/explore" element={<Explore />} />
<Route path="/mint" element={<Mint />} />
<Route path="/create-ap" element={<CreateAP />} />
<Route path="/create-ap/:id" element={<CreateAP />} />
{/** TODO remove for release */}
<Route path="/components-test" element={<ComponentsTest />} />
<Route path="/mint-test" element={<MintTest />} />
<Route path="*" element={<Navigate to="/" />} />
</Routes>
</AppPage>

View File

@ -46,63 +46,132 @@ const DropdownOption = ({ option }: DropdownOptionProps) => (
);
type DropdownButtonProps = {
/**
* The selected value of the dropdown.
*/
selectedValue: DropdownItem | undefined;
/**
* If it's true, the list of options will be displayed
*/
open: boolean;
/**
* Background color of the dropdown. Should be on tailwind palette.
*/
backgroundColor?: string;
/**
* Text color of the dropdown. Should be on tailwind palette.
*/
textColor?: string;
};
const DropdownButton = ({ selectedValue, open }: DropdownButtonProps) => (
<Listbox.Button
className={`relative w-full cursor-default border-solid border border-slate7 py-3 pl-3.5 pr-10 h-11 text-left focus:outline-none sm:text-sm ${
open
? 'border-b-0 rounded-t-xl bg-black border-slate6'
: 'rounded-xl bg-transparent'
}`}
>
<span
className={`block truncate ${
selectedValue && selectedValue.label ? 'text-slate12' : 'text-slate11'
} break-words`}
const DropdownButton = ({
selectedValue,
open, //TODO maybe would be deprecated
backgroundColor,
textColor,
}: DropdownButtonProps) => {
const textColorCss = textColor ? `text-${textColor}` : 'text-slate12';
const borderColor = backgroundColor
? `border-${backgroundColor}`
: 'border-slate7';
const backgroundColorClass = backgroundColor
? `bg-${backgroundColor}`
: 'bg-transparent';
return (
<Listbox.Button
className={`relative w-full cursor-default ${borderColor} border-solid border rounded-xl py-3 pl-3.5 pr-10 h-11 text-left focus:outline-none sm:text-sm
${backgroundColorClass}
`}
>
{selectedValue && selectedValue.label ? selectedValue.label : 'Select'}
</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-4">
<Icon name="chevron-down" />
</span>
</Listbox.Button>
);
<span
className={`block truncate ${
selectedValue && selectedValue.label
? `${textColorCss}`
: 'text-slate11'
} break-words`}
>
{selectedValue && selectedValue.label ? selectedValue.label : 'Select'}
</span>
<span
className={`pointer-events-none absolute inset-y-0 right-0 flex items-center pr-4 ${textColorCss}`}
>
<Icon name="chevron-down" />
</span>
</Listbox.Button>
);
};
export type DropdownItem = {
/**
* The key of the item.
*/
value: string;
/**
* The label to display of the item.
*/
label: string;
};
export type DropdownProps = {
/**
* List of items to be displayed in the dropdown.
*/
items: DropdownItem[];
/**
* The selected value of the dropdown.
*/
selectedValue: DropdownItem | undefined;
/**
* Callback when the selected value changes.
*/
onChange(option: DropdownItem): void;
/**
* Background color of the dropdown. Should be on tailwind palette. https://tailwindcss.com/docs/background-color
*/
backgroundColor?: string;
/**
* Text color of the dropdown. Should be on tailwind palette. https://tailwindcss.com/docs/text-color
*/
textColor?: string;
/**
* Width of the options list. Should be on tailwind width. https://tailwindcss.com/docs/width
*/
optionsWidth?: string;
};
export const Dropdown: React.FC<DropdownProps> = ({
items,
selectedValue,
onChange,
backgroundColor,
textColor,
optionsWidth,
}) => {
const handleDropdownChange = (option: DropdownItem) => {
onChange(option);
};
const width = optionsWidth ? `w-${optionsWidth}` : 'w-full';
return (
<Listbox value={selectedValue} by="value" onChange={handleDropdownChange}>
{({ open }) => (
<div className="relative max-w-full">
<DropdownButton selectedValue={selectedValue} open={open} />
<DropdownButton
selectedValue={selectedValue}
open={open}
backgroundColor={backgroundColor}
textColor={textColor}
/>
<Transition
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options className="absolute max-h-32 w-full z-10 overflow-auto rounded-b-xl bg-black px-3 pt-2 border-solid border-slate6 border text-base focus:outline-none sm:text-sm">
<Listbox.Options
className={`absolute mt-1 max-h-32 ${width} right-0 z-10 overflow-auto rounded-xl bg-black px-3 pt-2 border-solid border-slate6 border text-base focus:outline-none sm:text-sm`}
>
{items.map((option: DropdownItem) => (
<DropdownOption key={option.value} option={option} />
))}

View File

@ -21,7 +21,7 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
<InputStyled
{...props}
ref={ref}
css={{ ...(leftIcon && { pl: '$10' }) }}
css={{ ...(leftIcon && { pl: '$10' }), ...(props?.css || {}) }}
/>
</div>
);

View File

@ -13,7 +13,7 @@ export const NavBar: React.FC = () => {
<Logo />
<Styles.Navigation>
<Button as={Link} to="/" variant="link" color="gray">
<Button as={Link} to="/explore" variant="link" color="gray">
Explore
</Button>
<Button as={Link} to="/mint" variant="link" color="gray">

View File

@ -0,0 +1,12 @@
import { Flex } from '@/components';
import { dripStitches } from '@/theme';
const { styled } = dripStitches;
export abstract class Explore {
static readonly Container = styled(Flex, {
flexDirection: 'column',
width: '64.75rem', //TODO replace for max-width
margin: '0 auto',
});
}

View File

@ -0,0 +1,12 @@
import { Header } from './header';
import { Explore as ES } from './explore.styles';
import { ListNfas } from './list-nfas/list-nfas';
export const Explore: React.FC = () => {
return (
<ES.Container>
<Header />
<ListNfas />
</ES.Container>
);
};

View File

@ -0,0 +1,29 @@
import { Flex } from '@/components';
import { dripStitches } from '@/theme';
const { styled } = dripStitches;
export abstract class Header {
static readonly Container = styled(Flex, {
flexDirection: 'column',
gap: '$6',
my: '$16',
});
static readonly Text = styled('h2', {
fontSize: '$4xl',
maxWidth: '46rem',
});
static readonly GrayText = styled('span', {
color: '$slate11',
});
static readonly WhiteText = styled('span', {
color: '$slate12',
});
static readonly ButtonContainer = styled(Flex, {
gap: '$3',
});
}

View File

@ -0,0 +1,22 @@
import { Button } from '@/components';
import { Link } from 'react-router-dom';
import { Header as HS } from './header.styles';
export const Header = () => (
<HS.Container>
<HS.Text>
<HS.GrayText>
Created with a focus on decentralizing your applications,
</HS.GrayText>
<HS.WhiteText> NFAs are the only thing you need.</HS.WhiteText>
</HS.Text>
<HS.ButtonContainer>
<Button as={Link} to="/mint" colorScheme="blue" variant="outline">
Create an NFA
</Button>
{/* TODO replace with create ap route */}
<Button as={Link} to="/" colorScheme="gray" variant="outline">
Host an Access Point
</Button>
</HS.ButtonContainer>
</HS.Container>
);

View File

@ -0,0 +1 @@
export * from './explore';

View File

View File

@ -0,0 +1,12 @@
import { Flex } from '@/components';
import { NFAList } from './nfa-list';
import { ResultsSearch } from './results-search';
export const ListNfas: React.FC = () => {
return (
<Flex css={{ flexDirection: 'column' }}>
<ResultsSearch />
<NFAList />
</Flex>
);
};

View File

@ -52,7 +52,7 @@ export const NFAList = () => {
};
return (
<Flex css={{ flexDirection: 'column', my: '$5', gap: '$2' }}>
<Flex css={{ flexDirection: 'column', gap: '$2' }}>
<Flex css={{ gap: '$2' }}>
{/* TODO this will be remove when we have pagination component */}
<span>items per page: {pageSize}</span>

View File

@ -0,0 +1,38 @@
import { Dropdown, DropdownItem, Flex, Input } from '@/components';
import { useState } from 'react';
import { ResultsContainer, ResultsNumber, ResultsText } from './results.styles';
const orderResults: DropdownItem[] = [
{ value: 'a-z', label: 'Sort A-Z' },
{ value: 'z-a', label: 'Sort Z-A' },
];
export const ResultsSearch: React.FC = () => {
const [selectedValue, setSelectedValue] = useState<DropdownItem>(
orderResults[0]
); //TODO replace for context
return (
<Flex css={{ justifyContent: 'space-between' }}>
<ResultsContainer>
<ResultsText>All NFAs </ResultsText>
<ResultsNumber>(3,271)</ResultsNumber>
</ResultsContainer>
<Flex css={{ gap: '$3' }}>
<Input
placeholder="Search"
leftIcon="search"
css={{ width: '23rem' }}
/>
<Dropdown
items={orderResults}
selectedValue={selectedValue}
onChange={setSelectedValue}
backgroundColor="slate4"
textColor="slate11"
optionsWidth="40"
/>
</Flex>
</Flex>
);
};

View File

@ -0,0 +1,18 @@
import { dripStitches } from '@/theme';
const { styled } = dripStitches;
export const ResultsContainer = styled('div', {
fontSize: '$xl',
fontWeight: '$bold',
display: 'flex',
alignItems: 'center',
});
export const ResultsText = styled('span', {
color: '$slate12',
});
export const ResultsNumber = styled('span', {
color: '$slate11',
});

View File

@ -1,6 +1,5 @@
import { Flex } from '@/components';
import { Link } from 'react-router-dom';
import { NFAList } from './nfa-list/nfa-list';
export const Home = () => {
return (
@ -9,7 +8,6 @@ export const Home = () => {
<Link to="/mint">
<u>Mint NFA!</u>
</Link>
<NFAList />
</Flex>
);
};

View File

@ -1,4 +1,5 @@
export * from './home';
export * from './mint';
export * from './components-test';
export * from './explore';
export * from './access-point';

View File

@ -3,10 +3,19 @@
module.exports = {
content: ['./src/**/*.tsx'],
safelist: [
{
pattern: /(bg|border|text)-(slate)(4|11|12)/,
},
{
pattern: /w-(0|[1-9][0-9]?|100)/,
},
],
theme: {
extend: {
colors: {
//TODO if we're gonna have ligth mode we should add also the light colors cause tailwind doesn't have them
slate4: 'rgba(38, 41, 43, 1)',
slate5: 'rgba(43, 47, 49, 1)',
slate6: 'rgba(49, 53, 56, 1)',
slate7: 'rgba(58, 63, 66, 1)',