Skip to content

Commit

Permalink
refactor: polymorphic collapsible
Browse files Browse the repository at this point in the history
  • Loading branch information
jer3m01 committed Apr 3, 2024
1 parent 55823fe commit 159b0f8
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 24 deletions.
29 changes: 17 additions & 12 deletions packages/core/src/collapsible/collapsible-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/

import {
OverrideComponentProps,
mergeDefaultProps,
mergeRefs,
} from "@kobalte/utils";
Expand All @@ -20,31 +19,37 @@ import {
onCleanup,
onMount,
splitProps,
ValidComponent,
} from "solid-js";

import { AsChildProp, Polymorphic } from "../polymorphic";
import { Polymorphic, PolymorphicProps } from "../polymorphic";
import { createPresence } from "../primitives";
import { useCollapsibleContext } from "./collapsible-context";
import { CollapsibleDataSet, useCollapsibleContext } from "./collapsible-context";

export interface CollapsibleContentOptions extends AsChildProp {
/** The HTML styles attribute (object form only). */
export interface CollapsibleContentOptions {
}

export interface CollapsibleContentCommonProps {
id: string;
ref: HTMLElement | ((el: HTMLElement) => void);
style?: JSX.CSSProperties;
}

export interface CollapsibleContentProps
extends OverrideComponentProps<"div", CollapsibleContentOptions> {}
export interface CollapsibleContentRenderProps extends CollapsibleContentCommonProps, CollapsibleDataSet {}

export type CollapsibleContentProps = CollapsibleContentOptions & Partial<CollapsibleContentCommonProps>;

/**
* Contains the content to be rendered when the collapsible is expanded.
*/
export function CollapsibleContent(props: CollapsibleContentProps) {
let ref: HTMLDivElement | undefined;
export function CollapsibleContent<T extends ValidComponent = "div">(props: PolymorphicProps<T, CollapsibleContentProps>) {
let ref: HTMLElement | undefined;

const context = useCollapsibleContext();

const mergedProps = mergeDefaultProps(
{ id: context.generateId("content") },
props,
props as CollapsibleContentProps,
);

const [local, others] = splitProps(mergedProps, ["ref", "id", "style"]);
Expand Down Expand Up @@ -107,11 +112,11 @@ export function CollapsibleContent(props: CollapsibleContentProps) {
),
);

createEffect(() => onCleanup(context.registerContentId(local.id!)));
createEffect(() => onCleanup(context.registerContentId(local.id)));

return (
<Show when={presence.isPresent()}>
<Polymorphic
<Polymorphic<CollapsibleContentRenderProps>
as="div"
ref={mergeRefs((el) => {
presence.setRef(el);
Expand Down
30 changes: 23 additions & 7 deletions packages/core/src/collapsible/collapsible-root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ import {
createSignal,
createUniqueId,
splitProps,
ValidComponent,
} from "solid-js";

import { AsChildProp, Polymorphic } from "../polymorphic";
import { Polymorphic, PolymorphicProps } from "../polymorphic";
import { createDisclosureState, createRegisterId } from "../primitives";
import {
CollapsibleContext,
CollapsibleContextValue,
CollapsibleDataSet,
} from "./collapsible-context";

export interface CollapsibleRootOptions extends AsChildProp {
export interface CollapsibleRootOptions {
/** The controlled open state of the collapsible. */
open?: boolean;

Expand All @@ -50,16 +51,27 @@ export interface CollapsibleRootOptions extends AsChildProp {
forceMount?: boolean;
}

export interface CollapsibleRootProps
extends OverrideComponentProps<"div", CollapsibleRootOptions> {}
export interface CollapsibleRootCommonProps {
id: string;
}

export interface CollapsibleRootRenderProps
extends CollapsibleRootCommonProps, CollapsibleDataSet {
}

export type CollapsibleRootProps = CollapsibleRootOptions &
Partial<CollapsibleRootCommonProps>;

/**
* An interactive component which expands/collapses a content.
*/
export function CollapsibleRoot(props: CollapsibleRootProps) {
export function CollapsibleRoot<T extends ValidComponent = "div">(props: PolymorphicProps<T, CollapsibleRootProps>) {
const defaultId = `collapsible-${createUniqueId()}`;

const mergedProps = mergeDefaultProps({ id: defaultId }, props);
const mergedProps = mergeDefaultProps(
{ id: defaultId },
props as CollapsibleRootProps,
);

const [local, others] = splitProps(mergedProps, [
"open",
Expand Down Expand Up @@ -96,7 +108,11 @@ export function CollapsibleRoot(props: CollapsibleRootProps) {

return (
<CollapsibleContext.Provider value={context}>
<Polymorphic as="div" {...dataset()} {...others} />
<Polymorphic<CollapsibleRootRenderProps>
as="div"
{...dataset()}
{...others}
/>
</CollapsibleContext.Provider>
);
}
21 changes: 16 additions & 5 deletions packages/core/src/collapsible/collapsible-trigger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,30 @@
*/

import { OverrideComponentProps, callHandler } from "@kobalte/utils";
import { JSX, splitProps } from "solid-js";
import { JSX, splitProps, ValidComponent } from "solid-js";

import * as Button from "../button";
import { AsChildProp } from "../polymorphic";
import { PolymorphicProps } from "../polymorphic";
import { useCollapsibleContext } from "./collapsible-context";

export interface CollapsibleTriggerProps
extends OverrideComponentProps<"button", AsChildProp> {}
export interface CollapsibleTriggerOptions {
onClick?: any; // TODO
}

export interface CollapsibleTriggerCommonProps {
id: string;
ref: HTMLElement | ((el: HTMLElement) => void);
}

// TODO impl ButtonRenderProps!
export interface CollapsibleTriggerRenderProps extends CollapsibleTriggerCommonProps {}

export type CollapsibleTriggerProps = CollapsibleTriggerOptions & Partial<CollapsibleTriggerCommonProps>;

/**
* The button that expands/collapses the collapsible content.
*/
export function CollapsibleTrigger(props: CollapsibleTriggerProps) {
export function CollapsibleTrigger<T extends ValidComponent = "div">(props: PolymorphicProps<T, CollapsibleTriggerProps>) {
const context = useCollapsibleContext();

const [local, others] = splitProps(props, ["onClick"]);
Expand Down
14 changes: 14 additions & 0 deletions packages/core/src/collapsible/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
import {
CollapsibleContent as Content,
type CollapsibleContentOptions,
type CollapsibleContentCommonProps,
type CollapsibleContentRenderProps,
type CollapsibleContentProps,
} from "./collapsible-content";
import {
CollapsibleRoot as Root,
type CollapsibleRootOptions,
type CollapsibleRootCommonProps,
type CollapsibleRootRenderProps,
type CollapsibleRootProps,
} from "./collapsible-root";
import {
CollapsibleTrigger as Trigger,
type CollapsibleTriggerOptions,
type CollapsibleTriggerCommonProps,
type CollapsibleTriggerRenderProps,
type CollapsibleTriggerProps,
} from "./collapsible-trigger";

export type {
CollapsibleContentOptions,
CollapsibleContentCommonProps,
CollapsibleContentRenderProps,
CollapsibleContentProps,
CollapsibleRootOptions,
CollapsibleRootCommonProps,
CollapsibleRootRenderProps,
CollapsibleRootProps,
CollapsibleTriggerOptions,
CollapsibleTriggerCommonProps,
CollapsibleTriggerRenderProps,
CollapsibleTriggerProps,
};
export { Content, Root, Trigger };

0 comments on commit 159b0f8

Please sign in to comment.