/* * Portions of this file are based on code from react-spectrum. * Apache License Version 2.0, Copyright 2020 Adobe. * * Credits to the React Spectrum team: * https://github.com/adobe/react-spectrum/blob/c183944ce6a8ca1cf280a1c7b88d2ba393dd0252/packages/@react-aria/accordion/src/useAccordion.ts */ import { callHandler, composeEventHandlers, mergeDefaultProps, mergeRefs, } from "@kobalte/utils"; import { type Component, type JSX, type ValidComponent, createEffect, onCleanup, splitProps, } from "solid-js"; import * as Collapsible from "../collapsible"; import { useCollapsibleContext } from "../collapsible/collapsible-context"; import type { ElementOf, PolymorphicProps } from "../polymorphic"; import type { CollectionItemWithRef } from "../primitives"; import { createDomCollectionItem } from "../primitives/create-dom-collection"; import { createSelectableItem } from "../selection"; import { useAccordionContext } from "./accordion-context"; import { useAccordionItemContext } from "./accordion-item-context"; export interface AccordionTriggerOptions {} export interface AccordionTriggerCommonProps< T extends HTMLElement = HTMLElement, > extends Collapsible.CollapsibleTriggerCommonProps { id: string; onPointerDown: JSX.EventHandlerUnion; onPointerUp: JSX.EventHandlerUnion; onKeyDown: JSX.EventHandlerUnion; onMouseDown: JSX.EventHandlerUnion; onFocus: JSX.EventHandlerUnion; } export interface AccordionTriggerRenderProps extends AccordionTriggerCommonProps, Collapsible.CollapsibleTriggerRenderProps { "data-key": string | undefined; } export type AccordionTriggerProps< T extends ValidComponent | HTMLElement = HTMLElement, > = AccordionTriggerOptions & Partial>>; /** * Toggles the collapsed state of its associated item. It should be nested inside an `Accordion.Header`. */ export function AccordionTrigger( props: PolymorphicProps>, ) { let ref: HTMLElement | undefined; const accordionContext = useAccordionContext(); const itemContext = useAccordionItemContext(); const collapsibleContext = useCollapsibleContext(); const defaultId = itemContext.generateId("trigger"); const mergedProps = mergeDefaultProps( { id: defaultId }, props as AccordionTriggerProps, ); const [local, others] = splitProps(mergedProps, [ "ref", "onPointerDown", "onPointerUp", "onClick", "onKeyDown", "onMouseDown", "onFocus", ]); createDomCollectionItem({ getItem: () => ({ ref: () => ref, type: "item", key: itemContext.value(), textValue: "", // not applicable here disabled: collapsibleContext.disabled(), }), }); const selectableItem = createSelectableItem( { key: () => itemContext.value(), selectionManager: () => accordionContext.listState().selectionManager(), disabled: () => collapsibleContext.disabled(), shouldSelectOnPressUp: true, }, () => ref, ); const onKeyDown: JSX.EventHandlerUnion = (e) => { // Prevent `Enter` and `Space` default behavior which fires a click event when using a