jamis
Version:
一种支持通过JSON配置方式生成页面的组件库
432 lines (431 loc) • 13.4 kB
TypeScript
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<string, any>, store: IAppStore) => Promise<SchemaCollection>;
/**
* 是否嵌套在父路由里
*/
nested?: boolean;
/**
* 支持多层级。
*/
children?: Array<AppRouter>;
/** 是否默认展开, 只对有非叶子节点有效, 默认不展开 */
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> | 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<AppSchema, 'type' | 'className' | 'data'> {
children?: JSX.Element | ((props?: any) => JSX.Element);
store: IAppStore;
aside: Required<AppSchema>['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<NavigationObject>;
/**
* 父路由是否可以展开/收起
*/
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<HTMLAnchorElement>) => void;
/**
* 展开父项的函数, 如果不传, 表示默认全部展开, 无法收缩
*/
toggleExpand?: (link: LinkItem, e?: React.MouseEvent<Element, 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<LinkItem>;
path?: string;
target?: '_self' | '_blank' | '_parent' | '_top';
icon?: string;
visible?: boolean;
badge?: string;
badgeClassName?: SchemaClassName;
component?: React.ComponentType;
collapsable?: boolean;
}