// src/Close.tsx
import { callEventHandler } from "@corvu/utils/dom";
import {
  createMemo,
  splitProps
} from "solid-js";
import {
  DynamicButton
} from "@corvu/utils/dynamic";

// src/context.ts
import { createContext, useContext } from "solid-js";
import {
  createKeyedContext,
  useKeyedContext
} from "@corvu/utils/create/keyedContext";
var DialogContext = createContext();
var createDialogContext = (contextId) => {
  if (contextId === void 0) return DialogContext;
  const context = createKeyedContext(`dialog-${contextId}`);
  return context;
};
var useDialogContext = (contextId) => {
  if (contextId === void 0) {
    const context2 = useContext(DialogContext);
    if (!context2) {
      throw new Error(
        "[corvu]: Dialog context not found. Make sure to wrap Dialog components in <Dialog.Root>"
      );
    }
    return context2;
  }
  const context = useKeyedContext(`dialog-${contextId}`);
  if (!context) {
    throw new Error(
      `[corvu]: Dialog context with id "${contextId}" not found. Make sure to wrap Dialog components in <Dialog.Root contextId="${contextId}">`
    );
  }
  return context;
};
var InternalDialogContext = createContext();
var createInternalDialogContext = (contextId) => {
  if (contextId === void 0) return InternalDialogContext;
  const context = createKeyedContext(
    `dialog-internal-${contextId}`
  );
  return context;
};
var useInternalDialogContext = (contextId) => {
  if (contextId === void 0) {
    const context2 = useContext(InternalDialogContext);
    if (!context2) {
      throw new Error(
        "[corvu]: Dialog context not found. Make sure to wrap Dialog components in <Dialog.Root>"
      );
    }
    return context2;
  }
  const context = useKeyedContext(
    `dialog-internal-${contextId}`
  );
  if (!context) {
    throw new Error(
      `[corvu]: Dialog context with id "${contextId}" not found. Make sure to wrap Dialog components in <Dialog.Root contextId="${contextId}">`
    );
  }
  return context;
};

// src/Close.tsx
var DialogClose = (props) => {
  const [localProps, otherProps] = splitProps(props, [
    "contextId",
    "onClick"
  ]);
  const context = createMemo(
    () => useInternalDialogContext(localProps.contextId)
  );
  const onClick = (event) => {
    !callEventHandler(localProps.onClick, event) && context().setOpen(false);
  };
  return <DynamicButton
    onClick={onClick}
    aria-label="close"
    data-corvu-dialog-close=""
    {...otherProps}
  />;
};
var Close_default = DialogClose;

// src/Content.tsx
import { combineStyle } from "@corvu/utils/dom";
import {
  createMemo as createMemo2,
  Show,
  splitProps as splitProps2
} from "solid-js";
import { Dynamic } from "@corvu/utils/dynamic";
import { mergeRefs, some } from "@corvu/utils/reactivity";
import { dataIf } from "@corvu/utils";
import Dismissible from "solid-dismissible";
var DialogContent = (props) => {
  const [localProps, otherProps] = splitProps2(props, [
    "forceMount",
    "contextId",
    "ref",
    "style"
  ]);
  const context = createMemo2(
    () => useInternalDialogContext(localProps.contextId)
  );
  const show = () => some(context().open, () => localProps.forceMount, context().contentPresent);
  const enableDismissible = createMemo2(
    () => context().open() || context().contentPresent()
  );
  return <Dismissible
    element={context().contentRef}
    enabled={enableDismissible()}
    dismissibleId={context().dialogId()}
    onDismiss={() => context().setOpen(false)}
    dismissOnEscapeKeyDown={context().closeOnEscapeKeyDown}
    dismissOnOutsideFocus={context().closeOnOutsideFocus}
    dismissOnOutsidePointer={context().closeOnOutsidePointer}
    outsidePointerStrategy={context().closeOnOutsidePointerStrategy}
    outsidePointerIgnore={() => [context().triggerRef()]}
    noOutsidePointerEvents={context().noOutsidePointerEvents}
    onEscapeKeyDown={context().onEscapeKeyDown}
    onOutsideFocus={context().onOutsideFocus}
    onOutsidePointer={context().onOutsidePointer}
  >
      {(props2) => <Show when={show()}>
          <Dynamic
    as="div"
    ref={mergeRefs(context().setContentRef, localProps.ref)}
    style={combineStyle(
      {
        "pointer-events": props2.isLastLayer ? "auto" : void 0
      },
      localProps.style
    )}
    id={context().dialogId()}
    role={context().role()}
    tabIndex="-1"
    aria-describedby={context().descriptionId()}
    aria-labelledby={context().labelId()}
    aria-modal={context().modal() ? "true" : "false"}
    data-closed={dataIf(!context().open())}
    data-open={dataIf(context().open())}
    data-corvu-dialog-content=""
    {...otherProps}
  />
        </Show>}
    </Dismissible>;
};
var Content_default = DialogContent;

