@xyd-js/framework 0.1.0-build.189

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,1367 @@
1
+ // packages/react/components/FwBanner.tsx
2
+ import React3 from "react";
3
+ import { Banner as Banner2 } from "@xyd-js/components/writer";
4
+
5
+ // packages/react/contexts/framework.tsx
6
+ import React2, { createContext as createContext2, useContext as useContext2, useEffect, useState } from "react";
7
+ import { useNavigation } from "react-router";
8
+ import { Banner } from "@xyd-js/components/writer";
9
+ import { ProgressBar } from "@xyd-js/ui";
10
+
11
+ // packages/react/components/Surfaces.tsx
12
+ import React, { createContext, useContext } from "react";
13
+ var SurfaceContext = createContext({
14
+ surfaces: void 0
15
+ });
16
+ function Surface(props) {
17
+ const { target } = props;
18
+ const registry = useContext(SurfaceContext);
19
+ if (!registry.surfaces) {
20
+ return null;
21
+ }
22
+ const components = registry.surfaces.get(target);
23
+ if (!components) {
24
+ return null;
25
+ }
26
+ if (!Array.isArray(components)) {
27
+ if (typeof components === "function") {
28
+ const Component = components;
29
+ return /* @__PURE__ */ React.createElement(Component, { ...props.props });
30
+ }
31
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, components);
32
+ }
33
+ if (!components.length) {
34
+ return null;
35
+ }
36
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, components.map((Component, index) => {
37
+ if (typeof Component === "function") {
38
+ const Comp = Component;
39
+ return /* @__PURE__ */ React.createElement(Comp, { key: index, ...props.props });
40
+ }
41
+ return /* @__PURE__ */ React.createElement(React.Fragment, { key: index }, Component);
42
+ }));
43
+ }
44
+
45
+ // packages/react/contexts/framework.tsx
46
+ var framework = {
47
+ settings: {},
48
+ metadata: {
49
+ title: ""
50
+ },
51
+ sidebarGroups: [],
52
+ setMetadata: () => {
53
+ },
54
+ components: {},
55
+ BannerContent: null
56
+ };
57
+ var FrameworkContext = createContext2(framework);
58
+ function Framework(props) {
59
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
60
+ const navigation = useNavigation();
61
+ const [metadata, setMetadata] = useState(props.metadata);
62
+ const BannerContent = props.BannerContent || null;
63
+ const BannerComponent = ((_c = (_b = (_a = props == null ? void 0 : props.settings) == null ? void 0 : _a.components) == null ? void 0 : _b.banner) == null ? void 0 : _c.kind) === "secondary" ? Banner.Secondary : Banner;
64
+ const appearance = (_d = props.settings.theme) == null ? void 0 : _d.appearance;
65
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(FrameworkContext, { value: {
66
+ settings: Object.freeze({ ...props.settings }),
67
+ sidebarGroups: Object.freeze([...props.sidebarGroups]),
68
+ metadata: Object.freeze({ ...metadata, title: (metadata == null ? void 0 : metadata.title) || "" }),
69
+ setMetadata,
70
+ components: Object.freeze(props.components || {}),
71
+ BannerContent: props.BannerContent || null
72
+ } }, /* @__PURE__ */ React2.createElement(SurfaceContext, { value: {
73
+ surfaces: props.surfaces
74
+ } }, /* @__PURE__ */ React2.createElement(ProgressBar, { isActive: navigation.state === "loading" }), BannerContent && !((_e = appearance == null ? void 0 : appearance.banner) == null ? void 0 : _e.fixed) ? /* @__PURE__ */ React2.createElement(
75
+ BannerComponent,
76
+ {
77
+ label: (_h = (_g = (_f = props.settings) == null ? void 0 : _f.components) == null ? void 0 : _g.banner) == null ? void 0 : _h.label,
78
+ icon: (_k = (_j = (_i = props.settings) == null ? void 0 : _i.components) == null ? void 0 : _j.banner) == null ? void 0 : _k.icon,
79
+ href: (_n = (_m = (_l = props.settings) == null ? void 0 : _l.components) == null ? void 0 : _m.banner) == null ? void 0 : _n.href
80
+ },
81
+ /* @__PURE__ */ React2.createElement(BannerContent, null)
82
+ ) : null, props.children)));
83
+ }
84
+ var FrameworkPageContext = createContext2({
85
+ ContentComponent: () => /* @__PURE__ */ React2.createElement(React2.Fragment, null),
86
+ ContentOriginal: () => /* @__PURE__ */ React2.createElement(React2.Fragment, null),
87
+ metadata: {
88
+ title: ""
89
+ }
90
+ });
91
+ function FrameworkPage(props) {
92
+ const { setMetadata } = useContext2(FrameworkContext);
93
+ useEffect(() => {
94
+ setMetadata(props.metadata);
95
+ }, []);
96
+ return /* @__PURE__ */ React2.createElement(FrameworkPageContext, { value: {
97
+ ContentComponent: props.ContentComponent || (() => /* @__PURE__ */ React2.createElement(React2.Fragment, null)),
98
+ ContentOriginal: props.ContentOriginal || (() => /* @__PURE__ */ React2.createElement(React2.Fragment, null)),
99
+ metadata: Object.freeze(props.metadata),
100
+ breadcrumbs: Object.freeze(props.breadcrumbs),
101
+ rawPage: Object.freeze(props.rawPage),
102
+ toc: Object.freeze(props.toc || []),
103
+ navlinks: Object.freeze(props.navlinks)
104
+ } }, props.children);
105
+ }
106
+ function useSidebarGroups() {
107
+ const ctx = useContext2(FrameworkContext);
108
+ return ctx.sidebarGroups;
109
+ }
110
+ function useSettings() {
111
+ const ctx = useContext2(FrameworkContext);
112
+ return ctx.settings;
113
+ }
114
+ function useMetadata() {
115
+ const ctx = useContext2(FrameworkContext);
116
+ return ctx.metadata;
117
+ }
118
+ function useComponents() {
119
+ const ctx = useContext2(FrameworkContext);
120
+ return ctx.components;
121
+ }
122
+ function useToC() {
123
+ const ctx = useContext2(FrameworkPageContext);
124
+ const toc = ctx.toc || [];
125
+ return toc;
126
+ }
127
+ function useBreadcrumbs() {
128
+ const ctx = useContext2(FrameworkPageContext);
129
+ return ctx.breadcrumbs;
130
+ }
131
+ function useNavLinks() {
132
+ const ctx = useContext2(FrameworkPageContext);
133
+ return ctx.navlinks;
134
+ }
135
+ function useRawPage() {
136
+ const ctx = useContext2(FrameworkPageContext);
137
+ return ctx.rawPage;
138
+ }
139
+ function useContentComponent() {
140
+ const ctx = useContext2(FrameworkPageContext);
141
+ return ctx.ContentComponent;
142
+ }
143
+ function useContentOriginal() {
144
+ const ctx = useContext2(FrameworkPageContext);
145
+ return ctx.ContentOriginal;
146
+ }
147
+ function useAppearance() {
148
+ var _a;
149
+ const ctx = useContext2(FrameworkContext);
150
+ return (_a = ctx.settings.theme) == null ? void 0 : _a.appearance;
151
+ }
152
+ function useBannerContent() {
153
+ const ctx = useContext2(FrameworkContext);
154
+ return ctx.BannerContent;
155
+ }
156
+
157
+ // packages/react/components/FwBanner.tsx
158
+ function FwBanner() {
159
+ var _a, _b, _c, _d, _e, _f, _g, _h;
160
+ const BannerContent = useBannerContent();
161
+ const settings = useSettings();
162
+ const BannerComponent = ((_b = (_a = settings == null ? void 0 : settings.components) == null ? void 0 : _a.banner) == null ? void 0 : _b.kind) === "secondary" ? Banner2.Secondary : Banner2;
163
+ if (!BannerContent) {
164
+ return null;
165
+ }
166
+ return /* @__PURE__ */ React3.createElement(
167
+ BannerComponent,
168
+ {
169
+ label: (_d = (_c = settings == null ? void 0 : settings.components) == null ? void 0 : _c.banner) == null ? void 0 : _d.label,
170
+ icon: (_f = (_e = settings == null ? void 0 : settings.components) == null ? void 0 : _e.banner) == null ? void 0 : _f.icon,
171
+ href: (_h = (_g = settings == null ? void 0 : settings.components) == null ? void 0 : _g.banner) == null ? void 0 : _h.href
172
+ },
173
+ /* @__PURE__ */ React3.createElement(BannerContent, null)
174
+ );
175
+ }
176
+
177
+ // packages/react/components/FwBreadcrumbs.tsx
178
+ import React4 from "react";
179
+ import { Breadcrumbs } from "@xyd-js/components/writer";
180
+ function FwBreadcrumbs() {
181
+ const fwBreadcrumbs = useBreadcrumbs();
182
+ const breadcrumbs = fwBreadcrumbs == null ? void 0 : fwBreadcrumbs.map((item) => ({
183
+ title: item.title,
184
+ href: item.href
185
+ }));
186
+ return /* @__PURE__ */ React4.createElement(
187
+ Breadcrumbs,
188
+ {
189
+ items: breadcrumbs || []
190
+ }
191
+ );
192
+ }
193
+
194
+ // packages/react/components/FwCopyPage.tsx
195
+ import React5, { useState as useState2 } from "react";
196
+ import { Button, Icon } from "@xyd-js/components/writer";
197
+ import { useUXEvents } from "@xyd-js/analytics";
198
+ function FwCopyPage() {
199
+ const [isCopied, setIsCopied] = useState2(false);
200
+ const rawPage = useRawPage();
201
+ const ux = useUXEvents();
202
+ const handleCopy = () => {
203
+ navigator.clipboard.writeText(rawPage || "");
204
+ setIsCopied(true);
205
+ ux.docs.copy_page({});
206
+ setTimeout(() => setIsCopied(false), 2e3);
207
+ };
208
+ return /* @__PURE__ */ React5.createElement(
209
+ Button,
210
+ {
211
+ icon: isCopied ? /* @__PURE__ */ React5.createElement(Icon, { name: "check", size: 12 }) : /* @__PURE__ */ React5.createElement(Icon, { name: "copy", size: 12 }),
212
+ onClick: handleCopy
213
+ },
214
+ "Copy page"
215
+ );
216
+ }
217
+
218
+ // packages/react/components/FwJsonComponent.tsx
219
+ import React6 from "react";
220
+ import * as WriterComponents from "@xyd-js/components/writer";
221
+ import * as CoderComponents from "@xyd-js/components/coder";
222
+ import * as SystemComponents from "@xyd-js/components/system";
223
+ function FwJsonComponent(args) {
224
+ const components = useJsonComponents();
225
+ if (!args) {
226
+ return null;
227
+ }
228
+ if (React6.isValidElement(args)) {
229
+ return args;
230
+ }
231
+ if (typeof args === "string") {
232
+ return args;
233
+ }
234
+ if (!args || typeof args !== "object") {
235
+ return null;
236
+ }
237
+ if (!("component" in args)) {
238
+ return null;
239
+ }
240
+ const { component, props: { children, ...props } = {} } = args;
241
+ if (!component) {
242
+ return null;
243
+ }
244
+ let Component = resolveComponent(component, components);
245
+ if (Component) {
246
+ return /* @__PURE__ */ React6.createElement(Component, { ...props }, renderChildren(children));
247
+ }
248
+ Component = component;
249
+ return /* @__PURE__ */ React6.createElement(Component, { ...props }, renderChildren(children));
250
+ }
251
+ function useJsonComponents() {
252
+ const customComponents = useComponents();
253
+ const componentSources = /* @__PURE__ */ new Map();
254
+ const components = {};
255
+ const componentSets = [
256
+ {
257
+ group: "Writer",
258
+ components: WriterComponents
259
+ },
260
+ {
261
+ group: "Coder",
262
+ components: CoderComponents
263
+ },
264
+ {
265
+ group: "System",
266
+ components: SystemComponents
267
+ },
268
+ {
269
+ group: "Custom",
270
+ components: customComponents || {}
271
+ }
272
+ ];
273
+ componentSets.forEach((componentSet) => {
274
+ Object.entries(componentSet.components).forEach(([name, component]) => {
275
+ if (name.charAt(0) !== name.charAt(0).toUpperCase()) {
276
+ return;
277
+ }
278
+ if (typeof component !== "function") {
279
+ return;
280
+ }
281
+ if (name in components) {
282
+ const existingComponent = components[name];
283
+ const existingGroup = componentSources.get(name) || "Custom";
284
+ delete components[name];
285
+ components[`${existingGroup}.${name}`] = existingComponent;
286
+ components[`${componentSet.group}.${name}`] = component;
287
+ console.debug(`Component name conflict resolved: ${name} -> ${existingGroup}.${name} and ${componentSet.group}.${name}`);
288
+ } else {
289
+ components[name] = component;
290
+ componentSources.set(name, componentSet.group);
291
+ }
292
+ });
293
+ });
294
+ return components;
295
+ }
296
+ function renderChildren(children) {
297
+ if (!children) {
298
+ return null;
299
+ }
300
+ if (Array.isArray(children)) {
301
+ return children.map((child, index) => /* @__PURE__ */ React6.createElement(FwJsonComponent, { key: index, ...child }));
302
+ }
303
+ if (typeof children === "object" && children !== null && "component" in children) {
304
+ return /* @__PURE__ */ React6.createElement(FwJsonComponent, { ...children });
305
+ }
306
+ return children;
307
+ }
308
+ function resolveComponent(componentName, components) {
309
+ if (!componentName || typeof componentName !== "string") {
310
+ return null;
311
+ }
312
+ if (componentName.includes(".")) {
313
+ const parts = componentName.split(".");
314
+ let current = components;
315
+ for (const part of parts) {
316
+ if (current && typeof current === "object" && part in current) {
317
+ current = current[part];
318
+ } else {
319
+ return null;
320
+ }
321
+ }
322
+ return current;
323
+ }
324
+ return components[componentName] || null;
325
+ }
326
+
327
+ // packages/react/components/FwLink.tsx
328
+ import React7 from "react";
329
+ import { Link } from "react-router";
330
+ import { Anchor } from "@xyd-js/components/writer";
331
+
332
+ // packages/react/utils/isExternal.ts
333
+ function isExternal(filePath) {
334
+ return filePath.startsWith("http://") || filePath.startsWith("https://");
335
+ }
336
+
337
+ // packages/react/utils/pageLink.ts
338
+ function pageLink(page) {
339
+ if (page === "index" || page === "/index") {
340
+ return "/";
341
+ }
342
+ if (!page) {
343
+ return "";
344
+ }
345
+ if (page.startsWith("http://") || page.startsWith("https://")) {
346
+ return page;
347
+ }
348
+ return page.startsWith("/") ? page : `/${page}`;
349
+ }
350
+
351
+ // packages/react/utils/trailingSlash.ts
352
+ function trailingSlash(path) {
353
+ return path.endsWith("/") ? path.slice(0, -1) : path;
354
+ }
355
+
356
+ // packages/react/components/FwLink.tsx
357
+ function FwLink({ children, ...rest }) {
358
+ let to = "";
359
+ let external = false;
360
+ if (rest.href) {
361
+ try {
362
+ new URL(rest.href);
363
+ to = rest.href;
364
+ external = isExternal(rest.href);
365
+ } catch (error) {
366
+ if (rest.href.startsWith("/")) {
367
+ const url = new URL(`https://example.com${rest.href}`);
368
+ to = {
369
+ pathname: url.pathname,
370
+ search: url.search,
371
+ hash: url.hash
372
+ };
373
+ } else {
374
+ return /* @__PURE__ */ React7.createElement(Anchor, { as: "button" }, children);
375
+ return /* @__PURE__ */ React7.createElement(Anchor, { as: "button", onClick: () => {
376
+ const url = new URL(window.location.href);
377
+ const currentParams = url.searchParams;
378
+ new URLSearchParams(rest.href).forEach((value, key) => {
379
+ currentParams.set(key, value);
380
+ });
381
+ url.search = currentParams.toString();
382
+ history.replaceState(null, "", url);
383
+ } }, children);
384
+ }
385
+ }
386
+ }
387
+ let pathname = typeof to === "string" ? to : to.pathname || "";
388
+ if (pathname.startsWith("/mailto:")) {
389
+ pathname = fixMailTo(pathname);
390
+ to = pathname;
391
+ }
392
+ if ((rest.href || "").startsWith("/mailto:")) {
393
+ rest.href = fixMailTo(rest.href);
394
+ }
395
+ return /* @__PURE__ */ React7.createElement(
396
+ Anchor,
397
+ {
398
+ as: $Link,
399
+ ...rest,
400
+ to,
401
+ target: external ? "_blank" : rest.target
402
+ },
403
+ children
404
+ );
405
+ }
406
+ function fixMailTo(href) {
407
+ if (href.startsWith("/mailto:")) {
408
+ return href.replace("/mailto:", "mailto:");
409
+ }
410
+ return href;
411
+ }
412
+ function $Link(props) {
413
+ return /* @__PURE__ */ React7.createElement(
414
+ Link,
415
+ {
416
+ ...props
417
+ },
418
+ props.children
419
+ );
420
+ }
421
+
422
+ // packages/react/components/FwLogo.tsx
423
+ import React8, { isValidElement } from "react";
424
+ import { Link as Link2 } from "react-router";
425
+ import {
426
+ useColorScheme
427
+ } from "@xyd-js/components/writer";
428
+
429
+ // packages/react/hooks/useActiveMatchedSubNav.ts
430
+ import { useLocation, useMatches as useMatches2 } from "react-router";
431
+
432
+ // packages/react/hooks/useMatchedSegment.ts
433
+ import { useMatches } from "react-router";
434
+ function useMatchedSegment() {
435
+ var _a, _b, _c;
436
+ const settings = useSettings();
437
+ const matches = useMatches();
438
+ const lastMatchId = (_a = matches[matches.length - 1]) == null ? void 0 : _a.id;
439
+ const matchedSegment = (_c = (_b = settings.navigation) == null ? void 0 : _b.segments) == null ? void 0 : _c.find((item) => {
440
+ var _a2;
441
+ return (_a2 = item.pages) == null ? void 0 : _a2.find((page) => {
442
+ return sanitizeUrl(page.page || "") === sanitizeUrl(lastMatchId);
443
+ });
444
+ });
445
+ return matchedSegment || null;
446
+ }
447
+ function sanitizeUrl(url) {
448
+ if (url.startsWith("/")) {
449
+ return url;
450
+ }
451
+ return `/${url}`;
452
+ }
453
+
454
+ // packages/react/hooks/useTabSegments.ts
455
+ function useTabSegments() {
456
+ var _a;
457
+ const settings = useSettings();
458
+ const tabs = ((_a = settings.navigation) == null ? void 0 : _a.tabs) || [];
459
+ if (tabs == null ? void 0 : tabs.length) {
460
+ return {
461
+ route: "",
462
+ title: "",
463
+ pages: tabs
464
+ };
465
+ }
466
+ return null;
467
+ }
468
+
469
+ // packages/react/hooks/useMatchedSubNav.ts
470
+ function useMatchedSubNav() {
471
+ var _a, _b;
472
+ const matchedSegment = useMatchedSegment();
473
+ const tabSegments = useTabSegments();
474
+ const appearance = useAppearance();
475
+ if ((((_a = appearance == null ? void 0 : appearance.tabs) == null ? void 0 : _a.surface) === "center" || ((_b = appearance == null ? void 0 : appearance.tabs) == null ? void 0 : _b.surface) === "sidebar") && !matchedSegment) {
476
+ return null;
477
+ }
478
+ if (!matchedSegment || matchedSegment.appearance === "sidebarDropdown") {
479
+ return tabSegments;
480
+ }
481
+ return matchedSegment || null;
482
+ }
483
+
484
+ // packages/react/hooks/useActiveMatchedSubNav.ts
485
+ function useActiveMatchedSubNav() {
486
+ var _a;
487
+ const location = useLocation();
488
+ const matchedSubnav = useMatchedSubNav();
489
+ const matches = useMatches2();
490
+ const pathname = trailingSlash(location.pathname);
491
+ const lastMatch = matches[matches.length - 1];
492
+ const isIndex = (lastMatch == null ? void 0 : lastMatch.pathname) === "/";
493
+ return (_a = matchedSubnav == null ? void 0 : matchedSubnav.pages) == null ? void 0 : _a.filter((p) => typeof p.page === "string").findLast((item) => {
494
+ if (isIndex) {
495
+ return item.page === "index";
496
+ }
497
+ return pathname.startsWith(pageLink(item.page || ""));
498
+ });
499
+ }
500
+
501
+ // packages/react/hooks/useActivePage.ts
502
+ import { useMatches as useMatches3 } from "react-router";
503
+ function useActivePage(match = false) {
504
+ var _a, _b, _c;
505
+ const matches = useMatches3();
506
+ const matchedSubnav = useMatchedSubNav();
507
+ const settings = useSettings();
508
+ const lastMatch = matches[matches.length - 1];
509
+ const navigationItems = [
510
+ ...((_a = settings == null ? void 0 : settings.navigation) == null ? void 0 : _a.tabs) || [],
511
+ ...((_b = settings == null ? void 0 : settings.navigation) == null ? void 0 : _b.sidebarDropdown) || [],
512
+ ...((_c = settings == null ? void 0 : settings.webeditor) == null ? void 0 : _c.header) || []
513
+ ];
514
+ const isIndex = (lastMatch == null ? void 0 : lastMatch.pathname) === "/";
515
+ let active = navigationItems.find((item) => {
516
+ if (isIndex) {
517
+ return item.page === "index";
518
+ }
519
+ if (matchedSubnav) {
520
+ const routeMatch = pageLink(item.page || "") === pageLink(matchedSubnav == null ? void 0 : matchedSubnav.route);
521
+ if (routeMatch) {
522
+ return routeMatch;
523
+ }
524
+ if (match) {
525
+ const pageMatch = matchedSubnav == null ? void 0 : matchedSubnav.pages.findLast((page) => {
526
+ if (!page.page) {
527
+ return false;
528
+ }
529
+ return pageLink(lastMatch == null ? void 0 : lastMatch.id).startsWith(pageLink(page.page || ""));
530
+ });
531
+ return pageLink((pageMatch == null ? void 0 : pageMatch.page) || "") === pageLink(item.page || "");
532
+ }
533
+ return false;
534
+ }
535
+ return pageLink(item.page || "") === (lastMatch == null ? void 0 : lastMatch.id);
536
+ });
537
+ if (!active && !matchedSubnav && match) {
538
+ active = navigationItems.findLast((item) => {
539
+ if (!item.page) {
540
+ return false;
541
+ }
542
+ return pageLink(lastMatch == null ? void 0 : lastMatch.id).startsWith(pageLink(item.page || ""));
543
+ });
544
+ }
545
+ return (active == null ? void 0 : active.page) || "";
546
+ }
547
+
548
+ // packages/react/hooks/useActivePageRoute.ts
549
+ import { useMatches as useMatches4 } from "react-router";
550
+ function useActivePageRoute(match = false) {
551
+ var _a;
552
+ const matches = useMatches4();
553
+ const matchedSubnav = useMatchedSubNav();
554
+ const settings = useSettings();
555
+ const lastMatch = matches[matches.length - 1];
556
+ const sidebarRoutes = extractSidebarRoutes(((_a = settings == null ? void 0 : settings.navigation) == null ? void 0 : _a.sidebar) || []);
557
+ let active = sidebarRoutes.find((item) => {
558
+ if (matchedSubnav) {
559
+ const routeMatch = pageLink(item.route || "") === pageLink(matchedSubnav == null ? void 0 : matchedSubnav.route);
560
+ if (routeMatch) {
561
+ return routeMatch;
562
+ }
563
+ if (match) {
564
+ const pageMatch = matchedSubnav == null ? void 0 : matchedSubnav.pages.findLast((page) => {
565
+ if (!page.page) {
566
+ return false;
567
+ }
568
+ return pageLink(lastMatch == null ? void 0 : lastMatch.id).startsWith(pageLink(page.page || ""));
569
+ });
570
+ return pageLink((pageMatch == null ? void 0 : pageMatch.page) || "") === pageLink(item.route || "");
571
+ }
572
+ return false;
573
+ }
574
+ return pageLink(item.route || "") === (lastMatch == null ? void 0 : lastMatch.id);
575
+ });
576
+ if (!active && !matchedSubnav && match) {
577
+ active = sidebarRoutes.findLast((item) => {
578
+ if (!item.route) {
579
+ return false;
580
+ }
581
+ return pageLink(lastMatch == null ? void 0 : lastMatch.id).startsWith(pageLink(item.route || ""));
582
+ });
583
+ }
584
+ return active || null;
585
+ }
586
+ function extractSidebarRoutes(sidebar) {
587
+ const items = [];
588
+ if (!sidebar) return items;
589
+ for (const sidebarItem of sidebar) {
590
+ if (typeof sidebarItem === "object" && "pages" in sidebarItem) {
591
+ const wrapper = sidebarItem;
592
+ for (const page of wrapper.pages) {
593
+ if (typeof page === "object" && "route" in page && "pages" in page) {
594
+ items.push(page);
595
+ }
596
+ }
597
+ }
598
+ }
599
+ return items;
600
+ }
601
+
602
+ // packages/react/hooks/useActiveRoute.ts
603
+ import { useMatches as useMatches5 } from "react-router";
604
+ function useActiveRoute() {
605
+ var _a, _b;
606
+ const matches = useMatches5();
607
+ const settings = useSettings();
608
+ const lastMatch = matches[matches.length - 1];
609
+ const activeRoute = (_b = (_a = settings == null ? void 0 : settings.navigation) == null ? void 0 : _a.sidebar) == null ? void 0 : _b.find((item) => {
610
+ if (typeof item === "object" && "route" in item) {
611
+ return pageLink((lastMatch == null ? void 0 : lastMatch.id) || "") === pageLink(item.route || "");
612
+ }
613
+ return false;
614
+ });
615
+ if (typeof activeRoute === "object" && "route" in activeRoute) {
616
+ return activeRoute;
617
+ }
618
+ return null;
619
+ }
620
+
621
+ // packages/react/hooks/useActiveSegment.ts
622
+ import { useLocation as useLocation2 } from "react-router";
623
+ function useActiveSegment() {
624
+ var _a;
625
+ const location = useLocation2();
626
+ const pathname = trailingSlash(location.pathname);
627
+ const matchedSegment = useMatchedSegment();
628
+ const active = (_a = matchedSegment == null ? void 0 : matchedSegment.pages) == null ? void 0 : _a.findLast((item) => {
629
+ return pathname.startsWith(pageLink(item.page || ""));
630
+ });
631
+ return (active == null ? void 0 : active.page) || "";
632
+ }
633
+
634
+ // packages/react/hooks/useHeaderItems.ts
635
+ function useHeaderItems() {
636
+ var _a;
637
+ const settings = useSettings();
638
+ const header = ((_a = settings == null ? void 0 : settings.webeditor) == null ? void 0 : _a.header) || [];
639
+ const headerMap = header.reduce((acc, item) => {
640
+ const float = item.float || "default";
641
+ return {
642
+ ...acc,
643
+ [float]: [...acc[float] || [], item]
644
+ };
645
+ }, {});
646
+ return {
647
+ default: headerMap["default"] || [],
648
+ center: headerMap["center"] || [],
649
+ right: headerMap["right"] || []
650
+ };
651
+ }
652
+
653
+ // packages/react/hooks/useDefaultHeaderItems.ts
654
+ function useDefaultHeaderItems() {
655
+ const headerItems = useHeaderItems();
656
+ return headerItems.default;
657
+ }
658
+
659
+ // packages/react/hooks/useLogoLink.ts
660
+ function useLogoLink() {
661
+ var _a;
662
+ const settings = useSettings();
663
+ const logo = (_a = settings == null ? void 0 : settings.theme) == null ? void 0 : _a.logo;
664
+ if (!logo) {
665
+ return "/";
666
+ }
667
+ let to = "/";
668
+ if (typeof logo === "object" && ("page" in logo || "href" in logo)) {
669
+ return pageLink(logo.href || logo.page || "/");
670
+ }
671
+ return to;
672
+ }
673
+
674
+ // packages/react/hooks/useMatchedSegmentSidebarDropdown.ts
675
+ function useMatchedSegmentSidebarDropdown() {
676
+ const matchedSegment = useMatchedSegment();
677
+ if (!matchedSegment) {
678
+ return null;
679
+ }
680
+ if (matchedSegment.appearance === "sidebarDropdown") {
681
+ return matchedSegment;
682
+ }
683
+ return null;
684
+ }
685
+
686
+ // packages/react/components/FwLogo.tsx
687
+ function FwLogo() {
688
+ var _a, _b, _c;
689
+ const settings = useSettings();
690
+ const [clientColorScheme] = useColorScheme();
691
+ const colorScheme = clientColorScheme || ((_b = (_a = settings == null ? void 0 : settings.theme) == null ? void 0 : _a.appearance) == null ? void 0 : _b.colorScheme) || "light";
692
+ const logo = (_c = settings == null ? void 0 : settings.theme) == null ? void 0 : _c.logo;
693
+ if (typeof logo === "string") {
694
+ return /* @__PURE__ */ React8.createElement($Logo, { src: logo });
695
+ }
696
+ if (isValidElement(logo)) {
697
+ return /* @__PURE__ */ React8.createElement($Logo, null, logo);
698
+ }
699
+ if (typeof logo === "object") {
700
+ return /* @__PURE__ */ React8.createElement($Logo, { src: logo[colorScheme] });
701
+ }
702
+ return null;
703
+ }
704
+ function $Logo({ src, children }) {
705
+ const logoLink = useLogoLink();
706
+ return /* @__PURE__ */ React8.createElement("span", { part: "logo" }, /* @__PURE__ */ React8.createElement(Link2, { to: logoLink }, src ? /* @__PURE__ */ React8.createElement("img", { src }) : children));
707
+ }
708
+
709
+ // packages/react/components/FwNav.tsx
710
+ import React11 from "react";
711
+ import { Nav as Nav3 } from "@xyd-js/ui";
712
+ import {
713
+ ColorSchemeButton
714
+ } from "@xyd-js/components/writer";
715
+ import { LayoutPrimary } from "@xyd-js/components/layouts";
716
+
717
+ // packages/react/components/FwHeaderItems.tsx
718
+ import React10 from "react";
719
+ import { Icon as Icon2 } from "@xyd-js/components/writer";
720
+ import { Nav as Nav2 } from "@xyd-js/ui";
721
+
722
+ // packages/react/components/WebEditorComponent.tsx
723
+ import React9 from "react";
724
+ import { Nav, UISidebar } from "@xyd-js/ui";
725
+ function WebEditorComponent(Component, componentProps, defaultValue) {
726
+ return function WebEditorComponentInner(props) {
727
+ var _a;
728
+ let dataTags = {};
729
+ if (props.device === "mobile" || props.mobile && !props.desktop) {
730
+ dataTags["data-mobile"] = true;
731
+ }
732
+ if (props.device === "desktop" || props.desktop && !props.mobile) {
733
+ dataTags["data-desktop"] = true;
734
+ }
735
+ const content = /* @__PURE__ */ React9.createElement(
736
+ Component,
737
+ {
738
+ ...componentProps,
739
+ ...dataTags
740
+ },
741
+ props.component ? /* @__PURE__ */ React9.createElement(
742
+ FwJsonComponent,
743
+ {
744
+ component: props.component || "",
745
+ props: {
746
+ ...props.props,
747
+ children: (_a = props.props) == null ? void 0 : _a.children
748
+ }
749
+ }
750
+ ) : defaultValue,
751
+ props.children
752
+ );
753
+ return Object.keys(dataTags).length > 0 ? /* @__PURE__ */ React9.createElement("div", { ...dataTags }, content) : content;
754
+ };
755
+ }
756
+ WebEditorComponent.SidebarItem = WebEditorComponent(UISidebar.Item, { button: false, ghost: true });
757
+ WebEditorComponent.NavItemRaw = WebEditorComponent(Nav.ItemRaw);
758
+ WebEditorComponent.SidebarItemButton = WebEditorComponent(UISidebar.Item, { button: true, ghost: true });
759
+
760
+ // packages/react/components/FwHeaderItems.tsx
761
+ function FwHeaderItems() {
762
+ const headerItems = useHeaderItems();
763
+ return Object.entries(headerItems).reduce((acc, [key, value]) => {
764
+ const headerItems2 = value.map(FwHeaderItem);
765
+ return {
766
+ ...acc,
767
+ [key]: headerItems2
768
+ };
769
+ }, {
770
+ default: [],
771
+ center: [],
772
+ right: []
773
+ });
774
+ }
775
+ function FwHeaderItem(props) {
776
+ var _a;
777
+ const appearance = useAppearance();
778
+ let href = null;
779
+ if (typeof props.href === "string") {
780
+ href = pageLink(props.href);
781
+ }
782
+ if (!href && typeof props.page === "string") {
783
+ href = pageLink(props.page);
784
+ }
785
+ const isExternalArrow = !props.component && ((_a = appearance == null ? void 0 : appearance.header) == null ? void 0 : _a.externalArrow) && isExternal(href || "") ? true : false;
786
+ const WebEditorHeader = WebEditorComponent(Nav2.Item, {
787
+ key: props.page || "",
788
+ href,
789
+ value: props.href ? void 0 : props.page,
790
+ as: FwLink
791
+ }, props.title);
792
+ return /* @__PURE__ */ React10.createElement(
793
+ WebEditorHeader,
794
+ {
795
+ ...props,
796
+ key: keyId(props)
797
+ },
798
+ isExternalArrow ? /* @__PURE__ */ React10.createElement(Icon2.ExternalArrow, null) : null
799
+ );
800
+ }
801
+ function keyId(props) {
802
+ return `${(props == null ? void 0 : props.component) || "."}-${(props == null ? void 0 : props.title) || (props == null ? void 0 : props.href) || "."}`;
803
+ }
804
+
805
+ // packages/react/components/FwNav.tsx
806
+ function FwNav() {
807
+ var _a, _b, _c, _d, _e;
808
+ const activeHeaderPage = useActivePage();
809
+ const appearance = useAppearance();
810
+ const Header = FwHeaderItems();
811
+ const logo = ((_a = appearance == null ? void 0 : appearance.logo) == null ? void 0 : _a.header) ? /* @__PURE__ */ React11.createElement(
812
+ WebEditorComponent.NavItemRaw,
813
+ {
814
+ device: (_b = appearance == null ? void 0 : appearance.logo) == null ? void 0 : _b.header
815
+ },
816
+ /* @__PURE__ */ React11.createElement(FwLogo, null)
817
+ ) : null;
818
+ return /* @__PURE__ */ React11.createElement(
819
+ Nav3,
820
+ {
821
+ appearance: {
822
+ separator: ((_c = appearance == null ? void 0 : appearance.header) == null ? void 0 : _c.separator) || void 0
823
+ },
824
+ logo,
825
+ centerSurface: ((_d = Header == null ? void 0 : Header.center) == null ? void 0 : _d.length) ? /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(
826
+ Nav3.Tabs,
827
+ {
828
+ value: activeHeaderPage
829
+ },
830
+ Header.center
831
+ )) : null,
832
+ rightSurface: /* @__PURE__ */ React11.createElement(React11.Fragment, null, ((_e = Header == null ? void 0 : Header.right) == null ? void 0 : _e.length) ? /* @__PURE__ */ React11.createElement(
833
+ Nav3.Tabs,
834
+ {
835
+ value: activeHeaderPage
836
+ },
837
+ Header.right
838
+ ) : null, /* @__PURE__ */ React11.createElement(Surface, { target: "nav.right" /* NavRight */ })),
839
+ floatRightSurface: /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Nav3.ItemRaw, null, /* @__PURE__ */ React11.createElement(ColorSchemeButton, null)), /* @__PURE__ */ React11.createElement(Nav3.ItemRaw, null, /* @__PURE__ */ React11.createElement(LayoutPrimary.Hamburger, null)))
840
+ },
841
+ /* @__PURE__ */ React11.createElement(FwNav.DefaultItems, null)
842
+ );
843
+ }
844
+ FwNav.DefaultItems = function DefaultItems() {
845
+ const activeHeaderPage = useActivePage();
846
+ const defaultItems = useDefaultHeaderItems();
847
+ const items = defaultItems.map(FwHeaderItem);
848
+ return /* @__PURE__ */ React11.createElement(
849
+ Nav3.Tabs,
850
+ {
851
+ value: activeHeaderPage
852
+ },
853
+ items
854
+ );
855
+ };
856
+
857
+ // packages/react/components/FwNavLinks.tsx
858
+ import React12 from "react";
859
+ import { NavLinks } from "@xyd-js/components/writer";
860
+ function FwNavLinks() {
861
+ const navlinks = useNavLinks();
862
+ if ((navlinks == null ? void 0 : navlinks.prev) || (navlinks == null ? void 0 : navlinks.next)) {
863
+ return /* @__PURE__ */ React12.createElement(
864
+ NavLinks,
865
+ {
866
+ prev: navlinks.prev,
867
+ next: navlinks.next,
868
+ as: FwLink
869
+ }
870
+ );
871
+ }
872
+ return null;
873
+ }
874
+
875
+ // packages/react/components/FwSidebar.tsx
876
+ import React20 from "react";
877
+ import { UISidebar as UISidebar5 } from "@xyd-js/ui";
878
+
879
+ // packages/react/lib/FooSidebar.tsx
880
+ import React13, { createContext as createContext3, useContext as useContext3, useState as useState3, useEffect as useEffect2 } from "react";
881
+ import { useNavigation as useNavigation2 } from "react-router";
882
+ var FooSidebarContext = createContext3({
883
+ active: () => [false, () => {
884
+ }]
885
+ });
886
+ function FooSidebar(props) {
887
+ const { children, initialActiveItems } = props;
888
+ const groupBehaviour = useDefaultBehaviour(initialActiveItems);
889
+ return /* @__PURE__ */ React13.createElement(FooSidebarContext, { value: {
890
+ active: groupBehaviour
891
+ } }, children);
892
+ }
893
+ function useFooSidebar() {
894
+ return useContext3(FooSidebarContext);
895
+ }
896
+ function useDefaultBehaviour(initialActiveItems) {
897
+ const navigation = useNavigation2();
898
+ const [activeItems, setActiveItems] = useState3(() => createItemsMap(initialActiveItems));
899
+ const [, setForceUpdate] = useState3(0);
900
+ const forceUpdate = () => setForceUpdate((prev) => prev + 1);
901
+ useEffect2(() => {
902
+ if (navigation.state !== "loading") {
903
+ setActiveItems(createItemsMap(initialActiveItems));
904
+ forceUpdate();
905
+ }
906
+ }, [initialActiveItems, navigation.state]);
907
+ function addItem(item) {
908
+ const key = itemId(item);
909
+ setActiveItems((prev) => {
910
+ const newMap = new Map(prev);
911
+ newMap.set(key, true);
912
+ return newMap;
913
+ });
914
+ forceUpdate();
915
+ }
916
+ function deleteItem(item) {
917
+ const key = itemId(item);
918
+ setActiveItems((prev) => {
919
+ const newMap = new Map(prev);
920
+ newMap.delete(key);
921
+ return newMap;
922
+ });
923
+ forceUpdate();
924
+ }
925
+ function hasItem(item) {
926
+ const key = itemId(item);
927
+ return activeItems.get(key) || false;
928
+ }
929
+ return (item) => {
930
+ return [
931
+ hasItem(item) || false,
932
+ () => {
933
+ if (!hasItem(item)) {
934
+ addItem(item);
935
+ return;
936
+ }
937
+ deleteItem(item);
938
+ }
939
+ ];
940
+ };
941
+ }
942
+ function itemId(item) {
943
+ const id = `${item.uniqIndex}:${item.groupIndex}-${item.level}-${item.itemIndex}`;
944
+ return id;
945
+ }
946
+ function createItemsMap(items) {
947
+ const map = /* @__PURE__ */ new Map();
948
+ items.forEach((item) => {
949
+ const key = itemId(item);
950
+ map.set(key, true);
951
+ });
952
+ return map;
953
+ }
954
+
955
+ // packages/react/components/FwSidebarNavigationItem.tsx
956
+ import React14 from "react";
957
+ import { Icon as Icon3 } from "@xyd-js/components/writer";
958
+ import { UISidebar as UISidebar2 } from "@xyd-js/ui";
959
+ function FwSidebarNavigationItem(item) {
960
+ var _a;
961
+ const appearance = useAppearance();
962
+ return /* @__PURE__ */ React14.createElement(
963
+ UISidebar2.Item,
964
+ {
965
+ href: item.page || item.href,
966
+ icon: React14.isValidElement(item.icon) ? item.icon : /* @__PURE__ */ React14.createElement(Icon3, { name: item.icon || "" }),
967
+ key: keyId2(item)
968
+ },
969
+ /* @__PURE__ */ React14.createElement(
970
+ UISidebar2.ItemBody,
971
+ {
972
+ title: item.title,
973
+ right: ((_a = appearance == null ? void 0 : appearance.sidebar) == null ? void 0 : _a.externalArrow) && /* @__PURE__ */ React14.createElement(Icon3.ExternalArrow, null)
974
+ }
975
+ )
976
+ );
977
+ }
978
+ function keyId2(props) {
979
+ return `${(props == null ? void 0 : props.title) || (props == null ? void 0 : props.href) || "."}-${props.page || ""}`;
980
+ }
981
+
982
+ // packages/react/components/FwSidebarTabsDropdown.tsx
983
+ import React15 from "react";
984
+ import { Icon as Icon4 } from "@xyd-js/components/writer";
985
+ import { SidebarTabsDropdown, UISidebar as UISidebar3 } from "@xyd-js/ui";
986
+ function FwSidebarTabsDropdown() {
987
+ var _a;
988
+ const settings = useSettings();
989
+ const activeSegment = useActiveSegment();
990
+ const matchedSegmentSidebarDropdown = useMatchedSegmentSidebarDropdown();
991
+ const activePage = useActivePage(true);
992
+ const sidebarDropdown = ((_a = settings.navigation) == null ? void 0 : _a.sidebarDropdown) || [];
993
+ return /* @__PURE__ */ React15.createElement(UISidebar3.ItemGroup, null, /* @__PURE__ */ React15.createElement(
994
+ $NavigationItemsSidebarTabs,
995
+ {
996
+ active: activePage || "",
997
+ items: sidebarDropdown || []
998
+ }
999
+ ), /* @__PURE__ */ React15.createElement(
1000
+ $NavigationItemsSidebarTabs,
1001
+ {
1002
+ active: activeSegment || "",
1003
+ items: (matchedSegmentSidebarDropdown == null ? void 0 : matchedSegmentSidebarDropdown.pages) || []
1004
+ }
1005
+ ));
1006
+ }
1007
+ function $NavigationItemsSidebarTabs({ items, active }) {
1008
+ if (!(items == null ? void 0 : items.length)) {
1009
+ return null;
1010
+ }
1011
+ return /* @__PURE__ */ React15.createElement(
1012
+ SidebarTabsDropdown,
1013
+ {
1014
+ options: items.map((item) => ({
1015
+ label: item.title ?? "",
1016
+ description: item.description,
1017
+ value: item.page || item.href || "",
1018
+ icon: item.icon ? /* @__PURE__ */ React15.createElement(Icon4, { name: item.icon, size: 18 }) : null
1019
+ })),
1020
+ value: active || ""
1021
+ }
1022
+ );
1023
+ }
1024
+
1025
+ // packages/react/components/FwSidebarTopAnchors.tsx
1026
+ function FwSidebarTopAnchors() {
1027
+ var _a, _b, _c, _d;
1028
+ const settings = useSettings();
1029
+ const sidebarTopAnchors = (_d = (_c = (_b = (_a = settings == null ? void 0 : settings.navigation) == null ? void 0 : _a.anchors) == null ? void 0 : _b.sidebar) == null ? void 0 : _c.top) == null ? void 0 : _d.map(FwSidebarNavigationItem);
1030
+ return sidebarTopAnchors;
1031
+ }
1032
+
1033
+ // packages/react/components/FwWebEditorSidebarTop.tsx
1034
+ import React16 from "react";
1035
+ function FwWebEditorSidebarTop() {
1036
+ var _a, _b;
1037
+ const settings = useSettings();
1038
+ const webEditorSidebarTop = (_b = (_a = settings == null ? void 0 : settings.webeditor) == null ? void 0 : _a.sidebarTop) == null ? void 0 : _b.map((props, index) => {
1039
+ if (props.component) {
1040
+ return /* @__PURE__ */ React16.createElement(
1041
+ WebEditorComponent.SidebarItemButton,
1042
+ {
1043
+ key: keyId3(props, index),
1044
+ ...props
1045
+ }
1046
+ );
1047
+ }
1048
+ return /* @__PURE__ */ React16.createElement(
1049
+ WebEditorComponent.SidebarItem,
1050
+ {
1051
+ key: keyId3(props, index),
1052
+ ...props
1053
+ }
1054
+ );
1055
+ });
1056
+ return webEditorSidebarTop;
1057
+ }
1058
+ function keyId3(props, index) {
1059
+ return `${(props == null ? void 0 : props.component) || "."}-${(props == null ? void 0 : props.title) || (props == null ? void 0 : props.href) || "."}-${index}`;
1060
+ }
1061
+
1062
+ // packages/react/components/FwSidebarMobileHeaderItems.tsx
1063
+ import React17 from "react";
1064
+ function FwSidebarMobileHeaderItems() {
1065
+ var _a, _b;
1066
+ const headerItems = useHeaderItems();
1067
+ const headerLeftItems = (_a = headerItems == null ? void 0 : headerItems.default) == null ? void 0 : _a.map(FwSidebarNavigationItem);
1068
+ const headerRightItems = (_b = headerItems == null ? void 0 : headerItems.right) == null ? void 0 : _b.map(FwSidebarNavigationItem);
1069
+ const mergedHeaderItems = [...headerLeftItems, ...headerRightItems];
1070
+ if (!(mergedHeaderItems == null ? void 0 : mergedHeaderItems.length)) {
1071
+ return null;
1072
+ }
1073
+ return /* @__PURE__ */ React17.createElement("div", { "data-mobile": true }, mergedHeaderItems);
1074
+ }
1075
+
1076
+ // packages/react/components/FwSidebarTree.tsx
1077
+ import React19 from "react";
1078
+ import { useLocation as useLocation3 } from "react-router";
1079
+
1080
+ // packages/react/components/FwSidebarItem.tsx
1081
+ import React18 from "react";
1082
+ import { Icon as Icon5 } from "@xyd-js/components/writer";
1083
+ import { UISidebar as UISidebar4 } from "@xyd-js/ui";
1084
+ function FwSidebarItem(props) {
1085
+ const icon = props.icon ? /* @__PURE__ */ React18.createElement(Icon5, { name: props.icon || "", size: 16 }) : null;
1086
+ return /* @__PURE__ */ React18.createElement(React18.Fragment, null, props.group && /* @__PURE__ */ React18.createElement(UISidebar4.ItemHeader, { icon }, props.group), props.items.map((item, index) => /* @__PURE__ */ React18.createElement(
1087
+ FwSidebarItem.Item,
1088
+ {
1089
+ uniqIndex: item.uniqIndex,
1090
+ group: item.group,
1091
+ groupIndex: props.groupIndex,
1092
+ level: 0,
1093
+ itemIndex: index,
1094
+ key: index + item.href,
1095
+ title: item.title,
1096
+ sidebarTitle: item.sidebarTitle,
1097
+ url: item.url,
1098
+ pageMeta: item.pageMeta,
1099
+ href: item.href,
1100
+ items: item.items,
1101
+ active: item.active,
1102
+ icon: item.icon
1103
+ }
1104
+ )));
1105
+ }
1106
+ FwSidebarItem.Item = function FwSidebarItem2(props) {
1107
+ var _a, _b, _c, _d, _e, _f;
1108
+ const { active } = useFooSidebar();
1109
+ const [isActive, setActive] = active(props);
1110
+ const title = props.sidebarTitle || props.title || "";
1111
+ const nested = !!((_a = props.items) == null ? void 0 : _a.length);
1112
+ function handleClick() {
1113
+ if (!nested) {
1114
+ return;
1115
+ }
1116
+ setActive();
1117
+ }
1118
+ const hasActiveChild = (_b = props.items) == null ? void 0 : _b.some((item) => {
1119
+ var _a2;
1120
+ const [itemActive] = active(item);
1121
+ return itemActive && item.href || ((_a2 = item.items) == null ? void 0 : _a2.some((subItem) => {
1122
+ const [subItemActive] = active(subItem);
1123
+ return subItemActive && subItem.href;
1124
+ }));
1125
+ });
1126
+ const isActiveItem = !!(isActive && props.href);
1127
+ const isParentActive = hasActiveChild;
1128
+ const icon = /* @__PURE__ */ React18.createElement(Icon5, { name: props.icon || "", size: 16 });
1129
+ return /* @__PURE__ */ React18.createElement(
1130
+ UISidebar4.Item,
1131
+ {
1132
+ button: nested,
1133
+ href: props.url || props.href,
1134
+ active: isActiveItem,
1135
+ isParentActive,
1136
+ onClick: handleClick,
1137
+ icon,
1138
+ group: props.group
1139
+ },
1140
+ /* @__PURE__ */ React18.createElement("div", { part: "item-title-container" }, /* @__PURE__ */ React18.createElement(
1141
+ Surface,
1142
+ {
1143
+ target: "sidebar.item.left",
1144
+ props: {
1145
+ active: isActiveItem,
1146
+ pageMeta: props.pageMeta
1147
+ }
1148
+ }
1149
+ ), /* @__PURE__ */ React18.createElement("div", { part: "item-title" }, title), props.url && /* @__PURE__ */ React18.createElement(Icon5.ExternalArrow, null), /* @__PURE__ */ React18.createElement(
1150
+ Surface,
1151
+ {
1152
+ target: "sidebar.item.right",
1153
+ props: {
1154
+ active: isActiveItem,
1155
+ pageMeta: props.pageMeta
1156
+ }
1157
+ }
1158
+ )),
1159
+ props.group === false && ((_c = props.items) == null ? void 0 : _c.length) && /* @__PURE__ */ React18.createElement(React18.Fragment, null, (_d = props.items) == null ? void 0 : _d.map((item, index) => /* @__PURE__ */ React18.createElement(
1160
+ FwSidebarItem2,
1161
+ {
1162
+ uniqIndex: item.uniqIndex,
1163
+ group: item.group,
1164
+ groupIndex: props.groupIndex,
1165
+ level: (props.level || 0) + 1,
1166
+ itemIndex: index,
1167
+ key: index + item.href,
1168
+ title: item.title,
1169
+ href: item.href,
1170
+ items: item.items,
1171
+ active: active(item)[0],
1172
+ icon: item.icon,
1173
+ pageMeta: item.pageMeta
1174
+ }
1175
+ ))),
1176
+ props.group !== false && ((_e = props.items) == null ? void 0 : _e.length) && /* @__PURE__ */ React18.createElement(UISidebar4.SubTree, { isOpen: isActive }, /* @__PURE__ */ React18.createElement(React18.Fragment, null, (_f = props.items) == null ? void 0 : _f.map((item, index) => /* @__PURE__ */ React18.createElement(
1177
+ FwSidebarItem2,
1178
+ {
1179
+ uniqIndex: item.uniqIndex,
1180
+ group: item.group,
1181
+ groupIndex: props.groupIndex,
1182
+ level: (props.level || 0) + 1,
1183
+ itemIndex: index,
1184
+ key: index + item.href,
1185
+ title: item.title,
1186
+ href: item.href,
1187
+ items: item.items,
1188
+ active: active(item)[0],
1189
+ icon: item.icon,
1190
+ pageMeta: item.pageMeta
1191
+ }
1192
+ ))))
1193
+ );
1194
+ };
1195
+
1196
+ // packages/react/components/FwSidebarTree.tsx
1197
+ function useSidebarTree() {
1198
+ const location = useLocation3();
1199
+ const groups = useSidebarGroups();
1200
+ const pathname = trailingSlash(location.pathname);
1201
+ const initialActiveItems = [];
1202
+ groups.forEach((group, groupIndex) => {
1203
+ const activeLevels = recursiveSearch(group.items, pathname) || [];
1204
+ activeLevels.reduce((acc, index, level) => {
1205
+ initialActiveItems.push({
1206
+ ...acc[index],
1207
+ groupIndex,
1208
+ level,
1209
+ itemIndex: index
1210
+ });
1211
+ acc[index].active = true;
1212
+ return acc[index].items;
1213
+ }, group.items);
1214
+ return group;
1215
+ });
1216
+ const sidebarTree = (groups == null ? void 0 : groups.map((group, index) => /* @__PURE__ */ React19.createElement(
1217
+ FwSidebarItem,
1218
+ {
1219
+ key: index + group.group,
1220
+ ...group,
1221
+ groupIndex: index
1222
+ }
1223
+ ))) || [];
1224
+ return [sidebarTree, { initialActiveItems }];
1225
+ }
1226
+ function recursiveSearch(items, href, levels = []) {
1227
+ for (let i = 0; i < items.length; i++) {
1228
+ const item = items[i];
1229
+ if (item.href === href) {
1230
+ return [...levels, i];
1231
+ }
1232
+ if (item.items) {
1233
+ const result = recursiveSearch(item.items, href, [...levels, i]);
1234
+ if (result) {
1235
+ return result;
1236
+ }
1237
+ }
1238
+ }
1239
+ return null;
1240
+ }
1241
+
1242
+ // packages/react/components/FwSidebar.tsx
1243
+ var Sidebar = withSidebar(UISidebar5);
1244
+ function FwSidebar(props) {
1245
+ var _a, _b, _c, _d, _e, _f;
1246
+ const settings = useSettings();
1247
+ const appearance = useAppearance();
1248
+ const sidebarFooterAnchors = (_d = (_c = (_b = (_a = settings.navigation) == null ? void 0 : _a.anchors) == null ? void 0 : _b.sidebar) == null ? void 0 : _c.bottom) == null ? void 0 : _d.map(FwSidebarNavigationItem);
1249
+ return /* @__PURE__ */ React20.createElement(
1250
+ Sidebar,
1251
+ {
1252
+ footerItems: sidebarFooterAnchors && sidebarFooterAnchors,
1253
+ scrollShadow: (_e = appearance == null ? void 0 : appearance.sidebar) == null ? void 0 : _e.scrollShadow,
1254
+ scrollTransition: (_f = appearance == null ? void 0 : appearance.sidebar) == null ? void 0 : _f.scrollTransition
1255
+ },
1256
+ /* @__PURE__ */ React20.createElement(Surface, { target: "sidebar.top" /* SidebarTop */ }),
1257
+ /* @__PURE__ */ React20.createElement(FwSidebarTopAnchors, null),
1258
+ /* @__PURE__ */ React20.createElement(FwWebEditorSidebarTop, null),
1259
+ /* @__PURE__ */ React20.createElement(FwSidebarMobileHeaderItems, null),
1260
+ /* @__PURE__ */ React20.createElement(FwSidebarTabsDropdown, null)
1261
+ );
1262
+ }
1263
+ function withSidebar(Component) {
1264
+ return function WithSidebarContent(props) {
1265
+ const [sidebarTree, sidebarTreeFlags] = useSidebarTree();
1266
+ const { children, ...rest } = props;
1267
+ return /* @__PURE__ */ React20.createElement(
1268
+ FooSidebar,
1269
+ {
1270
+ initialActiveItems: sidebarTreeFlags.initialActiveItems
1271
+ },
1272
+ /* @__PURE__ */ React20.createElement(Component, { ...rest }, children, sidebarTree)
1273
+ );
1274
+ };
1275
+ }
1276
+
1277
+ // packages/react/components/FwSubNav.tsx
1278
+ import React21 from "react";
1279
+ import { SubNav } from "@xyd-js/ui";
1280
+ function FwSubNav() {
1281
+ var _a;
1282
+ const matchedSubnav = useMatchedSubNav();
1283
+ const active = useActiveMatchedSubNav();
1284
+ if (!matchedSubnav) {
1285
+ return null;
1286
+ }
1287
+ return /* @__PURE__ */ React21.createElement(
1288
+ SubNav,
1289
+ {
1290
+ title: (matchedSubnav == null ? void 0 : matchedSubnav.title) || "",
1291
+ value: (active == null ? void 0 : active.page) || "",
1292
+ onChange: () => {
1293
+ }
1294
+ },
1295
+ (_a = matchedSubnav == null ? void 0 : matchedSubnav.pages) == null ? void 0 : _a.map((item, index) => {
1296
+ let href = null;
1297
+ if (typeof item.href === "string") {
1298
+ href = pageLink(item.href);
1299
+ }
1300
+ if (!href && typeof item.page === "string") {
1301
+ href = pageLink(item.page);
1302
+ }
1303
+ return /* @__PURE__ */ React21.createElement(
1304
+ SubNav.Item,
1305
+ {
1306
+ value: typeof item.page !== "string" && href ? href : item.page || "",
1307
+ href: href || item.page || "",
1308
+ as: FwLink
1309
+ },
1310
+ item.title
1311
+ );
1312
+ })
1313
+ );
1314
+ }
1315
+
1316
+ // packages/react/components/FwToc.tsx
1317
+ import React22 from "react";
1318
+ import { Toc } from "@xyd-js/ui";
1319
+ function FwToc() {
1320
+ var _a, _b;
1321
+ const metadata = useMetadata();
1322
+ const settings = useSettings();
1323
+ const toc = useToC();
1324
+ if (!toc) {
1325
+ return null;
1326
+ }
1327
+ const maxDepth = (metadata == null ? void 0 : metadata.maxTocDepth) || ((_b = (_a = settings == null ? void 0 : settings.theme) == null ? void 0 : _a.writer) == null ? void 0 : _b.maxTocDepth) || 2;
1328
+ const renderTocItems = (items, uiDepth = 0) => {
1329
+ return items.map((item) => /* @__PURE__ */ React22.createElement(React22.Fragment, { key: item.id }, /* @__PURE__ */ React22.createElement(
1330
+ Toc.Item,
1331
+ {
1332
+ id: item.id,
1333
+ depth: uiDepth
1334
+ },
1335
+ item.value
1336
+ ), item.children && item.children.length > 0 && renderTocItems(item.children, uiDepth + 1)));
1337
+ };
1338
+ return /* @__PURE__ */ React22.createElement(Toc, { maxDepth }, renderTocItems(toc));
1339
+ }
1340
+ export {
1341
+ Framework,
1342
+ FrameworkPage,
1343
+ FwBanner,
1344
+ FwBreadcrumbs,
1345
+ FwCopyPage,
1346
+ FwJsonComponent,
1347
+ FwLink,
1348
+ FwLogo,
1349
+ FwNav,
1350
+ FwNavLinks,
1351
+ FwSidebar,
1352
+ FwSubNav,
1353
+ FwToc,
1354
+ Surface,
1355
+ SurfaceContext,
1356
+ useActivePage,
1357
+ useActivePageRoute,
1358
+ useActiveRoute,
1359
+ useAppearance,
1360
+ useComponents,
1361
+ useContentComponent,
1362
+ useContentOriginal,
1363
+ useMatchedSubNav,
1364
+ useMetadata,
1365
+ useSettings
1366
+ };
1367
+ //# sourceMappingURL=react.js.map