UNPKG

@flatbiz/pro-layout

Version:

WEB菜单布局

826 lines (821 loc) 25.4 kB
/// <reference types="prop-types" /> import { ModelType } from '@dimjs/model'; import { ButtonWrapperProps, ConfigProviderWrapperProps } from '@flatbiz/antd'; import { TAny, TPlainObject } from '@flatbiz/utils'; import { BreadcrumbProps, MenuProps } from 'antd'; import { MessageInstance } from 'antd/es/message/interface'; import { ModalStaticFunctions } from 'antd/es/modal/confirm'; import { NotificationInstance } from 'antd/es/notification/interface'; import { SizeType } from 'antd/lib/config-provider/SizeContext'; import { CSSProperties, ComponentType, ReactElement } from 'react'; export declare let message: MessageInstance; export declare let notification: NotificationInstance; export declare let modal: Omit<ModalStaticFunctions, "warn">; export type BreadProps = { children?: ReactElement; }; export declare const Bread: (props: BreadProps) => import("react/jsx-runtime").JSX.Element | null; export type HistoryBackProps = ButtonWrapperProps & { level?: number; }; /** * 通过面包屑路径返回 * @param props * @returns * ``` * 1. breads 模块面包屑配置 * 2. level回退级别,如果传递数据未获取到路由配置,则取上一级 * 例如:-1,-2,-3 * 3. 为什么不能使用useNavigate(-1) * 因为内部iframe和外部浏览器共用history历史记录,导致里外浏览器栈混乱 * 4. 什么场景使用 * 使用iframe tab的项目,在执行路由回退时使用 * 5. onClick返回 promise reject,则不会进行回退处理(V4.2.4) * ``` */ export declare const HistoryBackButton: (props: HistoryBackProps) => import("react/jsx-runtime").JSX.Element; export declare const useHistoryBack: (props?: { level?: number; }) => { path: string; }; export interface PageProps { loading?: boolean; className?: string; style?: CSSProperties; fullIndex?: number; bread?: JSX.Element; children?: ReactElement | ReactElement[]; elementId?: string; } /** * 页面包装组件 * ``` * 1. 如果初始化面包屑被隐藏,在特殊页面级可以独立设置显示面包屑 * <Page bread={<Bread />}/> * 2. 如果需要在 面包屑上添加按钮,初始化设置 bootstrap.hideDefaultBread = true,在需要按钮的页面上配置 * <Page bread={<Bread><Button>我是按钮</Button></Bread>}/> * ``` * @param props * @returns */ export declare const Page: (props: PageProps) => import("react/jsx-runtime").JSX.Element; export type PageWrapperServiceConfig = { onRequest: (params?: TAny) => Promise<TAny>; params?: TPlainObject | (() => TPlainObject); }; export interface PageWrapperProps extends Omit<PageProps, "children"> { /** 接口数据配置 */ serviceConfig: PageWrapperServiceConfig; /** children 为函数,参数【respData】为接口返回数据 */ children?: ReactElement | ReactElement[] | ((respData?: TAny) => ReactElement); /** * 是否异步,默认:false * ``` * true(异步):onRequest、react dom渲染同步执行 * false(同步):onRequest有结果了才渲染 react dom * ``` */ isAsync?: boolean; /** 自定义异常渲染处理 */ errorRender?: (error?: TAny) => ReactElement; } export type PageWrapperRefApi = { onRefresh: () => void; }; /** * 为Page内置接口处理流程组件,如果无全局初始化接口请求场景,请使用Page组件 * ``` * 包括 * 1. loading显示效果 * 2. error显示效果 * 3. 正常接口数据渲染 * ``` * @param props * @returns */ export declare const PageWrapper: import("react").ForwardRefExoticComponent<PageWrapperProps & import("react").RefAttributes<PageWrapperRefApi>>; export declare const usePageWrapper: () => { onReload: () => void; onRefresh: () => void; }; export interface FallbackProps { error: Error; resetErrorBoundary: (...args: Array<unknown>) => void; } export type TMenuItem = { id: string | number; name: string; path: string; link: string; target?: "_blank" | "_self"; metaTitle?: string; /** * iconImg&iconImgActive为自定义png图标 */ iconImg?: string; icon?: string; iconImgActive?: string; defaultPage?: string; parentId: null | number | string; children: TMenuItem[]; key?: string; }; export type TGlobalData = { appName: string; user: TAdminUser; menus: TMenuItem[]; apiBase: string; hostUrl: string; defaultPage?: string; routeBaseName: string; elemAclLimits: string[]; moduleName?: string; siblingProjectConfigs?: { routeBaseName: string; hostUrl: string; modules: { path: string; name: string; }[]; }[]; }; export type TAdminUser = null | { id: string; userName: string; avatar?: string; }; export type IframeTabItem = { id: string | number; link: string; name: string; metaTitle?: string; iframeKey: string; menuId?: string; pathSearch: string; }; export type BreadRouteMatchPath = { params: Readonly<Record<string, string | undefined>>; search: URLSearchParams; }; export type BreadRoutePathFn = (data: BreadRouteMatchPath) => string; export type RouteBreadConfigData = { /** * 当前面包屑UI显示名 */ name: string | (() => string); /** * 覆盖`path`如果存在,则点击跳转链接使用to, 通常情况 `path`匹配成功之后,可以指定对应的另外的 `to`来替换当前的`path`作为跳转链接. * 支持函数(match)获取计算后的动态`path` */ to?: string | BreadRoutePathFn; /** * 保留的URL query参数. 默认保留 `env` * ``` * 当 A 携带指定参数(例如id)跳转 B,当在B页面点击面包屑回到A希望携带参数id时,则A的面包屑配置为 { name:'xxx', query:['id'] } * ``` */ query?: string[]; }; export type RouteBreadConfig = RouteBreadConfigData | ((data: BreadRouteMatchPath) => RouteBreadConfigData); export type BreadConfigItem = { path: string; breadConfig: RouteBreadConfig; }; export type BreadDataItem = RouteBreadConfigData & { path: string; }; export interface TRouteItemProps { path: string; element: ReactElement | ComponentType | null; redirect?: string; caseSensitive?: boolean; /** * 面包屑配置 * ``` * 三种配置方式 * 1. 直接配置字符串 * 2. 配置对象 { name:'xxx' } * 3. 当存在父子结构的二级路由写法时,需要在此处配置数组,例如: * routeList: [ { path: '/home', element: lazy( () => import(\/* webpackChunkName: "xxx/xxx/module/chunks/home" *\/ './home') ), breadConfig: [ { path: '/', breadConfig: '首页' }, { path: '/detail', breadConfig: '详情' }, ], }] ./home 文件内容 export default () => { return ( <Routes> <Route path="/detail" element={<Detail />} /> <Route path="/" element={<Home />} /> </Routes> ); }; * ``` */ breadConfig?: string | RouteBreadConfig | { path: string; breadConfig: string | RouteBreadConfig; }[]; } export type TSidebarThemeConfig = { bgColor?: string; menuActiveBgColor?: string; menuActiveTextColor?: string; menuSelectedBgColor?: string; menuSelectedTextColor?: string; menuColor?: string; menuSubMenuBgColor?: string; menuTextFontSize?: number; menuItemHeight?: number; /** 默认值 16 */ inlineIndent?: number; }; export type THeaderThemeConfig = { bgColor?: string; textColor?: string; menuActiveBgColor?: string; menuActiveTextColor?: string; menuSelectedBgColor?: string; menuSelectedTextColor?: string; menuColor?: string; menuTextFontSize?: number; }; /** * 1. 隐藏面包屑:配置hideBreadsPathList * 2. iframe模式下,在main模块中,配置window['_iframeTabConfig'],可自定义iframeTab名称 * ``` * 例如 * window['_iframeTabConfig'] = { * '/mine': { * name: '我的信息', * }, * '/case/pool/detail': { * name: '案件池详情', * }, * }; * ``` */ export type BootstrapOptions = { className?: string; /** 是否紧凑模式 */ compact?: boolean; /** 初始化是否为dark模式 */ initDark?: boolean; /** * ``` * 1. 正常用法 * [ * { path: '/', element: <Home /> }, * { path: '/detail', element: <Detail />} * ] * * 2. 懒加载用法 * [{ * path: '/', * element: lazy(() => import(\/* webpackChunkName: "xxx/xxx/module/chunks/home" *\/ './home')), * },{ * path: '/detail', * element: lazy(() => import(\/* webpackChunkName: "xxx/xxx/module/chunks/detail" *\/ './detail')), * }] * * 3. 如果配置中没有path = '*' 或者 '/*',程序会在路由中添加 <Route path="*" element={<NotFound />} />,可自定义配置处理404页面 * 4. 如果GLOBAL中没有返回moduleName字段,path则需要添加moduleName前缀,例如: moduleName=/system/admin,则path = '/system/admin/xxx' * 5. 有问题可联系xg15472 * ``` */ routeList: TRouteItemProps[]; /** * layout模式 * ``` * 1. no-layout 无结构,常用于登录页面 * 2. iframe-main iframe main页面 * 3. iframe-tab iframe tab页面 * 4. normal 普通路由&刷新页面 * ``` */ layoutMode: "iframe-main" | "iframe-tab" | "normal" | "no-layout"; /** * 是否设置iframe多tab模式,layoutMode = 'iframe-main' 有效 * ``` * iframe-main 有两种渲染模式 * 1.单iframe tab模式 * 2.多iframe tab模式 * ``` */ multiFrameTabs?: boolean; /** * 是否禁用顶部菜单 */ disableTopbarMenu?: boolean; /** * 设置iframe模式TabBarExtra * ``` * 1. 赋值后,默认的刷新、删除Dropdown将被取消 * ``` */ iframeTabBarExtra?: JSX.Element; /** * 品牌logo尺寸:40px * ?(?不超过64) */ logoPath?: string; /** * 品牌名称 */ brandName?: string | JSX.Element; /** * 系统名称 */ systemName?: string; /** * 是否隐藏头部,默认值false */ hideHeader?: boolean; /** * 顶部结构高度。默认:64 */ headerHeight?: number; /** * @default 220 */ sidebarWidth?: number; /** * @default zhCN */ locale?: "en" | "zh-cn"; /** * iframe模式顶部菜单点击操作类型, * 1. refresh 刷新 * 2. route 路由切换 */ iframeTopbarMenuClickType?: "refresh" | "route"; /** ANTD 默认的组建尺寸,默认值:middle */ componentSize?: SizeType; /** header区域添加自定义功能 */ Header?: (() => JSX.Element) | null; /** 自定义左上角品牌区域 */ HeaderBrand?: (() => JSX.Element) | null; /** * layout内容区组件 *``` * layoutMode = 'iframe-main' 此配置无效 * layoutMode = 'iframe-tab' or 'normal'时,默认值为LayoutPage * ``` */ LayoutComponent?: ComponentType<{ style?: CSSProperties; hideHeader?: boolean; }>; /** 点击右上角默认退出登录操作 */ onSignOut?: (user: TAdminUser, hostUrl: string) => void; /** * 设置有右上角操作选项 * ``` * [ { label: '退出登录', key: '0', onClick: async () => { // }, icon: <LogoutOutlined />, }, { label: '自定义操作', key: '1', onClick: () => { // }, icon: <PieChartOutlined />, }, ] * ``` */ accountOperateMenuItems?: MenuProps["items"]; /** 面包屑起始标题 */ breadTitle?: string | ReactElement; /** 面包屑位置功能扩展 */ breadExtendRender?: ReactElement; /** 隐藏默认设置的面包屑,默认值false */ hideDefaultBread?: boolean; /** 设置全局 antd ConfigProvider */ configProviderProps?: ConfigProviderWrapperProps; /** * 配置theme后 sidebarThemeConfig 配置失效 */ sidebarMenuConfigProviderProps?: ConfigProviderWrapperProps; /** * 配置theme后 headerThemeConfig 配置失效 */ topMenuConfigProviderProps?: ConfigProviderWrapperProps; /** * 自定义header颜色 * ``` * 设置此属性后,内置的根据不同环境显示不同顶部背景色逻辑将失效 * ``` */ headerThemeConfig?: THeaderThemeConfig | { dark?: THeaderThemeConfig; light?: THeaderThemeConfig; }; /** 自定义侧边栏菜单颜色 */ sidebarThemeConfig?: TSidebarThemeConfig | { dark?: TSidebarThemeConfig; light?: TSidebarThemeConfig; }; /** 是否显示顶部菜单中收缩按键 */ showTopMenuShrink?: boolean; /** 是否隐藏侧边栏中收缩按键 */ hideSidebarShrink?: boolean; /** 初始化侧边栏为收起状态 */ initSidebarShrinkClosed?: boolean; /** 收缩按键onChange */ onShrinkChange?: (status: "open" | "close") => void; /** * 开启侧边栏鼠标悬浮打开、收起功能,一般与initSidebarShrinkClosed配合使用最佳 * ``` * 1. 鼠标悬浮侧边栏菜单打开 * 2. 鼠标离开侧边栏菜单收起 * 3. 手动点击打开侧边栏菜单,悬浮功能失效 * 4. 手动点击收起侧边栏菜单,悬浮功能生效 * ``` */ sidebarMouseHoverOpen?: boolean; /** * iframe tab点击是有刷新效果,默认:true */ iframeTabClickRefresh?: boolean; /** * 能匹配到菜单的情况下,是否隐藏菜单 * ``` * 1. disableTopbarMenu = true,该配置无效(无顶部菜单,侧边栏菜单不能隐藏) * 2. 不能通过这个属性来控制【未配置到菜单隐藏侧边栏逻辑】 * * 注意:隐藏侧边栏分为两种 * 1. 能匹配到菜单的情况下,需要隐藏菜单 * 2. 匹配不到菜单的情况下,隐藏 * ``` */ hideSidebarMenu?: boolean | ((pathname: string) => boolean); /** * 未配置到菜单情况下,是否隐藏侧边栏开关, 默认值 true/隐藏 * ``` * disableTopbarMenu = true,该配置无效(无顶部菜单,侧边栏菜单不能隐藏) * ``` */ unMatchHiddenSiderBar?: boolean; /** 收缩后侧边栏宽度,默认:80 */ collapsedWidth?: number; /** 侧边栏是否显示搜索框 */ sliderBarSearch?: boolean; /** iframeTab 页面可独立访问 */ iframeTabAloneView?: boolean; /** * ConfigProviderWrapper 内包裹层,可实现业务包裹层功能 */ containerWrapper?: ComponentType<{ children: ReactElement; }>; /** * 自定义用户名称,当前使用的是GLOBAL.user.userName字段 */ onCustomUserName?: (global: TGlobalData) => string | ReactElement; /** * 自定义用户头像,当前使用的是GLOBAL.user.avatar字段 */ onCustomUserAvatar?: (global: TGlobalData) => string | ReactElement; /** * 显示header bar菜单icon,默认不显示 */ showHeaderMenuIcon?: boolean; /** * 基本颜色配置 * ``` * 默认值: * dark: { bgColor: '#1b1a1a', blockBgColor: '#000' } * light: { bgColor: '#f9f9f9', blockBgColor: '#FFF' } * ``` */ bgColorConfig?: { dark?: { bgColor?: string; blockBgColor?: string; }; light?: { bgColor?: string; blockBgColor?: string; }; }; /** 菜单为空渲染,默认:请联系运营人员确定菜单数据配置 */ MenuEmptyRender?: ReactElement; /** 忽略菜单为空的判断 */ ignoreMenuEmptyJudge?: boolean; /** 初始化ErrorBoundary自定义异常渲染 */ ErrorFallback?: ComponentType<FallbackProps>; /** 初始化ErrorBoundary异常回调 */ onError?: (error: Error, info: { componentStack: string; }) => void; /** 初始化ErrorBoundary异常重置回调 */ onErrorReset?: (...args: any[]) => void; /** * model全局异常服务拦截,是否禁用全局异常处理 * @deprecated 已过期,判断业务中是否使用了model的全局异常拦截功能,如果没有使用可删除 */ disableErrorHandling?: boolean; /** * model全局异常服务拦截,自定义ErrorHandling * @deprecated 已过期,判断业务中是否使用了model的全局异常拦截功能,如果没有使用可删除 */ ErrorHandling?: (() => JSX.Element) | null; /** * model全局异常服务拦截,session 失效处理 * @deprecated 已过期,判断业务中是否使用了model的全局异常拦截功能,如果没有使用可删除 */ onSessionExpired?: (user: TAdminUser, hostUrl: string) => void; /** * model全局异常服务拦截,判断是否session失效,返回true则失效 * @deprecated 已过期,判断业务中是否使用了model的全局异常拦截功能,如果没有使用可删除 */ verifySessionExpired?: (err: any) => boolean; /** * sidebar菜单层级限制,层级以外的一级菜单会显示在内容区顶部 * ``` * 1. layoutMode = iframe-main && multiFrameTabs = false 有效 * 2. 效果可参考新版本find系统 * ``` */ siderBarMaxMenuLevel?: number; /** 侧边栏一级菜单是否可以多个打开,默认值: true */ siderBarFirstMenuFoldMultipleOpen?: boolean; /** 面包屑配置 */ breadcrumbProps?: Pick<BreadcrumbProps, "separator" | "className">; /** LayoutPage className属性 */ layoutPageClassName?: string; /** 取消iframe中路由地址同步至外部父窗口,在 iframe-main 中配置有效 */ cancelIframeRouteSyncParent?: boolean; /** 侧边栏菜单onChange事件 */ siderBarMenuOnChange?: (data: any) => void; /** * 隐藏面包屑 path 列表 * ``` * 1. 如果是 iframe 模式,需要在 iframe-tab 入口中配置 * ``` */ hideBreadsPathList?: string[]; /** iframeTab 激活事件 */ onIframeTabActiveEvent?: (item: TPlainObject) => void; /** iframeTab 渲染前处理函数,只有execute返回Promise.resolve()时,才会继续渲染 */ iframeTabRenderPreHook?: { execute: () => Promise<void>; /** 执行异常渲染 */ errorRender?: (data?: TPlainObject) => ReactElement; }; /** 显示生产环境的环境引导, 其他环境默认显示 */ showProdEnvGuide?: boolean; /** 开发环境环境引导配置 */ developmentEnvGuideConfigs?: { inte: string; rc: string; prod: string; }; }; export type LayoutCtxProps = { menus: TMenuItem[]; completeMenus: TMenuItem[]; siderBarMenus: TMenuItem[]; /** 平铺数组 */ siderBarTileMenus: TMenuItem[]; siderBarMenuActiveItem?: TMenuItem; topMenuActiveItem?: TMenuItem; iframeTabList: IframeTabItem[]; iframeTabActiveItem: IframeTabItem; sidebarWidth: number; componentSize: SizeType; routeList: TRouteItemProps[]; breads: BreadConfigItem[]; collapsed: boolean; onChangeCollapsed: (boo: boolean) => void; selectedKeys: string[]; opendKeys: string[]; onChangeSelectedKeys: (selectedKeys: string[]) => void; onChangeOpendKeys: (opendKeys: string[]) => void; addOrUpdateIframeTab: (item: TMenuItem) => void; onIframeChange: (id: string, type: "menuClick" | "iframeTabClick" | "iframeRefresh", options?: { locationMenu?: boolean; }) => void; /** 删除iframe tab并设置激活item */ onDeleteIframeTabItemAndSetActive: (type: "other" | "otherAll" | "all" | "me", id?: string) => void; /** 删除iframe tab,不操作激活item */ onDeleteIframeTabItem: (id: string) => void; onIframeChangeByHttpUrl: (url: string, options?: { name?: string; metaTitle?: string; }, targetIndex?: number) => void; onUpdateIframeTabName: (name: string) => void; normalModePositionMenu: (link: string) => void; iframeTopRouteMenuChange: (item: TMenuItem) => void; hideSidebarMenu?: boolean; /** 关闭当前iframe tab并打开指定iframe tab */ onDeleteCurrentIframeTabItemOpenTargetIframeTab: (id: string | number, menuId?: string | number) => void; /** 通过新iframe tab打开第三方菜单页面 */ onOpenNewIframeThirdMenuItem: (data: { menuItem: TMenuItem; link: string; name: string; }) => void; headerThemeConfig?: THeaderThemeConfig; sidebarThemeConfig?: TSidebarThemeConfig; onChangeActiveTabItemRedDot: (visible: boolean) => void; redDotMap: Record<string, boolean>; } & Omit<BootstrapOptions, "sidebarWidth" | "componentSize" | "locale" | "hideSidebarMenu" | "headerThemeConfig" | "sidebarThemeConfig">; export interface LeaveMenuProps { leaveMenus?: TMenuItem[]; selectedKeys?: string[]; } /** * ``` * 1. 外部针对出现 iframe tab标题为未知页面的配置、或者想修改二级页面tab标题的,在main模块中设置 * window['_iframeTabConfig'] = { * '/system-get/menu3/detail': { * name: '详情', * }, * }; * 2. 在后续版本中会废弃`全局拦截model异常处理功能`,废弃ErrorHandling、onSessionExpired、verifySessionExpired三个属性的使用 * ``` */ export declare const bootstrap: (options: BootstrapOptions) => void; /** * iframe tab 注册刷新方法 * ``` * 1. 定义refreshKey唯一值 * 2. 与 useRefreshRegisterIframeTab 结合实现iframe tab之间的刷新动作 * ``` */ export declare const useRegisterRefreshCurrentIframeTab: (refreshKey: string, onRefresh: (params?: TPlainObject) => Promise<void>) => void; /** * 根据 refreshKey,刷新指定iframe tab(在iframe tab中调用) * ``` * 1. 使用 useRegisterRefreshCurrentIframeTab 定义的refreshKey * 2. 可通过 params 给刷新方法传参 * ``` * @returns */ export declare const useRefreshRegisterIframeTab: () => (refreshKey: string, params?: TPlainObject) => void; /** * iframe tab 激活回调 * ``` * 1. 首次激活执行 callback,isFirst 为 true * ``` */ export declare const useIframeTabActive: (callback: (isFirst: boolean) => void) => void; export type IframeHandler<T = unknown> = (data: T) => void; /** * iframe通信Demo:https://fex.qa.tcshuke.com/docs/admin/main/exchange */ export type IframeApiProps = { /** 广播消息到所有的iframes子页面 */ broadcastMessages: <T>(data: T) => IframeApiProps; /** 发送特定消息到父亲级window对象 */ postMessage: <T>(data: T) => IframeApiProps; /** 打开新的iframe tab窗口 */ openNewTabItem: (data: { link: string; name: string; metaTitle?: string; }, /** 是否关闭当前iframe tab */ isClosed?: boolean) => IframeApiProps; /** * 通过新iframe tab打开第三方页面 * * ``` * 在第三方项目中触发在iframe main打开新tab,方法如下(案例:大数据-数据服务平台) const openNewTabItem = ( menuItem: { id: string; link: string; name: string }, ) => { if (menuItem?.id) { window.parent.postMessage( JSON.stringify({ type: 'FLATBIZ-LAYOUT', data: { type: 'redirect_to_frame_layout_menu_third_item', data: { menuId: menuItem.id, options: { link: menuItem.link, name: menuItem.name, }, }, }, }), '*' ); } else { message.error(`未查询到菜单数据`); } }; * ``` */ openNewThirdTabItem: (menuId: string | number, options: { link: string; name: string; }) => IframeApiProps; /** 打开新的浏览器窗口 */ openBrowserWindow: (url: string) => IframeApiProps; /** 刷新当前iframe tab */ locationHref: (url: string) => IframeApiProps; /** iframe tab路由变更,可修改当前url地址(不会重新刷新当前页面) */ tabItemHistoryChange: (link: string) => IframeApiProps; /** 通过菜单Id打开新的iframe tab窗口 */ openNewTabItemByMenuId: (id: string) => IframeApiProps; /** 关闭当前iframe-tab,跳转上一个链路tab */ closedIframeTabToPrevlink: () => IframeApiProps; /** 当前tabItem小红点实现切换 */ tabItemRedDotToggle: (visible: boolean) => void; /** * iframeTab操作 * ``` * 1. removeOther - 移除其他iframe-tab * 2. removeAll - 移除所有iframe-tab * 3. removeMe - 移除当前iframe-tab * 4. refreshMe - 刷新当前iframe-tab * ``` */ iframeTabOperation: (type: "removeOther" | "removeAll" | "removeMe" | "refreshMe") => void; /** 判断是否在iframe中 */ isInIframe: () => boolean; /** 判断iframe链路上一级是否存在 */ isExistPrevLink: () => boolean; /** 更新菜单徽标 */ updateMenuBadge: (data: { menuLink: string; badgeCount: number; }[]) => void; }; /** * 使用Iframe通讯的API * @param onReceivedMessageCallback 接收iframe通讯消息的回调函数引用 * @demo https://fex.qa.tcshuke.com/docs/admin/main/exchange * @example * ```tsx * const iframeApi = useIframe<MessageData>((data) => { * updateMessage(data); * }); * * const handleClick = hooks.useCallbackRef(() => { * iframeApi.broadcastMessages({ * fromHeader: '1', * }); * }); * * ``` */ export declare const useIframe: <T>(onReceivedMessageCallback?: IframeHandler<T>) => IframeApiProps; export declare const LayoutPage: (props: { style?: CSSProperties; children?: ReactElement; hideHeader?: boolean; elementId?: string; className?: string; showDevFloatHelp?: boolean; showProdEnvGuide: BootstrapOptions["showProdEnvGuide"]; developmentEnvGuideConfigs: BootstrapOptions["developmentEnvGuideConfigs"]; }) => import("react/jsx-runtime").JSX.Element; export type IState = { isDark?: boolean; }; export type ActionParams = { onSetTheme: "dark" | "light"; }; export declare const ProLayoutModel: ModelType<IState, ActionParams>; export declare const proLayoutModels: import("@dimjs/model").APIs<{ ProLayoutModel: ModelType<IState, ActionParams>; }>; /** * 获取iframeTab下的唯一值,iframeTab未删除时,唯一值不变,iframeTab删除后再打开,唯一值变化 */ export declare const getIframeTabUid: (prefix: string) => string; export interface MenuPubSubMap { changeMenuBadge: { menuLink: string; badgeCount: number; }[]; } export type IframeMainEvent = keyof MenuPubSubMap; export declare const menuPubSub: { /** 发布 */ publish<K extends IframeMainEvent>(event: K, data: MenuPubSubMap[K]): void; /** 订阅 */ subscribe<K extends IframeMainEvent>(event: K, callback: (data: MenuPubSubMap[K]) => void): void; /** 取消订阅 */ unsubscribe<K extends IframeMainEvent>(event: K, callback: (data: MenuPubSubMap[K]) => void): void; }; export {};