Files
documentation/node_modules/@docusaurus/theme-common/lib/components/Details/index.js
2024-03-22 03:47:51 +05:30

78 lines
3.1 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, { useRef, useState, } from 'react';
import clsx from 'clsx';
import useBrokenLinks from '@docusaurus/useBrokenLinks';
import useIsBrowser from '@docusaurus/useIsBrowser';
import { useCollapsible, Collapsible } from '../Collapsible';
import styles from './styles.module.css';
function isInSummary(node) {
if (!node) {
return false;
}
return node.tagName === 'SUMMARY' || isInSummary(node.parentElement);
}
function hasParent(node, parent) {
if (!node) {
return false;
}
return node === parent || hasParent(node.parentElement, parent);
}
/**
* A mostly un-styled `<details>` element with smooth collapsing. Provides some
* very lightweight styles, but you should bring your UI.
*/
export function Details({ summary, children, ...props }) {
useBrokenLinks().collectAnchor(props.id);
const isBrowser = useIsBrowser();
const detailsRef = useRef(null);
const { collapsed, setCollapsed } = useCollapsible({
initialState: !props.open,
});
// Use a separate state for the actual details prop, because it must be set
// only after animation completes, otherwise close animations won't work
const [open, setOpen] = useState(props.open);
const summaryElement = React.isValidElement(summary) ? (summary) : (<summary>{summary ?? 'Details'}</summary>);
return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions
<details {...props} ref={detailsRef} open={open} data-collapsed={collapsed} className={clsx(styles.details, isBrowser && styles.isBrowser, props.className)} onMouseDown={(e) => {
const target = e.target;
// Prevent a double-click to highlight summary text
if (isInSummary(target) && e.detail > 1) {
e.preventDefault();
}
}} onClick={(e) => {
e.stopPropagation(); // For isolation of multiple nested details/summary
const target = e.target;
const shouldToggle = isInSummary(target) && hasParent(target, detailsRef.current);
if (!shouldToggle) {
return;
}
e.preventDefault();
if (collapsed) {
setCollapsed(false);
setOpen(true);
}
else {
setCollapsed(true);
// Don't do this, it breaks close animation!
// setOpen(false);
}
}}>
{summaryElement}
<Collapsible lazy={false} // Content might matter for SEO in this case
collapsed={collapsed} disableSSRStyle // Allows component to work fine even with JS disabled!
onCollapseTransitionEnd={(newCollapsed) => {
setCollapsed(newCollapsed);
setOpen(!newCollapsed);
}}>
<div className={styles.collapsibleContent}>{children}</div>
</Collapsible>
</details>);
}
//# sourceMappingURL=index.js.map