Skip to content

Commit

Permalink
docs(headless): typedoc plugin for coveo search box and theming (#4361)
Browse files Browse the repository at this point in the history
https://coveord.atlassian.net/browse/KIT-3421

This is the first of a number of PRs to generate Headless documentation
using https://typedoc.org/
Here, I create a typedoc plugin to add an Atomic search box to the
generated website, and theme it.

I suggest merging to a typedoc-release-branch rather than to master
because the tags are in a messy state at the moment. I have enough to
work on the plugin, but that's it. My next task will be to go through
them to clean up and generate the typedoc website will all the content
we want. Avoiding master will also help to avoid conflicts with the v3
release. Typedoc can wait until v3.

You can preview by:
- checking out my branch
- running `npm install`
- running `npm run build:typedoc` from the headless package
- opening `packages/headless/docs/index.html`
  • Loading branch information
jpmarceau authored Sep 9, 2024
1 parent 47f0275 commit 2e8ed4d
Show file tree
Hide file tree
Showing 14 changed files with 552 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"adjustednumberoflikes",
"allo",
"Animalia",
"Argb",
"ARROWUP",
"Artemia",
"Artemiidae",
Expand Down Expand Up @@ -37,6 +38,7 @@
"coveo",
"coveobueno",
"coveointernaltesting",
"coveosearch",
"coveotaggedword",
"coversationid",
"CRGA",
Expand Down
3 changes: 3 additions & 0 deletions packages/headless/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
"publish:npm": "npm run-script -w=@coveo/release npm-publish",
"publish:bump": "npm run-script -w=@coveo/release bump",
"promote:npm:latest": "node ../../scripts/deploy/update-npm-tag.mjs latest",
"build:typedoc": "npm run build:typedoc:plugin && npm run build:typedoc:docs",
"build:typedoc:plugin": "npx tsc -p typedoc/tsconfig.json",
"build:typedoc:docs": "typedoc --tsconfig tsconfig.typedoc.json",
"build:doc": "npm run build:doc:extract && npm run build:doc:parse",
"build:doc:extract": "node ./scripts/extract-documentation.mjs",
"build:doc:parse": "ts-node --project ./doc-parser/tsconfig.build.json ./doc-parser/doc-parser.ts"
Expand Down
2 changes: 1 addition & 1 deletion packages/headless/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
],
"executor": "nx:run-commands",
"options": {
"commands": ["npm run build:prod", "npm run build:doc"],
"commands": ["npm run build:prod"],
"parallel": false,
"cwd": "packages/headless"
}
Expand Down
8 changes: 8 additions & 0 deletions packages/headless/tsconfig.typedoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"jsx": "react",
"jsxFactory": "JSX.createElement",
"jsxFragmentFactory": "JSX.Fragment"
}
}
3 changes: 2 additions & 1 deletion packages/headless/typedoc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
"./src/ssr.index.ts"
],
"projectDocuments": ["./src/docs/usage.md"],
"gitRevision": "typedoc-POC"
"gitRevision": "typedoc-POC",
"plugin": ["./typedoc/dist/index.js"]
}
66 changes: 66 additions & 0 deletions packages/headless/typedoc/assets/coveo-docs-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
82 changes: 82 additions & 0 deletions packages/headless/typedoc/assets/docs-style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
:root {
--light-color-background: #fff;
--light-color-background-secondary: #333357;
--light-color-text: #282829;
--light-color-text-aside: #399ffe;
--dark-color-background: #3f3f71;
--dark-color-background-secondary: #333357;
--dark-color-text: #f1f2ff;
--dark-color-text-aside: #399ffe;
--header-height: 5.5rem;
}

body {
font:
100 1em/1.625 'canada-type-gibson',
sans-serif;
}

.tsd-breadcrumb a {
font-weight: 400;
}

#tsd-search {
width: 27rem;
}

.tsd-page-toolbar {
height: var(--header-height);
border-bottom: none;
}
.tsd-page-toolbar .tsd-toolbar-contents {
padding: 1.25rem;
}
.tsd-page-toolbar .table-cell:first-child {
width: inherit;
min-width: 11rem;
}
.tsd-page-toolbar .tsd-toolbar-icon {
box-sizing: border-box;
line-height: 0;
padding: 12px 0;
}

#icon-menu rect {
fill: white;
}

#tsd-widgets {
padding-left: 0.5rem;
padding-top: 0.25rem;
}
#tsd-widgets .feedback a {
color: white;
font-size: 0.75rem;
font-weight: 400;
}

@media (max-width: 769px) {
.feedback {
display: none;
}
.has-menu .overlay {
top: var(--header-height);
}
html .col-sidebar {
display: none;
top: var(--header-height) !important;
}
#tsd-search {
display: none;
}
.has-menu #tsd-search {
display: block;
width: 90%;
}
.has-menu .coveo-logo-cell {
display: none;
}
.tsd-widget.active {
background-color: inherit;
}
}
61 changes: 61 additions & 0 deletions packages/headless/typedoc/lib/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {cpSync} from 'node:fs';
import {dirname, resolve} from 'node:path';
import {fileURLToPath} from 'node:url';
// following docs https://typedoc.org/guides/development/#plugins
// eslint-disable-next-line n/no-unpublished-import
import {Application, JSX, RendererEvent} from 'typedoc';
import {insertAtomicSearchBox} from './insertAtomicSearchBox.js';
import {insertCoveoLogo} from './insertCoveoLogo.js';
import {insertSurveyLink} from './insertSurveyLink.js';

