From e120d2b30bd504e86a25c7b1df76962829bc6ce1 Mon Sep 17 00:00:00 2001 From: Jakub Mroz <115979017+jakmro@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:26:03 +0100 Subject: [PATCH] docs: Add matching details section in the docs (#72) ## Description Add matching details section in the docs ### Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] Documentation update (improves or adds clarity to existing documentation) ### Checklist - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation accordingly - [x] My changes generate no new warnings --- docs/src/theme/MDXComponents.js | 7 ++ docs/src/theme/MDXComponents/Details.js | 20 ++++ .../theme/MDXComponents/DetailsStyling.tsx | 101 ++++++++++++++++++ .../src/theme/MDXComponents/styles.module.css | 50 +++++++++ docs/static/img/Arrow-dark.svg | 3 + docs/static/img/Arrow.svg | 3 + 6 files changed, 184 insertions(+) create mode 100644 docs/src/theme/MDXComponents.js create mode 100644 docs/src/theme/MDXComponents/Details.js create mode 100644 docs/src/theme/MDXComponents/DetailsStyling.tsx create mode 100644 docs/src/theme/MDXComponents/styles.module.css create mode 100644 docs/static/img/Arrow-dark.svg create mode 100644 docs/static/img/Arrow.svg diff --git a/docs/src/theme/MDXComponents.js b/docs/src/theme/MDXComponents.js new file mode 100644 index 0000000..c7bfa21 --- /dev/null +++ b/docs/src/theme/MDXComponents.js @@ -0,0 +1,7 @@ +// Import the original mapper +import MDXComponents from '@theme-original/MDXComponents'; + +export default { + // Re-use the default mapping + ...MDXComponents, +}; diff --git a/docs/src/theme/MDXComponents/Details.js b/docs/src/theme/MDXComponents/Details.js new file mode 100644 index 0000000..47305d4 --- /dev/null +++ b/docs/src/theme/MDXComponents/Details.js @@ -0,0 +1,20 @@ +import React from 'react'; +import DetailsStyling from '@site/src/theme/MDXComponents/DetailsStyling'; + +const MDXDetails = (props) => { + const items = React.Children.toArray(props.children); + // Split summary item from the rest to pass it as a separate prop to the + // Details theme component + const summary = items.find( + (item) => React.isValidElement(item) && item.props?.mdxType === 'summary' + ); + + const children = <>{items.filter((item) => item !== summary)}>; + return ( + + {children} + + ); +}; + +export default MDXDetails; diff --git a/docs/src/theme/MDXComponents/DetailsStyling.tsx b/docs/src/theme/MDXComponents/DetailsStyling.tsx new file mode 100644 index 0000000..8d79b5d --- /dev/null +++ b/docs/src/theme/MDXComponents/DetailsStyling.tsx @@ -0,0 +1,101 @@ +import { useCollapsible, Collapsible } from '@docusaurus/theme-common'; + +import clsx from 'clsx'; +import React from 'react'; +import { useRef, useState } from 'react'; + +import styles from './styles.module.css'; +import useIsBrowser from '@docusaurus/useIsBrowser'; +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +const DetailsStyling = ({ summary, children, ...props }): JSX.Element => { + const isBrowser = useIsBrowser(); + const { collapsed, setCollapsed } = useCollapsible({ + initialState: !props.open, + }); + + const arrowIcon = { + light: useBaseUrl('/img/Arrow.svg'), + dark: useBaseUrl('img/Arrow-dark.svg'), + }; + + const detailsRef = useRef(null); + const [open, setOpen] = useState(props.open); + + // As we need to modify our own summary, we need to extract original content of summary + const extractedSummaryElement = summary.props.children; + + return ( + { + const target = e.target as HTMLElement; + // 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 as HTMLElement; + 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); + } + }} + > + + + + {extractedSummaryElement} + + + { + setCollapsed(newCollapsed); + setOpen(!newCollapsed); + }} + > + {children} + + + ); +}; + +function isInSummary(node: HTMLElement | null): boolean { + if (!node) { + return false; + } + return node.tagName === 'SUMMARY' || isInSummary(node.parentElement); +} + +function hasParent(node: HTMLElement | null, parent: HTMLElement): boolean { + if (!node) { + return false; + } + return node === parent || hasParent(node.parentElement, parent); +} + +export default DetailsStyling; diff --git a/docs/src/theme/MDXComponents/styles.module.css b/docs/src/theme/MDXComponents/styles.module.css new file mode 100644 index 0000000..474f352 --- /dev/null +++ b/docs/src/theme/MDXComponents/styles.module.css @@ -0,0 +1,50 @@ +.details { + background-color: var(--swm-details-foreground); + box-shadow: -8px 8px 0 var(--swm-details-background); + + color: var(--swm-details-color); + } + + .details a { + color: var(--swm-details-color); + } + + .details > summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + padding: 1.5em 2em; + } + + .details > summary > p { + margin: 0; + } + + /* TODO: deprecation, need to remove this after Safari will support `::marker` */ + .details > summary::-webkit-details-marker { + display: none; + } + + .arrow { + height: 12px; + width: 12px; + margin-right: 1.5rem; + left: 0; + + transition: var(--swm-expandable-transition); + } + + .details[open]:not(.isBrowser) > summary > .arrow, + /* When JS works: we use the data-attribute for arrow animation */ + .details[data-collapsed='false'].isBrowser > summary > .arrow { + transform: rotate(180deg); + } + + .collapsibleContent { + padding: 0 2em 1.5em 2em; + } + + .collapsibleContent > *:last-child { + margin-bottom: 0; + } \ No newline at end of file diff --git a/docs/static/img/Arrow-dark.svg b/docs/static/img/Arrow-dark.svg new file mode 100644 index 0000000..b781299 --- /dev/null +++ b/docs/static/img/Arrow-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/static/img/Arrow.svg b/docs/static/img/Arrow.svg new file mode 100644 index 0000000..cb808e2 --- /dev/null +++ b/docs/static/img/Arrow.svg @@ -0,0 +1,3 @@ + + +
{extractedSummaryElement}