// src/Description.tsx
import {
  createEffect,
  createMemo as createMemo3,
  onCleanup,
  splitProps as splitProps3
} from "solid-js";
import { Dynamic as Dynamic2 } from "@corvu/utils/dynamic";
var DialogDescription = (props) => {
  const [localProps, otherProps] = splitProps3(props, [
    "contextId"
  ]);
  const context = createMemo3(
    () => useInternalDialogContext(localProps.contextId)
  );
  createEffect(() => {
    const _context = context();
    _context.registerDescriptionId();
    onCleanup(() => _context.unregisterDescriptionId());
  });
  return <Dynamic2
    as="p"
    id={context().descriptionId()}
    data-corvu-dialog-description=""
    {...otherProps}
  />;
};
var Description_default = DialogDescription;

// src/Label.tsx
import {
  createEffect as createEffect2,
  createMemo as createMemo4,
  onCleanup as onCleanup2,
  splitProps as splitProps4
} from "solid-js";
import { Dynamic as Dynamic3 } from "@corvu/utils/dynamic";
var DialogLabel = (props) => {
  const [localProps, otherProps] = splitProps4(props, [
    "contextId"
  ]);
  const context = createMemo4(
    () => useInternalDialogContext(localProps.contextId)
  );
  createEffect2(() => {
    const _context = context();
    _context.registerLabelId();
    onCleanup2(() => _context.unregisterLabelId());
  });
  return <Dynamic3
    as="h2"
    id={context().labelId()}
    data-corvu-dialog-label=""
    {...otherProps}
  />;
};
var Label_default = DialogLabel;

// src/Overlay.tsx
import { combineStyle as combineStyle2 } from "@corvu/utils/dom";
import {
  createMemo as createMemo5,
  Show as Show2,
  splitProps as splitProps5
} from "solid-js";
import { Dynamic as Dynamic4 } from "@corvu/utils/dynamic";
import { mergeRefs as mergeRefs2, some as some2 } from "@corvu/utils/reactivity";
import { dataIf as dataIf2 } from "@corvu/utils";
var DialogOverlay = (props) => {
  const [localProps, otherProps] = splitProps5(props, [
    "forceMount",
    "contextId",
    "ref",
    "style"
  ]);
  const context = createMemo5(
    () => useInternalDialogContext(localProps.contextId)
  );
  const show = () => some2(context().open, () => localProps.forceMount, context().overlayPresent);
  return <Show2 when={show()}>
      <Dynamic4
    as="div"
    ref={mergeRefs2(context().setOverlayRef, localProps.ref)}
    style={combineStyle2(
      {
        "pointer-events": "auto"
      },
      localProps.style
    )}
    aria-hidden="true"
    data-closed={dataIf2(!context().open())}
    data-open={dataIf2(context().open())}
    data-corvu-dialog-overlay=""
    {...otherProps}
  />
    </Show2>;
};
var Overlay_default = DialogOverlay;

