// src/Content.tsx
import { combineStyle } from "@corvu/utils/dom";
import {
  createMemo,
  Show,
  splitProps
} from "solid-js";
import { Dynamic } from "@corvu/utils/dynamic";
import { mergeRefs, some } from "@corvu/utils/reactivity";
import { dataIf } from "@corvu/utils";

// src/context.ts
import { createContext, useContext } from "solid-js";
import {
  createKeyedContext,
  useKeyedContext
} from "@corvu/utils/create/keyedContext";
var DisclosureContext = createContext();
var createDisclosureContext = (contextId) => {
  if (contextId === void 0) return DisclosureContext;
  const context = createKeyedContext(
    `disclosure-${contextId}`
  );
  return context;
};
var useDisclosureContext = (contextId) => {
  if (contextId === void 0) {
    const context2 = useContext(DisclosureContext);
    if (!context2) {
      throw new Error(
        "[corvu]: Disclosure context not found. Make sure to wrap Disclosure components in <Disclosure.Root>"
      );
    }
    return context2;
  }
  const context = useKeyedContext(
    `disclosure-${contextId}`
  );
  if (!context) {
    throw new Error(
      `[corvu]: Disclosure context with id "${contextId}" not found. Make sure to wrap Disclosure components in <Disclosure.Root contextId="${contextId}">`
    );
  }
  return context;
};
var InternalDisclosureContext = createContext();
var createInternalDisclosureContext = (contextId) => {
  if (contextId === void 0) return InternalDisclosureContext;
  const context = createKeyedContext(
    `disclosure-internal-${contextId}`
  );
  return context;
};
var useInternalDisclosureContext = (contextId) => {
  if (contextId === void 0) {
    const context2 = useContext(InternalDisclosureContext);
    if (!context2) {
      throw new Error(
        "[corvu]: Disclosure context not found. Make sure to wrap Disclosure components in <Disclosure.Root>"
      );
    }
    return context2;
  }
  const context = useKeyedContext(
    `disclosure-internal-${contextId}`
  );
  if (!context) {
    throw new Error(
      `[corvu]: Disclosure context with id "${contextId}" not found. Make sure to wrap Disclosure components in <Disclosure.Root contextId="${contextId}">`
    );
  }
  return context;
};

// src/Content.tsx
var DisclosureContent = (props) => {
  const [localProps, otherProps] = splitProps(props, [
    "forceMount",
    "contextId",
    "ref",
    "style"
  ]);
  const context = createMemo(
    () => useInternalDisclosureContext(localProps.contextId)
  );
  const show = () => some(
    context().expanded,
    () => localProps.forceMount,
    context().contentPresent
  );
  const contentWidth = createMemo(() => {
    const contentSize = context().contentSize();
    return contentSize ? contentSize[0] : void 0;
  });
  const contentHeight = createMemo(() => {
    const contentSize = context().contentSize();
    return contentSize ? contentSize[1] : void 0;
  });
  return <Show when={show() || context().collapseBehavior() === "hide"}>
      <Dynamic
    as="div"
    ref={mergeRefs(context().setContentRef, localProps.ref)}
    style={combineStyle(
      {
        display: !show() ? "none" : void 0,
        "--corvu-disclosure-content-width": `${contentWidth()}px`,
        "--corvu-disclosure-content-height": `${contentHeight()}px`
      },
      localProps.style
    )}
    id={context().disclosureId()}
    data-expanded={dataIf(context().expanded())}
    data-collapsed={dataIf(!context().expanded())}
    data-corvu-disclosure-content=""
    {...otherProps}
  />
    </Show>;
};
var Content_default = DisclosureContent;

