import type { JSX, ValidComponent } from "@solidjs/web";
import { dynamic } from "@solidjs/web";
import { createRenderEffect, omit, onCleanup, Show } from "solid-js";
import { composeRefs, userRef } from "../../internals/compose-refs";
import { mergeRootProps } from "../../internals/merge-root-props";
import { resolveClassStyle } from "../../internals/resolve-class-style";
import type { BaseUIComponentProps } from "../../internals/types";
import { useScrollAreaRootContext } from "../root/scroll-area-root-context.ts";
// biome-ignore lint/complexity/noBannedTypes: matches Base UI React — corner exposes no state fields, but a named type lets consumers reference `ScrollArea.Corner.State`.
export type ScrollAreaCornerState = {};
export interface ScrollAreaCornerProps
extends BaseUIComponentProps<"div", ScrollAreaCornerState> {
/** Tag/component to render. Defaults to `"div"`. */
as?: ValidComponent;
}
/**
* Small square sitting at the intersection of the two scrollbars. Renders
* a `
` element (or `as` override), or nothing when both scrollbars are
* visible is false.
*
* §1 wave 3: replaces `renderElement` with `dynamic(() => props.as ?? "div")`.
*/
export function ScrollAreaCorner(props: ScrollAreaCornerProps): JSX.Element {
const context = useScrollAreaRootContext();
const userStyling = resolveClassStyle(props, () => ({}));
const userProps = omit(props, "class", "style", "attrs", "as");
const localRef = (el: HTMLDivElement | null): void => {
context.cornerRef.current = el;
};
// `` swaps its children by unmounting the old branch without firing
// the ref callback with `null`, so the shared `cornerRef.current` would
// dangle at a detached node. Ref callbacks run ownerless in Solid 2
// (`onCleanup` there is a no-op — `[NO_OWNER_CLEANUP]`), so the cleanup
// lives in owned scopes instead: a render effect mirroring the ``
// condition handles branch swaps, and onCleanup handles disposal.
createRenderEffect(
() => context.hiddenState().corner,
(hidden) => {
if (hidden) {
context.cornerRef.current = null;
}
return undefined;
},
);
onCleanup(() => {
context.cornerRef.current = null;
});
const internalSlot = {
get style(): JSX.CSSProperties {
const size = context.cornerSize();
return {
position: "absolute",
bottom: 0,
"inset-inline-end": 0,
width: `${size.width}px`,
height: `${size.height}px`,
};
},
};
const styledUserProps = mergeRootProps(userStyling, userProps);
const merged = mergeRootProps(internalSlot, styledUserProps);
const Tag = dynamic(() => props.as ?? "div");
return (
);
}