// src/Portal.tsx
import { createMemo as createMemo6, Show as Show3, splitProps as splitProps6 } from "solid-js";
import { Portal } from "solid-js/web";
import { some as some3 } from "@corvu/utils/reactivity";
var DialogPortal = (props) => {
  const [localProps, otherProps] = splitProps6(props, [
    "forceMount",
    "contextId"
  ]);
  const context = createMemo6(
    () => useInternalDialogContext(localProps.contextId)
  );
  const show = () => some3(
    context().open,
    () => localProps.forceMount,
    context().contentPresent,
    context().overlayPresent
  );
  return <Show3 when={show()}>
      <Portal {...otherProps} />
    </Show3>;
};
var Portal_default = DialogPortal;

// src/Root.tsx
import {
  createMemo as createMemo7,
  createSignal,
  createUniqueId,
  mergeProps,
  untrack
} from "solid-js";
import { access } from "@corvu/utils/reactivity";
import createControllableSignal from "@corvu/utils/create/controllableSignal";
import createFocusTrap from "solid-focus-trap";
import createOnce from "@corvu/utils/create/once";
import createPresence from "solid-presence";
import createPreventScroll from "solid-prevent-scroll";
import createRegister from "@corvu/utils/create/register";
import { isFunction } from "@corvu/utils";
var DEFAULT_MODAL = true;
var DialogRoot = (props) => {
  const defaultedProps = mergeProps(
    {
      role: "dialog",
      initialOpen: false,
      modal: true,
      closeOnEscapeKeyDown: true,
      closeOnOutsideFocus: () => props.trapFocus ?? true,
      closeOnOutsidePointer: () => props.modal ?? DEFAULT_MODAL,
      closeOnOutsidePointerStrategy: "pointerup",
      noOutsidePointerEvents: () => props.modal ?? DEFAULT_MODAL,
      preventScroll: () => props.modal ?? DEFAULT_MODAL,
      hideScrollbar: true,
      preventScrollbarShift: true,
      preventScrollbarShiftMode: "padding",
      restoreScrollPosition: true,
      allowPinchZoom: true,
      trapFocus: true,
      restoreFocus: true,
      dialogId: createUniqueId()
    },
    props
  );
  const [open, setOpen] = createControllableSignal({
    value: () => defaultedProps.open,
    initialValue: defaultedProps.initialOpen,
    onChange: defaultedProps.onOpenChange
  });
  const [labelId, registerLabelId, unregisterLabelId] = createRegister({
    value: () => defaultedProps.labelId ?? createUniqueId()
  });
  const [descriptionId, registerDescriptionId, unregisterDescriptionId] = createRegister({
    value: () => defaultedProps.descriptionId ?? createUniqueId()
  });
  const [triggerRef, setTriggerRef] = createSignal(null);
  const [contentRef, setContentRef] = createSignal(null);
  const [overlayRef, setOverlayRef] = createSignal(null);
  const { present: contentPresent } = createPresence({
    show: open,
    element: contentRef,
    onStateChange: (state) => {
      if (state === "present") {
        defaultedProps.onContentPresentChange?.(true);
      } else if (state === "hidden") {
        defaultedProps.onContentPresentChange?.(false);
      }
    }
  });
  const { present: overlayPresent } = createPresence({
    show: open,
    element: overlayRef,
    onStateChange: (state) => {
      if (state === "present") {
        defaultedProps.onOverlayPresentChange?.(true);
      } else if (state === "hidden") {
        defaultedProps.onOverlayPresentChange?.(false);
      }
    }
  });
  createFocusTrap({
    element: contentRef,
    enabled: () => open() && defaultedProps.trapFocus,
    initialFocusElement: () => defaultedProps.initialFocusEl ?? null,
    restoreFocus: () => defaultedProps.restoreFocus,
    finalFocusElement: () => defaultedProps.finalFocusEl ?? null,
    onFinalFocus: defaultedProps.onFinalFocus,
    onInitialFocus: defaultedProps.onInitialFocus
  });
  createPreventScroll({
    element: contentRef,
    enabled: () => contentPresent() && access(defaultedProps.preventScroll),
    hideScrollbar: () => defaultedProps.hideScrollbar,
    preventScrollbarShift: () => defaultedProps.preventScrollbarShift,
    preventScrollbarShiftMode: () => defaultedProps.preventScrollbarShiftMode,
    restoreScrollPosition: () => defaultedProps.restoreScrollPosition,
    allowPinchZoom: () => defaultedProps.allowPinchZoom
  });
  const childrenProps = {
    get role() {
      return defaultedProps.role;
    },
    get open() {
      return open();
    },
    setOpen,
    get modal() {
      return defaultedProps.modal;
    },
    get closeOnEscapeKeyDown() {
      return defaultedProps.closeOnEscapeKeyDown;
    },
    get closeOnOutsideFocus() {
      return access(defaultedProps.closeOnOutsideFocus);
    },
    get closeOnOutsidePointer() {
      return access(defaultedProps.closeOnOutsidePointer);
    },
    get closeOnOutsidePointerStrategy() {
      return defaultedProps.closeOnOutsidePointerStrategy;
    },
    get noOutsidePointerEvents() {
      return access(defaultedProps.noOutsidePointerEvents);
    },
    get preventScroll() {
      return access(defaultedProps.preventScroll);
    },
    get hideScrollbar() {
      return defaultedProps.hideScrollbar;
    },
    get preventScrollbarShift() {
      return access(defaultedProps.preventScrollbarShift);
    },
    get preventScrollbarShiftMode() {
      return defaultedProps.preventScrollbarShiftMode;
    },
    get restoreScrollPosition() {
      return defaultedProps.restoreScrollPosition;
    },
    get allowPinchZoom() {
      return defaultedProps.allowPinchZoom;
    },
    get trapFocus() {
      return defaultedProps.trapFocus;
    },
    get restoreFocus() {
      return defaultedProps.restoreFocus;
    },
    get initialFocusEl() {
      return defaultedProps.initialFocusEl;
    },
    get finalFocusEl() {
      return defaultedProps.finalFocusEl;
    },
    get contentPresent() {
      return contentPresent();
    },
    get contentRef() {
      return contentRef();
    },
    get overlayPresent() {
      return overlayPresent();
    },
    get overlayRef() {
      return overlayRef();
    },
    get dialogId() {
      return defaultedProps.dialogId;
    },
    get labelId() {
      return labelId();
    },
    get descriptionId() {
      return descriptionId();
    }
  };
  const memoizedChildren = createOnce(() => defaultedProps.children);
  const resolveChildren = () => {
    const children = memoizedChildren()();
    if (isFunction(children)) {
      return children(childrenProps);
    }
    return children;
  };
  const memoizedDialogRoot = createMemo7(() => {
    const DialogContext2 = createDialogContext(defaultedProps.contextId);
    const InternalDialogContext2 = createInternalDialogContext(
      defaultedProps.contextId
    );
    return <DialogContext2.Provider
      value={{
        role: () => defaultedProps.role,
        open,
        setOpen,
        modal: () => defaultedProps.modal,
        closeOnEscapeKeyDown: () => defaultedProps.closeOnEscapeKeyDown,
        closeOnOutsideFocus: () => access(defaultedProps.closeOnOutsideFocus),
        closeOnOutsidePointer: () => access(defaultedProps.closeOnOutsidePointer),
        closeOnOutsidePointerStrategy: () => defaultedProps.closeOnOutsidePointerStrategy,
        noOutsidePointerEvents: () => access(defaultedProps.noOutsidePointerEvents),
        preventScroll: () => access(defaultedProps.preventScroll),
        hideScrollbar: () => defaultedProps.hideScrollbar,
        preventScrollbarShift: () => access(defaultedProps.preventScrollbarShift),
        preventScrollbarShiftMode: () => defaultedProps.preventScrollbarShiftMode,
        restoreScrollPosition: () => defaultedProps.restoreScrollPosition,
        allowPinchZoom: () => defaultedProps.allowPinchZoom,
        trapFocus: () => defaultedProps.trapFocus,
        restoreFocus: () => defaultedProps.restoreFocus,
        initialFocusEl: () => defaultedProps.initialFocusEl,
        finalFocusEl: () => defaultedProps.finalFocusEl,
        contentPresent,
        contentRef,
        overlayPresent,
        overlayRef,
        dialogId: () => defaultedProps.dialogId,
        labelId,
        descriptionId
      }}
    >
        <InternalDialogContext2.Provider
      value={{
        role: () => defaultedProps.role,
        open,
        setOpen,
        modal: () => defaultedProps.modal,
        closeOnEscapeKeyDown: () => defaultedProps.closeOnEscapeKeyDown,
        onEscapeKeyDown: defaultedProps.onEscapeKeyDown,
        closeOnOutsideFocus: () => access(defaultedProps.closeOnOutsideFocus),
        closeOnOutsidePointer: () => access(defaultedProps.closeOnOutsidePointer),
        closeOnOutsidePointerStrategy: () => defaultedProps.closeOnOutsidePointerStrategy,
        onOutsideFocus: defaultedProps.onOutsideFocus,
        onOutsidePointer: defaultedProps.onOutsidePointer,
        noOutsidePointerEvents: () => access(defaultedProps.noOutsidePointerEvents),
        preventScroll: () => access(defaultedProps.preventScroll),
        hideScrollbar: () => defaultedProps.hideScrollbar,
        preventScrollbarShift: () => access(defaultedProps.preventScrollbarShift),
        preventScrollbarShiftMode: () => defaultedProps.preventScrollbarShiftMode,
        restoreScrollPosition: () => defaultedProps.restoreScrollPosition,
        allowPinchZoom: () => defaultedProps.allowPinchZoom,
        trapFocus: () => defaultedProps.trapFocus,
        restoreFocus: () => defaultedProps.restoreFocus,
        initialFocusEl: () => defaultedProps.initialFocusEl,
        finalFocusEl: () => defaultedProps.finalFocusEl,
        contentPresent,
        contentRef,
        overlayPresent,
        overlayRef,
        dialogId: () => defaultedProps.dialogId,
        labelId,
        registerLabelId,
        unregisterLabelId,
        descriptionId,
        registerDescriptionId,
        unregisterDescriptionId,
        setContentRef,
        setOverlayRef,
        triggerRef,
        setTriggerRef
      }}
    >
          {untrack(() => resolveChildren())}
        </InternalDialogContext2.Provider>
      </DialogContext2.Provider>;
  });
  return memoizedDialogRoot;
};
var Root_default = DialogRoot;

