@xyd-js/framework 0.1.0-xyd.11 → 0.1.0-xyd.115

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.
package/dist/react.js ADDED
@@ -0,0 +1,612 @@
1
+ // packages/react/components/index.tsx
2
+ import React5, { isValidElement, useState as useState3 } from "react";
3
+ import { Link, useLocation as useLocation2, useMatches as useMatches2 } from "react-router";
4
+ import { Nav, SubNav, Toc, UISidebar as UISidebar2 } from "@xyd-js/ui";
5
+ import { Anchor, Breadcrumbs, Button as Button2, ColorSchemeButton, Icon as Icon2, NavLinks, useColorScheme } from "@xyd-js/components/writer";
6
+
7
+ // packages/react/components/Surfaces.tsx
8
+ import React, { createContext, useContext } from "react";
9
+ var SurfaceContext = createContext({
10
+ surfaces: void 0
11
+ });
12
+ function Surface(props) {
13
+ const { target } = props;
14
+ const registry = useContext(SurfaceContext);
15
+ if (!registry.surfaces) {
16
+ return null;
17
+ }
18
+ const components = registry.surfaces.get(target);
19
+ if (!components) {
20
+ return null;
21
+ }
22
+ if (!Array.isArray(components)) {
23
+ if (typeof components === "function") {
24
+ const Component = components;
25
+ return /* @__PURE__ */ React.createElement(Component, { ...props.props });
26
+ }
27
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, components);
28
+ }
29
+ if (!components.length) {
30
+ return null;
31
+ }
32
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, components.map((Component, index) => {
33
+ if (typeof Component === "function") {
34
+ const Comp = Component;
35
+ return /* @__PURE__ */ React.createElement(Comp, { key: index, ...props.props });
36
+ }
37
+ return /* @__PURE__ */ React.createElement(React.Fragment, { key: index }, Component);
38
+ }));
39
+ }
40
+
41
+ // packages/react/contexts/framework.tsx
42
+ import React2, { createContext as createContext2, useContext as useContext2, useEffect, useState } from "react";
43
+ import { useNavigation } from "react-router";
44
+ import { ProgressBar } from "@xyd-js/ui";
45
+ import { Banner } from "@xyd-js/components/writer";
46
+ var framework = {
47
+ settings: {},
48
+ metadata: {
49
+ title: ""
50
+ },
51
+ sidebarGroups: [],
52
+ setMetadata: () => {
53
+ },
54
+ components: {}
55
+ };
56
+ var FrameworkContext = createContext2(framework);
57
+ function Framework(props) {
58
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
59
+ const navigation = useNavigation();
60
+ const [metadata, setMetadata] = useState(props.metadata);
61
+ const BannerContent = props.BannerContent || null;
62
+ const BannerComponent = ((_c = (_b = (_a = props == null ? void 0 : props.settings) == null ? void 0 : _a.theme) == null ? void 0 : _b.banner) == null ? void 0 : _c.kind) === "secondary" ? Banner.Secondary : Banner;
63
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(FrameworkContext, { value: {
64
+ settings: Object.freeze({ ...props.settings }),
65
+ sidebarGroups: Object.freeze([...props.sidebarGroups]),
66
+ metadata: Object.freeze({ ...metadata, title: (metadata == null ? void 0 : metadata.title) || "" }),
67
+ setMetadata,
68
+ components: Object.freeze(props.components || {})
69
+ } }, /* @__PURE__ */ React2.createElement(SurfaceContext, { value: {
70
+ surfaces: props.surfaces
71
+ } }, /* @__PURE__ */ React2.createElement(ProgressBar, { isActive: navigation.state === "loading" }), BannerContent ? /* @__PURE__ */ React2.createElement(
72
+ BannerComponent,
73
+ {
74
+ label: (_f = (_e = (_d = props.settings) == null ? void 0 : _d.theme) == null ? void 0 : _e.banner) == null ? void 0 : _f.label,
75
+ icon: (_i = (_h = (_g = props.settings) == null ? void 0 : _g.theme) == null ? void 0 : _h.banner) == null ? void 0 : _i.icon
76
+ },
77
+ /* @__PURE__ */ React2.createElement(BannerContent, null)
78
+ ) : null, props.children)));
79
+ }
80
+ var FrameworkPageContext = createContext2({
81
+ ContentComponent: () => /* @__PURE__ */ React2.createElement(React2.Fragment, null),
82
+ metadata: {
83
+ title: ""
84
+ }
85
+ });
86
+ function FrameworkPage(props) {
87
+ const { setMetadata } = useContext2(FrameworkContext);
88
+ useEffect(() => {
89
+ setMetadata(props.metadata);
90
+ }, []);
91
+ return /* @__PURE__ */ React2.createElement(FrameworkPageContext, { value: {
92
+ ContentComponent: props.ContentComponent || (() => /* @__PURE__ */ React2.createElement(React2.Fragment, null)),
93
+ metadata: Object.freeze(props.metadata),
94
+ breadcrumbs: Object.freeze(props.breadcrumbs),
95
+ rawPage: Object.freeze(props.rawPage),
96
+ toc: Object.freeze(props.toc || []),
97
+ navlinks: Object.freeze(props.navlinks)
98
+ } }, props.children);
99
+ }
100
+ function useSidebarGroups() {
101
+ const ctx = useContext2(FrameworkContext);
102
+ return ctx.sidebarGroups;
103
+ }
104
+ function useSettings() {
105
+ const ctx = useContext2(FrameworkContext);
106
+ return ctx.settings;
107
+ }
108
+ function useMetadata() {
109
+ const ctx = useContext2(FrameworkContext);
110
+ return ctx.metadata;
111
+ }
112
+ function useComponents() {
113
+ const ctx = useContext2(FrameworkContext);
114
+ return ctx.components;
115
+ }
116
+ function useToC() {
117
+ const ctx = useContext2(FrameworkPageContext);
118
+ const toc = ctx.toc || [];
119
+ return toc;
120
+ }
121
+ function useBreadcrumbs() {
122
+ const ctx = useContext2(FrameworkPageContext);
123
+ return ctx.breadcrumbs;
124
+ }
125
+ function useNavLinks() {
126
+ const ctx = useContext2(FrameworkPageContext);
127
+ return ctx.navlinks;
128
+ }
129
+ function useRawPage() {
130
+ const ctx = useContext2(FrameworkPageContext);
131
+ return ctx.rawPage;
132
+ }
133
+ function useContentComponent() {
134
+ const ctx = useContext2(FrameworkPageContext);
135
+ return ctx.ContentComponent;
136
+ }
137
+
138
+ // packages/react/components/Sidebar/Sidebar.tsx
139
+ import React4 from "react";
140
+ import { UISidebar } from "@xyd-js/ui";
141
+ import { Icon } from "@xyd-js/components/writer";
142
+
143
+ // packages/react/components/Sidebar/SidebarGroup.tsx
144
+ import React3, { createContext as createContext3, useContext as useContext3, useState as useState2, useEffect as useEffect2 } from "react";
145
+ import { useNavigation as useNavigation2 } from "react-router";
146
+ var GroupContext = createContext3({
147
+ active: () => [false, () => {
148
+ }]
149
+ });
150
+ function FwSidebarGroupContext(props) {
151
+ const { children, initialActiveItems } = props;
152
+ const groupBehaviour = useDefaultBehaviour(initialActiveItems);
153
+ return /* @__PURE__ */ React3.createElement(GroupContext, { value: {
154
+ active: groupBehaviour
155
+ } }, children);
156
+ }
157
+ function useGroup() {
158
+ return useContext3(GroupContext);
159
+ }
160
+ function useDefaultBehaviour(initialActiveItems) {
161
+ const navigation = useNavigation2();
162
+ const [activeItems, setActiveItems] = useState2(() => createItemsMap(initialActiveItems));
163
+ const [, setForceUpdate] = useState2(0);
164
+ const forceUpdate = () => setForceUpdate((prev) => prev + 1);
165
+ useEffect2(() => {
166
+ if (navigation.state !== "loading") {
167
+ setActiveItems(createItemsMap(initialActiveItems));
168
+ forceUpdate();
169
+ }
170
+ }, [initialActiveItems, navigation.state]);
171
+ function addItem(item) {
172
+ const key = itemId(item);
173
+ setActiveItems((prev) => {
174
+ const newMap = new Map(prev);
175
+ newMap.set(key, true);
176
+ return newMap;
177
+ });
178
+ forceUpdate();
179
+ }
180
+ function deleteItem(item) {
181
+ const key = itemId(item);
182
+ setActiveItems((prev) => {
183
+ const newMap = new Map(prev);
184
+ newMap.delete(key);
185
+ return newMap;
186
+ });
187
+ forceUpdate();
188
+ }
189
+ function hasItem(item) {
190
+ const key = itemId(item);
191
+ return activeItems.get(key) || false;
192
+ }
193
+ return (item) => {
194
+ return [
195
+ hasItem(item) || false,
196
+ () => {
197
+ if (!hasItem(item)) {
198
+ addItem(item);
199
+ return;
200
+ }
201
+ deleteItem(item);
202
+ }
203
+ ];
204
+ };
205
+ }
206
+ function itemId(item) {
207
+ const id = `${item.uniqIndex}:${item.groupIndex}-${item.level}-${item.itemIndex}`;
208
+ return id;
209
+ }
210
+ function createItemsMap(items) {
211
+ const map = /* @__PURE__ */ new Map();
212
+ items.forEach((item) => {
213
+ const key = itemId(item);
214
+ map.set(key, true);
215
+ });
216
+ return map;
217
+ }
218
+
219
+ // packages/react/components/Sidebar/Sidebar.tsx
220
+ function FwSidebarItemGroup(props) {
221
+ const icon = props.icon ? /* @__PURE__ */ React4.createElement(Icon, { name: props.icon || "", size: 16 }) : null;
222
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(UISidebar.ItemHeader, { icon }, props.group), props.items.map((item, index) => /* @__PURE__ */ React4.createElement(
223
+ FwSidebarItem,
224
+ {
225
+ uniqIndex: item.uniqIndex,
226
+ groupIndex: props.groupIndex,
227
+ level: 0,
228
+ itemIndex: index,
229
+ key: index + item.href,
230
+ title: item.title,
231
+ sidebarTitle: item.sidebarTitle,
232
+ pageMeta: item.pageMeta,
233
+ href: item.href,
234
+ items: item.items,
235
+ active: item.active,
236
+ icon: item.icon
237
+ }
238
+ )));
239
+ }
240
+ function FwSidebarItem(props) {
241
+ var _a, _b, _c, _d;
242
+ const { active } = useGroup();
243
+ const [isActive, setActive] = active(props);
244
+ const title = props.sidebarTitle || props.title || "";
245
+ const nested = !!((_a = props.items) == null ? void 0 : _a.length);
246
+ function handleClick() {
247
+ if (!nested) {
248
+ return;
249
+ }
250
+ setActive();
251
+ }
252
+ const hasActiveChild = (_b = props.items) == null ? void 0 : _b.some((item) => {
253
+ var _a2;
254
+ const [itemActive] = active(item);
255
+ return itemActive && item.href || ((_a2 = item.items) == null ? void 0 : _a2.some((subItem) => {
256
+ const [subItemActive] = active(subItem);
257
+ return subItemActive && subItem.href;
258
+ }));
259
+ });
260
+ const isActiveItem = !!(isActive && props.href);
261
+ const isParentActive = hasActiveChild;
262
+ const icon = /* @__PURE__ */ React4.createElement(Icon, { name: props.icon || "", size: 16 });
263
+ return /* @__PURE__ */ React4.createElement(
264
+ UISidebar.Item,
265
+ {
266
+ button: nested,
267
+ href: props.href,
268
+ active: isActiveItem,
269
+ isParentActive,
270
+ onClick: handleClick,
271
+ icon
272
+ },
273
+ /* @__PURE__ */ React4.createElement("div", { part: "item-title-container" }, /* @__PURE__ */ React4.createElement(
274
+ Surface,
275
+ {
276
+ target: "sidebar.item.left",
277
+ props: {
278
+ active: isActiveItem,
279
+ pageMeta: props.pageMeta
280
+ }
281
+ }
282
+ ), /* @__PURE__ */ React4.createElement("div", { part: "item-title" }, title), /* @__PURE__ */ React4.createElement(
283
+ Surface,
284
+ {
285
+ target: "sidebar.item.right",
286
+ props: {
287
+ active: isActiveItem,
288
+ pageMeta: props.pageMeta
289
+ }
290
+ }
291
+ )),
292
+ ((_c = props.items) == null ? void 0 : _c.length) && /* @__PURE__ */ React4.createElement(UISidebar.SubTree, { isOpen: isActive }, /* @__PURE__ */ React4.createElement(React4.Fragment, null, (_d = props.items) == null ? void 0 : _d.map((item, index) => /* @__PURE__ */ React4.createElement(
293
+ FwSidebarItem,
294
+ {
295
+ uniqIndex: item.uniqIndex,
296
+ groupIndex: props.groupIndex,
297
+ level: (props.level || 0) + 1,
298
+ itemIndex: index,
299
+ key: index + item.href,
300
+ title: item.title,
301
+ href: item.href,
302
+ items: item.items,
303
+ active: active(item)[0],
304
+ icon: item.icon,
305
+ pageMeta: item.pageMeta
306
+ }
307
+ ))))
308
+ );
309
+ }
310
+
311
+ // packages/react/hooks/useMatchedNav.tsx
312
+ import { useMatches } from "react-router";
313
+ function useMatchedSubNav() {
314
+ var _a, _b, _c;
315
+ const settings = useSettings();
316
+ const matches = useMatches();
317
+ const lastMatchId = (_a = matches[matches.length - 1]) == null ? void 0 : _a.id;
318
+ let matchedSubnav = (_c = (_b = settings.navigation) == null ? void 0 : _b.segments) == null ? void 0 : _c.find((item) => {
319
+ var _a2;
320
+ return (_a2 = item.pages) == null ? void 0 : _a2.find((page) => {
321
+ return sanitizeUrl(page.page || "") === sanitizeUrl(lastMatchId);
322
+ });
323
+ });
324
+ if (!matchedSubnav) {
325
+ return null;
326
+ }
327
+ return matchedSubnav || null;
328
+ }
329
+ function sanitizeUrl(url) {
330
+ if (url.startsWith("/")) {
331
+ return url;
332
+ }
333
+ return `/${url}`;
334
+ }
335
+
336
+ // packages/react/components/index.tsx
337
+ function FwNavLogo() {
338
+ var _a;
339
+ const settings = useSettings();
340
+ const logo = typeof ((_a = settings == null ? void 0 : settings.theme) == null ? void 0 : _a.logo);
341
+ if (!logo) {
342
+ return null;
343
+ }
344
+ return /* @__PURE__ */ React5.createElement("a", { href: "/" }, /* @__PURE__ */ React5.createElement(FwLogo, null));
345
+ }
346
+ function FwNav({ kind }) {
347
+ var _a, _b;
348
+ const matches = useMatches2();
349
+ const matchedSubnav = useMatchedSubNav();
350
+ const settings = useSettings();
351
+ const lastMatch = matches[matches.length - 1];
352
+ const header = ((_a = settings == null ? void 0 : settings.navigation) == null ? void 0 : _a.header) || [];
353
+ const active = header.find((item) => {
354
+ if (matchedSubnav) {
355
+ return pageLink(item.page || "") === pageLink(matchedSubnav == null ? void 0 : matchedSubnav.route);
356
+ }
357
+ return pageLink(item.page || "") === (lastMatch == null ? void 0 : lastMatch.id);
358
+ });
359
+ function createHeader(item) {
360
+ return /* @__PURE__ */ React5.createElement(
361
+ Nav.Item,
362
+ {
363
+ key: (item.page || "") + item.page,
364
+ href: pageLink((item == null ? void 0 : item.page) || ""),
365
+ value: item.page || "",
366
+ as: $Link
367
+ },
368
+ item.title
369
+ );
370
+ }
371
+ const headerMap = header.reduce((acc, item) => {
372
+ const float = item.float || "default";
373
+ return {
374
+ ...acc,
375
+ [float]: [...acc[float] || [], createHeader(item)]
376
+ };
377
+ }, {});
378
+ const rightHeaderExists = ((_b = headerMap["right"]) == null ? void 0 : _b.length) > 0;
379
+ return /* @__PURE__ */ React5.createElement(
380
+ Nav,
381
+ {
382
+ value: (active == null ? void 0 : active.page) || "",
383
+ kind,
384
+ logo: /* @__PURE__ */ React5.createElement(FwNavLogo, null),
385
+ rightSurface: /* @__PURE__ */ React5.createElement(React5.Fragment, null, rightHeaderExists ? /* @__PURE__ */ React5.createElement(
386
+ Nav.Tab,
387
+ {
388
+ value: (active == null ? void 0 : active.page) || ""
389
+ },
390
+ headerMap["right"]
391
+ ) : null, /* @__PURE__ */ React5.createElement(Surface, { target: "nav.right" /* NavRight */ }), /* @__PURE__ */ React5.createElement(ColorSchemeButton, null))
392
+ },
393
+ headerMap["default"]
394
+ );
395
+ }
396
+ function FwSubNav() {
397
+ const matchedSubnav = useMatchedSubNav();
398
+ const location = useLocation2();
399
+ const pathname = trailingSlash(location.pathname);
400
+ if (!matchedSubnav) {
401
+ return null;
402
+ }
403
+ const active = matchedSubnav == null ? void 0 : matchedSubnav.pages.findLast((item) => {
404
+ return pathname.startsWith(pageLink(item.page || ""));
405
+ });
406
+ return /* @__PURE__ */ React5.createElement(
407
+ SubNav,
408
+ {
409
+ title: (matchedSubnav == null ? void 0 : matchedSubnav.title) || "",
410
+ value: (active == null ? void 0 : active.page) || "",
411
+ onChange: () => {
412
+ }
413
+ },
414
+ matchedSubnav == null ? void 0 : matchedSubnav.pages.map((item, index) => {
415
+ return /* @__PURE__ */ React5.createElement(
416
+ SubNav.Item,
417
+ {
418
+ value: item.page || "",
419
+ href: pageLink(item.page || ""),
420
+ as: $Link
421
+ },
422
+ item.title
423
+ );
424
+ })
425
+ );
426
+ }
427
+ function FwSidebarGroups(props) {
428
+ var _a, _b, _c;
429
+ const location = useLocation2();
430
+ const pathname = trailingSlash(location.pathname);
431
+ const groups = useSidebarGroups();
432
+ const settings = useSettings();
433
+ const footerItems = (_c = (_b = (_a = settings.navigation) == null ? void 0 : _a.anchors) == null ? void 0 : _b.bottom) == null ? void 0 : _c.map((anchor) => {
434
+ return /* @__PURE__ */ React5.createElement(UISidebar2.FooterItem, { href: anchor.url, icon: /* @__PURE__ */ React5.createElement(Icon2, { name: anchor.icon || "" }) }, anchor.name);
435
+ });
436
+ const initialActiveItems = [];
437
+ groups.forEach((group, groupIndex) => {
438
+ const activeLevels = recursiveSearch(group.items, pathname) || [];
439
+ activeLevels.reduce((acc, index, level) => {
440
+ initialActiveItems.push({
441
+ ...acc[index],
442
+ groupIndex,
443
+ level,
444
+ itemIndex: index
445
+ });
446
+ acc[index].active = true;
447
+ return acc[index].items;
448
+ }, group.items);
449
+ return group;
450
+ });
451
+ return /* @__PURE__ */ React5.createElement(
452
+ FwSidebarGroupContext,
453
+ {
454
+ initialActiveItems
455
+ },
456
+ /* @__PURE__ */ React5.createElement(UISidebar2, { footerItems: footerItems && footerItems }, /* @__PURE__ */ React5.createElement(Surface, { target: "sidebar.top" /* SidebarTop */ }), groups == null ? void 0 : groups.map((group, index) => /* @__PURE__ */ React5.createElement(
457
+ FwSidebarItemGroup,
458
+ {
459
+ key: index + group.group,
460
+ ...group,
461
+ groupIndex: index
462
+ }
463
+ )))
464
+ );
465
+ }
466
+ function FwToc() {
467
+ var _a;
468
+ const metadata = useMetadata();
469
+ const settings = useSettings();
470
+ const toc = useToC();
471
+ if (!toc) {
472
+ return null;
473
+ }
474
+ const maxDepth = (metadata == null ? void 0 : metadata.maxTocDepth) || ((_a = settings == null ? void 0 : settings.theme) == null ? void 0 : _a.maxTocDepth) || 2;
475
+ const renderTocItems = (items, uiDepth = 0) => {
476
+ return items.map((item) => /* @__PURE__ */ React5.createElement(React5.Fragment, { key: item.id }, /* @__PURE__ */ React5.createElement(
477
+ Toc.Item,
478
+ {
479
+ id: item.id,
480
+ depth: uiDepth
481
+ },
482
+ item.value
483
+ ), item.children && item.children.length > 0 && renderTocItems(item.children, uiDepth + 1)));
484
+ };
485
+ return /* @__PURE__ */ React5.createElement(Toc, { maxDepth }, renderTocItems(toc));
486
+ }
487
+ function FwBreadcrumbs() {
488
+ const fwBreadcrumbs = useBreadcrumbs();
489
+ const breadcrumbs = fwBreadcrumbs == null ? void 0 : fwBreadcrumbs.map((item) => ({
490
+ title: item.title,
491
+ href: item.href
492
+ }));
493
+ return /* @__PURE__ */ React5.createElement(
494
+ Breadcrumbs,
495
+ {
496
+ items: breadcrumbs || []
497
+ }
498
+ );
499
+ }
500
+ function FwNavLinks() {
501
+ const navlinks = useNavLinks();
502
+ if ((navlinks == null ? void 0 : navlinks.prev) || (navlinks == null ? void 0 : navlinks.next)) {
503
+ return /* @__PURE__ */ React5.createElement(
504
+ NavLinks,
505
+ {
506
+ prev: navlinks.prev,
507
+ next: navlinks.next,
508
+ as: $Link
509
+ }
510
+ );
511
+ }
512
+ return null;
513
+ }
514
+ function FwLogo() {
515
+ var _a, _b, _c, _d, _e, _f;
516
+ const settings = useSettings();
517
+ const [colorScheme] = useColorScheme();
518
+ if (typeof ((_a = settings == null ? void 0 : settings.theme) == null ? void 0 : _a.logo) === "string") {
519
+ return /* @__PURE__ */ React5.createElement("img", { src: (_b = settings == null ? void 0 : settings.theme) == null ? void 0 : _b.logo });
520
+ }
521
+ if (isValidElement((_c = settings == null ? void 0 : settings.theme) == null ? void 0 : _c.logo)) {
522
+ return /* @__PURE__ */ React5.createElement("a", { href: "/" }, (_d = settings == null ? void 0 : settings.theme) == null ? void 0 : _d.logo);
523
+ }
524
+ if (typeof ((_e = settings == null ? void 0 : settings.theme) == null ? void 0 : _e.logo) === "object" && colorScheme) {
525
+ return /* @__PURE__ */ React5.createElement("img", { src: (_f = settings == null ? void 0 : settings.theme) == null ? void 0 : _f.logo[colorScheme] });
526
+ }
527
+ return null;
528
+ }
529
+ function FwLink({ children, ...rest }) {
530
+ return /* @__PURE__ */ React5.createElement(Anchor, { ...rest, as: $Link }, children);
531
+ }
532
+ function FwCopyPage() {
533
+ const [isCopied, setIsCopied] = useState3(false);
534
+ const rawPage = useRawPage();
535
+ const handleCopy = () => {
536
+ navigator.clipboard.writeText(rawPage || "");
537
+ setIsCopied(true);
538
+ setTimeout(() => setIsCopied(false), 2e3);
539
+ };
540
+ return /* @__PURE__ */ React5.createElement(Button2, { icon: isCopied ? /* @__PURE__ */ React5.createElement(Icon2, { name: "check", size: 12 }) : /* @__PURE__ */ React5.createElement(Icon2, { name: "copy", size: 12 }), onClick: handleCopy }, "Copy page");
541
+ }
542
+ function $Link({ children, ...rest }) {
543
+ let to = "";
544
+ if (rest.href) {
545
+ try {
546
+ new URL(rest.href);
547
+ to = rest.href;
548
+ } catch (error) {
549
+ if (rest.href.startsWith("/")) {
550
+ const url = new URL(`https://example.com${rest.href}`);
551
+ to = {
552
+ pathname: url.pathname,
553
+ search: url.search,
554
+ hash: url.hash
555
+ };
556
+ } else {
557
+ return /* @__PURE__ */ React5.createElement(Anchor, { as: "button", onClick: () => {
558
+ const url = new URL(window.location.href);
559
+ const currentParams = url.searchParams;
560
+ new URLSearchParams(rest.href).forEach((value, key) => {
561
+ currentParams.set(key, value);
562
+ });
563
+ url.search = currentParams.toString();
564
+ history.replaceState(null, "", url);
565
+ } }, children);
566
+ }
567
+ }
568
+ }
569
+ return /* @__PURE__ */ React5.createElement(Link, { ...rest, to }, children);
570
+ }
571
+ function recursiveSearch(items, href, levels = []) {
572
+ for (let i = 0; i < items.length; i++) {
573
+ const item = items[i];
574
+ if (item.href === href) {
575
+ return [...levels, i];
576
+ }
577
+ if (item.items) {
578
+ const result = recursiveSearch(item.items, href, [...levels, i]);
579
+ if (result) {
580
+ return result;
581
+ }
582
+ }
583
+ }
584
+ return null;
585
+ }
586
+ function trailingSlash(path) {
587
+ return path.endsWith("/") ? path.slice(0, -1) : path;
588
+ }
589
+ function pageLink(page) {
590
+ return page.startsWith("/") ? page : `/${page}`;
591
+ }
592
+ export {
593
+ Framework,
594
+ FrameworkPage,
595
+ FwBreadcrumbs,
596
+ FwCopyPage,
597
+ FwLink,
598
+ FwLogo,
599
+ FwNav,
600
+ FwNavLinks,
601
+ FwSidebarGroups,
602
+ FwSubNav,
603
+ FwToc,
604
+ Surface,
605
+ SurfaceContext,
606
+ useComponents,
607
+ useContentComponent,
608
+ useMatchedSubNav,
609
+ useMetadata,
610
+ useSettings
611
+ };
612
+ //# sourceMappingURL=react.js.map