Fix Accordion per-item disabled
- Add disabled accessor to AccordionItemContextValue and itemCtx so per-item disabled prop disables the trigger button - Use getter for itemCtx.value to stay reactive with the local proxy - Guard onClick toggle against itemCtx.disabled() in addition to rootCtx.disabled() - Add one-liner JSDoc to all six exported accordion interfaces
This commit is contained in:
parent
94822186c2
commit
30ee5c877e
@ -2,6 +2,7 @@ import type { JSX } from "solid-js";
|
||||
import { splitProps } from "solid-js";
|
||||
import { useAccordionItemContext } from "./accordion-context";
|
||||
|
||||
/** Props for the collapsible content panel of an Accordion item. */
|
||||
export interface AccordionContentProps extends JSX.HTMLAttributes<HTMLDivElement> {
|
||||
children?: JSX.Element;
|
||||
}
|
||||
|
||||
@ -1,17 +1,20 @@
|
||||
import type { Accessor } from "solid-js";
|
||||
import { createContext, useContext } from "solid-js";
|
||||
|
||||
/** Shared state provided by AccordionRoot to all descendant accordion parts. */
|
||||
export interface AccordionRootContextValue {
|
||||
isExpanded: (value: string) => boolean;
|
||||
toggleItem: (value: string) => void;
|
||||
disabled: Accessor<boolean>;
|
||||
}
|
||||
|
||||
/** Per-item state provided by AccordionItem to its trigger and content. */
|
||||
export interface AccordionItemContextValue {
|
||||
value: string;
|
||||
isExpanded: Accessor<boolean>;
|
||||
triggerId: string;
|
||||
contentId: string;
|
||||
disabled: Accessor<boolean>;
|
||||
}
|
||||
|
||||
const AccordionRootContext = createContext<AccordionRootContextValue>();
|
||||
|
||||
@ -2,6 +2,7 @@ import type { JSX } from "solid-js";
|
||||
import { splitProps } from "solid-js";
|
||||
import { Dynamic } from "solid-js/web";
|
||||
|
||||
/** Props for the heading wrapper rendered around an Accordion trigger. */
|
||||
export interface AccordionHeaderProps extends JSX.HTMLAttributes<HTMLHeadingElement> {
|
||||
/** Heading level element. @default "h3" */
|
||||
as?: string;
|
||||
|
||||
@ -2,6 +2,7 @@ import type { JSX } from "solid-js";
|
||||
import { createUniqueId, splitProps } from "solid-js";
|
||||
import { AccordionItemContextProvider, useAccordionRootContext } from "./accordion-context";
|
||||
|
||||
/** Props for a single collapsible item within an Accordion. */
|
||||
export interface AccordionItemProps extends JSX.HTMLAttributes<HTMLDivElement> {
|
||||
value: string;
|
||||
disabled?: boolean;
|
||||
@ -16,10 +17,13 @@ export function AccordionItem(props: AccordionItemProps): JSX.Element {
|
||||
const contentId = createUniqueId();
|
||||
|
||||
const itemCtx = {
|
||||
value: local.value,
|
||||
get value() {
|
||||
return local.value;
|
||||
},
|
||||
isExpanded: () => rootCtx.isExpanded(local.value),
|
||||
triggerId,
|
||||
contentId,
|
||||
disabled: () => local.disabled ?? false,
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@ -2,6 +2,7 @@ import type { JSX } from "solid-js";
|
||||
import { createSignal, splitProps } from "solid-js";
|
||||
import { AccordionRootContextProvider, type AccordionRootContextValue } from "./accordion-context";
|
||||
|
||||
/** Props for the root accordion container that manages expanded state. */
|
||||
export interface AccordionRootProps extends JSX.HTMLAttributes<HTMLDivElement> {
|
||||
/** "single" allows one item open at a time; "multiple" allows any number. @default "single" */
|
||||
type?: "single" | "multiple";
|
||||
|
||||
@ -2,6 +2,7 @@ import type { JSX } from "solid-js";
|
||||
import { splitProps } from "solid-js";
|
||||
import { useAccordionItemContext, useAccordionRootContext } from "./accordion-context";
|
||||
|
||||
/** Props for the button that toggles an Accordion item open/closed. */
|
||||
export interface AccordionTriggerProps extends JSX.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
children?: JSX.Element;
|
||||
}
|
||||
@ -20,11 +21,11 @@ export function AccordionTrigger(props: AccordionTriggerProps): JSX.Element {
|
||||
aria-controls={itemCtx.contentId}
|
||||
data-state={itemCtx.isExpanded() ? "open" : "closed"}
|
||||
data-accordion-trigger
|
||||
disabled={rootCtx.disabled()}
|
||||
disabled={rootCtx.disabled() || itemCtx.disabled()}
|
||||
{...rest}
|
||||
onClick={(e) => {
|
||||
if (typeof rest.onClick === "function") rest.onClick(e);
|
||||
if (!rootCtx.disabled()) rootCtx.toggleItem(itemCtx.value);
|
||||
if (!rootCtx.disabled() && !itemCtx.disabled()) rootCtx.toggleItem(itemCtx.value);
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (typeof rest.onKeyDown === "function") rest.onKeyDown(e);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user