braid-design-system
Version:
Themeable design system for the SEEK Group
104 lines (103 loc) • 3.68 kB
JavaScript
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
import assert from "assert";
import { useContext } from "react";
import { Box } from "../Box/Box.mjs";
import { HeadingContext } from "../Heading/HeadingContext.mjs";
import { Text } from "../Text/Text.mjs";
import { TextContext } from "../Text/TextContext.mjs";
import { TextLinkButton } from "../TextLinkButton/TextLinkButton.mjs";
import { AvoidWidowIcon } from "../private/AvoidWidowIcon/AvoidWidowIcon.mjs";
import { buildDataAttributes } from "../private/buildDataAttributes.mjs";
import { DefaultTextPropsProvider } from "../private/defaultTextProps.mjs";
import { useDisclosure } from "./useDisclosure.mjs";
import { IconChevron } from "../icons/IconChevron/IconChevron.mjs";
const defaultSpaceForSize = {
large: "medium",
standard: "medium",
xsmall: "small",
small: "small"
};
const Disclosure = ({
id,
expandLabel,
collapseLabel = expandLabel,
space,
size: sizeProp,
children,
data,
weight,
...restProps
}) => {
assert(
typeof expandLabel === "undefined" || typeof expandLabel === "string",
"'expandLabel' must be a string"
);
assert(
typeof collapseLabel === "undefined" || typeof collapseLabel === "string",
"'collapseLabel' must be a string"
);
const textContext = useContext(TextContext);
const headingContext = useContext(HeadingContext);
const isInline = Boolean(textContext || headingContext);
assert(
typeof sizeProp === "undefined" || !isInline,
`Specifying a custom \`size\` for a \`Disclosure\` inside the context of a \`<${textContext ? "Text" : "Heading"}>\` component is invalid. See the documentation for correct usage: https://seek-oss.github.io/braid-design-system/components/Disclosure`
);
const { expanded, buttonProps, contentProps } = useDisclosure({
id,
...restProps.expanded !== void 0 ? {
onToggle: restProps.onToggle,
expanded: restProps.expanded
} : {
onToggle: restProps.onToggle
}
});
const size = sizeProp ?? (textContext == null ? void 0 : textContext.size) ?? "standard";
const defaultSpace = isInline ? (
/*
* If inline, only use `xxsmall` space between the trigger and the content
* to compensate for the additional space created by the line height of text.
*/
"xxsmall"
) : defaultSpaceForSize[size];
const trigger = /* @__PURE__ */ jsxs(TextLinkButton, { hitArea: "large", weight, ...buttonProps, children: [
expanded ? collapseLabel : expandLabel,
/* @__PURE__ */ jsx(AvoidWidowIcon, { iconPosition: "trailing", children: /* @__PURE__ */ jsx(IconChevron, { direction: expanded ? "up" : "down", alignY: "lowercase" }) })
] });
const component = isInline ? "span" : "div";
return /* @__PURE__ */ jsxs(
Box,
{
component,
display: isInline ? "inline" : void 0,
...buildDataAttributes({ data, validateRestProps: restProps }),
children: [
/* @__PURE__ */ jsx(
Box,
{
component,
display: isInline ? "inline" : void 0,
userSelect: "none",
children: isInline ? /* @__PURE__ */ jsxs(Fragment, { children: [
" ",
trigger
] }) : /* @__PURE__ */ jsx(Text, { size, children: trigger })
}
),
/* @__PURE__ */ jsx(
Box,
{
component,
paddingTop: space ?? defaultSpace,
display: expanded ? "block" : "none",
...contentProps,
children: isInline ? children : /* @__PURE__ */ jsx(DefaultTextPropsProvider, { size, children })
}
)
]
}
);
};
export {
Disclosure
};