UNPKG

jamis

Version:

一种支持通过JSON配置方式生成页面的组件库

352 lines (351 loc) 10 kB
import type { ActionObject, BaseSchemaScoped, BaseSchemaWithoutType, 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 { SchemaApi, SchemaCollection, SchemaObject, 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: JSObject, store: IAppStore) => Promise<SchemaCollection>; /** * 是否嵌套在父路由里 */ nested?: boolean; /** * 支持多层级。 */ children?: Array<AppRouter>; /** 是否默认展开, 只对有非叶子节点有效, 默认不展开 */ initialOpen?: boolean; /** * 菜单上的类名 */ className?: SchemaClassName; /** * 是否在导航中可见,适合于那种需要携带参数才显示的页面。比如具体某个数据的编辑页面。 */ visible?: boolean; /** * 默认是自动,即:自己选中或者有孩子节点选中则展开。 * 如果配置成 always 或者配置成 true 则永远展开。 * 如果配置成 false 则永远不展开。 */ /** 内部使用, 不可在schema里使用, 使用`url` */ path?: string; /** 内部使用, 暂时似乎无用 */ index?: number; /** 路由唯一id, 未指定时使用guid */ id?: string; /** * 路由的hooks配置 */ hooks?: Record<'beforeEnter', RouterHook | RouterHook[]>; /** * 运行后有效的beforeEnter hook */ __activeHookBeforeEnter?: RouterHook; [key: string]: any; } /** * @deprecated 请使用 AppRouter 替代 */ export type AppPage = AppRouter; /** * App 渲染器,适合 JSSDK 用来做多页渲染。 * */ export interface AppSchema extends BaseSchemaScoped { /** * 指定为 app 类型。 */ type: 'app'; api?: SchemaApi; /** * 系统名称 */ brandName?: SchemaCollection; /** * brand的样式类名 */ brandClassName?: SchemaClassName; /** * brand点击跳转的url */ brandLink?: string; brankLinkClassName?: SchemaClassName; /** * logo 图片地址,可以是 svg。 */ logo?: string; /** * 顶部区域 */ header?: SchemaCollection; /** * 元素`.cxd-Layout-header`的样式类 */ headerClassName?: SchemaClassName; headerBarClassName?: SchemaClassName; /** * 内容区(包括aside)样式类名 */ contentClassName?: SchemaClassName; contentStyle?: React.CSSProperties; /** * 内容体部分(不包括aside)样式类名 */ bodyClassName?: SchemaClassName; bodyStyle?: React.CSSProperties; /** * 边栏 */ aside?: { /** * 是否展示 */ visible?: SchemaBoolean; visibleOn?: SchemaExpression; /** * 边栏菜单前面的区域 */ beforeRegion?: SchemaCollection; /** * 边栏菜单后面的区域 */ afterRegion?: SchemaCollection; /** * 边栏菜单的样式类 */ className?: SchemaClassName; style?: CSSProperties; navClassName?: SchemaClassName; navStyle?: CSSProperties; /** * 子菜单列表样式类 */ subListClassName?: SchemaClassName; /** * 边栏菜单项的样式类 */ linkClassName?: SchemaClassName; /** * 是否显示收起/展开按钮, 默认是 true */ showFoldBtn?: boolean; foldBtnClassName?: SchemaClassName; }; /** * 页面集合。 */ pages?: Array<AppRouter> | AppRouter; /** * 所有路由页面的公共样式类 */ pageClassName?: SchemaClassName; /** * 所有路由页面的公共样式 */ pageStyle?: CSSProperties; /** * 底部区域。 */ footer?: SchemaCollection; footerClassName?: SchemaClassName; /** * css 类名。 */ className?: SchemaClassName; /** * 显示面包屑路径。 */ showBreadcrumb?: boolean; showBreadcrumbOn?: SchemaExpression; /** * 显示面包屑完整路径。 */ showFullBreadcrumbPath?: boolean; showFullBreadcrumbPathOn?: SchemaBoolean; /** * 显示面包屑首页路径。 */ showBreadcrumbHomePath?: boolean; showBreadcrumbHomePathOn?: boolean; breadcrumbClassName?: SchemaClassName; /** * 父路由只是展开, 不去跳转 */ parentToggleExpand?: boolean; /** * 控制是否显示菊花 */ showLoading?: boolean; showLoadingOn?: SchemaExpression; /** * 移动端下的左右抽屉的样式类 */ navDrawerClassName?: SchemaClassName; /** * 移动端下的左右抽屉内容区的样式类 */ navDrawerContentClassName?: SchemaClassName; tour?: boolean; tourOn?: SchemaBoolean; tourConfig?: TourConfig; } /** * 路由占位组件 */ 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; headerClassName?: string; contentClassName?: string; bodyClassName?: string; breadcrumbClassName?: string; footerClassName?: string; pageClassName?: string; aside: Required<AppSchema>['aside']; location?: Location; } export interface AppRouterProps extends RendererProps, AppRouterSchema { routerId: string; } export interface AsideNavProps extends ReactPropsBase { id?: string; 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 { 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; [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; }