Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/did-you-know-that-the-world-is-round.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@node-core/doc-kit': patch
---

Close Orama search when the target link is on the same page
5 changes: 5 additions & 0 deletions .changeset/yes-i-did-know-that-thank-you.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@node-core/doc-kit': patch
---

Render markdown `code` snippets in the sidebar
22 changes: 22 additions & 0 deletions src/generators/web/ui/components/SearchBox/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 => <a {...props} onClick={closeSearchModal} />;
Comment thread
avivkeller marked this conversation as resolved.

const SearchBox = ({ pathname }) => {
const client = useOrama(pathname);

Expand All @@ -21,6 +42,7 @@ const SearchBox = ({ pathname }) => {
noResultsTitle="No results found for"
onHit={hit => (
<SearchHit
as={SearchHitLink}
document={{
...hit.document,
href: relativeOrAbsolute(hit.document.href, pathname),
Expand Down
3 changes: 2 additions & 1 deletion src/generators/web/ui/components/SideBar/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import SideBar from '@node-core/ui-components/Containers/Sidebar';

import styles from './index.module.css';
import { relativeOrAbsolute } from '../../utils/relativeOrAbsolute.mjs';
import { renderLabel } from '../../utils/renderLabel.jsx';

import { project, version, versions, pages } from '#theme/config';

Expand Down Expand Up @@ -37,7 +38,7 @@ export default ({ metadata }) => {
}));

const items = pages.map(([heading, path]) => ({
label: heading,
label: renderLabel(heading),
link:
metadata.path === path
? `${metadata.basename}.html`
Expand Down
26 changes: 26 additions & 0 deletions src/generators/web/ui/utils/renderLabel.jsx
Original file line number Diff line number Diff line change
@@ -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 ? (
<code key={`code:${segment}`}>{segment}</code>
) : (
<span key={`text:${segment}`}>{segment}</span>
)
);
};
28 changes: 1 addition & 27 deletions www/theme/SideBar.jsx
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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 `<code>` 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 ? (
<code key={`code:${segment}`}>{segment}</code>
) : (
<span key={`text:${segment}`}>{segment}</span>
)
);
};

/**
* Orders the narrative pages by `GUIDE_ORDER`, leaving anything unlisted at the
* end in the alphabetical order `jsx-ast` already produced.
Expand Down
Loading