UNPKG

@flatbiz/layout

Version:

WEB菜单布局

328 lines (324 loc) 9.24 kB
/// <reference types="node" /> /// <reference types="prop-types" /> /// <reference types="scheduler" /> import { ButtonProps } from 'antd'; import { SizeType } from 'antd/lib/config-provider/SizeContext'; import { Locale } from 'antd/lib/locale-provider'; import { CSSProperties, ComponentType, FC, ReactElement } from 'react'; export interface AclProps { /** 标识当前组件的唯一性 */ aclName: string; children?: ReactElement; } export declare const isElemVisible: (elemAclLimits: string[], aclName: string) => boolean; export declare const Acl: ({ children, aclName }: AclProps) => JSX.Element | null; export declare type BreadRoutePathFn = (data: BreadRouteMatchPath) => string; export interface BreadRoute { /** * 当前面包屑UI显示名 */ name: string | (() => string); /** * Path 匹配,字符串,匹配URL路径 */ path: string; /** * 覆盖`path`如果存在,则点击跳转链接使用to, 通常情况 `path`匹配成功之后,可以指定对应的另外的 `to`来替换当前的`path`作为跳转链接. * 支持函数(match)获取计算后的动态`path` */ to?: string | BreadRoutePathFn; /** * 保留的URL query参数. 默认保留 `env` */ query?: string[]; } export declare type BreadsData = AppBreads | ((data: BreadRouteMatchPath) => AppBreads); export interface AppBreads { [index: string]: BreadRoute[]; } export declare type BreadRouteMatchPath = { params: Readonly<Record<string, string | undefined>>; search: URLSearchParams; }; export interface ModuleMenu { id: string | number; name: string; path?: string; link: string | null; sort?: number; target?: "_blank" | "_self" | null; metaTitle?: string; /** * iconImg&iconImgActive为自定义png图标 */ iconImg?: string; iconImgActive?: string; routeBaseName?: string; defaultPage?: string; parentId: null | number | string; children: ModuleMenu[]; } export declare type GlobalData = { appName?: string; user: AdminUser; menus: ModuleMenu[]; apiBase: string; hostUrl: string; defaultPage?: string; routeBaseName: string; elemAclLimits: string[]; }; export declare type AdminUser = null | { id: string; userName: string; emailAddress: string; }; export interface FallbackProps { error: Error; resetErrorBoundary: (...args: Array<unknown>) => void; } export declare type BootstrapOptions = { /** * 品牌logo尺寸:40px * ?(?不超过64) */ logoPath?: string; /** * 品牌名称 */ brandName?: string | JSX.Element; /** * 是否隐藏头部,默认值false */ hideHeader?: boolean; /** * @default 220 */ sidebarWidth?: number; /** * @default zhCN */ locale?: Locale; /** * 是否禁用顶部菜单 */ disableTopbarMenu?: boolean; /** * ANTD 默认的组建尺寸 */ componentSize?: SizeType; /** * 仅仅针对`LayoutFrame`有效 */ multiFrameTabs?: boolean; Footer?: (() => JSX.Element) | null; Header?: (() => JSX.Element) | null; HeaderBrand?: ((props: { logoPath?: string; }) => JSX.Element) | null; LayoutComponent?: ComponentType<{ style?: CSSProperties; }>; ErrorFallback?: ComponentType<FallbackProps>; /** * 是否禁用全局异常处理 * 如果未设置ErrorHandling,则走默认ErrorHandling逻辑 */ disableErrorHandling?: boolean; /** * 自定义ErrorHandling */ ErrorHandling?: (() => JSX.Element) | null; onError?: (error: Error, info: { componentStack: string; }) => void; onErrorReset?: (...args: any[]) => void; onSignOut?: (user: AdminUser, hostUrl: string) => void; AccountOperateMenus?: (() => JSX.Element) | null; onSessionExpired: (user: AdminUser, hostUrl: string) => void; verifySessionExpired: (err: any) => boolean; /** * 当sidebar菜单有level限制时,限制数目 */ leaveMenuLevel?: number; LeaveMenu?: ((props: LeaveMenuProps) => JSX.Element) | null; /** * 面包屑起始标题 */ breadTitle?: string | JSX.Element; /** * 面包屑位置功能扩展 */ breadExtendRender?: JSX.Element; /** * 隐藏默认设置的面包屑,默认值false */ hideDefaultBread?: boolean; headerThemeConfig?: { bgColor?: string; activeBgColor?: string; color?: string; activeColor?: string; }; sidebarThemeConfig?: { bgColor?: string; menuActiveBgColor?: string; menuSelectedBgColor?: string; color?: string; activeColor?: string; /** * 默认值 16 */ inlineIndent?: number; }; /** * 设置iframe模式TabBarExtra * ``` * 1. 赋值后,默认的刷新、删除Dropdown将被取消 * ``` */ iframeTabBarExtra?: JSX.Element; /** *是否显示顶部菜单中收缩按键 */ showTopMenuShrink?: boolean; /** * 是否隐藏侧边栏中收缩按键 */ hideSidebarShrink?: boolean; }; export declare type LayoutCtxProps = { breads: BreadsData; sidebarWidth: number; componentSize: SizeType; locale: Locale; routeConfig: RouteConfig; } & Omit<BootstrapOptions, "sidebarWidth" | "componentSize" | "locale">; export interface LeaveMenuProps { leaveMenus?: ModuleMenu[]; selectedKeys?: string[]; } export interface RouteItemProps { path: string; element: (props: any) => ReactElement | null; redirect?: string | false; caseSensitive?: boolean; } export interface ModuleItemProps { path: string; redirect: string | false; /** * allow use use lazy import(``) with webpack `webpackChunkName` */ module: ComponentType | null; caseSensitive?: boolean; } export declare class RouteConfig { private flattenTree; private flattenTreePaths; private modules; private routeBaseName; constructor(modules: ModuleItemProps[]); findOneByBestMatchedRequestUrlPath(reqPath: string, ignorePath: string): string | undefined; get routes(): RouteItemProps[]; } export declare const bootstrap: (routeConfig: RouteConfig, breads: BreadsData, options: BootstrapOptions, callback?: () => void) => void; export declare const Bread: (props: any) => JSX.Element | null; export declare type HistoryBackProps = { breads: BreadsData; level?: number; }; /** * 路由返回,依赖面包屑配置 * @param props * @returns * ``` * 1. breads 模块面包屑配置 * 2. level回退级别,如果传递数据未获取到路由配置,则取上一级 * 例如:-1,-2,-3 * 3. 为什么不能使用useNavigate(-1) * 因为内部iframe和外部浏览器共用history历史记录,导致里外浏览器栈混乱 * 4. 什么场景使用 * 使用iframe tab的项目,在执行路由回退时使用 * ``` */ export declare const HistoryBackButton: (props: HistoryBackProps & ButtonProps) => JSX.Element; export declare const useHistoryBack: (props: HistoryBackProps) => { path: string; }; export declare const LeaveMenuDefault: (props: LeaveMenuProps) => JSX.Element; export declare type LoaderProps = { spinning?: boolean; fullScreen?: boolean; style?: CSSProperties; inner?: boolean; }; export declare const Loader: ({ spinning, fullScreen, style }: LoaderProps) => JSX.Element; export interface PageProps { loading?: boolean; className?: string; style?: CSSProperties; fullIndex?: number; bread?: JSX.Element; children?: ReactElement | ReactElement[]; } export declare const Page: (props: PageProps) => JSX.Element; export declare const layoutContext: { useLayoutCtx: () => LayoutCtxProps; }; export declare type UseBreadRoute = { path: string; name: string; query: Record<string, string>; }; export declare const useBread: (breads: BreadsData, routeBaseName: string) => UseBreadRoute[]; export declare type IframeHandler<T = unknown> = (data: T) => void; /** * 使用Iframe通讯的API * @param onReceivedMessageCallback 接收iframe通讯消息的回调函数引用 * @example * ```tsx * const iframeApi = useIframe<MessageData>((data) => { * console.log('onMainMessageReceived', data.name); * updateMessage(data); * }); * * const handleClick = hooks.useCallbackRef(() => { * iframeApi.broadcastMessages({ * fromHeader: '1', * }); * }); * * ``` * @returns */ export declare const useIframe: <T>(onReceivedMessageCallback?: IframeHandler<T>) => { broadcastMessages<T_1>(data: T_1): any; postMessage<T_2>(data: T_2): any; openNewTabItem(data: { link: string; name: string; metaTitle?: string | undefined; }): any; openBrowserWindow(url: string): any; locationHref(url: string): any; }; /** * 用来处理, 当前URL state动态改变的时候, 我们需要reload菜单, 因为URL状态 Browserhash状态更改可能通过代码动态触发 */ export declare const useLayoutHistory: () => void; export declare const useMobileDetect: () => boolean; export declare const LayoutIFrame: FC; export declare const LayoutNormal: (props: any) => JSX.Element; export declare const LayoutPage: (props: { style?: CSSProperties; children: ReactElement; }) => JSX.Element; export declare const utils: { ensureSlash: (str: string, slashEndfix?: boolean) => string; isHttpUri: (uri?: string | undefined) => boolean; toLinkPath: (path?: string | null | undefined, query?: Record<string, any>) => string; toLinkPathWithQuery: (path?: string | null | undefined, query?: Record<string, any>) => string; urlJoin: (first: string, second: string) => string; menuRouteFilter: (routes: RouteItemProps[]) => RouteItemProps[]; }; export {};