// src/Root.tsx
import {
  createEffect,
  createMemo as createMemo2,
  createSignal,
  createUniqueId,
  mergeProps,
  on,
  untrack
} from "solid-js";
import createControllableSignal from "@corvu/utils/create/controllableSignal";
import createOnce from "@corvu/utils/create/once";
import createPresence from "solid-presence";
import { isFunction } from "@corvu/utils";
var DisclosureRoot = (props) => {
  const defaultedProps = mergeProps(
    {
      initialExpanded: false,
      collapseBehavior: "remove",
      preventInitialContentAnimation: false,
      disclosureId: createUniqueId()
    },
    props
  );
  const [expanded, setExpanded] = createControllableSignal({
    value: () => defaultedProps.expanded,
    initialValue: defaultedProps.initialExpanded,
    onChange: defaultedProps.onExpandedChange
  });
  const [contentRef, setContentRef] = createSignal(null);
  const [contentSize, setContentSize] = createSignal(
    null
  );
  const { present: contentPresent } = createPresence({
    show: expanded,
    element: contentRef,
    onStateChange: (state) => {
      if (state === "present") {
        defaultedProps.onContentPresentChange?.(true);
      } else if (state === "hidden") {
        defaultedProps.onContentPresentChange?.(false);
      }
    }
  });
  let initialOpen = defaultedProps.preventInitialContentAnimation && expanded();
  createEffect((animationName) => {
    expanded();
    const element = contentRef();
    if (!element) return;
    if (initialOpen) {
      const origionalAnimationName = element.style.animationName;
      element.style.animationName = "none";
      initialOpen = false;
      return origionalAnimationName;
    }
    if (animationName === void 0) return;
    element.style.animationName = animationName;
  });
  createEffect(
    on([contentRef, contentPresent], ([element]) => {
      if (!element) {
        setContentSize(null);
        return;
      }
      untrack(() => {
        const origionalAnimationName = element.style.animationName;
        element.style.animationName = "none";
        const width = element.offsetWidth;
        const height = element.offsetHeight;
        const currentSize = contentSize();
        if (currentSize === null || width !== currentSize[0] || height !== currentSize[1]) {
          setContentSize([element.offsetWidth, element.offsetHeight]);
        }
        element.style.animationName = origionalAnimationName;
      });
    })
  );
  const childrenProps = {
    get expanded() {
      return expanded();
    },
    setExpanded,
    get collapseBehavior() {
      return defaultedProps.collapseBehavior;
    },
    get preventInitialContentAnimation() {
      return defaultedProps.preventInitialContentAnimation;
    },
    get disclosureId() {
      return defaultedProps.disclosureId;
    },
    get contentPresent() {
      return contentPresent();
    },
    get contentRef() {
      return contentRef();
    },
    get contentSize() {
      return contentSize();
    }
  };
  const memoizedChildren = createOnce(() => defaultedProps.children);
  const resolveChildren = () => {
    const children = memoizedChildren()();
    if (isFunction(children)) {
      return children(childrenProps);
    }
    return children;
  };
  const memoizedDisclosureRoot = createMemo2(() => {
    const DisclosureContext2 = createDisclosureContext(defaultedProps.contextId);
    const InternalDisclosureContext2 = createInternalDisclosureContext(
      defaultedProps.contextId
    );
    return <DisclosureContext2.Provider
      value={{
        expanded,
        setExpanded,
        collapseBehavior: () => defaultedProps.collapseBehavior,
        preventInitialContentAnimation: () => defaultedProps.preventInitialContentAnimation,
        disclosureId: () => defaultedProps.disclosureId,
        contentPresent,
        contentRef,
        contentSize
      }}
    >
        <InternalDisclosureContext2.Provider
      value={{
        expanded,
        setExpanded,
        collapseBehavior: () => defaultedProps.collapseBehavior,
        preventInitialContentAnimation: () => defaultedProps.preventInitialContentAnimation,
        disclosureId: () => defaultedProps.disclosureId,
        contentPresent,
        contentRef,
        setContentRef,
        contentSize
      }}
    >
          {untrack(() => resolveChildren())}
        </InternalDisclosureContext2.Provider>
      </DisclosureContext2.Provider>;
  });
  return memoizedDisclosureRoot;
};
var Root_default = DisclosureRoot;

// src/Trigger.tsx
import { callEventHandler } from "@corvu/utils/dom";
import {
  createMemo as createMemo3,
  splitProps as splitProps2
} from "solid-js";
import {
  DynamicButton
} from "@corvu/utils/dynamic";
import { dataIf as dataIf2 } from "@corvu/utils";
var DisclosureTrigger = (props) => {
  const [localProps, otherProps] = splitProps2(props, [
    "contextId",
    "onClick"
  ]);
  const context = createMemo3(
    () => useInternalDisclosureContext(localProps.contextId)
  );
  const onClick = (e) => {
    !callEventHandler(localProps.onClick, e) && context().setExpanded((expanded) => !expanded);
  };
  return <DynamicButton
    onClick={onClick}
    aria-controls={context().disclosureId()}
    aria-expanded={context().expanded() ? "true" : "false"}
    data-collapsed={dataIf2(!context().expanded())}
    data-expanded={dataIf2(context().expanded())}
    data-corvu-disclosure-trigger=""
    {...otherProps}
  />;
};
var Trigger_default = DisclosureTrigger;

// src/index.ts
var Disclosure = Object.assign(Root_default, {
  Trigger: Trigger_default,
  Content: Content_default,
  useContext: useDisclosureContext
});
var index_default = Disclosure;
export {
  Content_default as Content,
  Root_default as Root,
  Trigger_default as Trigger,
  index_default as default,
  useDisclosureContext as useContext
};