// src/Trigger.tsx
import { callEventHandler as callEventHandler2 } from "@corvu/utils/dom";
import {
  createMemo as createMemo8,
  splitProps as splitProps7
} from "solid-js";
import {
  DynamicButton as DynamicButton2
} from "@corvu/utils/dynamic";
import { dataIf as dataIf3 } from "@corvu/utils";
import { mergeRefs as mergeRefs3 } from "@corvu/utils/reactivity";
var DialogTrigger = (props) => {
  const [localProps, otherProps] = splitProps7(props, [
    "contextId",
    "ref",
    "onClick"
  ]);
  const context = createMemo8(
    () => useInternalDialogContext(localProps.contextId)
  );
  const onClick = (e) => {
    !callEventHandler2(localProps.onClick, e) && context().setOpen((open) => !open);
  };
  return <DynamicButton2
    ref={mergeRefs3(context().setTriggerRef, localProps.ref)}
    onClick={onClick}
    aria-controls={context().dialogId()}
    aria-expanded={context().open() ? "true" : "false"}
    aria-haspopup="dialog"
    data-closed={dataIf3(!context().open())}
    data-open={dataIf3(context().open())}
    data-corvu-dialog-trigger=""
    {...otherProps}
  />;
};
var Trigger_default = DialogTrigger;

// src/index.ts
var Dialog = Object.assign(Root_default, {
  Trigger: Trigger_default,
  Portal: Portal_default,
  Overlay: Overlay_default,
  Content: Content_default,
  Label: Label_default,
  Description: Description_default,
  Close: Close_default,
  useContext: useDialogContext
});
var index_default = Dialog;
export {
  Close_default as Close,
  Content_default as Content,
  Description_default as Description,
  Label_default as Label,
  Overlay_default as Overlay,
  Portal_default as Portal,
  Root_default as Root,
  Trigger_default as Trigger,
  index_default as default,
  useDialogContext as useContext
};
