@xyd-js/framework 0.1.0-xyd.32 → 0.1.0-xyd.34

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 CHANGED
@@ -1,298 +1,280 @@
1
1
  // packages/react/components/index.tsx
2
- import React5, { isValidElement } from "react";
3
- import { useLocation as useLocation3 } from "react-router";
4
- import { Breadcrumbs, NavLinks } from "@xyd-js/components/writer";
5
- import { Toc, SubNav, UISidebar as UISidebar2, Nav } from "@xyd-js/ui";
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
6
 
7
- // packages/react/contexts/framework.tsx
7
+ // packages/react/components/Surfaces.tsx
8
8
  import React, { createContext, useContext } from "react";
9
+ var SurfaceTarget = /* @__PURE__ */ ((SurfaceTarget2) => {
10
+ SurfaceTarget2["NavRight"] = "nav.right";
11
+ SurfaceTarget2["SidebarTop"] = "sidebar.top";
12
+ SurfaceTarget2["PageFooterBottom"] = "page.footer.bottom";
13
+ SurfaceTarget2["SidebarItemLeft"] = "sidebar.item.left";
14
+ SurfaceTarget2["SidebarItemRight"] = "sidebar.item.right";
15
+ return SurfaceTarget2;
16
+ })(SurfaceTarget || {});
17
+ var SurfaceContext = createContext({
18
+ surfaces: void 0
19
+ });
20
+ var Surfaces = class {
21
+ constructor() {
22
+ this.registry = {};
23
+ }
24
+ define(target, component, opts) {
25
+ if (opts == null ? void 0 : opts.append) {
26
+ if (Array.isArray(this.registry[target])) {
27
+ this.registry[target].push(component);
28
+ return;
29
+ }
30
+ if (this.registry[target]) {
31
+ this.registry[target] = [this.registry[target], component];
32
+ return;
33
+ }
34
+ this.registry[target] = [component];
35
+ return;
36
+ }
37
+ this.registry[target] = component;
38
+ }
39
+ get(target) {
40
+ return this.registry[target];
41
+ }
42
+ };
43
+ function Surface(props) {
44
+ const { target } = props;
45
+ const registry = useContext(SurfaceContext);
46
+ if (!registry.surfaces) {
47
+ return null;
48
+ }
49
+ const components = registry.surfaces.get(target);
50
+ if (!components) {
51
+ return null;
52
+ }
53
+ if (!Array.isArray(components)) {
54
+ if (typeof components === "function") {
55
+ const Component = components;
56
+ return /* @__PURE__ */ React.createElement(Component, { ...props.props });
57
+ }
58
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, components);
59
+ }
60
+ if (!components.length) {
61
+ return null;
62
+ }
63
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, components.map((Component, index) => {
64
+ if (typeof Component === "function") {
65
+ const Comp = Component;
66
+ return /* @__PURE__ */ React.createElement(Comp, { key: index, ...props.props });
67
+ }
68
+ return /* @__PURE__ */ React.createElement(React.Fragment, { key: index }, Component);
69
+ }));
70
+ }
71
+
72
+ // packages/react/contexts/framework.tsx
73
+ import React2, { createContext as createContext2, useContext as useContext2, useEffect, useState } from "react";
74
+ import { useNavigation } from "react-router";
75
+ import { ProgressBar } from "@xyd-js/ui";
76
+ import { Banner } from "@xyd-js/components/writer";
9
77
  var framework = {
10
78
  settings: {},
11
- sidebarGroups: []
79
+ metadata: {
80
+ title: ""
81
+ },
82
+ sidebarGroups: [],
83
+ setMetadata: () => {
84
+ }
12
85
  };
