diff --git a/.changeset/did-you-know-that-the-world-is-round.md b/.changeset/did-you-know-that-the-world-is-round.md new file mode 100644 index 00000000..98ba0892 --- /dev/null +++ b/.changeset/did-you-know-that-the-world-is-round.md @@ -0,0 +1,5 @@ +--- +'@node-core/doc-kit': patch +--- + +Close Orama search when the target link is on the same page diff --git a/.changeset/yes-i-did-know-that-thank-you.md b/.changeset/yes-i-did-know-that-thank-you.md new file mode 100644 index 00000000..b03124c5 --- /dev/null +++ b/.changeset/yes-i-did-know-that-thank-you.md @@ -0,0 +1,5 @@ +--- +'@node-core/doc-kit': patch +--- + +Render markdown `code` snippets in the sidebar diff --git a/src/generators/web/ui/components/SearchBox/index.jsx b/src/generators/web/ui/components/SearchBox/index.jsx index 6a24e7c8..bdc795dc 100644 --- a/src/generators/web/ui/components/SearchBox/index.jsx +++ b/src/generators/web/ui/components/SearchBox/index.jsx @@ -11,6 +11,27 @@ import styles from './index.module.css'; import useOrama from '../../hooks/useOrama.mjs'; import { relativeOrAbsolute } from '../../utils/relativeOrAbsolute.mjs'; +/** + * Dismisses the search modal the clicked hit sits in. + * + * @param {MouseEvent} event + */ +const closeSearchModal = event => { + if (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) { + return; + } + + event.currentTarget.dispatchEvent( + new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }) + ); +}; + +/** + * A search hit link that dismisses the modal when followed. + * @param {Object} props - Anchor props, as passed by `SearchHit`. + */ +const SearchHitLink = props => ; + const SearchBox = ({ pathname }) => { const client = useOrama(pathname); @@ -21,6 +42,7 @@ const SearchBox = ({ pathname }) => { noResultsTitle="No results found for" onHit={hit => ( { })); const items = pages.map(([heading, path]) => ({ - label: heading, + label: renderLabel(heading), link: metadata.path === path ? `${metadata.basename}.html` diff --git a/src/generators/web/ui/utils/renderLabel.jsx b/src/generators/web/ui/utils/renderLabel.jsx new file mode 100644 index 00000000..a7390bc2 --- /dev/null +++ b/src/generators/web/ui/utils/renderLabel.jsx @@ -0,0 +1,26 @@ +/** + * Renders a raw Markdown heading. We intentionally + * only account for backticks, since running a full + * markdown parse is much slower (and there's never + * a case where'd have extremely complex markdown + * within a sidebar like this) + * + * @param {string} label - Raw heading text. + * @returns {import('preact').ComponentChildren} + */ +export const renderLabel = label => { + const segments = label.split('`'); + + if (segments.length === 1) { + return label; + } + + // Odd-indexed segments sat between a pair of backticks. + return segments.map((segment, index) => + index % 2 ? ( + {segment} + ) : ( + {segment} + ) + ); +}; diff --git a/www/theme/SideBar.jsx b/www/theme/SideBar.jsx index 001efce9..cdf32e19 100644 --- a/www/theme/SideBar.jsx +++ b/www/theme/SideBar.jsx @@ -1,6 +1,7 @@ import SideBar from '@node-core/ui-components/Containers/Sidebar'; import { relativeOrAbsolute } from '../../src/generators/web/ui/utils/relativeOrAbsolute.mjs'; +import { renderLabel } from '../../src/generators/web/ui/utils/renderLabel.jsx'; import { pages } from '#theme/config'; @@ -22,33 +23,6 @@ const GUIDE_ORDER = [ const isGenerator = ([, path]) => path.startsWith('/generators/'); -/** - * Page labels are raw heading text, so a heading like `` ## `web` Generator `` - * arrives with its backticks intact. The sidebar renders the label verbatim, - * showing the literal backticks. Split on backtick pairs and wrap the enclosed - * spans in `` so they render as inline code; labels without backticks pass - * through as a plain string. - * - * @param {string} label - * @returns {import('react').ReactNode} - */ -const renderLabel = label => { - const segments = label.split('`'); - - if (segments.length === 1) { - return label; - } - - // Odd-indexed segments sat between a pair of backticks. - return segments.map((segment, index) => - index % 2 ? ( - {segment} - ) : ( - {segment} - ) - ); -}; - /** * Orders the narrative pages by `GUIDE_ORDER`, leaving anything unlisted at the * end in the alphabetical order `jsx-ast` already produced.