Skip to content
Draft
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
1 change: 1 addition & 0 deletions src/generators/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The `web` generator accepts the following configuration options:
| `project` | `string` | `'Node.js'` | Project name used in page titles and the version selector |
| `title` | `string` | `'{project} v{version} Documentation'` | Title template for HTML pages (supports `{project}`, `{version}`) |
| `useAbsoluteURLs` | `boolean` | `false` | When `true`, all internal links use absolute URLs based on `baseURL` |
| `showSearchBar` | `boolean` | Whether `orama-db` is targeted | Explicitly show or hide the navigation search bar |
| `editURL` | `string` | `'${GITHUB_EDIT_URL}/doc/api{path}.md'` | URL template for "edit this page" links |
| `pageURL` | `string` | `'{baseURL}/latest-{version}/api{path}.html'` | URL template for documentation page links |
| `head` | `object` | See below | Configurable `<meta>`, `<link>`, and raw markup for the document head |
Expand Down
13 changes: 13 additions & 0 deletions src/generators/web/__tests__/generate.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ const createEntry = (api, name) => {
};

describe('web generate', () => {
it('renders the search bar only when it is enabled', async () => {
const config = await setConfig({ target: ['web'] });
const fs = createEntry('fs', 'File system');
const input = [toCodeItem(await buildContent([fs], fs))];

const [withoutSearch] = await generate(input);
assert.doesNotMatch(withoutSearch.html, /Start typing/);

config.web.showSearchBar = true;
const [withSearch] = await generate(input);
assert.match(withSearch.html, /Start typing/);
});

it('omits View As links for synthetic pages only', async () => {
await setConfig({});

Expand Down
1 change: 1 addition & 0 deletions src/generators/web/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type Configuration = {
templatePath: string;
title: string;
useAbsoluteURLs: boolean;
showSearchBar?: boolean;
head: HeadConfig;
// Options spread into LightningCSS while bundling CSS. `filename`, `code`,
// `cssModules`, and `resolver` are managed by the generator and ignored here.
Expand Down
4 changes: 2 additions & 2 deletions src/generators/web/ui/components/NavBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import GitHubIcon from '@node-core/ui-components/Icons/Social/GitHub';
import SearchBox from './SearchBox';
import { useTheme } from '../hooks/useTheme.mjs';

import { repository } from '#theme/config';
import { repository, showSearchBar } from '#theme/config';
import Logo from '#theme/Logo';

/**
Expand All @@ -21,7 +21,7 @@ export default ({ metadata }) => {
sidebarItemTogglerAriaLabel="Toggle navigation menu"
navItems={[]}
>
<SearchBox pathname={metadata.path} />
{showSearchBar && <SearchBox pathname={metadata.path} />}
<ThemeToggle
onChange={setThemePreference}
currentTheme={themePreference}
Expand Down
1 change: 1 addition & 0 deletions src/generators/web/ui/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ declare module '#theme/config' {
export const templatePath: Configuration['templatePath'];
export const title: Configuration['title'];
export const useAbsoluteURLs: Configuration['useAbsoluteURLs'];
export const showSearchBar: boolean;

// From config generation
export const version: SemVer;
Expand Down
31 changes: 31 additions & 0 deletions src/utils/configuration/__tests__/index.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mock.module('../../../generators/index.mjs', {
json: { defaultConfiguration: { format: 'json' } },
html: { defaultConfiguration: { format: 'html' } },
markdown: {},
web: { defaultConfiguration: {} },
},
},
});
Expand Down Expand Up @@ -231,6 +232,36 @@ describe('config.mjs', () => {
assert.ok(config.html);
assert.ok(config.markdown);
});

it('should show web search by default only when orama-db is targeted', async () => {
const withOrama = await createRunConfiguration({
target: ['web', 'orama-db'],
});
assert.strictEqual(withOrama.web.showSearchBar, true);

const withoutOrama = await createRunConfiguration({ target: ['web'] });
assert.strictEqual(withoutOrama.web.showSearchBar, false);
});

it('should preserve explicit web search visibility overrides', async () => {
mockImportFromURL.mock.mockImplementationOnce(async () =>
createMockConfig({ web: { showSearchBar: true } })
);
const forcedOn = await createRunConfiguration({
configFile: 'config.mjs',
target: ['web'],
});
assert.strictEqual(forcedOn.web.showSearchBar, true);

mockImportFromURL.mock.mockImplementationOnce(async () =>
createMockConfig({ web: { showSearchBar: false } })
);
const forcedOff = await createRunConfiguration({
configFile: 'config.mjs',
target: ['web', 'orama-db'],
});
assert.strictEqual(forcedOff.web.showSearchBar, false);
});
});

describe('setConfig and getConfig', () => {
Expand Down
6 changes: 6 additions & 0 deletions src/utils/configuration/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ export const assertRunnableOptions = config => {
export const createRunConfiguration = async options => {
const config = await loadConfigFile(options.configFile);
config.target &&= enforceArray(config.target);
const configuredShowSearchBar = config.web?.showSearchBar;

// Merge with defaults
const merged = deepMerge(
Expand All @@ -141,6 +142,11 @@ export const createRunConfiguration = async options => {
getDefaultConfig()
);

// Search is available by default when the pipeline builds an Orama database,
// while an explicit web-generator option can force it on or off.
merged.web.showSearchBar =
configuredShowSearchBar ?? enforceArray(merged.target).includes('orama-db');

// These need to be coerced
merged.threads = Math.max(merged.threads, 1);
merged.chunkSize = Math.max(merged.chunkSize, 1);
Expand Down