13
- var FrameworkContext = createContext(framework);
86
+ var FrameworkContext = createContext2(framework);
14
87
  function Framework(props) {
15
- return /* @__PURE__ */ React.createElement(FrameworkContext.Provider, { value: {
16
- settings: props.settings,
17
- sidebarGroups: props.sidebarGroups,
18
- toc: props.toc,
19
- breadcrumbs: props.breadcrumbs,
20
- navlinks: props.navlinks
88
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
89
+ const navigation = useNavigation();
90
+ const [metadata, setMetadata] = useState(props.metadata);
91
+ const BannerContent = props.BannerContent || null;
92
+ 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;
93
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(FrameworkContext, { value: {
94
+ settings: Object.freeze({ ...props.settings }),
95
+ sidebarGroups: Object.freeze([...props.sidebarGroups]),
96
+ metadata: Object.freeze({ ...metadata, title: (metadata == null ? void 0 : metadata.title) || "" }),
97
+ setMetadata
98
+ } }, /* @__PURE__ */ React2.createElement(SurfaceContext, { value: {
99
+ surfaces: props.surfaces
100
+ } }, /* @__PURE__ */ React2.createElement(ProgressBar, { isActive: navigation.state === "loading" }), BannerContent ? /* @__PURE__ */ React2.createElement(
101
+ BannerComponent,
102
+ {
103
+ label: (_f = (_e = (_d = props.settings) == null ? void 0 : _d.theme) == null ? void 0 : _e.banner) == null ? void 0 : _f.label,
104
+ icon: (_i = (_h = (_g = props.settings) == null ? void 0 : _g.theme) == null ? void 0 : _h.banner) == null ? void 0 : _i.icon
105
+ },
106
+ /* @__PURE__ */ React2.createElement(BannerContent, null)
107
+ ) : null, props.children)));
108
+ }
109
+ var FrameworkPageContext = createContext2({
110
+ ContentComponent: () => /* @__PURE__ */ React2.createElement(React2.Fragment, null),
111
+ metadata: {
112
+ title: ""
113
+ }
114
+ });
115
+ function FrameworkPage(props) {
116
+ const { setMetadata } = useContext2(FrameworkContext);
117
+ useEffect(() => {
118
+ setMetadata(props.metadata);
119
+ }, []);
120
+ return /* @__PURE__ */ React2.createElement(FrameworkPageContext, { value: {
121
+ ContentComponent: props.ContentComponent || (() => /* @__PURE__ */ React2.createElement(React2.Fragment, null)),
122
+ metadata: Object.freeze(props.metadata),
123
+ breadcrumbs: Object.freeze(props.breadcrumbs),
124
+ rawPage: Object.freeze(props.rawPage),
125
+ toc: Object.freeze(props.toc || []),
126
+ navlinks: Object.freeze(props.navlinks)
21
127
  } }, props.children);
22
128
  }
23
129
  function useSidebarGroups() {
24
- const ctx = useContext(FrameworkContext);
130
+ const ctx = useContext2(FrameworkContext);
25
131
  return ctx.sidebarGroups;
26
132
  }
27
133
  function useSettings() {
28
- const ctx = useContext(FrameworkContext);
134
+ const ctx = useContext2(FrameworkContext);
29
135
  return ctx.settings;
30
136
  }
137
+ function useMetadata() {
138
+ const ctx = useContext2(FrameworkContext);
139
+ return ctx.metadata;
140
+ }
31
141
  function useToC() {
32
- const ctx = useContext(FrameworkContext);
33
- return ctx.toc;
142
+ const ctx = useContext2(FrameworkPageContext);
143
+ const toc = ctx.toc || [];
144
+ return toc;
34
145
  }
35
146
  function useBreadcrumbs() {
36
- const ctx = useContext(FrameworkContext);
147
+ const ctx = useContext2(FrameworkPageContext);
37
148
  return ctx.breadcrumbs;
38
149
  }
39
150
  function useNavLinks() {
40
- const ctx = useContext(FrameworkContext);
151
+ const ctx = useContext2(FrameworkPageContext);
41
152
  return ctx.navlinks;
42
153
  }
154
+ function useRawPage() {
155
+ const ctx = useContext2(FrameworkPageContext);
156
+ return ctx.rawPage;
157
+ }
158
+ function useContentComponent() {
159
+ const ctx = useContext2(FrameworkPageContext);
160
+ return ctx.ContentComponent;
161
+ }
43
162
 
44
163
  // packages/react/components/Sidebar/Sidebar.tsx
45
- import React3 from "react";
46
- import { Badge } from "@xyd-js/components/writer";
164
+ import React4 from "react";
47
165
  import { UISidebar } from "@xyd-js/ui";
166
+ import { Icon } from "@xyd-js/components/writer";
48
167
 
49
168
  // packages/react/components/Sidebar/SidebarGroup.tsx
50
- import React2, { createContext as createContext3, useContext as useContext2, useEffect, useState } from "react";
51
- import { useLocation } from "react-router";
52
-
53
- // packages/react/contexts/ui.tsx
54
- import { createContext as createContext2 } from "react";
55
- var UIContext = createContext2({
56
- href: "",
57
- setHref: (v) => {
58
- }
59
- });
60
-
61
- // packages/react/components/Sidebar/SidebarGroup.tsx
62
- var groupContext = createContext3({
169
+ import React3, { createContext as createContext3, useContext as useContext3, useState as useState2, useEffect as useEffect2 } from "react";
170
+ import { useNavigation as useNavigation2 } from "react-router";
171
+ var GroupContext = createContext3({
63
172
  active: () => [false, () => {
64
- }],
65
- onClick: () => null
66
- // TODO: should be deprecated?
173
+ }]
67
174
  });
68
- function FwSidebarGroupContext({
69
- children,
70
- onePathBehaviour,
71
- clientSideRouting,
72
- initialActiveItems
73
- }) {
74
- let groupBehaviour;
75
- if (onePathBehaviour) {
76
- groupBehaviour = useOnePathBehaviour(initialActiveItems);
77
- } else {
78
- groupBehaviour = useDefaultBehaviour(initialActiveItems);
79
- }
80
- const location = useLocation();
81
- const [href, setHref] = useState(location.pathname);
82
- return /* @__PURE__ */ React2.createElement(UIContext.Provider, { value: {
83
- href,
84
- setHref: (value) => {
85
- setHref(value);
86
- }
87
- } }, /* @__PURE__ */ React2.createElement(groupContext.Provider, { value: {
88
- active: groupBehaviour,
89
- onClick: clientSideRouting ? (event, item) => {
90
- setHref(item.href);
91
- scrollToDataSlug(event, item);
92
- } : void 0
93
- } }, children));
175
+ function FwSidebarGroupContext(props) {
176
+ const { children, initialActiveItems } = props;
177
+ const groupBehaviour = useDefaultBehaviour(initialActiveItems);
178
+ return /* @__PURE__ */ React3.createElement(GroupContext, { value: {
179
+ active: groupBehaviour
180
+ } }, children);
94
181
  }
95
182
  function useGroup() {
96
- return useContext2(groupContext);
97
- }
98
- function getLastValue(set) {
99
- let value;
100
- for (value of set) ;
101
- return value;
102
- }
103
- function stringify(item) {
104
- var _a;
105
- return JSON.stringify({
106
- title: item.title,
107
- href: item.href,
108
- items: (_a = item.items) == null ? void 0 : _a.map((item2) => stringify(item2))
109
- });
110
- }
111
- function recursiveSearch(items, href, levels = []) {
112
- for (let i = 0; i < items.length; i++) {
113
- const item = items[i];
114
- if (item.href === href) {
115
- return [...levels, i];
116
- }
117
- if (item.items) {
118
- const result = recursiveSearch(item.items, href, [...levels, i]);
119
- if (result) {
120
- return result;
121
- }
122
- }
123
- }
124
- return null;
125
- }
126
- function calcActive(groups, url) {
127
- const initialActiveItems = [];
128
- groups.forEach((group) => {
129
- const activeLevels = recursiveSearch(group.items, url) || [];
130
- activeLevels.reduce((acc, index) => {
131
- initialActiveItems.push({
132
- ...acc[index],
133
- active: true
134
- });
135
- return acc[index].items;
136
- }, group.items);
137
- return group;
138
- });
139
- return initialActiveItems;
183
+ return useContext3(GroupContext);
140
184
  }
141
185
  function useDefaultBehaviour(initialActiveItems) {
142
- const groups = useSidebarGroups();
143
- const [weakSet] = useState(() => new Set(initialActiveItems.map((item) => stringify(item))));
144
- const [, setForceUpdate] = useState(0);
145
- useEffect(() => {
146
- window.addEventListener("xyd.history.pushState", (event) => {
147
- var _a;
148
- const url = (_a = event.detail) == null ? void 0 : _a.url;
149
- if (!url) {
150
- return;
151
- }
152
- const active = calcActive(groups, url);
153
- weakSet.clear();
154
- active.forEach((item) => {
155
- addItem(item);
156
- });
157
- });
158
- }, []);
186
+ const navigation = useNavigation2();
187
+ const [activeItems, setActiveItems] = useState2(() => createItemsMap(initialActiveItems));
188
+ const [, setForceUpdate] = useState2(0);
159
189
  const forceUpdate = () => setForceUpdate((prev) => prev + 1);
160
- const addItem = (item) => {
161
- weakSet.add(stringify(item));
162
- forceUpdate();
163
- };
164
- const deleteItem = (item) => {
165
- weakSet.delete(stringify(item));
166
- forceUpdate();
167
- };
168
- const hasItem = (item) => {
169
- return weakSet.has(stringify(item));
170
- };
171
- return (item) => [
172
- hasItem(item) || false,
173
- () => {
174
- if (hasItem(item)) {
175
- deleteItem(item);
176
- } else {
177
- addItem(item);
178
- }
190
+ useEffect2(() => {
191
+ if (navigation.state !== "loading") {
192
+ setActiveItems(createItemsMap(initialActiveItems));
193
+ forceUpdate();
179
194
  }
180
- ];
181
- }
182
- function useOnePathBehaviour(initialActiveItems) {
183
- const [weakSet] = useState(() => new Set(initialActiveItems.map((item) => stringify(item))));
184
- const [lastLevel, setLastLevel] = useState(false);
185
- const [, setForceUpdate] = useState(0);
186
- const forceUpdate = () => setForceUpdate((prev) => prev + 1);
187
- const addItem = (item) => {
188
- weakSet.add(stringify(item));
189
- forceUpdate();
190
- };
191
- const deleteItem = (item) => {
192
- weakSet.delete(stringify(item));
195
+ }, [initialActiveItems, navigation.state]);
196
+ function addItem(item) {
197
+ const key = itemId(item);
198
+ setActiveItems((prev) => {
199
+ const newMap = new Map(prev);
200
+ newMap.set(key, true);
201
+ return newMap;
202
+ });
193
203
  forceUpdate();
194
- };
195
- const hasItem = (item) => {
196
- return weakSet.has(stringify(item));
197
- };
198
- const clear = () => {
199
- weakSet.clear();
204
+ }
205
+ function deleteItem(item) {
206
+ const key = itemId(item);
207
+ setActiveItems((prev) => {
208
+ const newMap = new Map(prev);
209
+ newMap.delete(key);
210
+ return newMap;
211
+ });
200
212
  forceUpdate();
201
- };
202
- return (item) => [
203
- hasItem(item),
204
- () => {
205
- setLastLevel(item.level);
206
- if (hasItem(item) && item.level == 0) {
207
- setLastLevel(false);
208
- clear();
209
- return;
210
- }
211
- if (hasItem(item)) {
212
- setLastLevel(false);
213
+ }
214
+ function hasItem(item) {
215
+ const key = itemId(item);
216
+ return activeItems.get(key) || false;
217
+ }
218
+ return (item) => {
219
+ return [
220
+ hasItem(item) || false,
221
+ () => {
222
+ if (!hasItem(item)) {
223
+ addItem(item);
224
+ return;
225
+ }
213
226
  deleteItem(item);
214
- return;
215
- }
216
- if ((item.level || 0) > (lastLevel || 0) || lastLevel == false) {
217
- addItem(item);
218
- } else {
219
- const v = getLastValue(weakSet);
220
- deleteItem(JSON.parse(v));
221
- addItem(item);
222
227
  }
223
- }
224
- ];
228
+ ];
229
+ };
225
230
  }
226
- function scrollToDataSlug(event, item) {
227
- event.preventDefault();
228
- const dataSlug = document.querySelector(`[data-slug="${item.href}"]`);
229
- if (dataSlug) {
230
- dataSlug.scrollIntoView({ block: "start", inline: "nearest" });
231
- }
231
+ function itemId(item) {
232
+ const id = `${item.uniqIndex}:${item.groupIndex}-${item.level}-${item.itemIndex}`;
233
+ return id;
234
+ }
235
+ function createItemsMap(items) {
236
+ const map = /* @__PURE__ */ new Map();
237
+ items.forEach((item) => {
238
+ const key = itemId(item);
239
+ map.set(key, true);
240
+ });
241
+ return map;
232
242
  }
233
243
 
234
244
  // packages/react/components/Sidebar/Sidebar.tsx
235
245
  function FwSidebarItemGroup(props) {
236
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(UISidebar.ItemHeader, null, props.group), props.items.map((item, index) => /* @__PURE__ */ React3.createElement(
246
+ const icon = props.icon ? /* @__PURE__ */ React4.createElement(Icon, { name: props.icon || "", size: 16 }) : null;
247
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(UISidebar.ItemHeader, { icon }, props.group), props.items.map((item, index) => /* @__PURE__ */ React4.createElement(
237
248
  FwSidebarItem,
238
249
  {
250
+ uniqIndex: item.uniqIndex,
251
+ groupIndex: props.groupIndex,
252
+ level: 0,
253
+ itemIndex: index,
239
254
  key: index + item.href,
240
255
  title: item.title,
256
+ sidebarTitle: item.sidebarTitle,
257
+ pageMeta: item.pageMeta,
241
258
  href: item.href,
242
259
  items: item.items,
243
260
  active: item.active,
244
- level: 0
261
+ icon: item.icon
245
262
  }
246
263
  )));
247
264
  }
248
- var components = {
249
- Frontmatter: {
250
- // TODO: css
251
- Title: ({ children }) => /* @__PURE__ */ React3.createElement("div", { style: {
252
- display: "flex",
253
- alignItems: "center",
254
- width: "100%",
255
- gap: "10px"
256
- } }, children)
257
- },
258
- Badge: ({ children, ...rest }) => /* @__PURE__ */ React3.createElement(Badge, { ...rest }, children)
259
- };
260
- function mdxExport(code, components2) {
261
- const scope = {
262
- Fragment: React3.Fragment,
263
- jsxs: React3.createElement,
264
- jsx: React3.createElement,
265
- jsxDEV: React3.createElement,
266
- _jsxs: React3.createElement,
267
- _jsx: React3.createElement,
268
- ...components2
269
- };
270
- const fn = new Function(...Object.keys(scope), `return ${code}`);
271
- return fn(...Object.values(scope));
272
- }
273
265
  function FwSidebarItem(props) {
274
266
  var _a, _b, _c, _d;
275
- const { active, onClick } = useGroup();
267
+ const { active } = useGroup();
276
268
  const [isActive, setActive] = active(props);
277
- let Title;
278
- if (typeof props.title === "object" && "code" in props.title) {
279
- const code = props.title.code;
280
- Title = () => mdxExport(
281
- code.replace("() => ", ""),
282
- components
283
- );
284
- } else {
285
- Title = () => props.title;
286
- }
287
- const handleClick = () => {
288
- var _a2;
289
- if (props.href) {
290
- setActive();
291
- } else if ((_a2 = props.items) == null ? void 0 : _a2.length) {
292
- setActive();
269
+ const title = props.sidebarTitle || props.title || "";
270
+ const nested = !!((_a = props.items) == null ? void 0 : _a.length);
271
+ function handleClick() {
272
+ if (!nested) {
273
+ return;
293
274
  }
294
- };
295
- const hasActiveChild = (_a = props.items) == null ? void 0 : _a.some((item) => {
275
+ setActive();
276
+ }
277
+ const hasActiveChild = (_b = props.items) == null ? void 0 : _b.some((item) => {
296
278
  var _a2;
297
279
  const [itemActive] = active(item);
298
280
  return itemActive && item.href || ((_a2 = item.items) == null ? void 0 : _a2.some((subItem) => {
@@ -302,187 +284,190 @@ function FwSidebarItem(props) {
302
284
  });
303
285
  const isActiveItem = !!(isActive && props.href);
304
286
  const isParentActive = hasActiveChild;
305
- return /* @__PURE__ */ React3.createElement(
287
+ const icon = /* @__PURE__ */ React4.createElement(Icon, { name: props.icon || "", size: 16 });
288
+ return /* @__PURE__ */ React4.createElement(
306
289
  UISidebar.Item,
307
290
  {
308
- button: !!((_b = props.items) == null ? void 0 : _b.length),
291
+ button: nested,
309
292
  href: props.href,
310
293
  active: isActiveItem,
311
294
  isParentActive,
312
- onClick: handleClick
295
+ onClick: handleClick,
296
+ icon
313
297
  },
314
- /* @__PURE__ */ React3.createElement(Title, null),
315
- ((_c = props.items) == null ? void 0 : _c.length) && /* @__PURE__ */ React3.createElement(UISidebar.SubTree, { isOpen: isActive }, /* @__PURE__ */ React3.createElement(React3.Fragment, null, (_d = props.items) == null ? void 0 : _d.map((item, index) => /* @__PURE__ */ React3.createElement(
298
+ /* @__PURE__ */ React4.createElement("div", { part: "item-title-container" }, /* @__PURE__ */ React4.createElement(
299
+ Surface,
300
+ {
301
+ target: "sidebar.item.left",
302
+ props: {
303
+ active: isActiveItem,
304
+ pageMeta: props.pageMeta
305
+ }
306
+ }
307
+ ), /* @__PURE__ */ React4.createElement("div", { part: "item-title" }, title), /* @__PURE__ */ React4.createElement(
308
+ Surface,
309
+ {
310
+ target: "sidebar.item.right",
311
+ props: {
312
+ active: isActiveItem,
313
+ pageMeta: props.pageMeta
314
+ }
315
+ }
316
+ )),
317
+ ((_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(
316
318
  FwSidebarItem,
317
319
  {
320
+ uniqIndex: item.uniqIndex,
321
+ groupIndex: props.groupIndex,
322
+ level: (props.level || 0) + 1,
323
+ itemIndex: index,
318
324
  key: index + item.href,
319
325
  title: item.title,
320
326
  href: item.href,
321
327
  items: item.items,
322
328
  active: active(item)[0],
323
- level: (props.level || 0) + 1
329
+ icon: item.icon,
330
+ pageMeta: item.pageMeta
324
331
  }
325
332
  ))))
326
333
  );
327
334
  }
328
335
 
329
- // packages/react/utils/manualHydration.ts
330
- import React4 from "react";
331
- function manualHydration(obj, key = 0) {
332
- if (typeof obj !== "object" || obj === null) {
333
- return React4.createElement(React4.Fragment, { key });
334
- }
335
- const { type, props } = obj || {};
336
- if (typeof type !== "string" && typeof type !== "function") {
337
- return React4.createElement(React4.Fragment, { key });
338
- }
339
- let children = [];
340
- if (props == null ? void 0 : props.children) {
341
- if (Array.isArray(props.children)) {
342
- children = props.children.map((child, i) => manualHydration(child, key + i)) || [];
343
- } else {
344
- children = [manualHydration(props.children, key)];
345
- }
346
- }
347
- const elementProps = { ...props, children, key };
348
- return React4.createElement(type, elementProps);
349
- }
350
-
351
336
  // packages/react/hooks/useMatchedNav.tsx
352
- import { useLocation as useLocation2 } from "react-router";
353
- function normalizeHref(href) {
354
- if (href.startsWith("/")) {
355
- return href;
356
- }
357
- return `/${href}`;
358
- }
337
+ import { useMatches } from "react-router";
359
338
  function useMatchedSubNav() {
360
339
  var _a, _b, _c;
361
340
  const settings = useSettings();
362
- const location = useLocation2();
363
- const matchedSubnav = (_c = (_b = (_a = settings.structure) == null ? void 0 : _a.header) == null ? void 0 : _b.filter((item) => item.sub)) == null ? void 0 : _c.find((item) => {
341
+ const matches = useMatches();
342
+ const lastMatchId = (_a = matches[matches.length - 1]) == null ? void 0 : _a.id;
343
+ let matchedSubnav = (_c = (_b = settings.navigation) == null ? void 0 : _b.segments) == null ? void 0 : _c.find((item) => {
364
344
  var _a2;
365
- return normalizeHref(location.pathname).startsWith(normalizeHref(((_a2 = item.sub) == null ? void 0 : _a2.match) || ""));
345
+ return (_a2 = item.pages) == null ? void 0 : _a2.find((page) => {
346
+ return sanitizeUrl(page.page || "") === sanitizeUrl(lastMatchId);
347
+ });
366
348
  });
367
349
  if (!matchedSubnav) {
368
350
  return null;
369
351
  }
370
- return matchedSubnav.sub || null;
352
+ return matchedSubnav || null;
353
+ }
354
+ function sanitizeUrl(url) {
355
+ if (url.startsWith("/")) {
356
+ return url;
357
+ }
358
+ return `/${url}`;
371
359
  }
372
360
 
373
361
  // packages/react/components/index.tsx
374
362
  function FwNavLogo() {
375
- var _a, _b, _c;
363
+ var _a;
376
364
  const settings = useSettings();
377
- const logo = isValidElement((_a = settings == null ? void 0 : settings.styling) == null ? void 0 : _a.logo) ? (_b = settings == null ? void 0 : settings.styling) == null ? void 0 : _b.logo : manualHydration((_c = settings == null ? void 0 : settings.styling) == null ? void 0 : _c.logo);
378
- return /* @__PURE__ */ React5.createElement("a", { href: "/" }, logo);
365
+ const logo = typeof ((_a = settings == null ? void 0 : settings.theme) == null ? void 0 : _a.logo);
366
+ if (!logo) {
367
+ return null;
368
+ }
369
+ return /* @__PURE__ */ React5.createElement("a", { href: "/" }, /* @__PURE__ */ React5.createElement(FwLogo, null));
379
370
  }
380
371
  function FwNav({ kind }) {
381
- var _a, _b, _c;
372
+ var _a, _b;
373
+ const matches = useMatches2();
382
374
  const matchedSubnav = useMatchedSubNav();
383
- const location = useLocation3();
384
375
  const settings = useSettings();
385
- const headers = matchedSubnav ? matchedSubnav == null ? void 0 : matchedSubnav.items : (_a = settings == null ? void 0 : settings.structure) == null ? void 0 : _a.header;
386
- const active = headers == null ? void 0 : headers.find((item) => location.pathname.startsWith(item.url || ""));
376
+ const lastMatch = matches[matches.length - 1];
377
+ const header = ((_a = settings == null ? void 0 : settings.navigation) == null ? void 0 : _a.header) || [];
378
+ const active = header.find((item) => {
379
+ if (matchedSubnav) {
380
+ return pageLink(item.page || "") === pageLink(matchedSubnav == null ? void 0 : matchedSubnav.route);
381
+ }
382
+ return pageLink(item.page || "") === (lastMatch == null ? void 0 : lastMatch.id);
383
+ });
384
+ function createHeader(item) {
385
+ return /* @__PURE__ */ React5.createElement(
386
+ Nav.Item,
387
+ {
388
+ key: (item.page || "") + item.page,
389
+ href: pageLink((item == null ? void 0 : item.page) || ""),
390
+ value: item.page || "",
391
+ as: $Link
392
+ },
393
+ item.title
394
+ );
395
+ }
396
+ const headerMap = header.reduce((acc, item) => {
397
+ const float = item.float || "default";
398
+ return {
399
+ ...acc,
400
+ [float]: [...acc[float] || [], createHeader(item)]
401
+ };
402
+ }, {});
403
+ const rightHeaderExists = ((_b = headerMap["right"]) == null ? void 0 : _b.length) > 0;
387
404
  return /* @__PURE__ */ React5.createElement(
388
405
  Nav,
389
406
  {
390
- value: (active == null ? void 0 : active.url) || "",
407
+ value: (active == null ? void 0 : active.page) || "",
391
408
  kind,
392
409
  logo: /* @__PURE__ */ React5.createElement(FwNavLogo, null),
393
- onChange: () => {
394
- }
395
- },
396
- (_c = (_b = settings == null ? void 0 : settings.structure) == null ? void 0 : _b.header) == null ? void 0 : _c.map((item, index) => {
397
- if (item.sub) {
398
- return null;
399
- }
400
- return /* @__PURE__ */ React5.createElement(
401
- Nav.Item,
410
+ rightSurface: /* @__PURE__ */ React5.createElement(React5.Fragment, null, rightHeaderExists ? /* @__PURE__ */ React5.createElement(
411
+ Nav.Tab,
402
412
  {
403
- key: index + (item.url || "") + item.name,
404
- href: (item == null ? void 0 : item.url) || "",
405
- value: item.url
413
+ value: (active == null ? void 0 : active.page) || ""
406
414
  },
407
- item.name
408
- );
409
- })
415
+ headerMap["right"]
416
+ ) : null, /* @__PURE__ */ React5.createElement(Surface, { target: "nav.right" /* NavRight */ }), /* @__PURE__ */ React5.createElement(ColorSchemeButton, null))
417
+ },
418
+ headerMap["default"]
410
419
  );
411
420
  }
412
421
  function FwSubNav() {
413
422
  const matchedSubnav = useMatchedSubNav();
414
- const location = useLocation3();
423
+ const location = useLocation2();
424
+ const pathname = trailingSlash(location.pathname);
415
425
  if (!matchedSubnav) {
416
426
  return null;
417
427
  }
418
- const active = matchedSubnav == null ? void 0 : matchedSubnav.items.findLast((item) => location.pathname.startsWith(item.url || ""));
428
+ const active = matchedSubnav == null ? void 0 : matchedSubnav.pages.findLast((item) => {
429
+ return pathname.startsWith(pageLink(item.page || ""));
430
+ });
419
431
  return /* @__PURE__ */ React5.createElement(
420
432
  SubNav,
421
433
  {
422
- title: (matchedSubnav == null ? void 0 : matchedSubnav.name) || "",
423
- value: (active == null ? void 0 : active.url) || "",
434
+ title: (matchedSubnav == null ? void 0 : matchedSubnav.title) || "",
435
+ value: (active == null ? void 0 : active.page) || "",
424
436
  onChange: () => {
425
437
  }
426
438
  },
427
- matchedSubnav == null ? void 0 : matchedSubnav.items.map((item, index) => {
428
- return /* @__PURE__ */ React5.createElement(SubNav.Item, { value: item.url || "", href: item.url }, item.name);
439
+ matchedSubnav == null ? void 0 : matchedSubnav.pages.map((item, index) => {
440
+ return /* @__PURE__ */ React5.createElement(
441
+ SubNav.Item,
442
+ {
443
+ value: item.page || "",
444
+ href: pageLink(item.page || ""),
445
+ as: $Link
446
+ },
447
+ item.title
448
+ );
429
449
  })
430
450
  );
431
451
  }
432
- function recursiveSearch2(items, href, levels = []) {
433
- for (let i = 0; i < items.length; i++) {
434
- const item = items[i];
435
- if (item.href === href) {
436
- return [...levels, i];
437
- }
438
- if (item.items) {
439
- const result = recursiveSearch2(item.items, href, [...levels, i]);
440
- if (result) {
441
- return result;
442
- }
443
- }
444
- }
445
- return null;
446
- }
447
452
  function FwSidebarGroups(props) {
448
453
  var _a, _b, _c;
454
+ const location = useLocation2();
455
+ const pathname = trailingSlash(location.pathname);
449
456
  const groups = useSidebarGroups();
450
457
  const settings = useSettings();
451
- const footerItems = (_c = (_b = (_a = settings.structure) == null ? void 0 : _a.anchors) == null ? void 0 : _b.bottom) == null ? void 0 : _c.map((anchor) => {
452
- let icon;
453
- if (typeof anchor.icon === "string") {
454
- switch (anchor.icon) {
455
- case "icon-cookbook": {
456
- icon = /* @__PURE__ */ React5.createElement(IconCookbook, null);
457
- break;
458
- }
459
- case "icon-community": {
460
- icon = /* @__PURE__ */ React5.createElement(IconCommunity, null);
461
- break;
462
- }
463
- case "icon-marketplace": {
464
- icon = /* @__PURE__ */ React5.createElement(IconMarketplace, null);
465
- break;
466
- }
467
- case "icon-sdk": {
468
- icon = /* @__PURE__ */ React5.createElement(IconSDK, null);
469
- break;
470
- }
471
- default: {
472
- icon = null;
473
- }
474
- }
475
- } else {
476
- icon = isValidElement(anchor.icon) ? anchor.icon : manualHydration(anchor.icon);
477
- }
478
- return /* @__PURE__ */ React5.createElement(UISidebar2.FooterItem, { href: anchor.url, icon }, anchor.name);
458
+ const footerItems = (_c = (_b = (_a = settings.navigation) == null ? void 0 : _a.anchors) == null ? void 0 : _b.bottom) == null ? void 0 : _c.map((anchor) => {
459
+ return /* @__PURE__ */ React5.createElement(UISidebar2.FooterItem, { href: anchor.url, icon: /* @__PURE__ */ React5.createElement(Icon2, { name: anchor.icon || "" }) }, anchor.name);
479
460
  });
480
- const location = useLocation3();
481
461
  const initialActiveItems = [];
482
- groups.forEach((group) => {
483
- const activeLevels = recursiveSearch2(group.items, location.pathname) || [];
484
- activeLevels.reduce((acc, index) => {
485
- initialActiveItems.push(acc[index]);
462
+ groups.forEach((group, groupIndex) => {
463
+ const activeLevels = recursiveSearch(group.items, pathname) || [];
464
+ activeLevels.reduce((acc, index, level) => {
465
+ initialActiveItems.push({
466
+ ...acc[index],
467
+ groupIndex,
468
+ level,
469
+ itemIndex: index
470
+ });
486
471
  acc[index].active = true;
487
472
  return acc[index].items;
488
473
  }, group.items);
@@ -491,53 +476,45 @@ function FwSidebarGroups(props) {
491
476
  return /* @__PURE__ */ React5.createElement(
492
477
  FwSidebarGroupContext,
493
478
  {
494
- onePathBehaviour: props.onePathBehaviour,
495
- clientSideRouting: props.clientSideRouting,
496
479
  initialActiveItems
497
480
  },
498
- /* @__PURE__ */ React5.createElement(UISidebar2, { footerItems: footerItems && footerItems }, groups == null ? void 0 : groups.map((group, index) => /* @__PURE__ */ React5.createElement(
481
+ /* @__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(
499
482
  FwSidebarItemGroup,
500
483
  {
501
484
  key: index + group.group,
502
- ...group
485
+ ...group,
486
+ groupIndex: index
503
487
  }
504
488
  )))
505
489
  );
506
490
  }
507
491
  function FwToc() {
508
492
  var _a;
493
+ const metadata = useMetadata();
494
+ const settings = useSettings();
509
495
  const toc = useToC();
510
496
  if (!toc) {
511
497
  return null;
512
498
  }
513
- const flatToc = [];
514
- const flatten = (toc2) => {
515
- if (!toc2) {
516
- return;
517
- }
518
- toc2.forEach((item) => {
519
- flatToc.push({
520
- depth: item.depth,
521
- value: item.value
522
- });
523
- flatten(item.children);
524
- });
499
+ const maxDepth = (metadata == null ? void 0 : metadata.maxTocDepth) || ((_a = settings == null ? void 0 : settings.theme) == null ? void 0 : _a.maxTocDepth) || 2;
500
+ const renderTocItems = (items, uiDepth = 0) => {
501
+ return items.map((item) => /* @__PURE__ */ React5.createElement(React5.Fragment, { key: item.id }, /* @__PURE__ */ React5.createElement(
502
+ Toc.Item,
503
+ {
504
+ id: item.id,
505
+ depth: uiDepth
506
+ },
507
+ item.value
508
+ ), item.children && item.children.length > 0 && renderTocItems(item.children, uiDepth + 1)));
525
509
  };
526
- flatten(toc);
527
- const tocFinal = flatToc.filter((item) => item.depth === 2);
528
- const location = useLocation3();
529
- const defaultValue = location.hash ? location.hash.replace("#", "") : (_a = tocFinal[0]) == null ? void 0 : _a.value;
530
- return /* @__PURE__ */ React5.createElement(Toc, { defaultValue }, tocFinal.map((item, index) => /* @__PURE__ */ React5.createElement(
531
- Toc.Item,
532
- {
533
- key: index + item.value + item.depth,
534
- value: item.value
535
- },
536
- item.value
537
- )));
510
+ return /* @__PURE__ */ React5.createElement(Toc, { maxDepth }, renderTocItems(toc));
538
511
  }
539
512
  function FwBreadcrumbs() {
540
- const breadcrumbs = useBreadcrumbs();
513
+ const fwBreadcrumbs = useBreadcrumbs();
514
+ const breadcrumbs = fwBreadcrumbs == null ? void 0 : fwBreadcrumbs.map((item) => ({
515
+ title: item.title,
516
+ href: item.href
517
+ }));
541
518
  return /* @__PURE__ */ React5.createElement(
542
519
  Breadcrumbs,
543
520
  {
@@ -552,113 +529,110 @@ function FwNavLinks() {
552
529
  NavLinks,
553
530
  {
554
531
  prev: navlinks.prev,
555
- next: navlinks.next
532
+ next: navlinks.next,
533
+ as: $Link
556
534
  }
557
535
  );
558
536
  }
559
537
  return null;
560
538
  }
561
- function IconCookbook() {
562
- return /* @__PURE__ */ React5.createElement(
563
- "svg",
564
- {
565
- xmlns: "http://www.w3.org/2000/svg",
566
- viewBox: "0 0 24 24",
567
- width: "1em",
568
- height: "1em"
569
- },
570
- /* @__PURE__ */ React5.createElement(
571
- "path",
572
- {
573
- fillRule: "evenodd",
574
- d: "M14.447 7.106a1 1 0 0 1 .447 1.341l-4 8a1 1 0 1 1-1.788-.894l4-8a1 1 0 0 1 1.341-.447ZM6.6 7.2a1 1 0 0 1 .2 1.4L4.25 12l2.55 3.4a1 1 0 0 1-1.6 1.2l-3-4a1 1 0 0 1 0-1.2l3-4a1 1 0 0 1 1.4-.2Zm10.8 0a1 1 0 0 1 1.4.2l3 4a1 1 0 0 1 0 1.2l-3 4a1 1 0 0 1-1.6-1.2l2.55-3.4-2.55-3.4a1 1 0 0 1 .2-1.4Z",
575
- clipRule: "evenodd"
576
- }
577
- )
578
- );
539
+ function FwLogo() {
540
+ var _a, _b, _c, _d, _e, _f;
541
+ const settings = useSettings();
542
+ const [colorScheme] = useColorScheme();
543
+ if (typeof ((_a = settings == null ? void 0 : settings.theme) == null ? void 0 : _a.logo) === "string") {
544
+ return /* @__PURE__ */ React5.createElement("img", { src: (_b = settings == null ? void 0 : settings.theme) == null ? void 0 : _b.logo });
545
+ }
546
+ if (isValidElement((_c = settings == null ? void 0 : settings.theme) == null ? void 0 : _c.logo)) {
547
+ return /* @__PURE__ */ React5.createElement("a", { href: "/" }, (_d = settings == null ? void 0 : settings.theme) == null ? void 0 : _d.logo);
548
+ }
549
+ if (typeof ((_e = settings == null ? void 0 : settings.theme) == null ? void 0 : _e.logo) === "object" && colorScheme) {
550
+ return /* @__PURE__ */ React5.createElement("img", { src: (_f = settings == null ? void 0 : settings.theme) == null ? void 0 : _f.logo[colorScheme] });
551
+ }
552
+ return null;
579
553
  }
580
- function IconCommunity() {
581
- return /* @__PURE__ */ React5.createElement(
582
- "svg",
583
- {
584
- xmlns: "http://www.w3.org/2000/svg",
585
- fill: "currentColor",
586
- viewBox: "0 0 24 24",
587
- width: "1em",
588
- height: "1em"
589
- },
590
- /* @__PURE__ */ React5.createElement(
591
- "path",
592
- {
593
- fillRule: "evenodd",
594
- d: "M10.5 8.5a1.5 1.5 0 1 1 3 0 1.5 1.5 0 0 1-3 0ZM12 5a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7ZM3 9.5a1 1 0 1 1 2 0 1 1 0 0 1-2 0Zm1-3a3 3 0 1 0 0 6 3 3 0 0 0 0-6Zm16 2a1 1 0 1 0 0 2 1 1 0 0 0 0-2Zm-3 1a3 3 0 1 1 6 0 3 3 0 0 1-6 0ZM8 18c0-.974.438-1.684 1.142-2.185C9.876 15.293 10.911 15 12 15c1.09 0 2.124.293 2.858.815.704.5 1.142 1.21 1.142 2.185a1 1 0 1 0 2 0c0-1.692-.812-2.982-1.983-3.815C14.876 13.373 13.411 13 12 13c-1.41 0-2.876.373-4.017 1.185C6.812 15.018 6 16.308 6 18a1 1 0 1 0 2 0Zm-3.016-3.675a1 1 0 0 1-.809 1.16C2.79 15.732 2 16.486 2 17.5a1 1 0 1 1-2 0c0-2.41 1.978-3.655 3.825-3.985a1 1 0 0 1 1.16.81Zm14.84 1.16a1 1 0 1 1 .351-1.97C22.022 13.845 24 15.09 24 17.5a1 1 0 1 1-2 0c0-1.014-.79-1.768-2.175-2.015Z",
595
- clipRule: "evenodd"
596
- }
597
- )
598
- );
554
+ function FwLink({ children, ...rest }) {
555
+ return /* @__PURE__ */ React5.createElement(Anchor, { ...rest, as: $Link }, children);
599
556
  }
600
- function IconMarketplace() {
601
- return /* @__PURE__ */ React5.createElement(
602
- "svg",
603
- {
604
- xmlns: "http://www.w3.org/2000/svg",
605
- viewBox: "0 0 24 24",
606
- fill: "none",
607
- width: "1em",
608
- height: "1em"
609
- },
610
- /* @__PURE__ */ React5.createElement(
611
- "path",
612
- {
613
- "fill-rule": "evenodd",
614
- "clip-rule": "evenodd",
615
- d: "M3.78163 3.28449C3.8768 2.96725 4.16879 2.75 4.5 2.75H19.5C19.8312 2.75 20.1232 2.96725 20.2184 3.28449L21.7184 8.28449C21.7393 8.3544 21.75 8.42701 21.75 8.5C21.75 10.5711 20.0711 12.25 18 12.25C16.7733 12.25 15.6842 11.661 15 10.7504C14.3158 11.661 13.2267 12.25 12 12.25C10.7733 12.25 9.68417 11.661 9 10.7504C8.31583 11.661 7.2267 12.25 6 12.25C3.92893 12.25 2.25 10.5711 2.25 8.5C2.25 8.42701 2.26066 8.3544 2.28163 8.28449L3.78163 3.28449ZM9.75 8.5C9.75 9.74264 10.7574 10.75 12 10.75C13.2426 10.75 14.25 9.74264 14.25 8.5C14.25 8.08579 14.5858 7.75 15 7.75C15.4142 7.75 15.75 8.08579 15.75 8.5C15.75 9.74264 16.7574 10.75 18 10.75C19.2083 10.75 20.1942 9.79754 20.2477 8.60244L18.942 4.25H5.05802L3.75229 8.60244C3.80584 9.79753 4.79169 10.75 6 10.75C7.24264 10.75 8.25 9.74264 8.25 8.5C8.25 8.08579 8.58579 7.75 9 7.75C9.41421 7.75 9.75 8.08579 9.75 8.5Z"
616
- }
617
- ),
618
- /* @__PURE__ */ React5.createElement(
619
- "path",
620
- {
621
- "fill-rule": "evenodd",
622
- "clip-rule": "evenodd",
623
- d: "M4 10.25C4.41421 10.25 4.75 10.5858 4.75 11V19.75H6.5C6.91421 19.75 7.25 20.0858 7.25 20.5C7.25 20.9142 6.91421 21.25 6.5 21.25H4C3.58579 21.25 3.25 20.9142 3.25 20.5V11C3.25 10.5858 3.58579 10.25 4 10.25ZM20 10.25C20.4142 10.25 20.75 10.5858 20.75 11V20.5C20.75 20.9142 20.4142 21.25 20 21.25H10.5C10.0858 21.25 9.75 20.9142 9.75 20.5C9.75 20.0858 10.0858 19.75 10.5 19.75H19.25V11C19.25 10.5858 19.5858 10.25 20 10.25Z"
624
- }
625
- ),
626
- /* @__PURE__ */ React5.createElement(
627
- "path",
628
- {
629
- d: "M12.003 19C11.31 18.9996 10.6384 18.7598 10.102 18.3213C9.56564 17.8829 9.19745 17.2726 9.05983 16.594C8.92222 15.9154 9.02364 15.2101 9.34693 14.5976C9.67022 13.9852 10.1955 13.5032 10.8337 13.2333C11.5673 12.9262 12.393 12.9221 13.1296 13.2222C13.8661 13.5222 14.4536 14.1018 14.7631 14.8338C15.0727 15.5659 15.0791 16.3907 14.7808 17.1274C14.4827 17.8642 13.9042 18.4527 13.1724 18.7641C12.8025 18.9205 12.4047 19.0007 12.003 19ZM11.1458 14.7215C11.1124 14.7215 11.0803 14.7348 11.0567 14.7584C11.0331 14.782 11.0198 14.8141 11.0198 14.8475V17.1923C11.0198 17.2258 11.0331 17.2578 11.0567 17.2814C11.0803 17.305 11.1124 17.3183 11.1458 17.3183C11.1671 17.3183 11.188 17.3128 11.2065 17.3024L13.3399 16.13C13.3597 16.1192 13.3761 16.1032 13.3876 16.0838C13.3991 16.0644 13.4052 16.0423 13.4052 16.0197C13.4052 15.9972 13.3991 15.9751 13.3876 15.9557C13.3761 15.9362 13.3597 15.9203 13.3399 15.9094L11.2063 14.7373C11.1879 14.727 11.1671 14.7215 11.1458 14.7215Z"
557
+ function FwCopyPage() {
558
+ const [isCopied, setIsCopied] = useState3(false);
559
+ const rawPage = useRawPage();
560
+ const handleCopy = () => {
561
+ navigator.clipboard.writeText(rawPage || "");
562
+ setIsCopied(true);
563
+ setTimeout(() => setIsCopied(false), 2e3);
564
+ };
565
+ 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");
566
+ }
567
+ function $Link({ children, ...rest }) {
568
+ let to = "";
569
+ if (rest.href) {
570
+ try {
571
+ new URL(rest.href);
572
+ to = rest.href;
573
+ } catch (error) {
574
+ if (rest.href.startsWith("/")) {
575
+ const url = new URL(`https://example.com${rest.href}`);
576
+ to = {
577
+ pathname: url.pathname,
578
+ search: url.search,
579
+ hash: url.hash
580
+ };
581
+ } else {
582
+ return /* @__PURE__ */ React5.createElement(Anchor, { as: "button", onClick: () => {
583
+ const url = new URL(window.location.href);
584
+ const currentParams = url.searchParams;
585
+ new URLSearchParams(rest.href).forEach((value, key) => {
586
+ currentParams.set(key, value);
587
+ });
588
+ url.search = currentParams.toString();
589
+ history.replaceState(null, "", url);
590
+ } }, children);
630
591
  }
631
- )
632
- );
592
+ }
593
+ }
594
+ return /* @__PURE__ */ React5.createElement(Link, { ...rest, to }, children);
633
595
  }
634
- function IconSDK() {
635
- return /* @__PURE__ */ React5.createElement(
636
- "svg",
637
- {
638
- viewBox: "0 0 15 15",
639
- xmlns: "http://www.w3.org/2000/svg",
640
- width: "1em",
641
- height: "1em"
642
- },
643
- /* @__PURE__ */ React5.createElement(
644
- "path",
645
- {
646
- d: "M7.28856 0.796908C7.42258 0.734364 7.57742 0.734364 7.71144 0.796908L13.7114 3.59691C13.8875 3.67906 14 3.85574 14 4.05V10.95C14 11.1443 13.8875 11.3209 13.7114 11.4031L7.71144 14.2031C7.57742 14.2656 7.42258 14.2656 7.28856 14.2031L1.28856 11.4031C1.11252 11.3209 1 11.1443 1 10.95V4.05C1 3.85574 1.11252 3.67906 1.28856 3.59691L7.28856 0.796908ZM2 4.80578L7 6.93078V12.9649L2 10.6316V4.80578ZM8 12.9649L13 10.6316V4.80578L8 6.93078V12.9649ZM7.5 6.05672L12.2719 4.02866L7.5 1.80176L2.72809 4.02866L7.5 6.05672Z",
647
- fill: "currentColor",
648
- fillRule: "evenodd",
649
- clipRule: "evenodd"
596
+ function recursiveSearch(items, href, levels = []) {
597
+ for (let i = 0; i < items.length; i++) {
598
+ const item = items[i];
599
+ if (item.href === href) {
600
+ return [...levels, i];
601
+ }
602
+ if (item.items) {
603
+ const result = recursiveSearch(item.items, href, [...levels, i]);
604
+ if (result) {
605
+ return result;
650
606
  }
651
- )
652
- );
607
+ }
608
+ }
609
+ return null;
610
+ }
611
+ function trailingSlash(path) {
612
+ return path.endsWith("/") ? path.slice(0, -1) : path;
613
+ }
614
+ function pageLink(page) {
615
+ return page.startsWith("/") ? page : `/${page}`;
653
616
  }
654
617
  export {
655
618
  Framework,
619
+ FrameworkPage,
656
620
  FwBreadcrumbs,
621
+ FwCopyPage,
622
+ FwLink,
623
+ FwLogo,
657
624
  FwNav,
658
625
  FwNavLinks,
659
626
  FwSidebarGroups,
660
627
  FwSubNav,
661
628
  FwToc,
662
- useMatchedSubNav
629
+ Surface,
630
+ SurfaceContext,
631
+ SurfaceTarget,
632
+ Surfaces,
633
+ useContentComponent,
634
+ useMatchedSubNav,
635
+ useMetadata,
636
+ useSettings
663
637
  };
664
638
  //# sourceMappingURL=react.js.map