From ec36876b9fcaa2acbcb62d2a1d90c9136188cc86 Mon Sep 17 00:00:00 2001 From: Aarnav Tale Date: Sun, 19 Jan 2025 15:24:03 +0000 Subject: [PATCH] feat: begin redesign and component unification --- app/components/Button.tsx | 58 ++++++++++++++------------- app/components/Card.tsx | 30 ++++++-------- app/components/Dialog.tsx | 62 ++++------------------------- app/components/Header.tsx | 11 ++--- app/components/IconButton.tsx | 42 +++++++++++++++++++ app/components/Menu.tsx | 20 +++++----- app/components/Title.tsx | 13 ++++++ app/root.tsx | 3 +- app/routes/auth/login.tsx | 8 ++-- app/routes/machines/dialogs/new.tsx | 8 +--- 10 files changed, 124 insertions(+), 131 deletions(-) create mode 100644 app/components/IconButton.tsx create mode 100644 app/components/Title.tsx diff --git a/app/components/Button.tsx b/app/components/Button.tsx index 94c89d2..8afd5ed 100644 --- a/app/components/Button.tsx +++ b/app/components/Button.tsx @@ -1,38 +1,40 @@ import type { Dispatch, SetStateAction } from 'react'; +import React, { useRef } from 'react'; import { Button as AriaButton } from 'react-aria-components'; +import { useButton } from 'react-aria'; import { cn } from '~/utils/cn'; -type Props = Parameters[0] & { - readonly control?: [boolean, Dispatch>]; - readonly variant?: 'heavy' | 'light'; -}; +export interface ButtonProps extends React.HTMLProps { + variant?: 'heavy' + isDisabled?: boolean + children?: React.ReactNode +} + +export default function Button({ variant = 'light', ...props }: Props) { + const ref = useRef(null); + const { buttonProps } = useButton(props, ref); -export default function Button(props: Props) { return ( - { - props.control?.[1](true); - } - : props.onPress - } - /> - ); + > + {props.children} + + ) } diff --git a/app/components/Card.tsx b/app/components/Card.tsx index c186d5e..b6ce641 100644 --- a/app/components/Card.tsx +++ b/app/components/Card.tsx @@ -1,37 +1,31 @@ -import type { HTMLProps } from 'react'; -import { Heading as AriaHeading } from 'react-aria-components'; +import React from 'react'; +import Title from '~/components/Title'; import { cn } from '~/utils/cn'; -function Title(props: Parameters[0]) { - return ( - - ); -} - function Text(props: React.HTMLProps) { return (

); } -type Props = HTMLProps & { +type Props = React.HTMLProps & { variant?: 'raised' | 'flat'; }; -function Card(props: Props) { +interface Props extends React.HTMLProps { + variant?: 'raised' | 'flat'; +} + +function Card({ variant = 'raised', ...props }: Props) { return (

diff --git a/app/components/Dialog.tsx b/app/components/Dialog.tsx index 152b314..5a07e3f 100644 --- a/app/components/Dialog.tsx +++ b/app/components/Dialog.tsx @@ -1,4 +1,6 @@ -import type { Dispatch, ReactNode, SetStateAction } from 'react'; +import React, { Dispatch, ReactNode, SetStateAction } from 'react'; +import Button, { ButtonProps } from '~/components/Button'; +import Title from '~/components/Title'; import { Button as AriaButton, Dialog as AriaDialog, @@ -9,64 +11,16 @@ import { } from 'react-aria-components'; import { cn } from '~/utils/cn'; -type ButtonProps = Parameters[0] & { - readonly control?: [boolean, Dispatch>]; -}; - -function Button(props: ButtonProps) { - return ( - { - props.control?.[1](true); - } - : undefined - } - /> - ); +interface ActionProps extends ButtonProps { + variant: 'cancel' | 'confirm'; } -type ActionProps = Parameters[0] & { - readonly variant: 'cancel' | 'confirm'; -}; - function Action(props: ActionProps) { return ( - - ); -} - -function Title(props: Parameters[0]) { - return ( - ); } @@ -100,7 +54,7 @@ function Panel({ children, control, className }: PanelProps) { > {data.user ? ( - - - + + +

{data.user.name}

diff --git a/app/components/IconButton.tsx b/app/components/IconButton.tsx new file mode 100644 index 0000000..29f83f3 --- /dev/null +++ b/app/components/IconButton.tsx @@ -0,0 +1,42 @@ +import type { Dispatch, SetStateAction } from 'react'; +import React, { useRef } from 'react'; +import { Button as AriaButton } from 'react-aria-components'; +import { useButton } from 'react-aria'; +import { cn } from '~/utils/cn'; + +interface Props extends React.HTMLProps { + variant?: 'heavy' + isDisabled?: boolean + children: React.ReactNode + label: string +} + +export default function IconButton({ variant = 'light', ...props }: Props) { + const ref = useRef(null); + const { buttonProps } = useButton(props, ref); + + return ( + + ) +} diff --git a/app/components/Menu.tsx b/app/components/Menu.tsx index 8fa648e..60a22c6 100644 --- a/app/components/Menu.tsx +++ b/app/components/Menu.tsx @@ -1,4 +1,6 @@ import type { Dispatch, ReactNode, SetStateAction } from 'react'; +import Button from '~/components/Button'; +import IconButton from '~/components/IconButton'; import { Button as AriaButton, Menu as AriaMenu, @@ -8,16 +10,6 @@ import { } from 'react-aria-components'; import { cn } from '~/utils/cn'; -function Button(props: Parameters[0]) { - return ( - - ); -} - function Items(props: Parameters[0]) { return ( {children}; } -export default Object.assign(Menu, { Button, Item, ItemButton, Items }); +export default Object.assign(Menu, { + IconButton, + Button, + Item, + ItemButton, + Items +}); diff --git a/app/components/Title.tsx b/app/components/Title.tsx new file mode 100644 index 0000000..b070c29 --- /dev/null +++ b/app/components/Title.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +export interface TitleProps { + children: React.ReactNode; +} + +export default function Title({ children }: TitleProps) { + return ( +

+ {children} +

+ ); +} diff --git a/app/root.tsx b/app/root.tsx index 70d49db..bf2f38e 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -1,6 +1,7 @@ import type { LoaderFunctionArgs, LinksFunction, MetaFunction } from 'react-router'; import { Links, Meta, Outlet, Scripts, ScrollRestoration, useNavigation } from 'react-router'; import { loadContext } from '~/utils/config/headplane'; +import '@fontsource-variable/inter' import { ProgressBar } from 'react-aria-components'; import { ErrorPopup } from '~/components/Error'; @@ -30,7 +31,7 @@ export function Layout({ children }: { readonly children: React.ReactNode }) { - + {children} diff --git a/app/routes/auth/login.tsx b/app/routes/auth/login.tsx index e593f74..623f6d0 100644 --- a/app/routes/auth/login.tsx +++ b/app/routes/auth/login.tsx @@ -96,7 +96,7 @@ export default function Page() { return (
- + Welcome to Headplane {data.apiKey ? (
@@ -117,7 +117,7 @@ export default function Page() { type="password" />
) : undefined} @@ -131,8 +131,8 @@ export default function Page() { {data.oidc ? (
-
) : undefined} diff --git a/app/routes/machines/dialogs/new.tsx b/app/routes/machines/dialogs/new.tsx index badd729..fa03667 100644 --- a/app/routes/machines/dialogs/new.tsx +++ b/app/routes/machines/dialogs/new.tsx @@ -103,13 +103,7 @@ export default function New(data: NewProps) { - + Add Device