@netfoundry/docusaurus-theme 0.3.1 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ export type ProductSearchProps = {
2
+ appId: string;
3
+ apiKey: string;
4
+ indexName: string;
5
+ products?: string[];
6
+ extraContainerClasses?: string[];
7
+ };
8
+ export declare function ProductSearch({ appId, apiKey, indexName, products, extraContainerClasses, }: ProductSearchProps): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=ProductSearch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProductSearch.d.ts","sourceRoot":"","sources":["../../../../src/components/ProductSearch/ProductSearch.tsx"],"names":[],"mappings":"AA+BA,MAAM,MAAM,kBAAkB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CACpC,CAAC;AA2GF,wBAAgB,aAAa,CAAC,EAC1B,KAAK,EACL,MAAM,EACN,SAAS,EACT,QAA8D,EAC9D,qBAA0B,GAC7B,EAAE,kBAAkB,2CA2JpB"}
@@ -0,0 +1,140 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // src/components/ProductSearch/ProductSearch.tsx
3
+ import { useEffect, useMemo, useState } from "react";
4
+ import { InstantSearch, SearchBox, Pagination, Snippet, Configure, Stats, PoweredBy, useHits, useConfigure, useSearchBox, } from "react-instantsearch";
5
+ import { history } from "instantsearch.js/es/lib/routers";
6
+ import { singleIndex } from "instantsearch.js/es/lib/stateMappings";
7
+ import { liteClient as algoliasearch } from "algoliasearch/lite";
8
+ import styles from "./ProductSearch.module.css";
9
+ import clsx from "clsx";
10
+ function getUrl(h) {
11
+ return toRelative(((typeof h.url === "string" && h.url) ||
12
+ (Array.isArray(h.url) && h.url[0]) ||
13
+ h.url_without_anchor ||
14
+ h.url_without_variables ||
15
+ "#") + (h.anchor ? `#${h.anchor}` : ""));
16
+ }
17
+ function toRelative(href) {
18
+ try {
19
+ const u = new URL(href, typeof window !== "undefined" ? window.location.origin : "http://localhost");
20
+ return u.pathname + u.search + u.hash;
21
+ }
22
+ catch {
23
+ return href.startsWith("/") ? href : `/${href}`;
24
+ }
25
+ }
26
+ function shortUrl(h) {
27
+ return toRelative(getUrl(h));
28
+ }
29
+ function titleFrom(h) {
30
+ return (h.title ||
31
+ h.hierarchy?.lvl2 ||
32
+ h.hierarchy?.lvl1 ||
33
+ h.hierarchy?.lvl0 ||
34
+ shortUrl(h));
35
+ }
36
+ function ProductBadge({ p }) {
37
+ return p ? (_jsx("span", { className: `${styles.badge} ${styles[`p_${p}`]}`, children: p })) : null;
38
+ }
39
+ /** Configure-based filter (no remount, reliable) */
40
+ function ProductFilter({ product }) {
41
+ useConfigure({
42
+ facetFilters: product ? [[`docusaurus_tag:docs-${product}-current`]] : [],
43
+ });
44
+ return null;
45
+ }
46
+ /** Group by section (lvl0), then by page (no duplicate "Learn") */
47
+ function GroupedHits() {
48
+ const { hits } = useHits();
49
+ const sections = new Map();
50
+ for (const h of hits) {
51
+ const lvl0 = h.hierarchy?.lvl0 || "Other";
52
+ const page = h.url_without_anchor ||
53
+ (typeof h.url === "string" ? h.url.split("#")[0] : "") ||
54
+ "";
55
+ const byPage = sections.get(lvl0) || new Map();
56
+ const g = byPage.get(page) ||
57
+ { header: titleFrom(h), url: page || getUrl(h), lvl0, items: [] };
58
+ g.items.push(h);
59
+ byPage.set(page, g);
60
+ sections.set(lvl0, byPage);
61
+ }
62
+ return (_jsx("div", { className: styles.groupList, children: [...sections.entries()].map(([lvl0, byPage]) => (_jsxs("div", { className: styles.section, children: [_jsx("div", { className: styles.sectionHeader, children: lvl0 }), [...byPage.values()].map((g) => (_jsxs("div", { className: styles.group, children: [_jsxs("div", { className: styles.groupHeaderRow, children: [_jsx("a", { href: toRelative(g.url), className: styles.groupHeader, children: g.header }), _jsx(ProductBadge, { p: g.items[0].product })] }), _jsx("div", { className: styles.groupSnips, children: g.items.slice(0, 3).map((h, i) => (_jsx("div", { className: styles.snippet, children: _jsx(Snippet, { attribute: "content", hit: h }) }, i))) }), _jsx("div", { className: styles.groupUrl, children: _jsx("a", { href: getUrl(g.items[0]), children: shortUrl(g.items[0]) }) })] }, g.url)))] }, lvl0))) }));
63
+ }
64
+ function QueryWatcher({ onChange }) {
65
+ const { query } = useSearchBox();
66
+ useEffect(() => onChange(query.trim().length >= 2), [query, onChange]);
67
+ return null;
68
+ }
69
+ export function ProductSearch({ appId, apiKey, indexName, products = ["frontdoor", "openziti", "onprem", "zlan", "zrok"], extraContainerClasses = [], }) {
70
+ // read initial pill from ?product= for back/forward + shareable URLs
71
+ const [product, setProduct] = useState("");
72
+ const [searchLongEnough, setSearchLongEnough] = useState(false);
73
+ useEffect(() => {
74
+ if (typeof window === "undefined")
75
+ return;
76
+ const p = new URLSearchParams(window.location.search).get("product") || "";
77
+ setProduct(p);
78
+ }, []);
79
+ useEffect(() => {
80
+ if (typeof window === "undefined")
81
+ return;
82
+ const u = new URL(window.location.href);
83
+ if (product)
84
+ u.searchParams.set("product", product);
85
+ else
86
+ u.searchParams.delete("product");
87
+ window.history.replaceState({}, "", u);
88
+ }, [product]);
89
+ const base = useMemo(() => algoliasearch(appId, apiKey), [appId, apiKey]);
90
+ // Gate only when no query AND no pill active (prevents "freeze" on pill-only)
91
+ const searchClient = useMemo(() => ({
92
+ ...base,
93
+ search(requests) {
94
+ const allShort = requests.every((r) => (r.params?.query ?? "").length < 2);
95
+ if (allShort) { // block ALL searches until query >= 2
96
+ return Promise.resolve({
97
+ results: requests.map(() => ({
98
+ hits: [],
99
+ nbHits: 0,
100
+ page: 0,
101
+ nbPages: 0,
102
+ processingTimeMS: 0,
103
+ params: "",
104
+ query: "",
105
+ exhaustiveNbHits: false,
106
+ })),
107
+ });
108
+ }
109
+ return base.search(requests);
110
+ },
111
+ }), [base, product]);
112
+ return (_jsx("div", { className: styles.wrap, children: _jsxs(InstantSearch, { searchClient: searchClient, indexName: indexName, routing: {
113
+ router: history({ writeDelay: 300 }),
114
+ stateMapping: singleIndex(indexName),
115
+ }, children: [_jsx(QueryWatcher, { onChange: setSearchLongEnough }), _jsxs("div", { className: styles.topbar, children: [_jsx(SearchBox, { onKeyUp: (e) => {
116
+ setSearchLongEnough(e.target.value.length > 1);
117
+ }, autoFocus: true, classNames: { input: styles.searchInput }, placeholder: "Enter your search criteria here" }), _jsxs("div", { className: styles.pills, children: [_jsx("button", { className: `${styles.pill} ${!product ? styles.active : ""}`, onClick: () => searchLongEnough && setProduct(""), disabled: !searchLongEnough, children: "All" }), products.map((p) => (_jsx("button", { className: `${styles.pill} ${product === p ? styles.active : ""}`, onClick: () => searchLongEnough && setProduct(p), disabled: !searchLongEnough, children: p }, p)))] })] }), _jsx(Configure, { hitsPerPage: 20, attributesToRetrieve: [
118
+ "url",
119
+ "url_without_anchor",
120
+ "url_without_variables",
121
+ "anchor",
122
+ "hierarchy",
123
+ "product",
124
+ "content",
125
+ "title",
126
+ ], attributesToHighlight: [
127
+ "title",
128
+ "hierarchy.lvl1",
129
+ "hierarchy.lvl2",
130
+ "content",
131
+ ], attributesToSnippet: ["content:15"], snippetEllipsisText: "...", distinct: true }), searchLongEnough && _jsx(ProductFilter, { product: product }), _jsxs("div", { className: clsx(styles.container, extraContainerClasses), children: [_jsxs("div", { className: styles.results, children: [_jsx("div", { className: styles.meta, children: _jsx(Stats, {}) }), _jsx("div", { className: styles.grid, children: _jsx(GroupedHits, {}) }), _jsx(Pagination, { showFirst: false, showLast: false, classNames: {
132
+ root: styles.pagination,
133
+ list: styles.pageList,
134
+ item: styles.pageItem,
135
+ selectedItem: styles.pageItemSelected,
136
+ disabledItem: styles.pageItemDisabled,
137
+ link: styles.pageLink,
138
+ } })] }), _jsxs("div", { className: styles.footer, children: [_jsxs("div", { className: styles.kbdRow, children: [_jsxs("span", { children: [_jsx("kbd", { children: "Enter" }), " open"] }), _jsxs("span", { children: [_jsx("kbd", { children: "Up" }), _jsx("kbd", { children: "Down" }), " navigate"] }), _jsxs("span", { children: [_jsx("kbd", { children: "esc" }), " close"] })] }), _jsx(PoweredBy, {})] })] })] }) }));
139
+ }
140
+ //# sourceMappingURL=ProductSearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProductSearch.js","sourceRoot":"","sources":["../../../../src/components/ProductSearch/ProductSearch.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,190 @@
1
+ /* src/components/ProductSearch/ProductSearch.module.css */
2
+
3
+ /* ===== Layout ===== */
4
+ .wrap{max-width:980px;margin:0 auto;padding:1rem}
5
+ .topbar{display:flex;flex-wrap:wrap;gap:.6rem;justify-content:space-between;align-items:center;margin-bottom:.6rem}
6
+ .searchInput{
7
+ display:flex;
8
+ flex-grow:1;
9
+ height:44px;padding:0 .9rem;border-radius:12px;
10
+ border:1px solid var(--ifm-color-emphasis-300);background:var(--ifm-background-color);
11
+ transition:border-color .15s,box-shadow .15s,background .15s
12
+ }
13
+ .searchInput:focus{
14
+ outline:none;border-color:var(--ifm-color-primary);
15
+ box-shadow:0 0 0 3px color-mix(in oklab, var(--ifm-color-primary) 25%, transparent)
16
+ }
17
+
18
+ /* ===== Pills ===== */
19
+ .pills{display:flex;gap:.45rem;align-items:center;flex-wrap:wrap}
20
+ .pill{
21
+ display:flex;
22
+ background: teal;
23
+ all:unset;cursor:pointer;user-select:none;
24
+ padding:.38rem .7rem;border:1px solid var(--ifm-color-emphasis-300);
25
+ border-radius:999px;background:linear-gradient(180deg,var(--ifm-background-color),color-mix(in oklab,var(--ifm-background-color) 85%, black));
26
+ font-size:.82rem;line-height:1;transition:transform .12s,box-shadow .12s,border-color .12s,background .12s
27
+ }
28
+ .pill:hover{transform:translateY(-1px);box-shadow:0 4px 12px rgba(0,0,0,.08)}
29
+ .pill[disabled]{opacity:.45;pointer-events:none}
30
+ .active{
31
+ background:linear-gradient(180deg,var(--ifm-color-primary),color-mix(in oklab,var(--ifm-color-primary) 85%, black));
32
+ color:#fff;border-color:var(--ifm-color-primary)
33
+ }
34
+ .activeChip{padding:.28rem .55rem;border:1px solid var(--ifm-color-emphasis-300);
35
+ border-radius:999px;background:var(--ifm-background-color);font-size:.75rem}
36
+
37
+ /* ===== Meta ===== */
38
+ .meta{display:flex;justify-content:space-between;align-items:center;margin:.35rem 0 .6rem;font-size:.86rem;color:var(--ifm-color-emphasis-700)}
39
+
40
+ /* ===== Grouped Hits ===== */
41
+ .grid{display:block}
42
+ .groupList{display:flex;flex-direction:column;gap:.7rem}
43
+ .group{
44
+ border:1px solid var(--ifm-color-emphasis-200);border-radius:14px;background:var(--ifm-background-color);
45
+ padding:.8rem .95rem;box-shadow:0 2px 10px rgba(0,0,0,.05);
46
+ transition:border-color .15s,box-shadow .15s,transform .12s
47
+ }
48
+ .group:hover{border-color:var(--ifm-color-primary);box-shadow:0 10px 24px rgba(0,0,0,.12);transform:translateY(-1px)}
49
+ .groupHeaderRow{display:flex;align-items:center;justify-content:space-between;gap:.6rem}
50
+ .groupHeader{display:block;font-weight:800;letter-spacing:.2px;font-size:1.02rem;margin:0;text-decoration:none;color:var(--ifm-font-color-base)}
51
+ .breadcrumb{font-size:.76rem;color:var(--ifm-color-emphasis-700);margin:.08rem 0 .35rem}
52
+ .groupSnips{display:flex;flex-direction:column;gap:.3rem}
53
+ .snippet {
54
+ font-size:.92rem;
55
+ color:var(--ifm-color-emphasis-800);
56
+ line-height:1.35;
57
+ position:relative;
58
+ padding-left:1rem;
59
+ white-space:nowrap;
60
+ overflow:hidden;
61
+ text-overflow:ellipsis;
62
+ }
63
+ .snippet::before {
64
+ content:">";
65
+ position:absolute;
66
+ left:0;
67
+ color:var(--ifm-color-primary);
68
+ font-weight:700;
69
+ }
70
+ .groupUrl{
71
+ font-family:var(--content-font-family);
72
+ margin-top:.3rem;
73
+ white-space:nowrap;
74
+ overflow:hidden;
75
+ text-overflow:ellipsis
76
+ }
77
+
78
+ /* ===== Badges ===== */
79
+ .badge{padding:.16rem .55rem;border-radius:999px;font-size:.72rem;border:1px solid var(--ifm-color-emphasis-300)}
80
+ .p_frontdoor{background:#e8f3ff;border-color:#c6e1ff;color:#145ea8}
81
+ .p_openziti{background:#e9fff3;border-color:#c8f2df;color:#0d7a4e}
82
+ .p_onprem{background:#fff3e8;border-color:#ffdcbf;color:#9a4d00}
83
+ .p_zlan{background:#f1edff;border-color:#d9d0ff;color:#5335b7}
84
+ .p_zrok{background:#fff0f0;border-color:#ffd0d0;color:#b71c1c}
85
+
86
+ /* ===== Pagination ===== */
87
+ .pagination{display:flex;justify-content:center;margin:.8rem 0}
88
+ .pageList{display:flex;gap:.35rem;list-style:none;padding:0;margin:0}
89
+ .pageItem{display:inline-flex}
90
+ .pageItemDisabled{opacity:.45;pointer-events:none}
91
+ .pageItemSelected .pageLink{background:var(--ifm-color-primary);color:#fff;border-color:var(--ifm-color-primary)}
92
+ .pageLink{
93
+ display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;padding:0 .6rem;
94
+ border:1px solid var(--ifm-color-emphasis-300);border-radius:.55rem;text-decoration:none;font-size:.82rem;
95
+ transition:transform .12s,background .12s,border-color .12s
96
+ }
97
+ .pageLink:hover{transform:translateY(-1px);border-color:var(--ifm-color-primary)}
98
+
99
+ /* ===== Highlights ===== */
100
+ :global(mark){
101
+ background:#ffe955;color:inherit;border-radius:3px;box-shadow:0 0 0 2px rgba(255,233,85,.25) inset
102
+ }
103
+
104
+ /* ===== Dark mode tweaks ===== */
105
+ :global(html[data-theme='dark']) .group{border-color:rgba(255,255,255,.09);box-shadow:0 2px 10px rgba(0,0,0,.35)}
106
+ :global(html[data-theme='dark']) .breadcrumb{color:var(--ifm-color-emphasis-600)}
107
+ :global(html[data-theme='dark']) .groupUrl{opacity:.95}
108
+ :global(html[data-theme='dark']) .pill{background:linear-gradient(180deg,#1b1b1d,#161618);border-color:rgba(255,255,255,.08)}
109
+
110
+ /* ===== DocSearch modal polish ===== */
111
+ :global(.DocSearch-Modal){border-radius:16px;box-shadow:0 28px 80px rgba(0,0,0,.35)}
112
+ :global(.DocSearch-Input){height:48px;border-radius:12px}
113
+ :global(.DocSearch-Hit){border-radius:12px}
114
+ :global(.DocSearch-Hit a){border-radius:12px}
115
+ :global(.DocSearch-Hit-source){color:var(--ifm-color-primary)}
116
+ :global(.DocSearch-Footer){border-top:1px solid var(--ifm-color-emphasis-200)}
117
+
118
+ :global(.ais-SearchBox) { width: 100%; }
119
+
120
+ :global(.ais-SearchBox-form) {
121
+ display: flex;
122
+ align-items: center;
123
+ width: 100%;
124
+ gap:.55rem;
125
+ }
126
+
127
+ :global(.ais-SearchBox-input),
128
+ :global(.searchInput_ps_s) {
129
+ flex: 1 1 auto;
130
+ min-width: 0;
131
+ }
132
+
133
+ :global(.ais-SearchBox-submit),
134
+ :global(.ais-SearchBox-reset),
135
+ :global(.ais-SearchBox-loadingIndicator) {
136
+ flex: 0 0 auto;
137
+ }
138
+ :global(.ais-SearchBox-submitIcon) {
139
+ height: .75rem;
140
+ width: .75rem;
141
+ }
142
+ :global(.ais-SearchBox-reset) {
143
+ display: none;
144
+ }
145
+
146
+
147
+ .container{display:flex;flex-direction:column;flex-grow:1}
148
+ .results{flex:1 1 auto;overflow:auto}
149
+
150
+ .footer{
151
+ position:sticky;bottom:0;display:flex;justify-content:space-between;align-items:center;
152
+ gap:.75rem;background:var(--ifm-background-color);
153
+ border-top:1px solid var(--ifm-color-emphasis-200);
154
+ padding:.55rem .7rem;z-index:1;backdrop-filter:saturate(140%) blur(4px)
155
+ }
156
+ .kbdRow{display:flex;gap:.8rem;font-size:.82rem;color:var(--ifm-color-emphasis-700)}
157
+ .kbdRow kbd{border:1px solid var(--ifm-color-emphasis-300);border-bottom-width:2px;border-radius:7px;padding:.06rem .38rem;font-family:inherit}
158
+
159
+ .footer :global(.ais-PoweredBy){margin:0}
160
+ .footer :global(.ais-PoweredBy-logo){height:1rem}
161
+
162
+ /* tighten typographic weight in nested rows inside groups */
163
+ .groupList > div > div {color:var(--ifm-color-primary);}
164
+
165
+ /* Match pill colors to badge colors */
166
+ .pill.active[data-product="frontdoor"] {
167
+ background: #e8f3ff;
168
+ border-color: #c6e1ff;
169
+ color: #145ea8;
170
+ }
171
+ .pill.active[data-product="openziti"] {
172
+ background: #e9fff3;
173
+ border-color: #c8f2df;
174
+ color: #0d7a4e;
175
+ }
176
+ .pill.active[data-product="onprem"] {
177
+ background: #fff3e8;
178
+ border-color: #ffdcbf;
179
+ color: #9a4d00;
180
+ }
181
+ .pill.active[data-product="zlan"] {
182
+ background: #f1edff;
183
+ border-color: #d9d0ff;
184
+ color: #5335b7;
185
+ }
186
+ .pill.active[data-product="zrok"] {
187
+ background: #fff0f0;
188
+ border-color: #ffd0d0;
189
+ color: #b71c1c;
190
+ }
@@ -0,0 +1,3 @@
1
+ export { ProductSearch } from './ProductSearch';
2
+ export type { ProductSearchProps } from './ProductSearch';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ProductSearch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { ProductSearch } from './ProductSearch';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/ProductSearch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,37 @@
1
+ .trigger{all:unset;cursor:pointer;padding:.4rem .6rem;border:1px solid var(--ifm-color-emphasis-300);border-radius:8px}
2
+ .backdrop{
3
+ position:fixed;
4
+ inset:0;
5
+ background:rgba(0,0,0,.5);
6
+ display:flex;
7
+ align-items:flex-start;
8
+ justify-content:center;
9
+ padding-top:10vh;
10
+ z-index:9999;
11
+ width:100%;
12
+ }
13
+ .modal{
14
+ /*background:var(--ifm-background-color);*/
15
+ /*color:var(--ifm-font-color-base);*/
16
+ /*min-height:85vh;*/
17
+ /*max-height:85vh;*/
18
+ /*overflow:auto;*/
19
+ /*border-radius:12px;*/
20
+ /*padding:1rem;*/
21
+ }
22
+ .close{position:relative;cursor:pointer;font-size:1.5rem}
23
+ /* src/theme/SearchBar/SearchBar.module.css */
24
+ .pills{position:fixed;top:12px;right:18px;z-index:100000;display:flex;gap:.4rem;flex-wrap:wrap}
25
+ .pills button{all:unset;cursor:pointer;padding:.25rem .6rem;border:1px solid var(--ifm-color-emphasis-300);border-radius:999px;font-size:.8rem;background:var(--ifm-background-color)}
26
+ .pills button.active{background:var(--ifm-color-primary);color:#fff;border-color:transparent}
27
+
28
+ .modalSearchContainer {
29
+ max-height: 60vh;
30
+ }
31
+ .searchModal {
32
+ background: var(--ifm-background-color);
33
+ padding: 10px;
34
+ border-radius: 10px;
35
+ width: 80vw;
36
+ max-width: 800px;
37
+ }
@@ -0,0 +1,2 @@
1
+ export default function SearchBar(): import("react/jsx-runtime").JSX.Element | null;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../theme/SearchBar/index.tsx"],"names":[],"mappings":"AAUA,MAAM,CAAC,OAAO,UAAU,SAAS,mDA6DhC"}
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // theme/SearchBar/index.tsx
3
+ import { useEffect, useState } from "react";
4
+ import ReactDOM from "react-dom";
5
+ import { DocSearchButton } from "@docsearch/react";
6
+ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
7
+ import { ProductSearch } from "../../src/components/ProductSearch";
8
+ import styles from "./SearchBar.module.css";
9
+ import clsx from "clsx";
10
+ export default function SearchBar() {
11
+ const [open, setOpen] = useState(false);
12
+ const [mounted, setMounted] = useState(false);
13
+ const [mouseDownTarget, setMouseDownTarget] = useState(null);
14
+ useEffect(() => setMounted(true), []);
15
+ useEffect(() => {
16
+ const onKey = (e) => {
17
+ if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "k") {
18
+ e.preventDefault();
19
+ setOpen(true);
20
+ }
21
+ if (e.key === "Escape")
22
+ setOpen(false);
23
+ };
24
+ window.addEventListener("keydown", onKey);
25
+ return () => window.removeEventListener("keydown", onKey);
26
+ }, []);
27
+ useEffect(() => { document.body.style.overflow = open ? "hidden" : ""; }, [open]);
28
+ const { siteConfig } = useDocusaurusContext();
29
+ const { customFields, themeConfig } = siteConfig;
30
+ // Get Algolia config from customFields or themeConfig.algolia
31
+ const algoliaConfig = themeConfig?.algolia || {};
32
+ const appId = customFields?.ALGOLIA_APPID || algoliaConfig.appId || '';
33
+ const apiKey = customFields?.ALGOLIA_APIKEY || algoliaConfig.apiKey || '';
34
+ const indexName = customFields?.ALGOLIA_INDEXNAME || algoliaConfig.indexName || '';
35
+ if (!appId || !apiKey || !indexName) {
36
+ // Fall back to default DocSearch if no valid config
37
+ return null;
38
+ }
39
+ return (_jsxs(_Fragment, { children: [_jsx(DocSearchButton, { onClick: () => setOpen(true) }), mounted && open && ReactDOM.createPortal(_jsx("div", { className: styles.backdrop, onMouseDown: (e) => setMouseDownTarget(e.target), onMouseUp: (e) => {
40
+ if (e.target === mouseDownTarget && e.target === e.currentTarget) {
41
+ setOpen(false);
42
+ }
43
+ }, children: _jsx("div", { className: styles.searchModal, onClick: (e) => e.stopPropagation(), children: _jsx("div", { className: clsx(styles.modal), onClick: (e) => e.stopPropagation(), children: _jsx(ProductSearch, { appId: appId, apiKey: apiKey, indexName: indexName, extraContainerClasses: [styles.modalSearchContainer] }) }) }) }), document.body)] }));
44
+ }
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../theme/SearchBar/index.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@netfoundry/docusaurus-theme",
3
- "version": "0.3.1",
3
+ "version": "0.3.4",
4
4
  "description": "NetFoundry Docusaurus theme with shared layout, footer, and styling",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
7
7
  "files": [
8
8
  "dist",
9
- "css"
9
+ "css",
10
+ "theme"
10
11
  ],
11
12
  "scripts": {
12
13
  "clean": "node scripts/clean.mjs",
@@ -45,9 +46,13 @@
45
46
  "react-dom": "^18 || ^19"
46
47
  },
47
48
  "dependencies": {
49
+ "@docsearch/react": "^3",
50
+ "algoliasearch": "^5",
48
51
  "clsx": "^2.0.0",
52
+ "instantsearch.js": "^4",
49
53
  "react-device-detect": "^2.2.3",
50
- "react-github-btn": "^1.4.0"
54
+ "react-github-btn": "^1.4.0",
55
+ "react-instantsearch": "^7"
51
56
  },
52
57
  "devDependencies": {
53
58
  "@docusaurus/core": "^3",
@@ -0,0 +1,74 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
3
+ import {
4
+ NetFoundryLayout,
5
+ defaultNetFoundryFooterProps,
6
+ defaultSocialProps,
7
+ } from '../../src/ui';
8
+ import type { ThemeConfigWithNetFoundry } from '../../src/options';
9
+
10
+ export interface LayoutProps {
11
+ children: ReactNode;
12
+ noFooter?: boolean;
13
+ wrapperClassName?: string;
14
+ title?: string;
15
+ description?: string;
16
+ }
17
+
18
+ /**
19
+ * NetFoundry theme Layout component.
20
+ *
21
+ * This component wraps NetFoundryLayout and reads configuration from
22
+ * themeConfig.netfoundry in docusaurus.config.ts.
23
+ *
24
+ * To customize further, swizzle this component:
25
+ * npx docusaurus swizzle @netfoundry/docusaurus-theme Layout --wrap
26
+ */
27
+ export default function Layout({
28
+ children,
29
+ noFooter,
30
+ wrapperClassName,
31
+ title,
32
+ description,
33
+ }: LayoutProps): ReactNode {
34
+ const { siteConfig } = useDocusaurusContext();
35
+ const themeConfig = siteConfig.themeConfig as ThemeConfigWithNetFoundry;
36
+ const nfConfig = themeConfig.netfoundry ?? {};
37
+
38
+ // Build footer props from config, falling back to defaults
39
+ const footerProps = noFooter
40
+ ? undefined
41
+ : {
42
+ ...defaultNetFoundryFooterProps(),
43
+ ...nfConfig.footer,
44
+ socialProps: {
45
+ ...defaultSocialProps,
46
+ ...nfConfig.footer?.socialProps,
47
+ },
48
+ };
49
+
50
+ // Build star props if enabled
51
+ const starProps =
52
+ nfConfig.showStarBanner && nfConfig.starBanner
53
+ ? {
54
+ repoUrl: nfConfig.starBanner.repoUrl,
55
+ label: nfConfig.starBanner.label,
56
+ }
57
+ : undefined;
58
+
59
+ return (
60
+ <NetFoundryLayout
61
+ title={title}
62
+ description={description}
63
+ className={wrapperClassName}
64
+ noFooter={noFooter}
65
+ footerProps={footerProps}
66
+ starProps={starProps}
67
+ meta={{
68
+ siteName: siteConfig.title,
69
+ }}
70
+ >
71
+ {children}
72
+ </NetFoundryLayout>
73
+ );
74
+ }
@@ -0,0 +1,37 @@
1
+ .trigger{all:unset;cursor:pointer;padding:.4rem .6rem;border:1px solid var(--ifm-color-emphasis-300);border-radius:8px}
2
+ .backdrop{
3
+ position:fixed;
4
+ inset:0;
5
+ background:rgba(0,0,0,.5);
6
+ display:flex;
7
+ align-items:flex-start;
8
+ justify-content:center;
9
+ padding-top:10vh;
10
+ z-index:9999;
11
+ width:100%;
12
+ }
13
+ .modal{
14
+ /*background:var(--ifm-background-color);*/
15
+ /*color:var(--ifm-font-color-base);*/
16
+ /*min-height:85vh;*/
17
+ /*max-height:85vh;*/
18
+ /*overflow:auto;*/
19
+ /*border-radius:12px;*/
20
+ /*padding:1rem;*/
21
+ }
22
+ .close{position:relative;cursor:pointer;font-size:1.5rem}
23
+ /* src/theme/SearchBar/SearchBar.module.css */
24
+ .pills{position:fixed;top:12px;right:18px;z-index:100000;display:flex;gap:.4rem;flex-wrap:wrap}
25
+ .pills button{all:unset;cursor:pointer;padding:.25rem .6rem;border:1px solid var(--ifm-color-emphasis-300);border-radius:999px;font-size:.8rem;background:var(--ifm-background-color)}
26
+ .pills button.active{background:var(--ifm-color-primary);color:#fff;border-color:transparent}
27
+
28
+ .modalSearchContainer {
29
+ max-height: 60vh;
30
+ }
31
+ .searchModal {
32
+ background: var(--ifm-background-color);
33
+ padding: 10px;
34
+ border-radius: 10px;
35
+ width: 80vw;
36
+ max-width: 800px;
37
+ }
@@ -0,0 +1,72 @@
1
+ // theme/SearchBar/index.tsx
2
+ import React, {useEffect, useState} from "react";
3
+ import ReactDOM from "react-dom";
4
+ import {DocSearchButton} from "@docsearch/react";
5
+ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
6
+
7
+ import {ProductSearch} from "../../src/components/ProductSearch";
8
+ import styles from "./SearchBar.module.css";
9
+ import clsx from "clsx";
10
+
11
+ export default function SearchBar() {
12
+ const [open, setOpen] = useState(false);
13
+ const [mounted, setMounted] = useState(false);
14
+ const [mouseDownTarget, setMouseDownTarget] = useState<EventTarget | null>(null);
15
+
16
+ useEffect(() => setMounted(true), []);
17
+ useEffect(() => {
18
+ const onKey = (e: KeyboardEvent) => {
19
+ if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "k") {
20
+ e.preventDefault();
21
+ setOpen(true);
22
+ }
23
+ if (e.key === "Escape") setOpen(false);
24
+ };
25
+ window.addEventListener("keydown", onKey);
26
+ return () => window.removeEventListener("keydown", onKey);
27
+ }, []);
28
+ useEffect(() => { document.body.style.overflow = open ? "hidden" : ""; }, [open]);
29
+
30
+ const { siteConfig } = useDocusaurusContext();
31
+ const { customFields, themeConfig } = siteConfig;
32
+
33
+ // Get Algolia config from customFields or themeConfig.algolia
34
+ const algoliaConfig = (themeConfig as any)?.algolia || {};
35
+ const appId = (customFields?.ALGOLIA_APPID as string) || algoliaConfig.appId || '';
36
+ const apiKey = (customFields?.ALGOLIA_APIKEY as string) || algoliaConfig.apiKey || '';
37
+ const indexName = (customFields?.ALGOLIA_INDEXNAME as string) || algoliaConfig.indexName || '';
38
+
39
+ if (!appId || !apiKey || !indexName) {
40
+ // Fall back to default DocSearch if no valid config
41
+ return null;
42
+ }
43
+
44
+ return (
45
+ <>
46
+ <DocSearchButton onClick={() => setOpen(true)} />
47
+ {mounted && open && ReactDOM.createPortal(
48
+ <div
49
+ className={styles.backdrop}
50
+ onMouseDown={(e) => setMouseDownTarget(e.target)}
51
+ onMouseUp={(e) => {
52
+ if (e.target === mouseDownTarget && e.target === e.currentTarget) {
53
+ setOpen(false);
54
+ }
55
+ }}
56
+ >
57
+ <div className={styles.searchModal} onClick={(e) => e.stopPropagation()}>
58
+ <div className={clsx(styles.modal)} onClick={(e) => e.stopPropagation()}>
59
+ <ProductSearch
60
+ appId={appId}
61
+ apiKey={apiKey}
62
+ indexName={indexName}
63
+ extraContainerClasses={[styles.modalSearchContainer]}
64
+ />
65
+ </div>
66
+ </div>
67
+ </div>,
68
+ document.body
69
+ )}
70
+ </>
71
+ );
72
+ }