const __dirname = dirname(fileURLToPath(import.meta.url));

/**
* Called by TypeDoc when loaded as a plugin.
*/
export function load(app: Application) {
app.renderer.hooks.on('head.end', (event) => (
<>
<link
rel="stylesheet"
href={event.relativeURL('assets/docs-style.css')}
/>
<link
rel="stylesheet"
href="https://static.cloud.coveo.com/atomic/v2/themes/coveo.css"
/>
<script
type="module"
src="https://static.cloud.coveo.com/atomic/v2/atomic.esm.js"
></script>
<script>
<JSX.Raw html={`(${insertAtomicSearchBox.toString()})();`} />
</script>
<script>
<JSX.Raw html={`(${insertSurveyLink.toString()})();`} />
</script>
<script>
<JSX.Raw html={`(${insertCoveoLogo.toString()})();`} />
</script>
</>
));

const onRenderEnd = () => {
const filesToCopy = [
{
from: resolve(__dirname, '../assets/docs-style.css'),
to: resolve(app.options.getValue('out'), 'assets/docs-style.css'),
},
{
from: resolve(__dirname, '../assets/coveo-docs-logo.svg'),
to: resolve(app.options.getValue('out'), 'assets/coveo-docs-logo.svg'),
},
];

filesToCopy.forEach((file) => {
cpSync(file.from, file.to);
});
};

app.renderer.on(RendererEvent.END, onRenderEnd);
}
61 changes: 61 additions & 0 deletions packages/headless/typedoc/lib/insertAtomicSearchBox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
interface AtomicSearchInterfaceElement extends HTMLElement {
initialize(config: {
organizationId: string;
organizationEndpoints: OrganizationEndpoints;
accessToken: string;
search: {searchHub: string};
analytics: {originLevel2: string};
}): Promise<void>;
getOrganizationEndpoints(
organizationId: string
): Promise<OrganizationEndpoints>;
}

interface OrganizationEndpoints {
platform: string;
analytics: string;
search: string;
admin: string;
}

declare global {
interface HTMLElementTagNameMap {
'atomic-search-interface': AtomicSearchInterfaceElement;
}
}

export function insertAtomicSearchBox() {
document.addEventListener('DOMContentLoaded', () => {
const typedocSearchBox = document.getElementById('tsd-search');
if (typedocSearchBox) {
typedocSearchBox.innerHTML = '';
const searchInterface = document.createElement('atomic-search-interface');
const searchBox = document.createElement('atomic-search-box');
searchBox.setAttribute(
'redirection-url',
'https://docs.coveo.com/en/search'
);
searchInterface.appendChild(searchBox);
typedocSearchBox.appendChild(searchInterface);

(async () => {
await customElements.whenDefined('atomic-search-interface');
const searchInterfaceElement = document.querySelector(
'atomic-search-interface'
);
if (searchInterfaceElement) {
await searchInterfaceElement.initialize({
organizationId: 'coveosearch',
organizationEndpoints:
await searchInterfaceElement.getOrganizationEndpoints(
'coveosearch'
),
accessToken: 'xx6ac9d08f-eb9a-48d5-9240-d7c251470c93',
search: {searchHub: 'Coveo Docs Unified Search'},
analytics: {originLevel2: 'All'},
});
}
})();
}
});
}
23 changes: 23 additions & 0 deletions packages/headless/typedoc/lib/insertCoveoLogo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export function insertCoveoLogo() {
document.addEventListener('DOMContentLoaded', () => {
const toolbarContents = document.getElementsByClassName(
'tsd-toolbar-contents'
)[0];
if (toolbarContents) {
const logoCell = document.createElement('div');
logoCell.classList.add('table-cell', 'coveo-logo-cell');
const logoDiv = document.createElement('div');
logoDiv.classList.add('coveo-logo');
const logoLink = document.createElement('a');
logoLink.href = 'https://docs.coveo.com/en/0';
const logoImg = document.createElement('img');
logoImg.src = './assets/coveo-docs-logo.svg';
logoImg.alt = 'Coveo Docs Logo';

logoLink.appendChild(logoImg);
logoDiv.appendChild(logoLink);
logoCell.appendChild(logoDiv);
toolbarContents.insertBefore(logoCell, toolbarContents.firstChild);
}
});
}
16 changes: 16 additions & 0 deletions packages/headless/typedoc/lib/insertSurveyLink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export function insertSurveyLink() {
document.addEventListener('DOMContentLoaded', () => {
const toolbarWidgets = document.getElementById('tsd-widgets');
if (toolbarWidgets) {
const feedbackDiv = document.createElement('div');
feedbackDiv.classList.add('feedback');
const feedbackLink = document.createElement('a');
feedbackLink.href =
'https://docs.google.com/forms/d/e/1FAIpQLSeyNL18g4JWIDR5xEyIMY48JIjyjwXRmlCveecjXBNSLh4Ygg/viewform';
feedbackLink.target = '_blank';
feedbackLink.textContent = 'Feedback';
feedbackDiv.appendChild(feedbackLink);
toolbarWidgets.appendChild(feedbackDiv);
}
});
}
Loading

0 comments on commit 2e8ed4d

Please sign in to comment.