import type { ActionObject, PickClassStyleType, ReactPropsBase, RendererProps, SchemaBoolean, SchemaClassName, SchemaExpression } from 'jamis-core'; import type { CSSProperties, ReactNode } from 'react'; import type React from 'react'; import type { Location } from 'history'; import type { BaseSchemaScoped, BaseSchemaWithoutType, SchemaApi, SchemaCollection, SchemaObject, SchemaSlots, TourConfig } from '../types'; import type { IAppStore } from './AppStore'; export interface RouterHook { /** * 检查是否拦截, `true`表示要拦截, 执行failback逻辑; `false`代表放过 */ checkExpression: SchemaBoolean; /** 拦截后发起的动作 */ failbackAction?: ActionObject | ActionObject[]; /** * 是否停止渲染路由的schema, 默认是 true. * 当你配置了failbackAction, 而没有配置 failbackSchema时, 阻止schema的渲染 */ stopRender?: boolean; /** 拦截后使用的schema */ failbackSchema?: SchemaObject; } export interface AppRouter { /** * 菜单文字 */ label?: string; /** * 菜单图标,比如: FileOutlined */ icon?: string; /** * 路由规则, 比如:/banner/:id。当地址以 / 打头,则不继承上层的路径,否则将集成父级页面的路径。 * 也可以是外部链接 */ url?: string; /** * 单纯的地址。可以设置外部链接。 */ link?: string; /** * 当url或者link是绝对地址时, 设置打开策略 */ target?: '_self' | '_blank' | '_parent' | '_top'; /** * 当match url 时跳转到目标地址.没有配置 schema 和 shcemaApi 时有效. */ redirect?: string; /** * 当match url 转成渲染目标地址的页面.没有配置 schema 和 shcemaApi 时有效. */ rewrite?: string; /** * 不要出现多个,如果出现多个只有第一个有用。在路由找不到的时候作为默认页面。 */ isDefaultPage?: boolean; /** * 二选一,如果配置了 url 一定要配置。否则不知道如何渲染。 */ schema?: SchemaCollection; schemaApi?: SchemaApi; /** * 页面schema提供者, 和前面的schema/schemaApi互斥, 优先级从前往后 * @deprecated 请使用`schemaApi.fetcherProvider`来替代 */ schemaProvider?: (data: Record, store: IAppStore) => Promise; /** * 是否嵌套在父路由里 */ nested?: boolean; /** * 支持多层级。 */ children?: Array; /** 是否默认展开, 只对有非叶子节点有效, 默认不展开 */ initialOpen?: boolean; /** * 菜单上的类名 */ className?: SchemaClassName; /** * 是否在导航中可见,适合于那种需要携带参数才显示的页面。比如具体某个数据的编辑页面。 */ visible?: boolean; visibleOn?: SchemaBoolean; /** 是否隐藏导航栏 */ hideAsideNav?: boolean; hideAsideNavOn?: SchemaBoolean; /** * 默认是自动,即:自己选中或者有孩子节点选中则展开。 * 如果配置成 always 或者配置成 true 则永远展开。 * 如果配置成 false 则永远不展开。 */ /** 内部使用, 不可在schema里使用, 使用`url` */ path?: string; /** 内部使用, 暂时似乎无用 */ index?: number; /** 路由唯一id, 未指定时使用guid */ id?: string; /** * 路由的hooks配置 */ hooks?: Record<'beforeEnter', RouterHook | RouterHook[]>; /** * 运行后有效的beforeEnter hook */ __activeHookBeforeEnter?: RouterHook; /** 是否可以收缩起来, 只对父路由有用, 默认是`true` */ collapsable?: boolean; [key: string]: any; } /** * @deprecated 请使用 AppRouter 替代 */ export type AppPage = AppRouter; /** * App 组件,适合 JSSDK 用来做多页渲染。 * */ export interface AppSchema extends BaseSchemaScoped, AppSchemaDeprecated { /** * 指定为 app 类型。 */ type: 'app'; api?: SchemaApi; slots?: SchemaSlots< /** 整个导航头 */ 'Layout-header' /** LOGO区域 */ | 'Layout-logo' /** 导航头中右侧区域 */ | 'Layout-headerBar' /** 品牌链接位 */ | 'Layout-brandLink' /** 品牌名 */ | 'Layout-brandName' /** 左侧边栏前置区域 */ | 'App-asideBefore' /** 左侧边栏后置区域 */ | 'App-asideAfter' /** 路由页面的页脚 */ | 'Layout-footer' | (string & {})>; /** * 系统名称 */ brandName?: SchemaCollection | SchemaExpression; /** * brand点击跳转的url */ brandLink?: SchemaExpression; /** * 页面集合。 */ pages?: Array | AppRouter; /** * 显示面包屑路径。 * @deprecated 请使用`slots.AppBcn.className = 'hidden'`来替代 */ showBreadcrumb?: boolean; /** @deprecated 请使用`slots.AppBcn.className = 'hidden'`来替代 */ showBreadcrumbOn?: SchemaExpression; /** * 显示面包屑完整路径。 */ showFullBreadcrumbPath?: boolean; showFullBreadcrumbPathOn?: SchemaBoolean; /** * 显示面包屑首页路径。 */ showBreadcrumbHomePath?: boolean; showBreadcrumbHomePathOn?: boolean; /** * 父路由只是展开, 不去跳转 */ parentToggleExpand?: boolean; tour?: boolean; tourOn?: SchemaBoolean; tourConfig?: TourConfig; } export interface AppSchemaDeprecated { /** * brand的样式类名 * @deprecated 请使用`slots.Layout-brand.className`替代 */ brandClassName?: SchemaClassName; /** * @deprecated 请使用`slots.Layout-brandName.className`替代 */ brandNameClassName?: SchemaClassName; /** * @deprecated 请使用`slots.Layout-brandLink.className`替代 */ brandLinkClassName?: SchemaClassName; /** * logo 图片地址,可以是 svg。 * @deprecated 请使用`slots.Laylout-logo.body`替代 */ logo?: string; /** * 顶部区域 * @deprecated 请使用`slots.Layout-header.body` */ header?: SchemaCollection; /** * 元素`.cxd-Layout-header`的样式类 * @deprecated 请使用`slots.Layout-header.className`替代 */ headerClassName?: SchemaClassName; /** * @deprecated 请使用`slots.Layout-headerBar.className`替代 */ headerBarClassName?: SchemaClassName; /** * 内容区(包括aside)样式类名 * @deprecated 请使用`slots.Layout-content.className`替代 */ contentClassName?: SchemaClassName; /** * @deprecated 请使用`slots.Layout-content.style`替代 */ contentStyle?: React.CSSProperties; /** * 内容体部分(不包括aside)样式类名 * @deprecated 请使用`slots.Layout-body.className`替代 */ bodyClassName?: SchemaClassName; /** * @deprecated 请使用`slots.Layout-body.style`替代 */ bodyStyle?: React.CSSProperties; /** * 边栏 * * @deprecated 使用`slots`来替代 */ aside?: { /** * 是否展示 * @deprecated 请使用`slots.Layout-aside.className='hidden'`来替代 */ visible?: SchemaBoolean; /** * @deprecated 请使用`slots.Layout-aside.className='hidden'`来替代 */ visibleOn?: SchemaExpression; /** * 边栏菜单前面的区域 * @deprecated 使用`slots.App-asideBefore`来替代 */ beforeRegion?: SchemaCollection; /** * 边栏菜单后面的区域 * @deprecated 使用`slots.App-asideAfter`来替代 */ afterRegion?: SchemaCollection; /** * 边栏菜单的样式类 * @deprecated 请使用`slots.Layout-aside.className`替代 */ className?: SchemaClassName; /** @deprecated 请使用`slots.Layout-aside.style`替代 */ style?: CSSProperties; /** * @deprecated 请使用`slots.AsideNav.className`替代 */ navClassName?: SchemaClassName; /** * @deprecated 请使用`slots.AsideNav.style`替代 */ navStyle?: CSSProperties; /** * 子菜单列表样式类 * @deprecated 请使用`slots.AsideNav-subList.className`替代 */ subListClassName?: SchemaClassName; /** * 边栏菜单项的样式类 * @deprecated 请使用`slots.AsideNav-link.className`替代 */ linkClassName?: SchemaClassName; /** * 是否显示收起/展开按钮, 默认是 true * @deprecated 请使用`slots.App-foldBtn.className='hidden'`来隐藏 */ showFoldBtn?: boolean; /** * @deprecated 请使用`slots.App-foldBtn.className`替代 */ foldBtnClassName?: SchemaClassName; }; /** * 所有路由页面的公共样式类 * @deprecated 请使用`slots.App-page.className`替代 */ pageClassName?: SchemaClassName; /** * 所有路由页面的公共样式 * @deprecated 请使用`slots.App-page.style`替代 */ pageStyle?: CSSProperties; /** * 底部区域。 * * @deprecated 请使用`slots.Layout-footer.body`替代 */ footer?: SchemaCollection; /** * @deprecated 请使用`slots.Layout-footer.className`替代 */ footerClassName?: SchemaClassName; /** * @deprecated 请使用`slots.AppBcn.className`替代 */ breadcrumbClassName?: SchemaClassName; /** * 移动端下的左右抽屉的样式类 * @deprecated 请使用`slots.App-navDrawer.className`替代 */ navDrawerClassName?: SchemaClassName; /** * 移动端下的左右抽屉内容区的样式类 * @deprecated 请使用`slots.App-navDrawer-content.className`替代 */ navDrawerContentClassName?: SchemaClassName; /** * 控制是否显示菊花 * @deprecated 请使用`slots.App-spinner.className = 'hidden'`来替代 */ showLoading?: boolean; /** @deprecated 请使用`slots.App-spinner.className = 'hidden'`来替代 */ showLoadingOn?: SchemaExpression; } /** * 路由占位组件 */ export interface AppRouterSchema extends BaseSchemaWithoutType { type: 'app-router'; routerId: string; } export interface AppProps extends RendererProps, Omit { children?: JSX.Element | ((props?: any) => JSX.Element); store: IAppStore; aside: Required['aside']; location?: Location; } export interface AppRouterProps extends RendererProps, AppRouterSchema { routerId: string; } export interface AsideNavProps extends ReactPropsBase, PickClassStyleType { id?: string; /** * @deprecated 请使用`slots.className` */ subListClassName?: SchemaClassName; /** 是否收缩起来 */ folded?: boolean; navigations: Array; /** * 父路由是否可以展开/收起 */ expandable?: boolean; /** * 父路由初始展开层级 */ expandInitialLevel?: number; renderLink: (item: { link: LinkItem; key: string | number; toggleExpand?: (link: LinkItem, e?: React.MouseEvent) => void; depth?: number; }) => ReactNode; /** * 是否选中 */ checkIsActive: (link: LinkItem) => boolean | undefined; checkIsOpen: (link: LinkItem) => boolean; } export interface AsideNavLinkProps extends PickClassStyleType { folded?: boolean; link: LinkItem; depth: number; key: string | number; /** * 父路由只是展开, 不去跳转。 */ parentToggleExpand?: boolean; linkClassName?: SchemaClassName; filterClassName: (className: SchemaClassName) => string | undefined; /** * 渲染出内部的路由链接, 为了兼容examples里使用react-router的场景. * 此时不需要设置`onNavClick` */ renderRouterLink?: (linkClassName: string, children: JSX.Element[]) => JSX.Element; /** * 内部路由点击跳转逻辑, 当透传renderRouterLink时可以不用传递 */ onNavClick?: (e: React.MouseEvent) => void; /** * 展开父项的函数, 如果不传, 表示默认全部展开, 无法收缩 */ toggleExpand?: (link: LinkItem, e?: React.MouseEvent | undefined) => void; } export interface NavigationObject { label: string; children?: LinkItem[]; prefix?: JSX.Element; affix?: JSX.Element; className?: SchemaClassName; path?: string; initialOpen?: boolean; active?: boolean; open?: boolean; visible?: boolean; [propName: string]: any; } export interface LinkItem { id?: number; label: string; hidden?: boolean; open?: boolean; active?: boolean; className?: SchemaClassName; children?: Array; path?: string; target?: '_self' | '_blank' | '_parent' | '_top'; icon?: string; visible?: boolean; badge?: string; badgeClassName?: SchemaClassName; component?: React.ComponentType; collapsable?: boolean; }