File size: 3,717 Bytes
9697ede | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | import { Dialog as Kobalte } from "@kobalte/core/dialog"
import { type ComponentProps, type JSXElement, type ParentProps, Show, children, splitProps } from "solid-js"
import { useI18n } from "../../context/i18n"
import "./dialog-v2.css"
export interface DialogProps extends ParentProps {
size?: "normal" | "large" | "x-large"
variant?: "default" | "settings"
class?: ComponentProps<"div">["class"]
containerClass?: ComponentProps<"div">["class"]
classList?: ComponentProps<"div">["classList"]
fit?: boolean
}
export interface DialogHeaderProps extends ParentProps {
closeLabel?: string
hideClose?: boolean
}
export interface DialogTitleGroupProps {
title?: JSXElement
description: JSXElement
}
export function DialogFooter(props: ParentProps) {
return <div data-slot="dialog-footer">{props.children}</div>
}
export function DialogBody(props: ParentProps & { class?: ComponentProps<"div">["class"] }) {
const [local] = splitProps(props, ["class", "children"])
return (
<div data-slot="dialog-body" class={local.class}>
{local.children}
</div>
)
}
export function DialogTitle(props: ParentProps) {
return <Kobalte.Title data-slot="dialog-header-title">{props.children}</Kobalte.Title>
}
export function DialogTitleGroup(props: DialogTitleGroupProps) {
const title = children(() => props.title)
const description = children(() => props.description)
return (
<div data-slot="dialog-title-group">
<Show when={title()}>{(t) => <Kobalte.Title data-slot="dialog-title">{t()}</Kobalte.Title>}</Show>
<Kobalte.Description data-slot="dialog-description">{description()}</Kobalte.Description>
</div>
)
}
export function DialogHeader(props: DialogHeaderProps) {
const i18n = useI18n()
const [local] = splitProps(props, ["closeLabel", "hideClose", "children"])
const hideClose = () => local.hideClose === true
return (
<div data-slot="dialog-header" data-hide-close={hideClose() ? "" : undefined}>
{local.children}
{!hideClose() && (
<Kobalte.CloseButton data-slot="dialog-close-button" aria-label={local.closeLabel ?? i18n.t("ui.common.close")}>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M12.4446 3.55469L3.55566 12.4436M3.55566 3.55469L12.4446 12.4436"
stroke="currentColor"
stroke-linejoin="round"
/>
</svg>
</Kobalte.CloseButton>
)}
</div>
)
}
export function Dialog(props: DialogProps) {
const [local] = splitProps(props, ["size", "variant", "class", "containerClass", "classList", "fit", "children"])
return (
<div
data-component="dialog-v2"
data-variant={local.variant === "settings" ? "settings" : undefined}
data-fit={local.fit ? true : undefined}
data-size={local.size || "normal"}
>
<div data-slot="dialog-container" class={local.containerClass}>
<Kobalte.Content
data-slot="dialog-content"
classList={{
...local.classList,
[local.class ?? ""]: !!local.class,
}}
onOpenAutoFocus={(e) => {
const target = e.currentTarget as HTMLElement | null
const autofocusEl = target?.querySelector("[autofocus]") as HTMLElement | null
if (autofocusEl) {
e.preventDefault()
autofocusEl.focus({ preventScroll: true })
}
}}
>
{local.children}
</Kobalte.Content>
</div>
</div>
)
}
export const DialogV2 = Dialog
|