Clean up Dialog internals
This commit is contained in:
parent
87af246d71
commit
8ab23a1722
@ -1,6 +1,6 @@
|
|||||||
// packages/core/src/components/dialog/dialog-close.tsx
|
// packages/core/src/components/dialog/dialog-close.tsx
|
||||||
import type { Component, JSX } from "solid-js";
|
import type { Component, JSX } from "solid-js";
|
||||||
import { splitProps } from "solid-js";
|
import { mergeProps, splitProps } from "solid-js";
|
||||||
import { Dynamic } from "solid-js/web";
|
import { Dynamic } from "solid-js/web";
|
||||||
import { useInternalDialogContext } from "./dialog-context";
|
import { useInternalDialogContext } from "./dialog-context";
|
||||||
|
|
||||||
@ -20,8 +20,9 @@ export function DialogClose(props: DialogCloseProps): JSX.Element {
|
|||||||
ctx.setOpen(false);
|
ctx.setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const closeProps = mergeProps(rest, { onClick: handleClick });
|
||||||
return (
|
return (
|
||||||
<Dynamic component={local.as ?? "button"} onClick={handleClick} {...rest}>
|
<Dynamic component={local.as ?? "button"} {...closeProps}>
|
||||||
{local.children}
|
{local.children}
|
||||||
</Dynamic>
|
</Dynamic>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import type { JSX } from "solid-js";
|
|||||||
import { Show, createEffect, onCleanup, splitProps } from "solid-js";
|
import { Show, createEffect, onCleanup, splitProps } from "solid-js";
|
||||||
import { createDismiss } from "../../utilities/dismiss/create-dismiss";
|
import { createDismiss } from "../../utilities/dismiss/create-dismiss";
|
||||||
import { createFocusTrap } from "../../utilities/focus-trap/create-focus-trap";
|
import { createFocusTrap } from "../../utilities/focus-trap/create-focus-trap";
|
||||||
import { Portal } from "../../utilities/portal/portal";
|
|
||||||
import { createScrollLock } from "../../utilities/scroll-lock/create-scroll-lock";
|
import { createScrollLock } from "../../utilities/scroll-lock/create-scroll-lock";
|
||||||
import { useInternalDialogContext } from "./dialog-context";
|
import { useInternalDialogContext } from "./dialog-context";
|
||||||
|
|
||||||
@ -22,7 +21,8 @@ export interface DialogContentProps extends JSX.DialogHtmlAttributes<HTMLDialogE
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog content panel. Portals to body, manages focus trap, scroll lock, and dismiss.
|
* Dialog content panel. Manages focus trap, scroll lock, and dismiss.
|
||||||
|
* Renders inline; wrap with Dialog.Portal to control portaling.
|
||||||
* Only renders when open (unless forceMount is set).
|
* Only renders when open (unless forceMount is set).
|
||||||
*/
|
*/
|
||||||
export function DialogContent(props: DialogContentProps): JSX.Element {
|
export function DialogContent(props: DialogContentProps): JSX.Element {
|
||||||
@ -61,19 +61,17 @@ export function DialogContent(props: DialogContentProps): JSX.Element {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Show when={local.forceMount || ctx.isOpen()}>
|
<Show when={local.forceMount || ctx.isOpen()}>
|
||||||
<Portal>
|
<dialog
|
||||||
<dialog
|
ref={contentRef}
|
||||||
ref={contentRef}
|
id={ctx.contentId()}
|
||||||
id={ctx.contentId()}
|
aria-modal={ctx.modal() || undefined}
|
||||||
aria-modal={ctx.modal() || undefined}
|
aria-labelledby={ctx.titleId() || undefined}
|
||||||
aria-labelledby={ctx.titleId()}
|
aria-describedby={ctx.descriptionId() || undefined}
|
||||||
aria-describedby={ctx.descriptionId()}
|
data-state={ctx.isOpen() ? "open" : "closed"}
|
||||||
data-state={ctx.isOpen() ? "open" : "closed"}
|
{...rest}
|
||||||
{...rest}
|
>
|
||||||
>
|
{local.children}
|
||||||
{local.children}
|
</dialog>
|
||||||
</dialog>
|
|
||||||
</Portal>
|
|
||||||
</Show>
|
</Show>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,9 +16,6 @@ export interface InternalDialogContextValue {
|
|||||||
/** Registered ID from Dialog.Description — used for aria-describedby */
|
/** Registered ID from Dialog.Description — used for aria-describedby */
|
||||||
descriptionId: Accessor<string | undefined>;
|
descriptionId: Accessor<string | undefined>;
|
||||||
setDescriptionId: (id: string | undefined) => void;
|
setDescriptionId: (id: string | undefined) => void;
|
||||||
/** Whether Dialog.Trigger has been explicitly rendered */
|
|
||||||
hasTrigger: Accessor<boolean>;
|
|
||||||
setHasTrigger: (has: boolean) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const InternalDialogContext = createContext<InternalDialogContextValue>();
|
const InternalDialogContext = createContext<InternalDialogContextValue>();
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
// packages/core/src/components/dialog/dialog-portal.tsx
|
// packages/core/src/components/dialog/dialog-portal.tsx
|
||||||
import type { JSX } from "solid-js";
|
import type { JSX } from "solid-js";
|
||||||
import { splitProps } from "solid-js";
|
|
||||||
import { Portal } from "../../utilities/portal/portal";
|
import { Portal } from "../../utilities/portal/portal";
|
||||||
|
|
||||||
export interface DialogPortalProps {
|
export interface DialogPortalProps {
|
||||||
@ -11,10 +10,9 @@ export interface DialogPortalProps {
|
|||||||
|
|
||||||
/** Renders children into a portal (defaults to document.body). */
|
/** Renders children into a portal (defaults to document.body). */
|
||||||
export function DialogPortal(props: DialogPortalProps): JSX.Element {
|
export function DialogPortal(props: DialogPortalProps): JSX.Element {
|
||||||
const [local, rest] = splitProps(props, ["target", "children"]);
|
return props.target !== undefined ? (
|
||||||
return local.target !== undefined ? (
|
<Portal target={props.target}>{props.children}</Portal>
|
||||||
<Portal target={local.target}>{local.children}</Portal>
|
|
||||||
) : (
|
) : (
|
||||||
<Portal>{local.children}</Portal>
|
<Portal>{props.children}</Portal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// packages/core/src/components/dialog/dialog-root.tsx
|
// packages/core/src/components/dialog/dialog-root.tsx
|
||||||
import type { JSX } from "solid-js";
|
import type { JSX } from "solid-js";
|
||||||
import { createSignal } from "solid-js";
|
import { createUniqueId } from "solid-js";
|
||||||
import {
|
import {
|
||||||
type CreateDisclosureStateOptions,
|
type CreateDisclosureStateOptions,
|
||||||
createDisclosureState,
|
createDisclosureState,
|
||||||
@ -44,11 +44,9 @@ export function DialogRoot(props: DialogRootProps): JSX.Element {
|
|||||||
},
|
},
|
||||||
} as CreateDisclosureStateOptions);
|
} as CreateDisclosureStateOptions);
|
||||||
|
|
||||||
const contentId = `pettyui-dialog-${Math.random().toString(36).slice(2, 9)}`;
|
const contentId = createUniqueId();
|
||||||
const [titleId, setTitleId] = createRegisterId();
|
const [titleId, setTitleId] = createRegisterId();
|
||||||
const [descriptionId, setDescriptionId] = createRegisterId();
|
const [descriptionId, setDescriptionId] = createRegisterId();
|
||||||
const [hasTrigger, setHasTrigger] = createSignal(false);
|
|
||||||
|
|
||||||
const internalCtx: InternalDialogContextValue = {
|
const internalCtx: InternalDialogContextValue = {
|
||||||
isOpen: disclosure.isOpen,
|
isOpen: disclosure.isOpen,
|
||||||
setOpen: (open) => (open ? disclosure.open() : disclosure.close()),
|
setOpen: (open) => (open ? disclosure.open() : disclosure.close()),
|
||||||
@ -58,8 +56,6 @@ export function DialogRoot(props: DialogRootProps): JSX.Element {
|
|||||||
setTitleId,
|
setTitleId,
|
||||||
descriptionId,
|
descriptionId,
|
||||||
setDescriptionId,
|
setDescriptionId,
|
||||||
hasTrigger,
|
|
||||||
setHasTrigger,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
|
// packages/core/src/components/dialog/index.ts
|
||||||
import { DialogClose } from "./dialog-close";
|
import { DialogClose } from "./dialog-close";
|
||||||
import { DialogContent } from "./dialog-content";
|
import { DialogContent } from "./dialog-content";
|
||||||
import { useDialogContext } from "./dialog-context";
|
import { useDialogContext } from "./dialog-context";
|
||||||
import { DialogDescription } from "./dialog-description";
|
import { DialogDescription } from "./dialog-description";
|
||||||
import { DialogOverlay } from "./dialog-overlay";
|
import { DialogOverlay } from "./dialog-overlay";
|
||||||
import { DialogPortal } from "./dialog-portal";
|
import { DialogPortal } from "./dialog-portal";
|
||||||
// packages/core/src/components/dialog/index.ts
|
|
||||||
import { DialogRoot } from "./dialog-root";
|
import { DialogRoot } from "./dialog-root";
|
||||||
import { DialogTitle } from "./dialog-title";
|
import { DialogTitle } from "./dialog-title";
|
||||||
import { DialogTrigger } from "./dialog-trigger";
|
import { DialogTrigger } from "./dialog-trigger";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user