WIP
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import React from 'react';
|
||||
|
||||
type DefaultDivProps = JSX.IntrinsicElements['div'];
|
||||
|
||||
interface LocalBlurProps {
|
||||
disableOnMd?: boolean;
|
||||
}
|
||||
|
||||
export type BlurProps = LocalBlurProps & DefaultDivProps;
|
||||
|
||||
export const Blur = ({
|
||||
disableOnMd,
|
||||
className,
|
||||
onClick,
|
||||
...props
|
||||
}: BlurProps): JSX.Element => {
|
||||
return (
|
||||
<div
|
||||
className={`absolute inset-0 z-10 w-full h-full transition-opacity ${
|
||||
disableOnMd ? 'md:hidden' : 'test'
|
||||
} ${className}`}
|
||||
{...props}
|
||||
>
|
||||
<div
|
||||
onClick={onClick}
|
||||
className={`absolute inset-0 w-full h-full backdrop-filter backdrop-blur-sm ${
|
||||
disableOnMd ? 'md:hidden' : 'test'
|
||||
}`}
|
||||
tabIndex={0}
|
||||
></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,28 +1,50 @@
|
||||
import React from 'react';
|
||||
|
||||
import MaterialButton from '@material-ui/core/Button';
|
||||
import type { ButtonProps as MaterialButtonProps } from '@material-ui/core/Button/Button';
|
||||
type DefaultButtonProps = JSX.IntrinsicElements['button'];
|
||||
|
||||
interface LocalButtonProps {
|
||||
text: string;
|
||||
icon?: JSX.Element;
|
||||
circle?: boolean;
|
||||
active?: boolean;
|
||||
border?: boolean;
|
||||
}
|
||||
|
||||
export type ButtonProps = MaterialButtonProps & LocalButtonProps;
|
||||
export type ButtonProps = LocalButtonProps & DefaultButtonProps;
|
||||
|
||||
export const Button = ({ text, icon, ...props }: ButtonProps): JSX.Element => {
|
||||
export const Button = ({
|
||||
icon,
|
||||
circle,
|
||||
className,
|
||||
active,
|
||||
border,
|
||||
disabled,
|
||||
children,
|
||||
...props
|
||||
}: ButtonProps): JSX.Element => {
|
||||
return (
|
||||
<MaterialButton
|
||||
<button
|
||||
className={`items-center select-none flex dark:text-white ${
|
||||
active && !disabled ? 'bg-gray-100 dark:bg-gray-700' : ''
|
||||
} ${
|
||||
circle ? 'rounded-full h-10 w-10' : 'rounded-md p-3 space-x-3 text-sm'
|
||||
} ${
|
||||
disabled
|
||||
? 'cursor-not-allowed dark:bg-primaryDark bg-white'
|
||||
: 'cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700 hover:shadow-md'
|
||||
} ${border ? 'border dark:border-gray-600' : ''} ${className}`}
|
||||
{...props}
|
||||
className="dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700"
|
||||
>
|
||||
<div className="flex p-3">
|
||||
{icon &&
|
||||
React.cloneElement(icon, {
|
||||
className: 'h-6 w-6 mr-3 text-gray-500 dark:text-gray-400',
|
||||
})}
|
||||
<span>{text}</span>
|
||||
</div>
|
||||
</MaterialButton>
|
||||
{icon && (
|
||||
<div
|
||||
className={`text-gray-500 dark:text-gray-400 ${
|
||||
circle ? 'mx-auto' : ''
|
||||
}`}
|
||||
>
|
||||
{icon}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<span>{children}</span>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Blur } from '@components/generic/Blur';
|
||||
|
||||
type DefaultAsideProps = JSX.IntrinsicElements['aside'];
|
||||
|
||||
interface LocalDrawerProps {
|
||||
open: boolean;
|
||||
permenant?: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
export type DrawerProps = LocalDrawerProps & DefaultAsideProps;
|
||||
|
||||
export const Drawer = ({
|
||||
open,
|
||||
permenant,
|
||||
onClose,
|
||||
children,
|
||||
...props
|
||||
}: DrawerProps): JSX.Element => {
|
||||
return (
|
||||
<>
|
||||
{open && <Blur disableOnMd={true} onClick={onClose} />}
|
||||
|
||||
<aside
|
||||
className={`transform top-0 left-0 bg-white dark:bg-secondaryDark shadow-md max-w-xs w-full border-r dark:border-gray-600 h-full overflow-auto ease-in-out transition-all duration-300 z-30 ${
|
||||
permenant ? '' : 'absolute'
|
||||
} ${open ? 'translate-x-0' : '-translate-x-full'}`}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</aside>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import MaterialIconButton from '@material-ui/core/IconButton';
|
||||
import type { IconButtonProps } from '@material-ui/core/IconButton/IconButton';
|
||||
|
||||
export const IconButton = ({
|
||||
children,
|
||||
...props
|
||||
}: IconButtonProps): JSX.Element => {
|
||||
return (
|
||||
<MaterialIconButton {...props} className="text-gray-500 dark:text-gray-400">
|
||||
{children}
|
||||
</MaterialIconButton>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
import React from 'react';
|
||||
|
||||
type DefaultInputProps = JSX.IntrinsicElements['input'];
|
||||
|
||||
interface LocalInputProps {
|
||||
icon?: JSX.Element;
|
||||
label?: string;
|
||||
valid?: boolean;
|
||||
validationMessage?: string;
|
||||
}
|
||||
|
||||
export type InputProps = LocalInputProps & DefaultInputProps;
|
||||
|
||||
export const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
function Input(
|
||||
{ icon, label, valid, validationMessage, id, ...props }: InputProps,
|
||||
ref,
|
||||
) {
|
||||
return (
|
||||
<div className="w-full">
|
||||
<label
|
||||
htmlFor={id}
|
||||
className="block text-sm font-medium dark:text-white"
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
<div className="relative">
|
||||
{icon && (
|
||||
<div className="absolute inset-y-0 left-0 flex items-center px-3 pointer-events-none">
|
||||
{React.cloneElement(icon, {
|
||||
className: 'w-5 h-5 text-gray-500 dark:text-gray-600',
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
<input
|
||||
id={id}
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={`block w-full h-11 rounded-md border shadow-sm focus:outline-none focus:border-primary dark:focus:border-primary bg-white dark:bg-secondaryDark dark:border-gray-600 dark:text-white ${
|
||||
icon ? 'pl-9' : 'pl-2'
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
{!valid && (
|
||||
<div className="text-sm text-gray-600">{validationMessage}</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,82 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Listbox } from '@headlessui/react';
|
||||
import { CheckIcon, SelectorIcon } from '@heroicons/react/solid';
|
||||
|
||||
export interface SelectProps {
|
||||
label: string;
|
||||
options: {
|
||||
name: string;
|
||||
value: string;
|
||||
icon: JSX.Element;
|
||||
}[];
|
||||
id: string;
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
}
|
||||
|
||||
export const Select = ({
|
||||
label,
|
||||
options,
|
||||
id,
|
||||
value,
|
||||
onChange,
|
||||
}: SelectProps): JSX.Element => {
|
||||
return (
|
||||
<div className="w-full">
|
||||
<label htmlFor={id} className="block text-sm font-medium dark:text-white">
|
||||
{label}
|
||||
</label>
|
||||
|
||||
<Listbox value={value} onChange={onChange}>
|
||||
<div className="relative mt-1">
|
||||
<Listbox.Button className="relative w-full text-left bg-white border rounded-md shadow-sm h-11 focus:outline-none focus:border-primary dark:focus:border-primary dark:bg-secondaryDark dark:border-gray-600 dark:text-white">
|
||||
<span className="block truncate">{value}</span>
|
||||
<span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
||||
<SelectorIcon
|
||||
className="w-5 h-5 text-gray-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</span>
|
||||
</Listbox.Button>
|
||||
|
||||
<Listbox.Options className="absolute w-full bg-white border rounded-md shadow-sm focus:outline-none dark:bg-secondaryDark dark:border-gray-600 dark:text-white">
|
||||
{options.map((option) => (
|
||||
<Listbox.Option
|
||||
key={option.value}
|
||||
className={({ active }): string =>
|
||||
`cursor-default select-none relative py-2 pl-10 pr-4 first:rounded-t-md last:rounded-b-md dark:text-white ${
|
||||
active ? 'bg-gray-200 dark:bg-primaryDark' : 'text-gray-900'
|
||||
}`
|
||||
}
|
||||
value={option.value}
|
||||
>
|
||||
{({ selected, active }): JSX.Element => (
|
||||
<>
|
||||
<span
|
||||
className={`${
|
||||
selected ? 'font-medium' : 'font-normal'
|
||||
} block truncate`}
|
||||
>
|
||||
{option.name}
|
||||
</span>
|
||||
{selected ? (
|
||||
<span
|
||||
className={`${
|
||||
active ? 'text-amber-600' : 'text-amber-600'
|
||||
}
|
||||
absolute inset-y-0 left-0 flex items-center pl-3`}
|
||||
>
|
||||
<CheckIcon className="w-5 h-5" aria-hidden="true" />
|
||||
</span>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</Listbox.Option>
|
||||
))}
|
||||
</Listbox.Options>
|
||||
</div>
|
||||
</Listbox>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
import React from 'react';
|
||||
|
||||
type DefaultDivProps = JSX.IntrinsicElements['div'];
|
||||
|
||||
interface LocalSidebarItemProps {
|
||||
title: string;
|
||||
description: string;
|
||||
selected: boolean;
|
||||
icon: JSX.Element;
|
||||
}
|
||||
|
||||
export type SidebarItemProps = LocalSidebarItemProps & DefaultDivProps;
|
||||
|
||||
export const SidebarItem = ({
|
||||
title,
|
||||
description,
|
||||
selected,
|
||||
icon,
|
||||
}: SidebarItemProps): JSX.Element => {
|
||||
return (
|
||||
<div
|
||||
className={`flex p-5 cursor-pointer select-none dark:hover:bg-primaryDark ${
|
||||
selected ? 'bg-gray-200 dark:bg-primaryDark' : 'dark:bg-secondaryDark'
|
||||
}`}
|
||||
>
|
||||
<div className="text-gray-500 dark:text-gray-400">{icon}</div>
|
||||
<div className="ml-3 text-left">
|
||||
<div className="font-medium text-left">{title}</div>
|
||||
<div className="mt-0.5 text-gray-400 text-sm">{description}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user