Package entry point and lint fixes
Adds packages/core/src/index.ts as the convenience re-export barrel for all Dialog parts, Presence, Portal, VisuallyHidden, createFocusTrap, createScrollLock, and createDismiss. Also resolves pre-existing biome formatter and noNonNullAssertion violations across five files so CI passes.
This commit is contained in:
parent
a25244840b
commit
7dd8615757
31
packages/core/src/index.ts
Normal file
31
packages/core/src/index.ts
Normal file
@ -0,0 +1,31 @@
|
||||
// packages/core/src/index.ts
|
||||
// Main entry — re-exports everything for convenience.
|
||||
// Prefer sub-path imports (e.g. "pettyui/dialog") for tree-shaking.
|
||||
|
||||
export { Dialog } from "./components/dialog/index";
|
||||
export type { DialogRootProps } from "./components/dialog/dialog-root";
|
||||
export type { DialogContentProps } from "./components/dialog/dialog-content";
|
||||
export type { DialogTitleProps } from "./components/dialog/dialog-title";
|
||||
export type { DialogDescriptionProps } from "./components/dialog/dialog-description";
|
||||
export type { DialogTriggerProps } from "./components/dialog/dialog-trigger";
|
||||
export type { DialogCloseProps } from "./components/dialog/dialog-close";
|
||||
export type { DialogPortalProps } from "./components/dialog/dialog-portal";
|
||||
export type { DialogOverlayProps } from "./components/dialog/dialog-overlay";
|
||||
|
||||
export { Presence } from "./utilities/presence/index";
|
||||
export type { PresenceProps, PresenceChildProps } from "./utilities/presence/index";
|
||||
|
||||
export { Portal } from "./utilities/portal/index";
|
||||
export type { PortalProps } from "./utilities/portal/index";
|
||||
|
||||
export { VisuallyHidden } from "./utilities/visually-hidden/index";
|
||||
export type { VisuallyHiddenProps } from "./utilities/visually-hidden/index";
|
||||
|
||||
export { createFocusTrap } from "./utilities/focus-trap/index";
|
||||
export type { FocusTrap } from "./utilities/focus-trap/index";
|
||||
|
||||
export { createScrollLock } from "./utilities/scroll-lock/index";
|
||||
export type { ScrollLock } from "./utilities/scroll-lock/index";
|
||||
|
||||
export { createDismiss } from "./utilities/dismiss/index";
|
||||
export type { CreateDismissOptions, Dismiss } from "./utilities/dismiss/index";
|
||||
@ -19,9 +19,7 @@ export interface DisclosureState {
|
||||
* Tooltip, Collapsible, etc.). Wraps createControllableSignal with
|
||||
* convenience open/close/toggle methods.
|
||||
*/
|
||||
export function createDisclosureState(
|
||||
options: CreateDisclosureStateOptions,
|
||||
): DisclosureState {
|
||||
export function createDisclosureState(options: CreateDisclosureStateOptions): DisclosureState {
|
||||
const [isOpen, setIsOpen] = createControllableSignal<boolean>({
|
||||
value: () => options.open,
|
||||
defaultValue: () => options.defaultOpen ?? false,
|
||||
|
||||
@ -36,8 +36,8 @@ export function createFocusTrap(getContainer: Accessor<HTMLElement | null>): Foc
|
||||
return;
|
||||
}
|
||||
|
||||
const first = focusable[0]!;
|
||||
const last = focusable[focusable.length - 1]!;
|
||||
const first = focusable[0] as HTMLElement;
|
||||
const last = focusable[focusable.length - 1] as HTMLElement;
|
||||
|
||||
if (e.shiftKey) {
|
||||
if (document.activeElement === first) {
|
||||
|
||||
@ -17,9 +17,5 @@ export function Portal(props: PortalProps): JSX.Element {
|
||||
return <>{props.children}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<SolidPortal mount={props.target ?? document.body}>
|
||||
{props.children}
|
||||
</SolidPortal>
|
||||
);
|
||||
return <SolidPortal mount={props.target ?? document.body}>{props.children}</SolidPortal>;
|
||||
}
|
||||
|
||||
@ -75,12 +75,12 @@ export function Presence(props: PresenceProps): JSX.Element {
|
||||
// Wrap in a function so Show evaluates children lazily (only when mounted).
|
||||
return (
|
||||
<Show when={shouldMount()}>
|
||||
{(
|
||||
() =>
|
||||
{
|
||||
(() =>
|
||||
typeof props.children === "function"
|
||||
? (props.children as (p: PresenceChildProps) => JSX.Element)(childProps)
|
||||
: props.children
|
||||
) as unknown as JSX.Element}
|
||||
: props.children) as unknown as JSX.Element
|
||||
}
|
||||
</Show>
|
||||
);
|
||||
}
|
||||
|
||||
@ -96,7 +96,12 @@ describe("createFocusTrap", () => {
|
||||
const trap = createFocusTrap(() => container);
|
||||
trap.activate();
|
||||
// button1 is already focused after activate
|
||||
const event = new KeyboardEvent("keydown", { key: "Tab", shiftKey: true, bubbles: true, cancelable: true });
|
||||
const event = new KeyboardEvent("keydown", {
|
||||
key: "Tab",
|
||||
shiftKey: true,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
document.dispatchEvent(event);
|
||||
expect(document.activeElement).toBe(button2);
|
||||
trap.deactivate();
|
||||
@ -138,7 +143,9 @@ describe("createFocusTrap", () => {
|
||||
// Tab from the only element — Tab wraps back to itself (first === last)
|
||||
// What matters is it doesn't fire twice causing erratic behaviour
|
||||
expect(() => {
|
||||
document.dispatchEvent(new KeyboardEvent("keydown", { key: "Tab", bubbles: true, cancelable: true }));
|
||||
document.dispatchEvent(
|
||||
new KeyboardEvent("keydown", { key: "Tab", bubbles: true, cancelable: true }),
|
||||
);
|
||||
}).not.toThrow();
|
||||
trap.deactivate();
|
||||
dispose();
|
||||
|
||||
@ -4,7 +4,11 @@ import { Portal } from "../../src/utilities/portal/portal";
|
||||
|
||||
describe("Portal", () => {
|
||||
it("renders children into document.body by default", () => {
|
||||
render(() => <Portal><div data-testid="portal-content">hello</div></Portal>);
|
||||
render(() => (
|
||||
<Portal>
|
||||
<div data-testid="portal-content">hello</div>
|
||||
</Portal>
|
||||
));
|
||||
// Content should be in document.body, not the render container
|
||||
expect(document.body.querySelector("[data-testid='portal-content']")).toBeTruthy();
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user