diff --git a/app/components/Button.tsx b/app/components/Button.tsx index 058df8e..56431b8 100644 --- a/app/components/Button.tsx +++ b/app/components/Button.tsx @@ -1,26 +1,36 @@ -import clsx from 'clsx' -import { type ButtonHTMLAttributes, type DetailedHTMLProps } from 'react' +import { type Dispatch, type SetStateAction } from 'react' +import { Button as AriaButton } from 'react-aria-components' -type Properties = { - readonly variant?: 'emphasized' | 'normal' | 'destructive'; -} & DetailedHTMLProps, HTMLButtonElement> +import { cn } from '~/utils/cn' -export default function Action(properties: Properties) { +type ButtonProperties = Parameters[0] & { + readonly control?: [boolean, Dispatch>]; + readonly variant?: 'heavy' | 'light'; +} + +export default function Button(properties: ButtonProperties) { return ( - + // If control is passed, set the state value + onPress={properties.control ? () => { + properties.control?.[1](true) + } : undefined} + /> ) } + diff --git a/app/components/Card.tsx b/app/components/Card.tsx index 080ac49..eea885e 100644 --- a/app/components/Card.tsx +++ b/app/components/Card.tsx @@ -1,14 +1,47 @@ -import clsx from 'clsx' import { type HTMLProps } from 'react' +import { Heading as AriaHeading } from 'react-aria-components' -type Properties = HTMLProps +import { cn } from '~/utils/cn' -export default function Card(properties: Properties) { +function Title(properties: Parameters[0]) { + return ( + + ) +} + +function Text(properties: React.HTMLProps) { + return ( +

+ ) +} + +type Properties = HTMLProps & { + variant?: 'raised' | 'flat'; +} + +function Card(properties: Properties) { return (

@@ -16,3 +49,5 @@ export default function Card(properties: Properties) {
) } + +export default Object.assign(Card, { Title, Text }) diff --git a/app/components/Dialog.tsx b/app/components/Dialog.tsx index 1243bd0..9c43c0a 100644 --- a/app/components/Dialog.tsx +++ b/app/components/Dialog.tsx @@ -23,6 +23,7 @@ function Button(properties: ButtonProperties) { className={cn( 'w-fit text-sm rounded-lg px-4 py-2', 'bg-main-700 dark:bg-main-800 text-white', + 'hover:bg-main-800 dark:hover:bg-main-700', properties.isDisabled && 'opacity-50 cursor-not-allowed', properties.className )} diff --git a/app/components/Error.tsx b/app/components/Error.tsx index 37e9656..79ae97f 100644 --- a/app/components/Error.tsx +++ b/app/components/Error.tsx @@ -1,52 +1,46 @@ import { AlertIcon } from '@primer/octicons-react' import { isRouteErrorResponse, useRouteError } from '@remix-run/react' -import { useState } from 'react' import { cn } from '~/utils/cn' +import Card from './Card' import Code from './Code' -import Dialog from './Dialog' type Properties = { readonly type?: 'full' | 'embedded'; } export function ErrorPopup({ type = 'full' }: Properties) { - // eslint-disable-next-line react/hook-use-state - const open = useState(true) - const error = useRouteError() const routing = isRouteErrorResponse(error) const message = (error instanceof Error ? error.message : 'An unexpected error occurred') return ( - - - {() => ( - <> -
- - {routing ? error.status : 'Error'} - - -
- - {routing ? ( - error.statusText - ) : ( - - {message} - - )} - - - )} -
-
+
+ +
+ + {routing ? error.status : 'Error'} + + +
+ + {routing ? ( + error.statusText + ) : ( + + {message} + + )} + +
+
) } diff --git a/app/components/Input.tsx b/app/components/Input.tsx deleted file mode 100644 index 2c3e39f..0000000 --- a/app/components/Input.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import clsx from 'clsx' -import { type DetailedHTMLProps, type InputHTMLAttributes } from 'react' - -type Properties = { - readonly variant?: 'embedded' | 'normal'; -} & DetailedHTMLProps, HTMLInputElement> - -export default function Input(properties: Properties) { - return ( - - ) -} diff --git a/app/components/Switch.tsx b/app/components/Switch.tsx index 793e629..f881a66 100644 --- a/app/components/Switch.tsx +++ b/app/components/Switch.tsx @@ -15,23 +15,17 @@ export default function Switch(properties: SwitchProperties) { >
diff --git a/app/components/TextField.tsx b/app/components/TextField.tsx index 9b6499b..7c47646 100644 --- a/app/components/TextField.tsx +++ b/app/components/TextField.tsx @@ -9,7 +9,7 @@ import { cn } from '~/utils/cn' type TextFieldProperties = Parameters[0] & { readonly label: string; readonly placeholder: string; - readonly state: [string, Dispatch>]; + readonly state?: [string, Dispatch>]; } export default function TextField(properties: TextFieldProperties) { @@ -21,7 +21,7 @@ export default function TextField(properties: TextFieldProperties) { > { - properties.state[1](event.target.value) + properties.state?.[1](event.target.value) }} /> diff --git a/app/root.tsx b/app/root.tsx index c5b9849..ab5e426 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -46,7 +46,7 @@ export function Layout({ children }: { readonly children: React.ReactNode }) { - + {children} diff --git a/app/routes/_data.acls._index/editor.tsx b/app/routes/_data.acls._index/editor.tsx index 0137b1f..b93f18a 100644 --- a/app/routes/_data.acls._index/editor.tsx +++ b/app/routes/_data.acls._index/editor.tsx @@ -87,9 +87,9 @@ export default function Editor({ data, acl, setAcl, mode }: EditorProperties) { - diff --git a/app/routes/_data.acls._index/fallback.tsx b/app/routes/_data.acls._index/fallback.tsx index de07fd5..7f98197 100644 --- a/app/routes/_data.acls._index/fallback.tsx +++ b/app/routes/_data.acls._index/fallback.tsx @@ -28,20 +28,12 @@ export default function Fallback({ acl, where }: FallbackProperties) { {where === 'server' ? ( <> - diff --git a/app/routes/_data.dns._index/domains.tsx b/app/routes/_data.dns._index/domains.tsx index 47f435a..7bdbfbe 100644 --- a/app/routes/_data.dns._index/domains.tsx +++ b/app/routes/_data.dns._index/domains.tsx @@ -17,13 +17,12 @@ import { import { CSS } from '@dnd-kit/utilities' import { LockIcon, ThreeBarsIcon } from '@primer/octicons-react' import { type FetcherWithComponents, useFetcher } from '@remix-run/react' -import clsx from 'clsx' import { useEffect, useState } from 'react' +import { Button, Input } from 'react-aria-components' -import Button from '~/components/Button' -import Input from '~/components/Input' import Spinner from '~/components/Spinner' import TableList from '~/components/TableList' +import { cn } from '~/utils/cn' type Properties = { readonly baseDomain?: string; @@ -115,9 +114,8 @@ export default function Domains({ baseDomain, searchDomains, disabled }: Propert {disabled ? undefined : ( { @@ -126,9 +124,14 @@ export default function Domains({ baseDomain, searchDomains, disabled }: Propert /> {fetcher.state === 'idle' ? ( ) : undefined} {showOr ? ( -
-
- or -
+
+
+ or +
) : undefined} {data.oidc ? (