@xyd-js/framework 0.1.0-xyd.11 → 0.1.0-xyd.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/Sidebar-CdavG0uc.d.ts +23 -0
- package/dist/hydration.d.ts +17 -0
- package/dist/hydration.js +269 -0
- package/dist/hydration.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/react.d.ts +72 -0
- package/dist/react.js +612 -0
- package/dist/react.js.map +1 -0
- package/package.json +19 -16
- package/packages/hydration/README.md +0 -3
- package/packages/hydration/index.ts +0 -3
- package/packages/hydration/settings-to-props.ts +0 -325
- package/packages/react/README.md +0 -3
- package/packages/react/components/index.tsx +0 -337
- package/packages/react/components/sidebar/index.ts +0 -3
- package/packages/react/components/sidebar/sidebar-group.tsx +0 -240
- package/packages/react/components/sidebar/sidebar.tsx +0 -127
- package/packages/react/contexts/framework.tsx +0 -78
- package/packages/react/contexts/index.ts +0 -2
- package/packages/react/contexts/ui.tsx +0 -6
- package/packages/react/hooks/index.ts +0 -3
- package/packages/react/hooks/useMatchedNav.tsx +0 -29
- package/packages/react/index.ts +0 -12
- package/packages/react/utils/manualHydration.ts +0 -25
- package/packages/theme/context.tsx +0 -19
- package/packages/theme/index.ts +0 -0
- package/postcss.config.cjs +0 -5
- package/src/index.ts +0 -1
- package/src/types.ts +0 -7
- package/tsconfig.json +0 -45
- package/tsup.config.ts +0 -28
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../packages/react/components/index.tsx","../packages/react/components/Surfaces.tsx","../packages/react/contexts/framework.tsx","../packages/react/components/Sidebar/Sidebar.tsx","../packages/react/components/Sidebar/SidebarGroup.tsx","../packages/react/hooks/useMatchedNav.tsx"],"sourcesContent":["import React, { isValidElement, useState } from \"react\";\nimport { Link, type To, useLocation, useMatches } from \"react-router\";\n\nimport { Header } from \"@xyd-js/core\";\nimport type { ITOC } from \"@xyd-js/ui\";\nimport { Nav, SubNav, Toc, UISidebar } from \"@xyd-js/ui\"\nimport { Anchor, Breadcrumbs, Button, ColorSchemeButton, Icon, NavLinks, useColorScheme } from \"@xyd-js/components/writer\";\n\nimport { Surface } from \"./Surfaces\";\nimport { SurfaceTarget } from \"../../../src\";\n\nimport { useBreadcrumbs, useMetadata, useNavLinks, useRawPage, useSettings, useSidebarGroups, useToC } from \"../contexts\";\nimport { FwSidebarGroupContext, FwSidebarItemGroup, FwSidebarItemProps } from \"./Sidebar\";\n\nimport { useMatchedSubNav } from \"../hooks\";\n\nfunction FwNavLogo() {\n const settings = useSettings()\n\n const logo = typeof settings?.theme?.logo\n\n if (!logo) {\n return null\n }\n\n return <a href=\"/\">\n <FwLogo />\n </a>\n}\n\nexport function FwNav({ kind }: { kind?: \"middle\" }) {\n const matches = useMatches()\n const matchedSubnav = useMatchedSubNav()\n const settings = useSettings()\n\n const lastMatch = matches[matches.length - 1]\n\n const header = settings?.navigation?.header || []\n\n const active = header.find(item => {\n if (matchedSubnav) {\n return pageLink(item.page || \"\") === pageLink(matchedSubnav?.route)\n }\n\n return pageLink(item.page || \"\") === lastMatch?.id\n })\n\n function createHeader(item: Header) {\n return <Nav.Item\n key={(item.page || \"\") + item.page}\n href={pageLink(item?.page || \"\")}\n value={item.page || \"\"}\n as={$Link}\n >\n {item.title}\n </Nav.Item>\n }\n\n const headerMap = header.reduce<Record<string, React.ReactNode[]>>((acc, item) => {\n const float = item.float || \"default\";\n return {\n ...acc,\n [float]: [...(acc[float] || []), createHeader(item)]\n };\n }, {});\n\n const rightHeaderExists = headerMap[\"right\"]?.length > 0\n\n // TODO: in the future better floating system - just pure css?\n return <Nav\n value={active?.page || \"\"}\n kind={kind}\n logo={<FwNavLogo />}\n rightSurface={<>\n {\n rightHeaderExists\n ? <Nav.Tab\n value={active?.page || \"\"}\n >\n {headerMap[\"right\"]}\n </Nav.Tab>\n : null\n }\n\n <Surface target={SurfaceTarget.NavRight} />\n\n <ColorSchemeButton />\n </>}\n >\n {headerMap[\"default\"]}\n </Nav>\n}\n\nexport function FwSubNav() {\n const matchedSubnav = useMatchedSubNav()\n const location = useLocation()\n const pathname = trailingSlash(location.pathname)\n\n if (!matchedSubnav) {\n return null\n }\n\n // TODO: in the future routing props from settings like {match: \"/docs/api/browser\"}\n const active = matchedSubnav?.pages.findLast(item => {\n return pathname.startsWith(pageLink(item.page || \"\"))\n })\n\n // TODO: value\n return <SubNav\n title={matchedSubnav?.title || \"\"}\n value={active?.page || \"\"}\n onChange={() => {\n }}\n >\n {matchedSubnav?.pages.map((item, index) => {\n return <SubNav.Item\n value={item.page || \"\"}\n href={pageLink(item.page || \"\")}\n as={$Link}\n\n >\n {item.title}\n </SubNav.Item>\n })}\n </SubNav>\n}\n\nexport interface FwSidebarGroupsProps {\n}\n\nexport function FwSidebarGroups(props: FwSidebarGroupsProps) {\n const location = useLocation()\n const pathname = trailingSlash(location.pathname)\n const groups = useSidebarGroups()\n const settings = useSettings()\n\n const footerItems = settings.navigation?.anchors?.bottom?.map(anchor => {\n return <UISidebar.FooterItem href={anchor.url} icon={<Icon name={anchor.icon || \"\"} />}>\n {anchor.name}\n </UISidebar.FooterItem>\n })\n\n const initialActiveItems: any[] = []\n groups.forEach((group, groupIndex) => {\n const activeLevels = recursiveSearch(group.items, pathname) || []\n\n activeLevels.reduce((acc, index, level) => {\n initialActiveItems.push({\n ...acc[index],\n groupIndex: groupIndex,\n level: level,\n itemIndex: index,\n })\n acc[index].active = true\n return acc[index].items\n }, group.items)\n\n return group\n })\n\n\n // TODO: better API for elements like logo search\n return <FwSidebarGroupContext\n initialActiveItems={initialActiveItems}\n >\n <UISidebar footerItems={footerItems && footerItems}>\n <Surface target={SurfaceTarget.SidebarTop} />\n\n {\n groups?.map((group, index) => <FwSidebarItemGroup\n key={index + group.group}\n {...group}\n groupIndex={index}\n />)\n }\n </UISidebar>\n </FwSidebarGroupContext>\n}\n\nexport function FwToc() {\n const metadata = useMetadata()\n const settings = useSettings()\n const toc = useToC()\n\n if (!toc) {\n return null\n }\n\n const maxDepth = metadata?.maxTocDepth || settings?.theme?.maxTocDepth || 2\n\n const renderTocItems = (items: Readonly<ITOC[]>, uiDepth = 0) => {\n return items.map((item) => (\n <React.Fragment key={item.id}>\n <Toc.Item\n id={item.id}\n depth={uiDepth}\n >\n {item.value}\n </Toc.Item>\n {item.children && item.children.length > 0 && renderTocItems(item.children, uiDepth + 1)}\n </React.Fragment>\n ))\n }\n\n // TODO: maxDepth for specific `#heading`\n return <Toc maxDepth={maxDepth}>\n {renderTocItems(toc)}\n </Toc>\n}\n\nexport function FwBreadcrumbs() {\n const fwBreadcrumbs = useBreadcrumbs()\n\n const breadcrumbs = fwBreadcrumbs?.map(item => ({\n title: item.title,\n href: item.href\n }))\n\n return <Breadcrumbs\n items={breadcrumbs || []}\n />\n}\n\nexport function FwNavLinks() {\n const navlinks = useNavLinks()\n\n if (navlinks?.prev || navlinks?.next) {\n return <NavLinks\n prev={navlinks.prev}\n next={navlinks.next}\n as={$Link}\n />\n }\n\n return null\n}\n\nexport function FwLogo() {\n const settings = useSettings()\n const [colorScheme] = useColorScheme()\n\n if (typeof settings?.theme?.logo === \"string\") {\n return <img src={settings?.theme?.logo} />\n }\n\n if (isValidElement(settings?.theme?.logo)) {\n return <a href=\"/\">\n {settings?.theme?.logo}\n </a>\n }\n\n if (typeof settings?.theme?.logo === \"object\" && colorScheme) {\n return <img src={settings?.theme?.logo[colorScheme as \"light\" | \"dark\"]} />\n }\n\n return null\n}\n\nexport function FwLink({ children, ...rest }) {\n return <Anchor {...rest} as={$Link}>\n {children}\n </Anchor>\n}\n\nexport function FwCopyPage() {\n const [isCopied, setIsCopied] = useState(false)\n\n const rawPage = useRawPage()\n // const events = useEvents()\n\n const handleCopy = () => {\n navigator.clipboard.writeText(rawPage || \"\")\n setIsCopied(true)\n // events.CopyPage({}) TODO: finish this\n\n setTimeout(() => setIsCopied(false), 2000)\n }\n\n // TODO: `xyd` icons must be always loaded\n return <Button icon={isCopied ? <Icon name=\"check\" size={12} /> : <Icon name=\"copy\" size={12} />} onClick={handleCopy}>\n Copy page\n </Button>\n}\n\nfunction $Link({ children, ...rest }) {\n let to: To = \"\"\n\n if (rest.href) {\n try {\n new URL(rest.href)\n to = rest.href\n } catch (error) {\n if (rest.href.startsWith(\"/\")) {\n const url = new URL(`https://example.com${rest.href}`)\n to = {\n pathname: url.pathname,\n search: url.search,\n hash: url.hash,\n }\n } else {\n return <Anchor as=\"button\" onClick={() => { // TODO: !!! in the future we should use react-router but it rerenders tha page !!!\n const url = new URL(window.location.href)\n const currentParams = url.searchParams\n\n // Update parameters from the new params\n new URLSearchParams(rest.href).forEach((value, key) => {\n currentParams.set(key, value)\n })\n\n url.search = currentParams.toString()\n history.replaceState(null, '', url)\n }}>\n {children}\n </Anchor>\n }\n }\n }\n\n return <Link {...rest} to={to}>\n {children}\n </Link>\n}\n\nfunction recursiveSearch(items: FwSidebarItemProps[], href: string, levels: any[] = []) {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n\n if (item.href === href) {\n return [...levels, i]\n }\n\n if (item.items) {\n const result = recursiveSearch(item.items, href, [...levels, i])\n if (result) {\n return result\n }\n }\n }\n return null\n}\n\n\nfunction trailingSlash(path: string) {\n return path.endsWith(\"/\") ? path.slice(0, -1) : path\n}\n\nfunction pageLink(page: string) {\n return page.startsWith(\"/\") ? page : `/${page}`\n}\n","import React, { createContext, useContext, ComponentType } from 'react'\n\nimport { ROSurface, SurfaceTargetType } from '../../../src'\n\n\ninterface SurfaceContext {\n surfaces?: ROSurface\n}\n\nexport const SurfaceContext = createContext<SurfaceContext>({\n surfaces: undefined,\n})\n\ninterface SurfaceProps {\n target: SurfaceTargetType\n props?: any // TODO: fix any\n}\n\nexport function Surface(props: SurfaceProps): React.JSX.Element | null {\n const { target } = props\n\n const registry = useContext(SurfaceContext)\n\n if (!registry.surfaces) {\n return null\n }\n\n const components = registry.surfaces.get(target)\n\n if (!components) {\n return null\n }\n\n if (!Array.isArray(components)) {\n if (typeof components === 'function') {\n const Component = components as ComponentType<any>\n return <Component {...props.props} />\n }\n\n return <React.Fragment>{components}</React.Fragment>\n }\n\n if (!components.length) {\n return null\n }\n\n return <>\n {components.map((Component, index) => {\n if (typeof Component === 'function') {\n const Comp = Component as ComponentType<any>\n return <Comp key={index} {...props.props} />\n }\n return <React.Fragment key={index}>{Component}</React.Fragment>\n })}\n </>\n}","import React, { createContext, useContext, useEffect, useState } from \"react\";\nimport { useNavigation } from \"react-router\";\n\nimport { Metadata, Settings } from \"@xyd-js/core\";\nimport { type ITOC, type IBreadcrumb, type INavLinks, ProgressBar } from \"@xyd-js/ui\";\nimport { Banner, Button } from \"@xyd-js/components/writer\";\n\nimport { FwSidebarGroupProps } from \"../components/Sidebar\";\nimport { SurfaceContext } from \"../components/Surfaces\";\nimport {Surfaces} from \"../../../src\"\n\nexport interface IFramework {\n settings: Readonly<Settings>\n\n sidebarGroups: Readonly<FwSidebarGroupProps[]>\n metadata: Readonly<Metadata>\n setMetadata: (metadata: Metadata) => void\n components?: Readonly<{[componentName: string]: React.ComponentType<any>}>\n}\n\nconst framework: IFramework = {\n settings: {},\n metadata: {\n title: \"\",\n },\n sidebarGroups: [],\n setMetadata: () => { },\n components: {}\n}\nconst FrameworkContext = createContext<IFramework>(framework)\n\nexport interface FrameworkProps {\n children: React.ReactNode\n\n settings: Settings,\n metadata: Metadata,\n sidebarGroups: FwSidebarGroupProps[],\n surfaces: Surfaces,\n components?: {[componentName: string]: React.ComponentType<any>},\n BannerContent: React.ComponentType<any>\n}\n\nexport function Framework(props: FrameworkProps) {\n const navigation = useNavigation()\n\n const [metadata, setMetadata] = useState<Metadata | undefined>(props.metadata)\n\n const BannerContent = props.BannerContent || null\n const BannerComponent = props?.settings?.theme?.banner?.kind === \"secondary\" ? Banner.Secondary : Banner\n return <>\n <FrameworkContext value={{\n settings: Object.freeze({ ...props.settings }),\n sidebarGroups: Object.freeze([...props.sidebarGroups]),\n metadata: Object.freeze({ ...metadata, title: metadata?.title || \"\" }),\n setMetadata: setMetadata,\n components: Object.freeze(props.components || {})\n }}>\n <SurfaceContext value={{\n surfaces: props.surfaces\n }}>\n <ProgressBar isActive={navigation.state === 'loading'} />\n {BannerContent ? <BannerComponent\n label={props.settings?.theme?.banner?.label}\n icon={props.settings?.theme?.banner?.icon}\n >\n <BannerContent />\n </BannerComponent> : null}\n {props.children}\n </SurfaceContext>\n </FrameworkContext>\n </>\n}\n\ninterface FrameworkPageProps {\n children: React.ReactNode\n\n ContentComponent?: (props: { components: any, children: React.ReactNode }) => React.JSX.Element\n\n metadata: Metadata\n breadcrumbs?: IBreadcrumb[],\n rawPage?: string\n toc?: ITOC[],\n navlinks?: INavLinks\n}\n\ninterface IFrameworkPageContext {\n ContentComponent: (props: { components: any, children: React.ReactNode }) => React.JSX.Element\n metadata: Readonly<Metadata>\n breadcrumbs?: Readonly<IBreadcrumb[]>\n rawPage?: Readonly<string>\n toc?: Readonly<ITOC[]>\n navlinks?: Readonly<INavLinks>\n}\n\nconst FrameworkPageContext = createContext<IFrameworkPageContext>({\n ContentComponent: () => <></>,\n metadata: {\n title: \"\",\n }\n})\n\nexport function FrameworkPage(props: FrameworkPageProps) {\n const { setMetadata } = useContext(FrameworkContext)\n\n useEffect(() => {\n setMetadata(props.metadata)\n }, [])\n\n return <FrameworkPageContext value={{\n ContentComponent: props.ContentComponent || (() => <></>),\n metadata: Object.freeze(props.metadata),\n breadcrumbs: Object.freeze(props.breadcrumbs),\n rawPage: Object.freeze(props.rawPage),\n toc: Object.freeze(props.toc || []),\n navlinks: Object.freeze(props.navlinks),\n }}>\n {props.children}\n </FrameworkPageContext>\n}\n\nexport function useSidebarGroups() {\n const ctx = useContext(FrameworkContext)\n\n return ctx.sidebarGroups\n}\n\nexport function useSettings() {\n const ctx = useContext(FrameworkContext)\n\n return ctx.settings\n}\n\nexport function useMetadata() {\n const ctx = useContext(FrameworkContext)\n\n return ctx.metadata\n}\n\nexport function useComponents() {\n const ctx = useContext(FrameworkContext)\n\n return ctx.components\n}\n\nexport function useToC() {\n const ctx = useContext(FrameworkPageContext)\n const toc = ctx.toc || [] // TODO: !!! `|| []` IS NEEDED CUZ ISSUES WITH HYDRATION !!!\n\n return toc\n}\n\nexport function useBreadcrumbs() {\n const ctx = useContext(FrameworkPageContext)\n\n return ctx.breadcrumbs\n}\n\nexport function useNavLinks() {\n const ctx = useContext(FrameworkPageContext)\n\n return ctx.navlinks\n}\n\n\nexport function useRawPage() {\n const ctx = useContext(FrameworkPageContext)\n\n return ctx.rawPage\n}\n\nexport function useContentComponent() {\n const ctx = useContext(FrameworkPageContext)\n\n return ctx.ContentComponent\n}\n","import React, { } from \"react\"\n\nimport { UISidebar } from \"@xyd-js/ui\";\n\nimport { Icon } from \"@xyd-js/components/writer\";\nimport { Metadata } from \"@xyd-js/core\";\n\nimport { useGroup } from \"./SidebarGroup\";\nimport { Surface } from \"../Surfaces\";\n\n// TODO: custom hooks for active onclick handler etc?\n\nexport interface FwSidebarGroupProps {\n group: string\n\n groupIndex: number\n\n items: FwSidebarItemProps[]\n\n icon?: string\n}\n\nexport function FwSidebarItemGroup(props: FwSidebarGroupProps) {\n const icon = props.icon ? <Icon name={props.icon || \"\"} size={16} /> : null\n\n return <>\n <UISidebar.ItemHeader icon={icon}>\n {props.group}\n </UISidebar.ItemHeader>\n\n {props.items.map((item, index) => <FwSidebarItem\n uniqIndex={item.uniqIndex}\n groupIndex={props.groupIndex}\n level={0}\n itemIndex={index}\n key={index + item.href}\n title={item.title}\n sidebarTitle={item.sidebarTitle}\n pageMeta={item.pageMeta}\n href={item.href}\n items={item.items}\n active={item.active}\n icon={item.icon}\n />)}\n </>\n}\n\nexport interface FwSidebarItemProps {\n title: string\n\n href: string\n\n uniqIndex: number\n\n icon?: string\n\n sidebarTitle?: string\n\n items?: FwSidebarItemProps[]\n\n active?: boolean\n\n // internal\n readonly level?: number\n readonly groupIndex?: number\n readonly itemIndex?: number\n readonly pageMeta?: Metadata\n // internal\n}\n\nfunction FwSidebarItem(props: FwSidebarItemProps) {\n const { active } = useGroup()\n const [isActive, setActive] = active(props)\n\n const title = props.sidebarTitle || props.title || \"\"\n const nested = !!props.items?.length\n\n function handleClick() {\n if (!nested) {\n return\n }\n\n setActive()\n }\n\n // Determine if this is a parent of the active item with href\n const hasActiveChild = props.items?.some(item => {\n const [itemActive] = active(item)\n return (itemActive && item.href) || item.items?.some(subItem => {\n const [subItemActive] = active(subItem)\n return subItemActive && subItem.href\n })\n })\n\n // An item should only be considered active if it's the final target (has href)\n const isActiveItem = !!(isActive && props.href)\n // Only mark as parent active if it's a parent of an active item with href\n const isParentActive = hasActiveChild\n\n const icon = <Icon name={props.icon || \"\"} size={16} />\n\n return <UISidebar.Item\n button={nested}\n href={props.href}\n active={isActiveItem}\n isParentActive={isParentActive}\n onClick={handleClick}\n icon={icon}\n >\n <div part=\"item-title-container\">\n <Surface\n target=\"sidebar.item.left\"\n props={{\n active: isActiveItem,\n pageMeta: props.pageMeta,\n }}\n />\n <div part=\"item-title\">\n {title}\n </div>\n <Surface\n target=\"sidebar.item.right\"\n props={{\n active: isActiveItem,\n pageMeta: props.pageMeta,\n }}\n />\n </div>\n\n {\n props.items?.length && <UISidebar.SubTree isOpen={isActive}>\n <>\n {\n props.items?.map((item, index) => <FwSidebarItem\n uniqIndex={item.uniqIndex}\n groupIndex={props.groupIndex}\n level={(props.level || 0) + 1}\n itemIndex={index}\n key={index + item.href}\n title={item.title}\n href={item.href}\n items={item.items}\n active={active(item)[0]}\n icon={item.icon}\n pageMeta={item.pageMeta}\n />)\n }\n </>\n </UISidebar.SubTree>\n }\n </UISidebar.Item>\n}\n","import React, { createContext, useContext, useState, useEffect } from \"react\";\n\nimport { FwSidebarItemProps } from \"./Sidebar\";\nimport { useLocation, useNavigation } from \"react-router\";\n\nexport interface FwGroupContext {\n active: (item: FwSidebarItemProps) => [boolean, () => void],\n}\n\nconst GroupContext = createContext<FwGroupContext>({\n active: () => [false, () => {\n }],\n})\n\ninterface FwSidebarGroupContextProps {\n children: React.ReactNode,\n initialActiveItems: any[]\n}\n\nexport function FwSidebarGroupContext(props: FwSidebarGroupContextProps) {\n const { children, initialActiveItems } = props\n\n const groupBehaviour = useDefaultBehaviour(initialActiveItems) // TODO: support different behaviours?\n\n return <GroupContext value={{\n active: groupBehaviour,\n }}>\n {children}\n </GroupContext>\n}\n\nexport function useGroup() {\n return useContext(GroupContext)\n}\n\n// TOOD: issues if same page url on initialitems\n// TODO: the time of chaning is not perfectly the same with react-router \n// TODO: better data structure + algorithm\n// TODO: !!!! REFACTOR !!! !!! nagivation loaders !!!\nfunction useDefaultBehaviour(initialActiveItems: any[]) {\n const navigation = useNavigation();\n const [activeItems, setActiveItems] = useState(() => createItemsMap(initialActiveItems));\n\n const [, setForceUpdate] = useState(0);\n const forceUpdate = () => setForceUpdate((prev) => prev + 1);\n\n useEffect(() => {\n if (navigation.state !== 'loading') {\n setActiveItems(createItemsMap(initialActiveItems));\n forceUpdate();\n }\n }, [initialActiveItems, navigation.state]);\n\n function addItem(item: FwSidebarItemProps) {\n const key = itemId(item);\n\n setActiveItems(prev => {\n const newMap = new Map(prev);\n newMap.set(key, true);\n return newMap;\n });\n forceUpdate();\n }\n\n function deleteItem(item: FwSidebarItemProps) {\n const key = itemId(item);\n\n setActiveItems(prev => {\n const newMap = new Map(prev);\n newMap.delete(key);\n return newMap;\n });\n forceUpdate();\n }\n\n function hasItem(item: FwSidebarItemProps) {\n const key = itemId(item);\n\n return activeItems.get(key) || false;\n }\n\n return (item: FwSidebarItemProps): [boolean, () => void] => {\n return [\n hasItem(item) || false,\n () => {\n if (!hasItem(item)) {\n addItem(item);\n return;\n }\n deleteItem(item);\n }\n ]\n }\n}\n\nfunction itemId(item: FwSidebarItemProps) {\n const id = `${item.uniqIndex}:${item.groupIndex}-${item.level}-${item.itemIndex}`\n \n return id;\n}\n\nfunction createItemsMap(items: any[]): Map<string, boolean> {\n const map = new Map<string, boolean>();\n items.forEach(item => {\n const key = itemId(item);\n map.set(key, true);\n });\n return map;\n}","import { useMatches } from \"react-router\";\n\nimport { useSettings } from \"../contexts\";\n\n// TODO: better data structures\nexport function useMatchedSubNav() {\n const settings = useSettings()\n const matches = useMatches()\n\n const lastMatchId = matches[matches.length - 1]?.id\n\n let matchedSubnav = settings.navigation?.segments\n ?.find(item => item.pages?.find(page => {\n return sanitizeUrl(page.page || \"\") === sanitizeUrl(lastMatchId)\n }))\n\n if (!matchedSubnav) {\n return null\n }\n\n return matchedSubnav || null\n}\n\n\nfunction sanitizeUrl(url: string) {\n if (url.startsWith(\"/\")) {\n return url\n }\n\n return `/${url}`\n}"],"mappings":"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","names":["React","useState","useLocation","useMatches","UISidebar","Button","Icon","React","createContext","useContext","createContext","React","useContext","React","React","createContext","useContext","useState","useEffect","useNavigation","React","_a","_a","React","useMatches","useLocation","UISidebar","Icon","useState","Button"]}
|
package/package.json
CHANGED
|
@@ -1,38 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xyd-js/framework",
|
|
3
|
-
"version": "0.1.0-xyd.
|
|
3
|
+
"version": "0.1.0-xyd.115",
|
|
4
4
|
"description": "",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
|
-
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
"./package.json": "./package.json",
|
|
10
10
|
"./index.css": "./dist/index.css",
|
|
11
11
|
".": {
|
|
12
|
-
"
|
|
13
|
-
"import": "./dist/index.mjs"
|
|
12
|
+
"import": "./dist/index.js"
|
|
14
13
|
},
|
|
15
14
|
"./hydration": {
|
|
16
|
-
"
|
|
17
|
-
"import": "./dist/hydration.mjs"
|
|
15
|
+
"import": "./dist/hydration.js"
|
|
18
16
|
},
|
|
19
17
|
"./react": {
|
|
20
|
-
"
|
|
21
|
-
"import": "./dist/react.mjs"
|
|
18
|
+
"import": "./dist/react.js"
|
|
22
19
|
}
|
|
23
20
|
},
|
|
21
|
+
"files": [
|
|
22
|
+
"package.json",
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
24
25
|
"author": "",
|
|
25
26
|
"dependencies": {},
|
|
26
27
|
"peerDependencies": {
|
|
27
|
-
"react": "^
|
|
28
|
-
"react-dom": "^
|
|
29
|
-
"react-router": "^7.
|
|
30
|
-
"@xyd-js/ui": "0.1.0-xyd.
|
|
31
|
-
"@xyd-js/
|
|
32
|
-
"@xyd-js/
|
|
33
|
-
"@xyd-js/content": "0.1.0-xyd.
|
|
28
|
+
"react": "^19.1.0",
|
|
29
|
+
"react-dom": "^19.1.0",
|
|
30
|
+
"react-router": "^7.6.2",
|
|
31
|
+
"@xyd-js/ui": "0.1.0-xyd.99",
|
|
32
|
+
"@xyd-js/components": "0.1.0-xyd.94",
|
|
33
|
+
"@xyd-js/core": "0.1.0-xyd.96",
|
|
34
|
+
"@xyd-js/content": "0.1.0-xyd.97"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
37
|
+
"@types/react": "^19.1.0",
|
|
38
|
+
"@types/react-dom": "^19.1.0",
|
|
36
39
|
"@babel/preset-react": "^7.24.7",
|
|
37
40
|
"@mdx-js/rollup": "^3.0.1",
|
|
38
41
|
"@types/node": "22.5.5",
|
|
@@ -43,7 +46,7 @@
|
|
|
43
46
|
"remark-frontmatter": "^5.0.0",
|
|
44
47
|
"remark-mdx-frontmatter": "^5.0.0",
|
|
45
48
|
"typescript": "5.6.2",
|
|
46
|
-
"vite": "^
|
|
49
|
+
"vite": "^7.0.0",
|
|
47
50
|
"tsup": "^8.3.0"
|
|
48
51
|
},
|
|
49
52
|
"scripts": {
|
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
// server-only
|
|
2
|
-
|
|
3
|
-
import {Sidebar, PageFrontMatter, Settings, SidebarMulti} from "@xyd-js/core";
|
|
4
|
-
import {filterNavigationByLevels, pageFrontMatters} from "@xyd-js/content/navigation";
|
|
5
|
-
import {IBreadcrumb, INavLinks} from "@xyd-js/ui";
|
|
6
|
-
|
|
7
|
-
import {FwSidebarGroupProps} from "../react";
|
|
8
|
-
|
|
9
|
-
// TODO: framework vs content responsibility
|
|
10
|
-
|
|
11
|
-
function filterNavigation(settings: Settings, slug: string): Sidebar[] {
|
|
12
|
-
const sidebarItems: Sidebar[] = []
|
|
13
|
-
|
|
14
|
-
let multiSidebarMatch: SidebarMulti | null = null
|
|
15
|
-
|
|
16
|
-
settings?.structure?.sidebar.filter(sidebar => {
|
|
17
|
-
if ("match" in sidebar) {
|
|
18
|
-
const sideMatch = normalizeHref(sidebar.match)
|
|
19
|
-
const normalizeSlug = normalizeHref(slug)
|
|
20
|
-
|
|
21
|
-
// TODO: startWith is not enough e.g `/docs/apps/buildISSUE` if `/docs/apps/build`
|
|
22
|
-
if (normalizeSlug.startsWith(sideMatch)) {
|
|
23
|
-
if (multiSidebarMatch) {
|
|
24
|
-
const findByMatchLvl = multiSidebarMatch.match.split("/").length
|
|
25
|
-
const urlMatchLvl = sideMatch.split("/").length
|
|
26
|
-
|
|
27
|
-
if (urlMatchLvl > findByMatchLvl) {
|
|
28
|
-
multiSidebarMatch = sidebar
|
|
29
|
-
}
|
|
30
|
-
} else {
|
|
31
|
-
multiSidebarMatch = sidebar
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// TODO: better algorithm
|
|
39
|
-
const ok = filterNavigationByLevels(settings?.structure?.header || [], slug)(sidebar)
|
|
40
|
-
|
|
41
|
-
if (ok) {
|
|
42
|
-
sidebarItems.push(sidebar)
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
if (multiSidebarMatch != null) {
|
|
47
|
-
const side = multiSidebarMatch as SidebarMulti
|
|
48
|
-
sidebarItems.push(...side.items)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return sidebarItems
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// TODO: rename this because it's no longer 'navigation' because it returns breadcrumbs, sidebar and nextlinks props
|
|
55
|
-
// TODO: breadcrumbs and frontmatters as content plugins?
|
|
56
|
-
// TODO: idea - calculate breadcrumbs and navlinks near server-side component?
|
|
57
|
-
|
|
58
|
-
function normalizeHrefCheck(first: string, second: string) {
|
|
59
|
-
if (first.startsWith("/")) {
|
|
60
|
-
first = first.slice(1)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (second.startsWith("/")) {
|
|
64
|
-
second = second.slice(1)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return first === second
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function normalizeHref(href: string) {
|
|
71
|
-
if (href.startsWith("/")) {
|
|
72
|
-
return href
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return `/${href}`
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function safePageLink(page: string): string {
|
|
79
|
-
return page?.startsWith("/") ? page : `/${page}`
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// mapNavigationToProps maps @xyd-js/core navigation into @xyd-js/ui props
|
|
83
|
-
export async function mapSettingsToProps(
|
|
84
|
-
settings: Settings,
|
|
85
|
-
slug: string
|
|
86
|
-
): Promise<{
|
|
87
|
-
groups: FwSidebarGroupProps[],
|
|
88
|
-
breadcrumbs: IBreadcrumb[]
|
|
89
|
-
navlinks?: INavLinks
|
|
90
|
-
}> {
|
|
91
|
-
const filteredNav = filterNavigation(settings, slug)
|
|
92
|
-
const frontmatters = await pageFrontMatters(filteredNav)
|
|
93
|
-
|
|
94
|
-
const slugFrontmatter = frontmatters[slug] || null
|
|
95
|
-
const breadcrumbs: IBreadcrumb[] = []
|
|
96
|
-
let navlinks: INavLinks | undefined = undefined
|
|
97
|
-
|
|
98
|
-
function mapItems(
|
|
99
|
-
page: string | Sidebar,
|
|
100
|
-
currentNav: Sidebar,
|
|
101
|
-
nav: Sidebar[]
|
|
102
|
-
) {
|
|
103
|
-
if (typeof page !== "string") {
|
|
104
|
-
const items = page.pages?.map((p) => mapItems(p, page, nav))
|
|
105
|
-
|
|
106
|
-
if (items?.find(item => normalizeHrefCheck(item.href, slug))) {
|
|
107
|
-
breadcrumbs.unshift({
|
|
108
|
-
title: page.group || "",
|
|
109
|
-
href: "", // TODO:
|
|
110
|
-
})
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
title: page.group,
|
|
115
|
-
href: "",
|
|
116
|
-
active: false,
|
|
117
|
-
items,
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const matterTitle = frontmatters && frontmatters[page] && frontmatters[page].title
|
|
122
|
-
|
|
123
|
-
let title = ""
|
|
124
|
-
|
|
125
|
-
if (typeof matterTitle === "string") {
|
|
126
|
-
title = matterTitle
|
|
127
|
-
} else {
|
|
128
|
-
// @ts-ignore
|
|
129
|
-
title = matterTitle
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (!title) {
|
|
133
|
-
console.error("Title not found for page", page)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// TODO: better data structures - for example flat array of filtered nav
|
|
137
|
-
if (slugFrontmatter && (slugFrontmatter === frontmatters[page])) {
|
|
138
|
-
const nlinks = mapNavToLinks(page, currentNav, nav, frontmatters)
|
|
139
|
-
|
|
140
|
-
if (nlinks) {
|
|
141
|
-
navlinks = nlinks
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (currentNav.group) {
|
|
145
|
-
breadcrumbs.push({
|
|
146
|
-
title: currentNav.group,
|
|
147
|
-
href: "", // TODO:
|
|
148
|
-
})
|
|
149
|
-
}
|
|
150
|
-
breadcrumbs.push({
|
|
151
|
-
// @ts-ignore
|
|
152
|
-
title,
|
|
153
|
-
href: page,
|
|
154
|
-
})
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return {
|
|
158
|
-
// @ts-ignore
|
|
159
|
-
title,
|
|
160
|
-
href: safePageLink(page),
|
|
161
|
-
active: false // TODO:
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const groups = filteredNav.map((nav) => {
|
|
166
|
-
// TODO: finish
|
|
167
|
-
if ("match" in nav) {
|
|
168
|
-
return {
|
|
169
|
-
group: "",
|
|
170
|
-
items: [],
|
|
171
|
-
} as FwSidebarGroupProps
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
return {
|
|
175
|
-
group: nav.group,
|
|
176
|
-
items: nav.pages?.map((p) => {
|
|
177
|
-
// @ts-ignore
|
|
178
|
-
return mapItems(p, nav, filteredNav)
|
|
179
|
-
}) || [],
|
|
180
|
-
} as FwSidebarGroupProps
|
|
181
|
-
}) || []
|
|
182
|
-
|
|
183
|
-
return {
|
|
184
|
-
groups,
|
|
185
|
-
breadcrumbs,
|
|
186
|
-
navlinks
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function mapNavToLinks(
|
|
191
|
-
page: string | Sidebar,
|
|
192
|
-
currentNav: Sidebar,
|
|
193
|
-
nav: Sidebar[],
|
|
194
|
-
frontmatters: PageFrontMatter
|
|
195
|
-
): INavLinks | undefined {
|
|
196
|
-
if (!currentNav.group) {
|
|
197
|
-
console.error("current nav need group to calculate navlinks")
|
|
198
|
-
return
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const currentPageIndex = currentNav?.pages?.findIndex(p => page === p)
|
|
202
|
-
const foundPageIndex = currentPageIndex != undefined && currentPageIndex !== -1
|
|
203
|
-
|
|
204
|
-
if (!foundPageIndex) {
|
|
205
|
-
return
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
let prev = currentNav?.pages?.[currentPageIndex - 1]
|
|
209
|
-
let next = currentNav?.pages?.[currentPageIndex + 1]
|
|
210
|
-
|
|
211
|
-
if (prev && next) {
|
|
212
|
-
if (typeof prev !== "string" || typeof next !== "string") {
|
|
213
|
-
console.error("currently nested pages for navlinks are not supported (step 1)")
|
|
214
|
-
return
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const prevTitle = frontmatters[prev]?.title || ""
|
|
218
|
-
const nextTitle = frontmatters[next]?.title || ""
|
|
219
|
-
|
|
220
|
-
// prev and next found on same nav (pages)
|
|
221
|
-
return {
|
|
222
|
-
prev: {
|
|
223
|
-
// @ts-ignore
|
|
224
|
-
title: prevTitle,
|
|
225
|
-
href: safePageLink(prev),
|
|
226
|
-
},
|
|
227
|
-
next: {
|
|
228
|
-
// @ts-ignore
|
|
229
|
-
title: nextTitle,
|
|
230
|
-
href: safePageLink(next),
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const currentNavPosition = nav.findIndex(n => n.group === currentNav.group)
|
|
236
|
-
const foundNavIndex = currentNavPosition != undefined && currentNavPosition !== -1
|
|
237
|
-
|
|
238
|
-
if (!foundNavIndex) {
|
|
239
|
-
return
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// search prev in previous nav
|
|
243
|
-
if (!prev) {
|
|
244
|
-
const prevNav = nav[currentNavPosition - 1]
|
|
245
|
-
|
|
246
|
-
if (prevNav) {
|
|
247
|
-
const prevNavLastPge = prevNav?.pages?.[prevNav.pages.length - 1]
|
|
248
|
-
|
|
249
|
-
if (typeof prevNavLastPge != "string") {
|
|
250
|
-
console.error("currently nested pages for navlinks are not supported (step 2)")
|
|
251
|
-
} else {
|
|
252
|
-
prev = prevNavLastPge
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// search next in next nav
|
|
258
|
-
if (!next) {
|
|
259
|
-
const nextNav = nav[currentNavPosition + 1]
|
|
260
|
-
|
|
261
|
-
if (nextNav) {
|
|
262
|
-
const nextNavFirstPage = nextNav?.pages?.[0]
|
|
263
|
-
|
|
264
|
-
if (typeof nextNavFirstPage != "string") {
|
|
265
|
-
console.error("currently nested pages for navlinks are not supported (step 3)")
|
|
266
|
-
} else {
|
|
267
|
-
next = nextNavFirstPage
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
if (!prev) {
|
|
274
|
-
if (typeof next == "string") {
|
|
275
|
-
const nextTitle = frontmatters[next]?.title || ""
|
|
276
|
-
|
|
277
|
-
return {
|
|
278
|
-
next: {
|
|
279
|
-
// @ts-ignore
|
|
280
|
-
title: nextTitle,
|
|
281
|
-
href: safePageLink(next),
|
|
282
|
-
},
|
|
283
|
-
}
|
|
284
|
-
} else {
|
|
285
|
-
console.error("currently nested pages for navlinks are not supported (step 4)")
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
if (!next) {
|
|
290
|
-
if (typeof prev == "string") {
|
|
291
|
-
const nextTitle = frontmatters[prev]?.title || ""
|
|
292
|
-
|
|
293
|
-
return {
|
|
294
|
-
prev: {
|
|
295
|
-
// @ts-ignore
|
|
296
|
-
title: nextTitle,
|
|
297
|
-
href: safePageLink(prev),
|
|
298
|
-
},
|
|
299
|
-
}
|
|
300
|
-
} else {
|
|
301
|
-
console.error("currently nested pages for navlinks are not supported (step 5)")
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
if (typeof prev !== "string" || typeof next !== "string") {
|
|
306
|
-
console.error("currently nested pages for navlinks are not supported (step 6)")
|
|
307
|
-
return
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const prevTitle = frontmatters[prev]?.title || ""
|
|
311
|
-
const nextTitle = frontmatters[next]?.title || ""
|
|
312
|
-
|
|
313
|
-
return {
|
|
314
|
-
prev: {
|
|
315
|
-
// @ts-ignore
|
|
316
|
-
title: prevTitle,
|
|
317
|
-
href: safePageLink(prev),
|
|
318
|
-
},
|
|
319
|
-
next: {
|
|
320
|
-
// @ts-ignore
|
|
321
|
-
title: nextTitle,
|
|
322
|
-
href: safePageLink(next),
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
package/packages/react/README.md
DELETED