From 7d39bb3d89253cb7c6e302e6baaa9ffec5f2fdbe Mon Sep 17 00:00:00 2001 From: SrJuggernaut Date: Thu, 4 Jan 2024 21:46:10 -0600 Subject: [PATCH] feat: improve ui components --- .gitignore | 5 +- bun.lockb | Bin 263050 -> 263050 bytes package.json | 2 +- src/components/ui/Alert.tsx | 36 ++++++++------ src/components/ui/ButtonGroup.tsx | 20 ++++++++ src/components/ui/Chip.tsx | 19 ++++++++ src/components/ui/Collapse.tsx | 36 ++++++++++++++ src/components/ui/IconButton.tsx | 4 +- src/components/ui/ListGroup.tsx | 20 ++++++++ src/components/ui/ListGroupItem.tsx | 19 ++++++++ src/components/ui/Tooltip.tsx | 28 +++++++++++ src/components/ui/Typography.tsx | 19 +++----- src/components/ui/form/Input.tsx | 17 ++++--- src/components/ui/form/PasswordInput.tsx | 57 +++++++++++++++++++++++ 14 files changed, 245 insertions(+), 37 deletions(-) create mode 100644 src/components/ui/ButtonGroup.tsx create mode 100644 src/components/ui/Chip.tsx create mode 100644 src/components/ui/Collapse.tsx create mode 100644 src/components/ui/ListGroup.tsx create mode 100644 src/components/ui/ListGroupItem.tsx create mode 100644 src/components/ui/Tooltip.tsx create mode 100644 src/components/ui/form/PasswordInput.tsx diff --git a/.gitignore b/.gitignore index 8d30874..ae2b362 100644 --- a/.gitignore +++ b/.gitignore @@ -192,4 +192,7 @@ dist # End of https://www.toptal.com/developers/gitignore/api/node,yarn,nextjs # Panda Css -src/styled-system \ No newline at end of file +src/styled-system + +# Vscode +.vscode diff --git a/bun.lockb b/bun.lockb index 0a7a2b099cde522720dc1c4b97fa0a7b698e08c5..1cc8b0b5822db58b45cc0bc56eab9cdfa4471a16 100755 GIT binary patch delta 254 zcmVEDv0 z2h+~DP(P_T&(!QNHmM+^gCd%Bu_9+F_{Q3B#pGnST^a!}aX{UjO39Pw2X5{LJ%iB| z%6BLwE0Phr9ZyyD)XZaMHY1J?EnA( delta 254 zcmVJ^zcoSx}@sb`H4OSS}>erW`aT*%q^MNrwdT^a!}aX>@OMo4nRW5TZ}PFZW_ zdj>B*Vo?{I9nZ7U+g_jJ6$W4%BK)yr4x>mb*Zgrf1!Oi+kCv+1LAh|oVxTz6Kv0Lx zivhRIivpS{2Lb>900000mu|HJ7y&T1hqVI7o|klk10a{5RRapQcvJ(qVgWR_GPeU* EOpZlvGXMYp diff --git a/package.json b/package.json index 612d7c1..58f4183 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "@fortawesome/react-fontawesome": "^0.2.0", "appwrite": "^13.0.1", "entgamers-database": "^0.0.5", - "entgamers-panda-preset": "0.1.0", + "entgamers-panda-preset": "0.1.1", "formik": "^2.4.5", "framer-motion": "^10.16.16", "isomorphic-fetch": "^3.0.0", diff --git a/src/components/ui/Alert.tsx b/src/components/ui/Alert.tsx index 48c1292..a3f6001 100644 --- a/src/components/ui/Alert.tsx +++ b/src/components/ui/Alert.tsx @@ -1,35 +1,41 @@ import { cx } from '@/styled-system/css' import { alert, type AlertVariantProps } from '@/styled-system/recipes/alert' import { type MergeOmitting } from '@/types/utilities' -import { faTimes } from '@fortawesome/free-solid-svg-icons' +import { faTimes } from '@fortawesome/free-solid-svg-icons/faTimes' import { FontAwesomeIcon, type FontAwesomeIconProps } from '@fortawesome/react-fontawesome' -import { type ButtonHTMLAttributes, type DetailedHTMLProps, type FC, type HTMLAttributes } from 'react' +import { type DetailedHTMLProps, type FC, type HTMLAttributes, type ReactNode } from 'react' +import IconButton, { type IconButtonProps } from './IconButton' -export type AlertProps = MergeOmitting, HTMLDivElement>, AlertVariantProps> +type ComposedAlertProps = MergeOmitting, HTMLDivElement>, AlertVariantProps> -const Alert: FC = ({ children, className, ...props }) => { - const [alertArgs, allOtherProps] = alert.splitVariantProps(props) +const Alert: FC = ({ className, children, ...props }) => { + const [alertRecipeArgs, allOtherAlertProps] = alert.splitVariantProps(props) return (
{children}
) } -export type AlertCloseButtonProps = MergeOmitting, HTMLButtonElement>, AlertVariantProps> +type ComposedAlertCloseButtonProps = MergeOmitting & { + children?: ReactNode +} -export const AlertCloseButton: FC = ({ children, className, ...props }) => { - const [alertArgs, allOtherProps] = alert.splitVariantProps(props) +export const AlertCloseButton: FC = ({ children, className, ...props }) => { + const [alertRecipeArgs, allOtherAlertProps] = alert.splitVariantProps(props) return ( - + {children === undefined + ? + : children + } + ) } diff --git a/src/components/ui/ButtonGroup.tsx b/src/components/ui/ButtonGroup.tsx new file mode 100644 index 0000000..b0259e3 --- /dev/null +++ b/src/components/ui/ButtonGroup.tsx @@ -0,0 +1,20 @@ +import { cx } from '@/styled-system/css' +import { buttonGroup, type ButtonGroupVariantProps } from '@/styled-system/recipes/button-group' +import { type MergeOmitting } from '@/types/utilities' +import { type DetailedHTMLProps, type FC, type HTMLAttributes } from 'react' + +export type ButtonGroupProps = MergeOmitting, HTMLDivElement>, ButtonGroupVariantProps> + +const ButtonGroup: FC = ({ children, className, ...rest }) => { + const [buttonGroupRecipeArgs, allOtherButtonGroupProps] = buttonGroup.splitVariantProps(rest) + return ( +
+ {children} +
+ ) +} + +export default ButtonGroup diff --git a/src/components/ui/Chip.tsx b/src/components/ui/Chip.tsx new file mode 100644 index 0000000..5b3a707 --- /dev/null +++ b/src/components/ui/Chip.tsx @@ -0,0 +1,19 @@ +import { cx } from '@/styled-system/css' +import { chip, type ChipVariantProps } from '@/styled-system/recipes/chip' +import { type MergeOmitting } from '@/types/utilities' +import { type DetailedHTMLProps, type FC, type HTMLAttributes } from 'react' + +export type ChipProps = MergeOmitting, HTMLSpanElement>, ChipVariantProps> + +const Chip: FC = ({ children, className, ...rest }) => { + const [chipRecipeArgs, allOtherChipProps] = chip.splitVariantProps(rest) + return ( + + {children} + + ) +} +export default Chip diff --git a/src/components/ui/Collapse.tsx b/src/components/ui/Collapse.tsx new file mode 100644 index 0000000..d912d67 --- /dev/null +++ b/src/components/ui/Collapse.tsx @@ -0,0 +1,36 @@ +import { cx } from '@/styled-system/css' +import { collapse, type CollapseVariantProps } from '@/styled-system/recipes/collapse' +import { type MergeOmitting } from '@/types/utilities' +import { type DetailedHTMLProps, type DetailsHTMLAttributes, type FC, type HTMLAttributes, type ReactNode } from 'react' + +export type CollapseProps = MergeOmitting, HTMLDetailsElement>, CollapseVariantProps> & { + children?: ReactNode + contentProps?: HTMLAttributes + summary: ReactNode + summaryProps?: HTMLAttributes +} + +const Collapse: FC = ({ children, className, summary, summaryProps, contentProps, ...rest }) => { + const [collapseRecipeArgs, allOtherCollapseProps] = collapse.splitVariantProps(rest) + return ( +
+ + {summary} + +
+ {children} +
+
+ ) +} + +export default Collapse diff --git a/src/components/ui/IconButton.tsx b/src/components/ui/IconButton.tsx index 25423ec..5b9d6a1 100644 --- a/src/components/ui/IconButton.tsx +++ b/src/components/ui/IconButton.tsx @@ -1,9 +1,9 @@ import { cx } from '@/styled-system/css' import { iconButton, type IconButtonVariantProps } from '@/styled-system/recipes/icon-button' import { type MergeOmitting } from '@/types/utilities' -import React, { type FC } from 'react' +import { type ButtonHTMLAttributes, type DetailedHTMLProps, type FC } from 'react' -type ComposedIconButtonProps = MergeOmitting, IconButtonVariantProps> +type ComposedIconButtonProps = MergeOmitting, HTMLButtonElement>, IconButtonVariantProps> export interface IconButtonProps extends ComposedIconButtonProps {} diff --git a/src/components/ui/ListGroup.tsx b/src/components/ui/ListGroup.tsx new file mode 100644 index 0000000..022eaae --- /dev/null +++ b/src/components/ui/ListGroup.tsx @@ -0,0 +1,20 @@ +import { cx } from '@/styled-system/css' +import { listGroup, type ListGroupVariantProps } from '@/styled-system/recipes/list-group' +import { type MergeOmitting } from '@/types/utilities' +import { type DetailedHTMLProps, type FC, type HTMLAttributes } from 'react' + +type ComposedInputProps = MergeOmitting, HTMLUListElement>, ListGroupVariantProps> + +const ListGroup: FC = ({ children, className, ...rest }) => { + const [listGroupRecipeArgs, allOtherListGroupProps] = listGroup.splitVariantProps(rest) + return ( +
    + {children} +
+ ) +} + +export default ListGroup diff --git a/src/components/ui/ListGroupItem.tsx b/src/components/ui/ListGroupItem.tsx new file mode 100644 index 0000000..e59e5e8 --- /dev/null +++ b/src/components/ui/ListGroupItem.tsx @@ -0,0 +1,19 @@ +import { cx } from '@/styled-system/css' +import { listGroup, type ListGroupVariantProps } from '@/styled-system/recipes/list-group' +import { type MergeOmitting } from '@/types/utilities' +import { type DetailedHTMLProps, type FC, type LiHTMLAttributes } from 'react' + +type ComposedInputProps = MergeOmitting, HTMLLIElement>, ListGroupVariantProps> + +const ListGroupItem: FC = ({ children, className, ...rest }) => { + const [listGroupRecipeArgs, allOtherListGroupProps] = listGroup.splitVariantProps(rest) + return ( +
  • + {children} +
  • + ) +} +export default ListGroupItem diff --git a/src/components/ui/Tooltip.tsx b/src/components/ui/Tooltip.tsx new file mode 100644 index 0000000..706f8b6 --- /dev/null +++ b/src/components/ui/Tooltip.tsx @@ -0,0 +1,28 @@ +import { cx } from '@/styled-system/css' +import { tooltip, type TooltipVariantProps } from '@/styled-system/recipes/tooltip' +import { type MergeOmitting } from '@/types/utilities' +import { type DetailedHTMLProps, type FC, type HTMLAttributes, type ReactNode } from 'react' + +type ComposedTooltipProps = MergeOmitting, HTMLDivElement>, TooltipVariantProps> & { + title: ReactNode +} + +const Tooltip: FC = ({ children, className, title, ...rest }) => { + const [tooltipRecipeArgs, allOtherTooltipProps] = tooltip.splitVariantProps(rest) + return ( +
    + {children} + +
    + ) +} + +export default Tooltip diff --git a/src/components/ui/Typography.tsx b/src/components/ui/Typography.tsx index 601117b..7899a57 100644 --- a/src/components/ui/Typography.tsx +++ b/src/components/ui/Typography.tsx @@ -1,9 +1,9 @@ import { cx } from '@/styled-system/css' -import { typography, type TypographyVariantProps } from '@/styled-system/recipes' +import { typography, type TypographyVariantProps } from '@/styled-system/recipes/typography' import { type MergeOmitting } from '@/types/utilities' -import React, { type ElementType, type FC } from 'react' +import { type ElementType, type FC, type HTMLAttributes } from 'react' -type ComposedTypographyProps = MergeOmitting, TypographyVariantProps> +type ComposedTypographyProps = MergeOmitting, TypographyVariantProps> export interface TypographyProps extends ComposedTypographyProps { component?: ElementType @@ -33,19 +33,14 @@ const variantToComponent = (variant: TypographyVariantProps['variant']): Element } } -const isHeading = (text: string): boolean => { - return text.startsWith('h') -} - const Typography: FC = ({ children, className, component, ...rest }) => { const [typographyRecipeArgs, allOtherTypographyProps] = typography.splitVariantProps(rest) const Component = component ?? variantToComponent(typographyRecipeArgs.variant) - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - typographyRecipeArgs.color = typographyRecipeArgs.color !== undefined - ? typographyRecipeArgs.color - : typeof typographyRecipeArgs.variant === 'string' && isHeading(typographyRecipeArgs.variant) + typographyRecipeArgs.color = typographyRecipeArgs.color ?? ( + typeof typographyRecipeArgs.variant === 'string' && typographyRecipeArgs.variant.startsWith('h') ? 'primary' - : undefined + : 'inherit' + ) return ( , HTMLInputElement>, InputVariantProps> +type ComposedInputProps = MergeOmitting, HTMLInputElement>, InputVariantProps> -const Input: FC = ({ className, ...props }) => { - const [inputCss, rest] = input.splitVariantProps(props) +export interface InputProps extends ComposedInputProps {} + +const Input: FC = ({ children, className, ...rest }) => { + const [inputRecipeArgs, allOtherInputProps] = input.splitVariantProps(rest) return ( + className={cx(input(inputRecipeArgs), className)} + {...allOtherInputProps} + > + {children} + ) } + export default Input diff --git a/src/components/ui/form/PasswordInput.tsx b/src/components/ui/form/PasswordInput.tsx new file mode 100644 index 0000000..25debe6 --- /dev/null +++ b/src/components/ui/form/PasswordInput.tsx @@ -0,0 +1,57 @@ +import IconButton from '@/components/ui/IconButton' +import Tooltip from '@/components/ui/Tooltip' +import { css, cx } from '@/styled-system/css' +import { input, type InputVariantProps } from '@/styled-system/recipes/input' +import { type MergeOmitting } from '@/types/utilities' +import { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { useState, type FC, type InputHTMLAttributes } from 'react' + +export type InputProps = MergeOmitting, 'type'>, InputVariantProps> + +const PasswordInput: FC = ({ className, ...props }) => { + const [showPassword, setShowPassword] = useState(false) + const [inputCss, rest] = input.splitVariantProps(props) + return ( +
    + +
    + + { setShowPassword(!showPassword) }} + > + + + +
    +
    + ) +} +export default PasswordInput