summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/components
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-12-14 20:32:14 -0600
committerAdam <[email protected]>2025-12-14 21:38:59 -0600
commitdda579c8ad30f81ade458769971d85ff7afee64c (patch)
tree343c82906735fcfc82a5b2a178660aaab5bccb45 /packages/ui/src/components
parent4246cdb069502c96ab11e260eb36a07a0370b710 (diff)
downloadopencode-dda579c8ad30f81ade458769971d85ff7afee64c.tar.gz
opencode-dda579c8ad30f81ade458769971d85ff7afee64c.zip
wip(desktop): progress
Diffstat (limited to 'packages/ui/src/components')
-rw-r--r--packages/ui/src/components/dialog.css2
-rw-r--r--packages/ui/src/components/dialog.tsx123
2 files changed, 38 insertions, 87 deletions
diff --git a/packages/ui/src/components/dialog.css b/packages/ui/src/components/dialog.css
index fa5e1171e..6fa71c64c 100644
--- a/packages/ui/src/components/dialog.css
+++ b/packages/ui/src/components/dialog.css
@@ -60,6 +60,7 @@
[data-slot="dialog-header"] {
display: flex;
padding: 16px;
+ padding-left: 20px;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
@@ -82,6 +83,7 @@
[data-slot="dialog-description"] {
display: flex;
padding: 16px;
+ padding-left: 20px;
padding-top: 0;
margin-top: -8px;
justify-content: space-between;
diff --git a/packages/ui/src/components/dialog.tsx b/packages/ui/src/components/dialog.tsx
index aebb77885..47d6af42e 100644
--- a/packages/ui/src/components/dialog.tsx
+++ b/packages/ui/src/components/dialog.tsx
@@ -1,96 +1,45 @@
-import {
- Dialog as Kobalte,
- DialogRootProps,
- DialogTitleProps,
- DialogCloseButtonProps,
- DialogDescriptionProps,
-} from "@kobalte/core/dialog"
-import { ComponentProps, type JSX, onCleanup, onMount, Show, splitProps } from "solid-js"
+import { Dialog as Kobalte } from "@kobalte/core/dialog"
+import { ComponentProps, JSXElement, Match, ParentProps, Show, Switch } from "solid-js"
import { IconButton } from "./icon-button"
-export interface DialogProps extends DialogRootProps {
- trigger?: JSX.Element
+export interface DialogProps extends ParentProps {
+ title?: JSXElement
+ description?: JSXElement
+ action?: JSXElement
class?: ComponentProps<"div">["class"]
classList?: ComponentProps<"div">["classList"]
}
-function DialogRoot(props: DialogProps) {
- let trigger!: HTMLElement
- const [local, others] = splitProps(props, ["trigger", "class", "classList", "children"])
-
- const resetTabIndex = () => {
- trigger.tabIndex = 0
- }
-
- const handleTriggerFocus = (e: FocusEvent & { currentTarget: HTMLElement | null }) => {
- const firstChild = e.currentTarget?.firstElementChild as HTMLElement
- if (!firstChild) return
-
- firstChild.focus()
- trigger.tabIndex = -1
-
- firstChild.addEventListener("focusout", resetTabIndex)
- onCleanup(() => {
- firstChild.removeEventListener("focusout", resetTabIndex)
- })
- }
-
- onMount(() => {
- // @ts-ignore
- document?.activeElement?.blur?.()
- })
-
+export function Dialog(props: DialogProps) {
return (
- <Kobalte {...others}>
- <Show when={props.trigger}>
- <Kobalte.Trigger ref={trigger} data-component="dialog-trigger" onFocusIn={handleTriggerFocus}>
- {props.trigger}
- </Kobalte.Trigger>
- </Show>
- <Kobalte.Portal>
- <Kobalte.Overlay data-component="dialog-overlay" />
- <div data-component="dialog">
- <div data-slot="dialog-container">
- <Kobalte.Content
- data-slot="dialog-content"
- classList={{
- ...(local.classList ?? {}),
- [local.class ?? ""]: !!local.class,
- }}
- >
- {local.children}
- </Kobalte.Content>
- </div>
- </div>
- </Kobalte.Portal>
- </Kobalte>
+ <div data-component="dialog">
+ <div data-slot="dialog-container">
+ <Kobalte.Content
+ data-slot="dialog-content"
+ classList={{
+ ...(props.classList ?? {}),
+ [props.class ?? ""]: !!props.class,
+ }}
+ >
+ <Show when={props.title || props.action}>
+ <div data-slot="dialog-header">
+ <Show when={props.title}>
+ <Kobalte.Title data-slot="dialog-title">{props.title}</Kobalte.Title>
+ </Show>
+ <Switch>
+ <Match when={props.action}>{props.action}</Match>
+ <Match when={true}>
+ <Kobalte.CloseButton data-slot="dialog-close-button" as={IconButton} icon="close" variant="ghost" />
+ </Match>
+ </Switch>
+ </div>
+ </Show>
+ <Show when={props.description}>
+ <Kobalte.Description data-slot="dialog-description">{props.description}</Kobalte.Description>
+ </Show>
+ <div data-slot="dialog-body">{props.children}</div>
+ </Kobalte.Content>
+ </div>
+ </div>
)
}
-
-function DialogHeader(props: ComponentProps<"div">) {
- return <div data-slot="dialog-header" {...props} />
-}
-
-function DialogBody(props: ComponentProps<"div">) {
- return <div data-slot="dialog-body" {...props} />
-}
-
-function DialogTitle(props: DialogTitleProps & ComponentProps<"h2">) {
- return <Kobalte.Title data-slot="dialog-title" {...props} />
-}
-
-function DialogDescription(props: DialogDescriptionProps & ComponentProps<"p">) {
- return <Kobalte.Description data-slot="dialog-description" {...props} />
-}
-
-function DialogCloseButton(props: DialogCloseButtonProps & ComponentProps<"button">) {
- return <Kobalte.CloseButton data-slot="dialog-close-button" as={IconButton} icon="close" variant="ghost" {...props} />
-}
-
-export const Dialog = Object.assign(DialogRoot, {
- Header: DialogHeader,
- Title: DialogTitle,
- Description: DialogDescription,
- CloseButton: DialogCloseButton,
- Body: DialogBody,
-})