This commit is contained in:
2026-09-22 16:04:51 +08:00
parent b9e401af4f
commit 1726a18093
27 changed files with 2469 additions and 1835 deletions
Vendored
+146 -87
View File
@@ -1,5 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { ReactNode } from 'react';
import { PopupContainerProps } from './container';
export { PopupContainerProps } from './container';
declare const _default: OperationAuth;
@@ -23,93 +24,151 @@ declare class OperationAuth {
#private;
}
/** antd Button 的视觉类型 */
type ButtonType = 'primary' | 'default' | 'danger' | ''
/** 按钮尺寸 */
type ButtonSize = 'large' | 'middle' | 'small'
/** 按钮外观分类,对应 entry(cate) 的参数 */
type ButtonCate = 'default' | 'link' | 'circle' | 'round' | 'dashed'
/** 按钮触发的行为类型 */
type WidgetType =
| 'redirect'
| 'func'
| 'component'
| 'fsdpf-component'
| 'grid-layout-form'
| 'grid-layout'
| 'data-list'
| 'destroy'
/** antd Tooltip / Popconfirm 支持的弹出位置 */
type PlacementType =
| 'top' | 'left' | 'right' | 'bottom'
| 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'
| 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom'
/** Button props.tooltip 配置 */
interface ButtonTooltip {
/** 提示文字 */
title: string
/** 弹出位置 */
placement?: PlacementType
/** 是否启用,0 视同 false */
enabled?: boolean | number
getPopupContainer?: (e: HTMLElement) => HTMLElement
}
/** Button props.confirm 二次确认气泡配置 */
interface ButtonConfirm {
/** 确认提示文字 */
title: string
cancelText?: string
okText?: string
/** 确认按钮类型 */
okType?: ButtonType
placement?: PlacementType
/** 是否启用,0 视同 false */
enabled?: boolean | number
getPopupContainer?: (e: HTMLElement) => HTMLElement
arrow?: boolean | { pointAtCenter: boolean }
}
/**
* 按钮点击行为的容器配置;在 PopupContainerProps 基础上叠加 Popover 专有字段和 Button 专有的 mode,
* 流经 Button → Popover → Popup.modal 三层,各层按需取用不同字段
*/
interface WidgetContainerProps extends Omit<PopupContainerProps, 'placement'> {
/** 'popover' 时按钮触发内嵌气泡卡片,否则走 Popup.modal */
mode?: 'popover' | string
/** 弹窗标题,支持 lodash template 插值(以点击时的 raw data 为上下文) */
title?: string
/** antd Popover 的弹出位置(12 方向) */
placement?: PlacementType | string
/** antd Popover 对齐微调配置 */
align?: unknown
/** antd Popover 的 zIndex */
zIndex?: number
/** antd Popover 的箭头配置 */
arrow?: boolean | { pointAtCenter: boolean }
getPopupContainer?: (e: HTMLElement) => HTMLElement
/** 气泡挂载到 body,false 时挂载到触发元素父节点;默认 true */
isPopupMountBodyContainer?: boolean
}
/** useButton 第二个参数:回调处理器 */
interface UseButtonHandlers {
onAfterClick?: (result: unknown) => void
onBeforeClick?: (data: unknown) => void
}
/** useButton 返回 / ButtonProps 共用的状态字段 */
interface UseButtonStatus {
loading?: boolean
disabled?: boolean
}
/** useButton 第一个参数:行为配置 */
interface UseButtonProps {
/** 行为目标:组件 / 函数 / 路由 / 表达式,含义随 widgetType 而定 */
widget?: unknown
/** 行为类型,决定 widget 的解释方式和触发后的动作 */
widgetType?: WidgetType
/** 触发时附带的额外数据,合并到 widgetProps 求值结果后传给动作处理器 */
widgetData?: Record<string, unknown>
/** 触发前解析的 props 映射配置(经 getWidgetPropsData 求值) */
widgetProps?: Record<string, unknown>
/** 传给目标弹窗/表单/请求的 $setting 配置 */
widgetSetting?: Record<string, unknown>
/** 传给弹窗容器的配置(title/placement/zIndex 等) */
widgetContainerProps?: WidgetContainerProps
}
/** Button 组件的 props(所有变体共用) */
interface ButtonProps extends UseButtonProps, UseButtonHandlers, UseButtonStatus {
className?: string
/** 覆盖工厂默认外观分类 */
variant?: ButtonCate
children?: ReactNode
/** 按钮文字,与 children 二选一 */
name?: string
/** 图标 class 名 */
icon?: string
type?: ButtonType
iconPosition?: 'start' | 'end'
/** 按钮操作的权限标识 */
noAuthType?: string
/** onClick 时传给动作处理器的数据源 */
data?: unknown
tooltip?: ButtonTooltip
confirm?: ButtonConfirm
[key: string]: unknown
}
/** useButton 返回值:[点击处理函数(已防抖), 当前 loading/disabled 状态] */
type UseButtonReturn = [(data: unknown) => void, UseButtonStatus]
/** ButtonGroupPopover props.options 中每一项的结构(ButtonProps + uuid + 必填 widgetType) */
interface ButtonOption extends ButtonProps {
/** 操作项唯一标识,用于权限校验 */
uuid?: string
widgetType: WidgetType
/** 操作项自身的容器配置,与外层 widgetContainerProps 合并 */
widgetContainerSetting?: WidgetContainerProps
}
/**
* Button 组件点击行为的核心 hook;按 widgetType 把点击行为分发到对应的处理器
* (跳转/自定义函数/弹窗组件/表单弹窗/数据列表弹窗/删除请求等)
* @param {Object} config
* @param {*} config.widget 目标(组件/函数名/表达式/路由等,含义随 widgetType 而定)
* @param {'redirect'|'func'|'component'|'fsdpf-component'|'grid-layout-form'|'data-list'|'destroy'} [config.widgetType] 行为类型
* @param {*} [config.widgetData] 触发时附带的数据
* @param {Object} [config.widgetProps] 触发前解析的 props 配置(经 getWidgetPropsData)
* @param {Object} [config.widgetSetting] 传给目标(弹窗/表单/请求)的配置
* @param {Object} [config.widgetContainerProps] 传给弹窗容器的 props
* @param {Object} [handlers]
* @param {(result: *) => void} [handlers.onAfterClick] 动作完成后的回调
* @param {(data: *) => void} [handlers.onBeforeClick] 动作开始前的回调
* @returns {[(data: *) => void, {loading?: boolean, disabled?: boolean}]} [点击处理函数(已做 300ms 防抖), 当前 loading/disabled 状态]
* @param {UseButtonProps} config
* @param {UseButtonHandlers} [handlers]
* @returns {UseButtonReturn} [点击处理函数(已做 300ms 防抖), 当前 loading/disabled 状态]
*/
declare function useButton({ widget, widgetType, widgetData, widgetProps, widgetSetting, widgetContainerProps, }: {
widget: any;
widgetType?: "redirect" | "func" | "component" | "fsdpf-component" | "grid-layout-form" | "data-list" | "destroy";
widgetData?: any;
widgetProps?: any;
widgetSetting?: any;
widgetContainerProps?: any;
}, { onAfterClick, onBeforeClick }?: {
onAfterClick?: (result: any) => void;
onBeforeClick?: (data: any) => void;
}): [(data: any) => void, {
loading?: boolean;
disabled?: boolean;
}];
declare function useButton({ widget, widgetType, widgetData, widgetProps, widgetSetting, widgetContainerProps, }: UseButtonProps, { onAfterClick, onBeforeClick }?: UseButtonHandlers): UseButtonReturn;
declare function Button({ className, variant, children, name, icon, type, iconPosition, noAuthType, onAfterClick, onBeforeClick, data, loading: customLoading, disabled: customDisabled, tooltip, confirm, widget, widgetType, widgetData, widgetProps, widgetSetting, widgetContainerProps, ...props }: {
[x: string]: any;
className: any;
variant: any;
children: any;
name: any;
icon: any;
type?: string;
iconPosition?: string;
noAuthType: any;
onAfterClick: any;
onBeforeClick: any;
data: any;
loading: any;
disabled: any;
tooltip: any;
confirm: any;
widget?: () => void;
widgetType: any;
widgetData: any;
widgetProps: any;
widgetSetting: any;
widgetContainerProps: any;
}): React.JSX.Element;
declare namespace Button {
namespace propTypes {
let type: PropTypes.Requireable<string>;
let size: PropTypes.Requireable<string>;
let name: PropTypes.Requireable<string>;
let icon: PropTypes.Requireable<string>;
let iconPosition: PropTypes.Requireable<string>;
let data: PropTypes.Requireable<any>;
let widget: PropTypes.Requireable<any>;
let widgetType: PropTypes.Requireable<string>;
let widgetData: PropTypes.Requireable<object>;
let widgetProps: PropTypes.Requireable<object>;
let widgetSetting: PropTypes.Requireable<object>;
let widgetContainerProps: PropTypes.Requireable<object>;
let tooltip: PropTypes.Requireable<Required<PropTypes.InferProps<{
title: PropTypes.Validator<string>;
placement: PropTypes.Requireable<string>;
enabled: PropTypes.Requireable<NonNullable<number | boolean>>;
getPopupContainer: PropTypes.Requireable<(...args: any[]) => any>;
}>>>;
let confirm: PropTypes.Requireable<Required<PropTypes.InferProps<{
title: PropTypes.Validator<string>;
cancelText: PropTypes.Requireable<string>;
okText: PropTypes.Requireable<string>;
okType: PropTypes.Requireable<string>;
placement: PropTypes.Requireable<string>;
enabled: PropTypes.Requireable<NonNullable<number | boolean>>;
getPopupContainer: PropTypes.Requireable<(...args: any[]) => any>;
arrow: PropTypes.Requireable<NonNullable<boolean | Required<PropTypes.InferProps<{
pointAtCenter: PropTypes.Requireable<boolean>;
}>>>>;
}>>>;
}
}
export { _default as auth, Button as default, useButton };
export { _default as auth, useButton };
export type { ButtonCate, ButtonConfirm, ButtonOption, ButtonProps, ButtonSize, ButtonTooltip, ButtonType, PlacementType, UseButtonHandlers, UseButtonProps, UseButtonReturn, UseButtonStatus, WidgetContainerProps, WidgetType };
+4 -4
View File
@@ -1,6 +1,6 @@
import { an as o, am as s, ao as u } from "./common/main.js";
import { al as s, ak as u, am as e } from "./common/main.js";
export {
o as auth,
s as default,
u as useButton
s as auth,
u as default,
e as useButton
};
+986 -1002
View File
File diff suppressed because it is too large Load Diff
+56 -116
View File
@@ -1,51 +1,8 @@
import * as React from 'react';
import React__default, { ReactElement, ComponentType } from 'react';
import PropTypes from 'prop-types';
/**
* 渲染一个 iconfont symbol 图标(依赖 Iconfont.init 注入的 SVG symbol 脚本)
* @param {Object} props
* @param {string} [props.className] 额外的 class 名
* @param {string} props.type 图标名,对应 svg symbol 的 id
* @param {Object} [props.style] 行内样式
*/
declare function Iconfont({ className, type, style, rotate, spin, twoToneColor, compact, ...props }: {
className?: string;
type: string;
style?: any;
}): React__default.JSX.Element;
declare namespace Iconfont {
export namespace propTypes {
let className: PropTypes.Requireable<string>;
let type: PropTypes.Validator<string>;
let style: PropTypes.Requireable<object>;
}
export { createScriptUrlElements as init };
}
/**
* 依次注入 iconfont symbol 的 script 地址(单个 url 只会注入一次);
* 也是 Iconfont.init 挂载的实现,支持传入多个 url 按顺序加载(前一个 load/error 后再加载下一个)
* @param {string[]} [scriptUrls] iconfont symbol 脚本地址列表
* @param {number} [index] 内部递归用的当前下标
*/
declare function createScriptUrlElements(scriptUrls?: string[], index?: number): void;
/**
* 包装一个弹窗内容组件,让它可以通过 $setProps 更新自己的 props(与外部传入的 widgetProps 做浅合并),
* 同时注入 $close 用于关闭弹窗
* @param {Object} props
* @param {import('react').ReactElement|Function} props.widget 要渲染的元素或组件
* @param {Object} [props.widgetProps] 外部传入的初始 props,变化时会合并进内部状态
* @param {(result?: *) => void} props.$close 关闭弹窗的函数,会透传给 widget
* @param {(patch: Object) => void} [props.onSetProps] $setProps 被调用时的回调,用于同步外部状态
*/
declare function SetPropsWrapper({ widget, widgetProps: externalProps, $close, onSetProps }: {
widget: React.ReactElement | Function;
widgetProps?: any;
$close: (result?: any) => void;
onSetProps?: (patch: any) => void;
}): Function | React__default.ReactElement<any, string | React__default.JSXElementConstructor<any>>;
export { default as Icon } from './iconfont';
export { default as SetPropsWrapper } from './container';
import React, { ReactElement, ComponentType, ReactNode, CSSProperties } from 'react';
import { SlotKey } from './container';
export { Empty, Loading, NotFound, Popup } from './container';
/**
* 通用错误边界组件
@@ -57,7 +14,7 @@ declare function SetPropsWrapper({ widget, widgetProps: externalProps, $close, o
* @param {Function} [props.onReset] 重置回调 () => void
* @param {any[]} [props.resetKeys] 任一值变化时自动重置(类似 react-error-boundary)
*/
declare class ErrorBoundary extends React__default.Component<any, any, any> {
declare class ErrorBoundary extends React.Component<any, any, any> {
static getDerivedStateFromError(error: any): {
error: any;
};
@@ -75,8 +32,42 @@ declare class ErrorBoundary extends React__default.Component<any, any, any> {
/** widget 支持的三种形式 */
type WidgetInput = string | ReactElement | ComponentType
/** theme 布局区块 key,用于 classNames / styles(在 SlotKey 基础上加入容器区块) */
type LayoutKey = SlotKey | 'header' | 'body' | 'footer'
/** theme function 收到的上下文,ele slot 展开 + children + 样式 + $setting */
type ThemeContext = {
/** 已渲染的 widget 实例 */
children: ReactNode
/** slot 注入的标题 */
title?: ReactNode
/** slot 注入的副标题 */
subTitle?: ReactNode
/** slot 注入的额外内容,通常显示在底栏左侧(与 actions 两端对齐) */
extras?: ReactNode
/** slot 注入的操作区,通常显示在底栏右侧(与 extras 两端对齐) */
actions?: ReactNode
/** 根节点 className */
className?: string
/** 各布局区块的 className */
classNames?: Partial<Record<LayoutKey, string>>
/** 根节点行内样式 */
style?: CSSProperties
/** 各布局区块的行内样式 */
styles?: Partial<Record<LayoutKey, CSSProperties>>
/** 即 themeProps,主题自身的配置 */
$setting?: Record<string, unknown>
}
/** theme function render prop 签名 */
type ThemeRenderer = (ctx: ThemeContext) => ReactNode
/** fallbackOnError 的 function 形式 */
type FallbackOnError = (error: Error, reset: null) => ReactNode
/**
* 按组件名动态加载并渲染组件,支持 theme 容器框架(string 异步加载 或 function render prop)
* @param {Object} [props]
* @param {WidgetInput} [props.widget] 组件名(@pkg/xxx)、ReactElement 或组件函数/类
* @param {Object} [props.widgetProps] 直接 spread 给 widget 的 props
* @param {Object} [props.widgetSetting] 传给 widget 的 $setting
@@ -91,71 +82,20 @@ type WidgetInput = string | ReactElement | ComponentType
* @param {ReactNode | FallbackOnError} [props.fallbackOnError]
* @param {(error: Error, info: null) => void} [props.onError]
*/
declare function ImportWidgetComponent({ widget, widgetProps, widgetSetting, theme, themeProps, className, classNames, style, styles, fallback, fallbackOnError, onError, }?: WidgetInput): any;
declare function ImportWidgetComponent({ widget, widgetProps, widgetSetting, theme, themeProps, className, classNames, style, styles, fallback, fallbackOnError, onError, }?: {
widget?: WidgetInput;
widgetProps?: any;
widgetSetting?: any;
theme?: string | ThemeRenderer;
themeProps?: any;
className?: string;
classNames?: Partial<Record<LayoutKey, string>>;
style?: React.CSSProperties;
styles?: Partial<Record<LayoutKey, React.CSSProperties>>;
fallback?: any;
fallbackOnError?: React.ReactNode | FallbackOnError;
onError?: (error: Error, info: null) => void;
}): any;
/** 空状态占位组件 */
declare function Empty(): React__default.JSX.Element;
/** 加载中占位组件 */
declare function Loading(): React__default.JSX.Element;
/** 未找到占位组件 */
declare function NotFound(): React__default.JSX.Element;
declare namespace FFPopup {
export { modal };
export { confirm };
export { form };
export { notification };
export { success };
export { error };
}
/**
* 打开一个任意组件的弹窗
* @param {Function} widget 要渲染的组件
* @param {Object} [widgetData] 传给组件的 props
* @param {Object} [widgetContainerProps] 传给弹窗容器(PopupContainer)的 props
* @returns {Promise<*>&{update: Function}} resolve 弹窗关闭时传入的值;promise.update(patch, containerPatch) 可用来更新弹窗内容
*/
declare function modal(widget: Function, widgetData?: any, widgetContainerProps?: any): Promise<any> & {
update: Function;
};
/**
* 弹出一个确认框
* @param {*} content 确认框内容
* @param {Object} [opts] 其余透传给 Confirm 组件的 props
* @returns {Promise<*>} 点击确认时 resolve,点击取消/关闭时按 modal 的语义处理
*/
declare function confirm(content: any, opts?: any): Promise<any>;
/**
* 弹出一个模态表单;取消时 reject(false)
* @param {Array} fields 表单字段配置(传给 FormModal 的 fields)
* @param {Object} [widgetContainerProps] 传给弹窗容器的 props
* @param {Object} [formProps] 传给表单的额外 props
* @returns {Promise<Object>} 提交后的表单数据
*/
declare function form(fields: any[], widgetContainerProps?: any, formProps?: any): Promise<any>;
/**
* 弹出一条消息提示
* @param {*} content 提示内容
* @param {Object} [opts] 其余透传给 Notification 组件的 props,duration/showProgress 会转发到容器 props
* @returns {Promise<*>}
*/
declare function notification(content: any, { showProgress, duration, ...opts }?: any): Promise<any>;
/**
* 成功提示(绿色图标样式的 notification)
* @param {*} content 提示内容
* @param {Object} [opts] 其余透传给 notification 的选项
* @returns {Promise<*>}
*/
declare function success(content: any, opts?: any): Promise<any>;
/**
* 错误提示(红色图标样式的 notification)
* @param {*} content 提示内容
* @param {Object} [opts] 其余透传给 notification 的选项
* @returns {Promise<*>}
*/
declare function error(content: any, opts?: any): Promise<any>;
export { Empty, ErrorBoundary, Iconfont as Icon, ImportWidgetComponent, Loading, NotFound, FFPopup as Popup, SetPropsWrapper };
export { ErrorBoundary, ImportWidgetComponent };
export type { FallbackOnError, LayoutKey, ThemeContext, ThemeRenderer, WidgetInput };
+11 -9
View File
@@ -1,11 +1,13 @@
import { au as r, aK as p, al as s, aL as t, av as n, aw as e, at as d, aJ as m } from "./common/main.js";
import { as as s, aI as t, aj as m, aJ as n, at as e, au as d, ar as i, aH as u } from "./common/main.js";
import "react/jsx-runtime";
import "react";
export {
r as Empty,
p as ErrorBoundary,
s as Icon,
t as ImportWidgetComponent,
n as Loading,
e as NotFound,
d as Popup,
m as SetPropsWrapper
s as Empty,
t as ErrorBoundary,
m as Icon,
n as ImportWidgetComponent,
e as Loading,
d as NotFound,
i as Popup,
u as SetPropsWrapper
};
+107 -94
View File
@@ -1,87 +1,101 @@
import * as React from 'react';
import React__default from 'react';
import PropTypes from 'prop-types';
import React, { ReactNode, CSSProperties } from 'react';
import { GridLayoutFormField } from './grid-layout-form';
/** 空状态占位组件 */
declare function Empty(): React__default.JSX.Element;
declare function Empty(): React.JSX.Element;
/** 加载中占位组件 */
declare function Loading(): React__default.JSX.Element;
declare function Loading(): React.JSX.Element;
/** 未找到占位组件 */
declare function NotFound(): React__default.JSX.Element;
declare function NotFound(): React.JSX.Element;
/**
* 为页面级布局提供 SlotContext,把子元素(通常是 FFContainer)挂载的
* title/subTitle/actions/extras 等插槽内容收集起来,再作为 props 传回给这个子元素
* @param {Object} props
* @param {import('react').ReactElement} props.children 单个子元素(字符串类型的元素会跳过插槽逻辑,原样返回)
* @param {ReactElement} props.children 单个子元素(字符串类型的元素会跳过插槽逻辑,原样返回)
*/
declare function FFPageRender({ children }: {
children: React.ReactElement;
}): React__default.JSX.Element;
declare namespace FFPageRender {
namespace propTypes {
let children: PropTypes.Validator<PropTypes.ReactElementLike>;
}
}
}): React.JSX.Element;
/** FFContainer 内部用来把 title/subTitle/actions/extras 等具名插槽挂载到外层布局的 context */
declare const SlotContext: React__default.Context<{
ele: {};
mount: () => void;
unmount: () => void;
}>;
/** 已知的内容插槽 key(由 FFContainer.slot / PopupContainer 维护) */
type SlotKey = 'title' | 'subTitle' | 'actions' | 'extras'
/** 插槽元素映射;由 FFPageRender / PopupContainer 的 useState 维护 */
interface SlotElements {
/** title 插槽内容 */
title?: ReactNode
/** 副标题插槽内容 */
subTitle?: ReactNode
/** 操作按钮插槽内容 */
actions?: ReactNode
/** 扩展区插槽内容 */
extras?: ReactNode
/** 挂载到外层布局根节点的 className */
rootClassName?: string
[key: string]: ReactNode | string | undefined
}
/**
* 页面级容器,通过 SlotContext 把 title/subTitle/actions/extras 挂载到外层布局的对应插槽位置
* @param {Object} props
* @param {string} [props.rootClassName] 挂载到外层布局根节点的 className
* @param {string} [props.className] 容器自身的 className
* @param {*} [props.children] 容器内容
* @param {*} [props.actions] 挂载到 actions 插槽的内容
* @param {*} [props.title] 挂载到 title 插槽的内容
* @param {*} [props.subTitle] 挂载到 sub-title 插槽的内容
* @param {*} [props.extras] 挂载到 extras 插槽的内容
* @param {Object} [props.style] 容器行内样式
* SlotContext 的值结构;由 FFPageRender / PopupContainer 提供,FFContainer / slot 内部消费
* (也可在自定义 theme 容器中消费)
*/
declare function FFContainer({ rootClassName, className, children, actions, title, subTitle, extras, style }: {
rootClassName?: string;
className?: string;
children?: any;
actions?: any;
title?: any;
subTitle?: any;
extras?: any;
style?: any;
}): React__default.JSX.Element;
declare namespace FFContainer {
function Action({ children, className }: {
children: any;
className: any;
}): any;
function Title({ children, className }: {
children: any;
className: any;
}): any;
function SubTitle({ children, className }: {
children: any;
className: any;
}): any;
function Extra({ children, className }: {
children: any;
className: any;
}): any;
namespace propTypes {
let className: PropTypes.Requireable<string>;
let style: PropTypes.Requireable<object>;
let title: PropTypes.Requireable<any>;
let subTitle: PropTypes.Requireable<any>;
let actions: PropTypes.Requireable<any>;
let extras: PropTypes.Requireable<any>;
}
interface SlotContextValue {
/** 已挂载的插槽元素映射 */
ele: SlotElements
/** 挂载一个插槽元素 */
mount: (slot: string, element: ReactNode) => void
/** 卸载一个插槽元素 */
unmount: (slot: string) => void
}
/** Popup.modal / PopupContainer 的容器配置参数 */
interface PopupContainerProps {
/** 弹窗标题;支持 lodash template 插值(以触发时的 raw data 为上下文) */
title?: string
/**
* 弹出位置;'center'(默认)渲染为居中模态框,
* 'left'/'right'/'top'/'bottom' 渲染为对应方向的抽屉
*/
placement?: 'center' | 'left' | 'top' | 'right' | 'bottom'
/** 内容区宽度(模态框有效) */
width?: number | string
/** 内容区高度 */
height?: number | string
/** 内容区行内样式(模态框有效) */
style?: CSSProperties
/** 根节点额外 class */
className?: string
/** 各分区 class */
classNames?: {
header?: string
body?: string
footer?: string
close?: string
}
/** 点击蒙层是否关闭弹窗,默认 false */
maskClosable?: boolean
[key: string]: unknown
}
/**
* Popup.modal 的返回值;
* 关闭时 resolve 传入的值,`update` 可在弹窗打开期间动态更新内容 props 和容器 props
*/
type PopupHandle<T = unknown> = Promise<T> & {
update: (
widgetPatch?: Record<string, unknown>,
containerPatch?: Partial<PopupContainerProps>
) => void
}
/** FFContainer 内部用来把 title/subTitle/actions/extras 等具名插槽挂载到外层布局的 context
* @type {Context<SlotContextValue>}
*/
declare const SlotContext: React.Context<SlotContextValue>;
declare namespace FFPopup {
export { modal };
export { confirm };
@@ -93,55 +107,53 @@ declare namespace FFPopup {
/**
* 打开一个任意组件的弹窗
* @param {Function} widget 要渲染的组件
* @param {Object} [widgetData] 传给组件的 props
* @param {Object} [widgetContainerProps] 传给弹窗容器(PopupContainer)的 props
* @returns {Promise<*>&{update: Function}} resolve 弹窗关闭时传入的值;promise.update(patch, containerPatch) 可用来更新弹窗内容
* @param {ComponentType} widget 要渲染的组件
* @param {Record<string, unknown>} [widgetData] 传给组件的 props
* @param {PopupContainerProps} [widgetContainerProps] 传给弹窗容器(PopupContainer)的 props
* @returns {PopupHandle} 关闭时 resolve 传入的值;`promise.update(patch, containerPatch)` 可动态更新弹窗
*/
declare function modal(widget: Function, widgetData?: any, widgetContainerProps?: any): Promise<any> & {
update: Function;
};
declare function modal(widget: React.ComponentType, widgetData?: Record<string, unknown>, widgetContainerProps?: PopupContainerProps): PopupHandle;
/**
* 弹出一个确认框
* @param {*} content 确认框内容
* @param {ReactNode} content 确认框内容
* @param {Object} [opts] 其余透传给 Confirm 组件的 props
* @returns {Promise<*>} 点击确认时 resolve,点击取消/关闭时按 modal 的语义处理
* @returns {PopupHandle} 点击确认时 resolve,点击取消/关闭时 resolve(false)
*/
declare function confirm(content: any, opts?: any): Promise<any>;
declare function confirm(content: React.ReactNode, opts?: any): PopupHandle;
/**
* 弹出一个模态表单;取消时 reject(false)
* @param {Array} fields 表单字段配置(传给 FormModal 的 fields)
* @param {Object} [widgetContainerProps] 传给弹窗容器的 props
* @param {Object} [formProps] 传给表单的额外 props
* @returns {Promise<Object>} 提交后的表单数据
* 弹出一个模态表单;取消时 resolve(false)
* @param {GridLayoutFormField[]} fields 表单字段配置(传给 FormModal 的 fields)
* @param {PopupContainerProps} [widgetContainerProps] 传给弹窗容器的 props
* @param {Record<string, unknown>} [formProps] 传给表单的额外 props
* @returns {PopupHandle<Record<string, unknown>>} 提交后的表单数据
*/
declare function form(fields: any[], widgetContainerProps?: any, formProps?: any): Promise<any>;
declare function form(fields: GridLayoutFormField[], widgetContainerProps?: PopupContainerProps, formProps?: Record<string, unknown>): PopupHandle<Record<string, unknown>>;
/**
* 弹出一条消息提示
* @param {*} content 提示内容
* @param {Object} [opts] 其余透传给 Notification 组件的 props,duration/showProgress 会转发到容器 props
* @returns {Promise<*>}
* @param {ReactNode} content 提示内容
* @param {Object} [opts] 其余透传给 Notification 组件的 props,duration/showProgress 会转发到容器 props
* @returns {PopupHandle}
*/
declare function notification(content: any, { showProgress, duration, ...opts }?: any): Promise<any>;
declare function notification(content: React.ReactNode, { showProgress, duration, ...opts }?: any): PopupHandle;
/**
* 成功提示(绿色图标样式的 notification)
* @param {*} content 提示内容
* 成功提示(绿色图标样式的 notification)
* @param {ReactNode} content 提示内容
* @param {Object} [opts] 其余透传给 notification 的选项
* @returns {Promise<*>}
* @returns {PopupHandle}
*/
declare function success(content: any, opts?: any): Promise<any>;
declare function success(content: React.ReactNode, opts?: any): PopupHandle;
/**
* 错误提示(红色图标样式的 notification)
* @param {*} content 提示内容
* 错误提示(红色图标样式的 notification)
* @param {ReactNode} content 提示内容
* @param {Object} [opts] 其余透传给 notification 的选项
* @returns {Promise<*>}
* @returns {PopupHandle}
*/
declare function error(content: any, opts?: any): Promise<any>;
declare function error(content: React.ReactNode, opts?: any): PopupHandle;
/**
* 弹层渲染出口(通常挂载一份到页面根部);负责渲染 FFPopup 触发的所有弹窗/模态框和 notification。
* 在挂载前调用 FFPopup 的方法会被排队,挂载后统一渲染出来
*/
declare function FFPopupRender(): React__default.JSX.Element;
declare function FFPopupRender(): React.JSX.Element;
declare namespace FFPopupRender {
let $popups: Map<any, any>;
let $index: number;
@@ -149,4 +161,5 @@ declare namespace FFPopupRender {
function $onClick(...args: any[]): Promise<any>;
}
export { SlotContext as Context, Empty, Loading, NotFound, FFPageRender as PageRender, FFPopup as Popup, FFPopupRender as PopupRender, FFContainer as default };
export { SlotContext as Context, Empty, Loading, NotFound, FFPageRender as PageRender, FFPopup as Popup, FFPopupRender as PopupRender };
export type { PopupContainerProps, PopupHandle, SlotContextValue, SlotElements, SlotKey };
+5 -5
View File
@@ -1,11 +1,11 @@
import { aq as e, au as o, av as p, aw as t, ar as d, at as n, as as r, ap as u } from "./common/main.js";
import { ao as s, as as e, at as p, au as t, ap as n, ar as d, aq as r, an as u } from "./common/main.js";
export {
e as Context,
o as Empty,
s as Context,
e as Empty,
p as Loading,
t as NotFound,
d as PageRender,
n as Popup,
n as PageRender,
d as Popup,
r as PopupRender,
u as default
};
+109 -30
View File
@@ -1,33 +1,112 @@
import React from 'react';
import { WidgetType, WidgetContainerProps } from './button';
/**
* 按一串中间件(middleware)链式转换数据;每个中间件可以是函数,也可以是要动态加载的
* 组件名字符串(通过 core.getWidgetComponent 解析),支持嵌套数组表示的中间件组
*/
declare class DataConverter {
static "__#private@#resolver": any;
static "__#private@#newMiddleware": any;
/**
* @param {...(Array|[string|Function, *])} middlewares 中间件列表,每项是
* [中间件名或函数, 传给中间件的配置],或者是这种元组的嵌套数组(会被展开)
*/
constructor(...middlewares: (any[] | [string | Function, any])[]);
/**
* 依次跑完所有中间件,把 value 转换成最终结果;单个中间件报错会被跳过,不中断整条链
* @param {*} value 原始值
* @param {*} [record] 关联的记录数据,中间件里可通过 this.getRecord() 取到
* @returns {Promise<*>} 转换后的结果
*/
toValue: (value: any, record?: any) => Promise<any>;
/**
* 把 toValue 的异步转换结果渲染成 React 元素;转换完成前显示 loading,转换出错则显示错误信息
* @param {*} value 原始值
* @param {*} record 关联的记录数据
* @param {*} [loading] 转换完成前显示的占位内容
* @returns {React.ReactElement}
*/
toRender: (value: any, record: any, loading?: any) => React.ReactElement;
#private;
// ===== 用户数据结构(复用类型,JSDoc 无法跨文件引用,放 .d.ts) =====
interface UserRoleBinding {
user_uuid: string
role_uuid: string
created_at: string
updated_at: string
created_user: string
owned_user: string
}
export { DataConverter as default };
interface UserInfo {
uuid: string
username: string
nickname: string
email: string
last_login_ip: string
is_active: 0 | 1
UserRole: UserRoleBinding[]
[key: string]: unknown
}
interface MenuItem {
/** 菜单唯一标识 */
uuid: string
/** 菜单显示名称 */
name: string
/** 图标 class 名 */
icon: string
/** 行为目标(组件标识 / 路由 uuid 等),含义随 widgetType 而定 */
widget: string
/** 行为类型 */
widgetType: WidgetType
/** 传给目标组件的 props 映射配置 */
widgetProps: Record<string, unknown>
/** 传给目标组件的 $setting 配置 */
widgetSetting: Record<string, unknown>
/** 弹窗容器配置 */
widgetContainerSetting: WidgetContainerProps
/** 子菜单 */
children?: MenuItem[]
}
interface RouteItem {
/** 路由唯一标识 */
uuid: string
/** 路由名称 */
name: string
/** react-router path,支持动态参数(如 /page/:id) */
uri: string
/** 是否为布局路由(外层 layout,不直接渲染页面内容) */
isLayout: boolean
/** 是否需要登录才能访问 */
isLogin: boolean
/** 是否为手机端专属路由 */
isPhone: boolean
/** 路由类型 */
type: Exclude<WidgetType, 'redirect'>
/** 是否精确匹配路径 */
exact: boolean
/** widget 标识(等同于 ButtonProps.widget),经 core.getWidgetComponent 加载 */
component: string
/** 传给页面组件的 props 映射配置 */
widgetProps: Record<string, unknown>
/** 传给页面组件的 $setting 配置 */
widgetSetting: Record<string, unknown>
/** 弹窗容器配置 */
widgetContainerSetting: WidgetContainerProps
/** 附加配置(如 layout 标识等) */
extra?: Record<string, unknown>
}
// ===== http — Proxy 模式产生交叉类型,JSDoc 无法表达 =====
/** 每次请求自动附加的请求头 */
interface HttpHeaders {
/** 客户端平台标识,固定为 'web' */
Platform: string
/** SaaS 租户标识,单租户时为 null */
SaaS: string | null
/** JWT Bearer token,未登录时为 undefined */
Authorization: string | undefined
}
// ===== func — ff-worker-pipe 无类型文件,显式声明 =====
/**
* 基于 Worker 的表达式执行引擎单例;
* exec 在独立 Worker 上下文中求值一段 JS 表达式/源码
*/
interface WorkerPipeInstance {
/**
* 在 Worker 上下文中执行一段 JS 表达式
* @param expression 要执行的表达式字符串
* @param args 传给表达式的参数(可在表达式内作为第一个参数使用)
* @param fns 注入到表达式执行作用域的额外可调用函数
* @param session 会话标识;相同 session 共享 Worker 侧工作区(this)
*/
exec: (
expression: string,
args?: Record<string, unknown>,
fns?: Record<string, Function>,
session?: string
) => Promise<unknown>
/** 清除指定 session 的 Worker 侧工作区 */
clear: (session: string) => void
}
export type { HttpHeaders, MenuItem, RouteItem, UserInfo, UserRoleBinding, WorkerPipeInstance };
+303 -175
View File
@@ -1,51 +1,259 @@
import React from 'react';
import PropTypes from 'prop-types';
import React, { ReactNode as ReactNode$1, ComponentType, ReactElement } from 'react';
import { ButtonOption, WidgetContainerProps } from './button';
import { GridLayoutProps } from './grid-layout';
/** 宫格卡片的 GridLayout 布局配置,透传给 DataListContent / GridLayout */
interface DataListItemForGridLayout extends GridLayoutProps {}
/** 列表操作按钮配置(行内操作 / 批量操作通用) */
type DataListOperation = ButtonOption & {
/** 操作后是否刷新:0 不刷新,1 整体刷新,2 局部刷新(只更新当前行) */
isRefresh?: 0 | 1 | 2
}
/** 表格列配置,在 antd ColumnType 基础上扩展数据列表能力 */
interface DataListColumn {
/** 列标题 */
title?: string
/** 对应数据字段名 */
dataIndex?: string | string[]
/** 列唯一 key */
key?: string
/** 列宽(px) */
width?: number
/** 是否固定宽度,不参与自适应缩放 */
isWidthFixed?: boolean
/** 固定列方向 */
fixed?: 'left' | 'right' | boolean
/** 对齐方式 */
align?: 'left' | 'center' | 'right'
/** 自定义渲染函数 */
render?: (value: unknown, record: Record<string, unknown>, index: number) => ReactNode$1
/** 渲染中间件列表,由 DataConverter 链式处理 */
middlewares?: unknown[]
/** 动态渲染控件标识(通过 core.getWidgetComponent 加载) */
widgetByJs?: string
/** widgetByJs 的 $setting 配置 */
widgetByJsSetting?: Record<string, unknown>
/** 是否可行内编辑 */
editableByJs?: boolean
/** 行内编辑配置 */
editableByJsSetting?: {
formSetting?: { primaryKey?: string; help?: string; validators?: Record<string, unknown> }
widgetSetting?: Record<string, unknown>
widgetContainerSetting?: WidgetContainerProps
}
[key: string]: unknown
}
/** 列表 tab 配置项 */
interface DataListTab {
/** tab 唯一标识(优先使用) */
value?: unknown
/** tab 编码(value 不存在时使用) */
code?: unknown
/** tab 显示文本 */
label?: string
[key: string]: unknown
}
/** DataList / DataListHelper 各区块自定义 className */
interface DataListClassNames {
sider?: string
filter?: string
footer?: string
toolbar?: string
container?: string
content?: string
item?: string
empty?: string
}
/** DataList layouts prop — 各子区块组件,false 表示全部隐藏 */
interface DataListLayouts {
sider?: ComponentType<any> | ReactElement | null
filter?: ComponentType<any> | ReactElement | null
footer?: ComponentType<any> | ReactElement | null
toolbar?: ComponentType<any> | ReactElement | null
empty?: ComponentType<any> | ReactElement | null
}
/** 行选择配置 */
interface DataListRowSelection {
/** 选择模式 */
type?: 'checkbox' | 'radio'
/** 受控选中的行 key 列表 */
selectedRowKeys?: unknown[]
/** 默认选中行 key(非受控) */
defaultSelectedRowKeys?: unknown[]
/** 选中行变化回调 */
onChange?: (keys: unknown[], rows: Record<string, unknown>[]) => void
/** 选择列宽度(px),默认 32 */
columnWidth?: number
[key: string]: unknown
}
/** /api/_/{listCode} 返回的列表结构配置,由 DataListHelper 通过 setStructure 消费 */
interface DataListStructure {
/** 关联资源标识 */
resource?: string
/** 主键字段名 */
primaryKey?: string
/** 表格列配置 */
columns?: DataListColumn[]
/** 行内操作按钮配置 */
itemOperations?: DataListOperation[]
/** 批量操作按钮配置 */
batchOperations?: DataListOperation[]
/** 是否使用表单布局模式的筛选条件 */
isConditionFormLayout?: boolean
/** 是否启用树形侧边栏 */
isTreeSider?: boolean
/** 树形侧边栏配置 */
treeSiderConfig?: Record<string, unknown>
/** 主题组件标识 */
theme?: string
/** 传给主题组件的 $setting */
themeConfig?: Record<string, unknown>
/** 是否使用宫格卡片布局 */
isItemGridLayout?: boolean
/**
* 宫格卡片布局配置(API 格式)
* 注:themeConfig 在 DataListHelper 中会被重命名为 themeProps 后再传给组件
*/
itemGridLayout?: Omit<DataListItemForGridLayout, 'themeProps'> & { themeConfig?: Record<string, unknown> }
/** 列表标题 */
title?: string
/** 是否分页 */
isPaginate?: boolean
/** tab 配置 */
tabs?: DataListTab[]
/** 行选择模式 */
selectionType?: 'checkbox' | 'radio'
/** 是否启用动态刷新(WebSocket 订阅) */
isDynamicRefresh?: boolean
[key: string]: unknown
}
/**
* 行内操作权限映射:key 为操作按钮 uuid,value 为拥有该权限的行主键列表;
* 由后端 list-operations-access 接口返回,通过 useOperationCallback 管理
*/
type DataListItemOperationsAccess = Map<string, unknown[]>
/** 列表查询参数,用于分页/筛选/tab/关键字等,经 base62 编码后传给后端 */
interface DataListQueryParams {
/** 当前页码,默认 1 */
page?: number
/** 每页条数,默认 30 */
pageSize?: number
/** 当前选中的 tab 值 */
tab?: unknown
/** 关键字搜索值 */
keyword?: string
/** 筛选条件(字段名 → 值) */
condition?: Record<string, unknown>
/** 侧边栏选中值 */
sider?: unknown
/** 数据总条数(仅用于回显,不参与请求) */
total?: number
/** 附加请求参数,透传到后端 */
payload?: Record<string, unknown>
[key: string]: unknown
}
/**
* DataList 对外暴露的操作 API;
* 由 DataList 通过 Context 注入,供动态脚本及子组件(如 ff-button)调用
*/
interface DataListAPI {
/** 获取当前查询参数;k 为字段名时返回单个值,'init' 或空时返回全量对象 */
getBase62params: (k?: string, defaultValue?: unknown) => unknown
/** 获取当前已选中行数据 */
getSelectedRows: () => Record<string, unknown>[]
reload: (params?: Partial<DataListQueryParams>) => void
setPage: (page: number, pageSize?: number) => void
setPageSize: (pageSize: number) => void
setTab: (tab: unknown) => void
setSider: (sider: unknown) => void
setKeyword: (keyword: string) => void
setCondition: (value: Record<string, unknown>, keyword?: string) => void
}
/** DataListContext 的值结构,由 DataList 通过 Provider 注入,内部子组件通过 useContext 消费 */
interface DataListContextValue extends DataListAPI {
listCode?: string
classNames?: DataListClassNames
onReload: (params?: Partial<DataListQueryParams>) => void
onClickCallback?: (isRefresh: number, item?: Record<string, unknown> | null) => void
onConditionChange: (value: Record<string, unknown>, keyword?: string) => void
onTabChange: (tab: unknown) => void
onSiderChange: (sider: unknown) => void
onKeywordChange: (keyword: string) => void
onPageChange: (page: number, pageSize?: number) => void
onPageSizeChange: (pageSize: number) => void
}
/** useDataListHelper 的返回值:继承 DataListQueryParams 当前状态 + 数据 + 各维度更新方法 */
interface DataListHelperState extends DataListQueryParams {
/** 当前页数据 */
dataSource: Record<string, unknown>[]
/** 操作权限映射:操作 uuid → 有权限的行主键列表 */
itemOperationsAccess: DataListItemOperationsAccess
/** 主键字段名(来自结构配置) */
primaryKey?: string
onReload: DataListContextValue['onReload']
onTabChange: DataListContextValue['onTabChange']
onPageChange: DataListContextValue['onPageChange']
onPageSizeChange: DataListContextValue['onPageSizeChange']
onConditionChange: DataListContextValue['onConditionChange']
onSiderChange: DataListContextValue['onSiderChange']
onKeywordChange: DataListContextValue['onKeywordChange']
onClickCallback?: DataListContextValue['onClickCallback']
}
/** DataListHelper 通过 ref 暴露的方法 */
interface DataListHelperRef {
/** 触发整体刷新 */
reload: () => void
/** 获取已选中行数据 */
getSelectedRows: () => Record<string, unknown>[]
/** Button 操作完成后通知列表刷新:isRefresh=1 整体刷新,2 局部刷新(item 为当前行数据) */
emitOperation: (isRefresh: number, item?: Record<string, unknown> | null) => void
}
/**
* 处理表格列配置:为每列注入 onCell,并按 middlewares/widgetByJs 组装渲染中间件链(通过 DataConverter)生成最终的 render 函数
* @param {Array<Object>} columns 原始列配置(可能包含 widgetByJs/widgetByJsSetting/middlewares/render)
* @param {DataListColumn[]} columns 原始列配置(可能包含 widgetByJs/widgetByJsSetting/middlewares/render)
* @param {Object} [base62params={}] 分页/查询参数,仅作为依赖项触发重新计算
* @returns {Array<Object>} 处理后可直接传给 antd Table 的列配置
* @returns {DataListColumn[]} 处理后可直接传给 antd Table 的列配置
*/
declare function useColumnsRender(columns: Array<any>, base62params?: any): Array<any>;
declare function useColumnsRender(columns: DataListColumn[], base62params?: any): DataListColumn[];
/**
* 补全 antd Table 的 components 配置,确保 body.cell 默认使用可编辑单元格组件 DataListCellEditable
* @param {Object} [components={}] 原始 components 配置
* @returns {Object} 补全后的 components 配置
*/
declare function useCellEditableComponents(components?: any): any;
/**
* 根据 listCode 拉取列表结构配置(字段/列/分页/布局等元数据)
* @param {string} listCode 列表标识
* @returns {Object} 列表结构配置,请求完成前为空对象
*/
declare function useStructure(listCode: string): any;
/**
* 根据 listCode 及查询参数拉取列表数据
* @param {string} listCode 列表标识
* @param {Object} [base62params={}] 查询参数,会与 page:1 合并后进行 base62 编码请求
* @returns {Object} 接口返回的数据,包含 dataSource 等字段;请求完成前为 { dataSource: [] }
*/
declare function useDataSource(listCode: string, base62params?: any): any;
/**
* 生成一个按权限映射过滤某行数据可用行内操作按钮的函数
* @param {Array<Object>} [itemOperations=[]] 行内操作按钮配置
* @param {Map<string, Array>} [itemOperationsAccess=new Map] 操作 uuid 到有权限的数据主键列表的映射
* @param {DataListOperation[]} [itemOperations=[]] 行内操作按钮配置
* @param {DataListItemOperationsAccess} [itemOperationsAccess=new Map] 操作 uuid 到有权限的数据主键列表的映射
* @param {string} [pk='id'] 主键字段名
* @param {string} [resource] 数据嵌套的资源字段名(主键从 data[resource][pk] 取值)
* @returns {(data: Object) => Array<Object>} 传入一行数据,返回其可用操作按钮列表
* @returns {(data: Record<string, unknown>) => DataListOperation[]} 传入一行数据,返回其可用操作按钮列表
*/
declare function useItemOperationsAccess(itemOperations?: Array<any>, itemOperationsAccess?: Map<string, any[]>, pk?: string, resource?: string): (data: any) => Array<any>;
declare function useItemOperationsAccess(itemOperations?: DataListOperation[], itemOperationsAccess?: DataListItemOperationsAccess, pk?: string, resource?: string): (data: Record<string, unknown>) => DataListOperation[];
/**
* 判断是否需要渲染操作列:操作按钮需通过全局权限校验(auth.check),且(若配置了行级权限映射)当前数据中至少一行拥有权限
* @param {Array<Object>} [operations=[]] 操作按钮配置
* @param {Map<string, Array>} [itemOperationsAccess=new Map] 操作 uuid 到有权限的数据主键列表的映射
* @param {Array<Object>} [dataSource=[]] 当前页数据
* @param {DataListOperation[]} [operations=[]] 操作按钮配置
* @param {DataListItemOperationsAccess} [itemOperationsAccess=new Map] 操作 uuid 到有权限的数据主键列表的映射
* @param {Record<string, unknown>[]} [dataSource=[]] 当前页数据
* @param {string} [pk='id'] 主键字段名
* @param {string} [resource] 数据嵌套的资源字段名
* @returns {boolean} 是否存在可展示的操作列
*/
declare function useHasOperationColumn(operations?: Array<any>, itemOperationsAccess?: Map<string, any[]>, dataSource?: Array<any>, pk?: string, resource?: string): boolean;
declare function useHasOperationColumn(operations?: DataListOperation[], itemOperationsAccess?: DataListItemOperationsAccess, dataSource?: Record<string, unknown>[], pk?: string, resource?: string): boolean;
/**
* 生成行内/批量操作点击后的处理逻辑:isRefresh=1 触发整体刷新(onReload),isRefresh=2 仅拉取该行最新详情与权限并合并回 dataSource(局部刷新)
* @param {Object} props 列表状态,须包含 dataSource/itemOperationsAccess/onReload
@@ -58,91 +266,10 @@ declare function useOperationCallback(props: any, listCode: string, primaryKey?:
/**
* 组合式获取并管理列表数据(分页/tab/筛选条件/侧边栏/关键字等),供 DataListHelper 使用
* @param {string} listCode 列表标识
* @param {Object} base62params 初始查询参数
* @returns {Object} 列表状态与操作方法(dataSource/tab/page/pageSize/condition/sider/keyword/total/itemOperationsAccess/onXxxChange/onReload/payload 等)
* @param {DataListQueryParams} base62params 初始查询参数
* @returns {DataListHelperState}
*/
declare function useDataListHelper(listCode: string, base62params: any): any;
/**
* 数据列表根组件:根据 isItemGridLayout 选择宫格(DataListFramework)或表格(DataTableFramework)布局,
* 也可通过 theme 动态加载自定义主题组件替代默认布局;并通过 DataListContext 向下透传分页/筛选/选中等状态与操作方法
* @param {Object} props
* @param {boolean} [props.isItemGridLayout] 是否使用宫格布局(否则使用表格布局,theme 设置时忽略)
* @param {string} [props.theme] 自定义主题组件标识,设置后通过 core.getWidgetComponent 动态加载并替代默认布局
* @param {Object} [props.themeProps] 传给自定义主题组件的 $setting
* @param {Function} [props.onClickCallback] 行内/批量操作点击后的回调
* @param {Function} [props.onReload] 刷新回调
* @param {string} [props.listCode] 列表标识
* @param {number} [props.total=0] 数据总条数
* @param {number} [props.page=0] 当前页码
* @param {Function} [props.onPageChange] 页码变更回调
* @param {number} [props.pageSize=30] 每页条数
* @param {Function} [props.onPageSizeChange] 每页条数变更回调
* @param {*} [props.tab] 当前选中的 tab
* @param {Function} [props.onTabChange] tab 变更回调
* @param {string} [props.keyword] 关键字搜索值
* @param {Function} [props.onKeywordChange] 关键字变更回调
* @param {Object} [props.condition] 筛选条件
* @param {Function} [props.onConditionChange] 筛选条件变更回调
* @param {*} [props.sider] 侧边栏选中值
* @param {Function} [props.onSiderChange] 侧边栏选中值变更回调
* @param {boolean|Object} [props.layouts] 自定义子布局组件集合(sider/filter/footer/toolbar/empty),false 表示全部隐藏
* @param {Object} [props.classNames={}] 各区块自定义 className
* @param {Object} [props.payload={}] 附加请求参数
* @param {Array} [props.dataSource=[]] 列表数据
* @param {Object} [props.rowSelection] 行选择配置
* @param {Function} [props.getSelectedRows] 获取已选中行的方法,未提供时默认返回 dataSource
* @param {string} [props.primaryKey] 主键字段名
*/
declare function DataList({ isItemGridLayout, theme, themeProps, onClickCallback, onReload, listCode, total, page, onPageChange, pageSize, onPageSizeChange, tab, onTabChange, keyword, onKeywordChange, condition, onConditionChange, sider, onSiderChange, layouts, classNames, payload, dataSource, rowSelection, getSelectedRows: getSelectedRowsProp, primaryKey, ...props }: {
isItemGridLayout?: boolean;
theme?: string;
themeProps?: any;
onClickCallback?: Function;
onReload?: Function;
listCode?: string;
total?: number;
page?: number;
onPageChange?: Function;
pageSize?: number;
onPageSizeChange?: Function;
tab?: any;
onTabChange?: Function;
keyword?: string;
onKeywordChange?: Function;
condition?: any;
onConditionChange?: Function;
sider?: any;
onSiderChange?: Function;
layouts?: boolean | any;
classNames?: any;
payload?: any;
dataSource?: any[];
rowSelection?: any;
getSelectedRows?: Function;
primaryKey?: string;
}): React.JSX.Element;
declare namespace DataList {
namespace propTypes {
let classNames: PropTypes.Requireable<Required<PropTypes.InferProps<{
sider: PropTypes.Requireable<string>;
filter: PropTypes.Requireable<string>;
footer: PropTypes.Requireable<string>;
toolbar: PropTypes.Requireable<string>;
container: PropTypes.Requireable<string>;
content: PropTypes.Requireable<string>;
item: PropTypes.Requireable<string>;
empty: PropTypes.Requireable<string>;
}>>>;
let layouts: PropTypes.Requireable<NonNullable<boolean | Required<PropTypes.InferProps<{
sider: PropTypes.Requireable<NonNullable<PropTypes.ReactElementLike | PropTypes.ReactComponentLike>>;
filter: PropTypes.Requireable<NonNullable<PropTypes.ReactElementLike | PropTypes.ReactComponentLike>>;
footer: PropTypes.Requireable<NonNullable<PropTypes.ReactElementLike | PropTypes.ReactComponentLike>>;
toolbar: PropTypes.Requireable<NonNullable<PropTypes.ReactElementLike | PropTypes.ReactComponentLike>>;
empty: PropTypes.Requireable<NonNullable<PropTypes.ReactElementLike | PropTypes.ReactComponentLike>>;
}>>>>;
}
}
declare function useDataListHelper(listCode: string, base62params: DataListQueryParams): DataListHelperState;
/**
* 列表筛选区:isConditionFormLayout 为 true 时拉取后台配置的条件表单结构并渲染 GridLayoutForm,否则渲染默认的关键字搜索框
@@ -179,12 +306,12 @@ declare namespace DataListFilter {
* @param {Object} props
* @param {string} [props.className] 自定义 className
* @param {string} [props.title] 列表标题
* @param {Array<Object>} [props.tabs] tab 配置列表
* @param {DataListTab[]} [props.tabs] tab 配置列表
*/
declare function DataListToolbar({ className, title, tabs }: {
className?: string;
title?: string;
tabs?: Array<any>;
tabs?: DataListTab[];
}): React.JSX.Element;
/**
@@ -204,29 +331,29 @@ declare function DataListSider({ className, width, isTreeSider }: {
* 列表底部:渲染批量操作按钮与分页器;operations 为空且不分页时不渲染任何内容
* @param {Object} props
* @param {string} [props.className] 自定义 className
* @param {Array<Object>} [props.operations] 批量操作按钮配置
* @param {DataListOperation[]} [props.operations] 批量操作按钮配置
* @param {boolean} [props.isOperations] 是否展示批量操作按钮
* @param {boolean} [props.isPaginate] 是否展示分页器
*/
declare function DataListFooter({ className, operations, isOperations, isPaginate }: {
className?: string;
operations?: Array<any>;
operations?: DataListOperation[];
isOperations?: boolean;
isPaginate?: boolean;
}): React.JSX.Element;
/**
* DataList 的开箱即用封装:根据 listCode 自动拉取结构与数据、管理分页/筛选/选中等状态,
* 并通过 ref 暴露 onReload/onClickCallback/getSelectedRows
* 并通过 ref 暴露 reload/emitOperation/getSelectedRows
* @param {Object} props
* @param {string} props.listCode 列表标识
* @param {Object} [props.base62params] 初始查询参数
* @param {DataListQueryParams} [props.base62params] 初始查询参数
* @param {string} [props.className] 自定义 className
* @param {string} [props.theme] 自定义主题组件标识,未传时使用结构配置中的 theme
* @param {Object} [props.themeProps] 传给主题组件的 $setting,会与结构配置中的 themeConfig 合并
* @param {boolean|Object} [props.layouts] 自定义子布局组件集合
* @param {Object} [props.classNames] 各区块自定义 className
* @param {Object} [props.rowSelection] 行选择配置(type/selectedRowKeys/defaultSelectedRowKeys/onChange 等)
* @param {DataListLayouts|false} [props.layouts] 自定义子布局组件集合
* @param {DataListClassNames} [props.classNames] 各区块自定义 className
* @param {DataListRowSelection} [props.rowSelection] 行选择配置(type/selectedRowKeys/defaultSelectedRowKeys/onChange 等)
* @param {(dataSource: Array, meta: Object) => void} [props.onDataSourceChange] dataSource 变更后的回调
*/
declare const DataListHelper: React.ForwardRefExoticComponent<React.RefAttributes<any>>;
@@ -234,7 +361,7 @@ declare const DataListHelper: React.ForwardRefExoticComponent<React.RefAttribute
declare const _default: React.Context<{
listCode: string;
classNames: {};
getBase62params: (k: any, defaultValue: any) => void;
getBase62params: (k: string, defaultValue: unknown) => void;
getSelectedRows: () => any[];
onReload: () => void;
onClickCallback: () => void;
@@ -258,22 +385,22 @@ declare const _default: React.Context<{
* @param {Object} props
* @param {string} [props.className] 自定义 className
* @param {string} [props.primaryKey] 主键字段名
* @param {Array<Object>} [props.columns=[]] 列配置
* @param {Array<Object>} [props.dataSource=[]] 表格数据
* @param {(record: Object, index: number) => *} [props.operationRender] 操作列渲染函数,提供时会追加一列操作列
* @param {DataListColumn[]} [props.columns=[]] 列配置
* @param {Record<string, unknown>[]} [props.dataSource=[]] 表格数据
* @param {(record: Record<string, unknown>, index: number) => ReactNode} [props.operationRender] 操作列渲染函数,提供时会追加一列操作列
* @param {number} [props.operationWidth=180] 操作列宽度
* @param {Object} [props.components={}] antd Table 的 components 配置
* @param {Object} [props.rowSelection] 行选择配置
* @param {DataListRowSelection} [props.rowSelection] 行选择配置
*/
declare function DataListTable({ className, primaryKey, columns, dataSource, operationRender, operationWidth, components, rowSelection, ...props }: {
className?: string;
primaryKey?: string;
columns?: Array<any>;
dataSource?: Array<any>;
operationRender?: (record: any, index: number) => any;
columns?: DataListColumn[];
dataSource?: Record<string, unknown>[];
operationRender?: (record: Record<string, unknown>, index: number) => ReactNode;
operationWidth?: number;
components?: any;
rowSelection?: any;
rowSelection?: DataListRowSelection;
}): React.JSX.Element;
/**
@@ -285,20 +412,20 @@ declare function DataListTable({ className, primaryKey, columns, dataSource, ope
* @param {number} [props.rowHeight] 行高
* @param {[number, number]} [props.itemMargin] 卡片间距 [marginX, marginY]
* @param {*} [props.containerPadding] 容器内边距
* @param {Array<Object>} [props.fields] 卡片内字段/组件布局配置
* @param {GridLayoutItem[]} [props.fields] 卡片内字段/组件布局配置
* @param {string} [props.primaryKey] 主键字段名
* @param {Array<Object>} [props.dataSource] 列表数据
* @param {(dataSource: Array) => *} [props.beforeRender=null] 数据渲染前的额外内容
* @param {(dataSource: Array) => *} [props.afterRender=null] 数据渲染后的额外内容
* @param {Record<string, unknown>[]} [props.dataSource] 列表数据
* @param {(dataSource: Record<string, unknown>[]) => ReactNode} [props.beforeRender=null] 数据渲染前的额外内容
* @param {(dataSource: Record<string, unknown>[]) => ReactNode} [props.afterRender=null] 数据渲染后的额外内容
* @param {string} [props.itemClassName] 传给每张卡片(itemRender.children)的 className
* @param {(children: *, data: Object, index: number) => *} [props.itemRender] 卡片渲染包装函数
* @param {(children: ReactNode, data: Record<string, unknown>, index: number) => ReactNode} [props.itemRender] 卡片渲染包装函数
* @param {*} [props.empty] 空数据时展示的内容
* @param {string} [props.className] 自定义 className
* @param {Object} [props.style={}] 容器行内样式
* @param {string} [props.theme] GridLayout 主题
* @param {Object} [props.themeProps={}] GridLayout 主题参数
* @param {Array<Object>} [props.groups=[{ key: 'default', label: '默认' }]] 分组配置
* @param {Object} [props.rowSelection] 行选择配置(selectedRowKeys/onChange/type)
* @param {GridLayoutGroup[]} [props.groups=[{ key: 'default', label: '默认' }]] 分组配置
* @param {DataListRowSelection} [props.rowSelection] 行选择配置(selectedRowKeys/onChange/type)
*/
declare function DataListContent({ column, colWidth, cols, rowHeight, itemMargin, containerPadding, fields, primaryKey, dataSource, beforeRender, afterRender, itemClassName, itemRender, empty, className, style, theme, themeProps, groups, rowSelection, }: {
column?: number;
@@ -307,20 +434,20 @@ declare function DataListContent({ column, colWidth, cols, rowHeight, itemMargin
rowHeight?: number;
itemMargin?: [number, number];
containerPadding?: any;
fields?: Array<any>;
fields?: _[];
primaryKey?: string;
dataSource?: Array<any>;
beforeRender?: (dataSource: any[]) => any;
afterRender?: (dataSource: any[]) => any;
dataSource?: Record<string, unknown>[];
beforeRender?: (dataSource: Record<string, unknown>[]) => _;
afterRender?: (dataSource: Record<string, unknown>[]) => _;
itemClassName?: string;
itemRender?: (children: any, data: any, index: number) => any;
itemRender?: (children: _, data: Record<string, unknown>, index: number) => _;
empty?: any;
className?: string;
style?: any;
theme?: string;
themeProps?: any;
groups?: Array<any>;
rowSelection?: any;
groups?: _[];
rowSelection?: DataListRowSelection;
}): React.JSX.Element;
/**
@@ -328,46 +455,46 @@ declare function DataListContent({ column, colWidth, cols, rowHeight, itemMargin
* @param {Object} props
* @param {string} [props.listCode] 列表标识
* @param {string} [props.className] 自定义 className
* @param {Object} [props.layouts={}] 子布局组件集合 { sider, filter, toolbar, footer, empty }
* @param {Array<Object>} [props.dataSource] 列表数据
* @param {DataListLayouts} [props.layouts={}] 子布局组件集合 { sider, filter, toolbar, footer, empty }
* @param {Record<string, unknown>[]} [props.dataSource] 列表数据
* @param {boolean} [props.isPaginate] 是否分页
* @param {boolean} [props.isItemOperations] 是否展示行内操作按钮
* @param {boolean} [props.isBatchOperations] 是否展示批量操作按钮
* @param {Array<Object>} [props.batchOperations] 批量操作按钮配置
* @param {Array<Object>} [props.itemOperations] 行内操作按钮配置
* @param {Map<string, Array>} [props.itemOperationsAccess] 行内操作权限映射
* @param {DataListOperation[]} [props.batchOperations] 批量操作按钮配置
* @param {DataListOperation[]} [props.itemOperations] 行内操作按钮配置
* @param {DataListItemOperationsAccess} [props.itemOperationsAccess] 行内操作权限映射
* @param {string} [props.resource] 数据嵌套的资源字段名
* @param {string} [props.primaryKey] 主键字段名
* @param {string} [props.title] 列表标题
* @param {Object} [props.itemGridLayout] 卡片宫格布局配置,透传给 DataListContent
* @param {DataListItemForGridLayout} [props.itemGridLayout] 卡片宫格布局配置,透传给 DataListContent
* @param {Object} [props.$setting] 主题设置,包含 column/colWidth/beforeRender/afterRender/style/itemMargin/containerPadding/isMarkSelected
* @param {Array<Object>} [props.tabs] tab 配置
* @param {DataListTab[]} [props.tabs] tab 配置
* @param {boolean} [props.isConditionFormLayout] 是否使用条件表单布局
* @param {boolean} [props.isTreeSider] 是否展示树形侧边栏
* @param {Object} [props.treeSiderConfig] 树形侧边栏配置
* @param {Object} [props.rowSelection] 行选择配置
* @param {DataListRowSelection} [props.rowSelection] 行选择配置
*/
declare function DataListFramework({ listCode, className, layouts, dataSource, isPaginate, isItemOperations, isBatchOperations, batchOperations, itemOperations, itemOperationsAccess, resource, primaryKey, title, itemGridLayout, $setting, tabs, isConditionFormLayout, isTreeSider, treeSiderConfig, rowSelection, }: {
listCode?: string;
className?: string;
layouts?: any;
dataSource?: Array<any>;
layouts?: DataListLayouts;
dataSource?: Record<string, unknown>[];
isPaginate?: boolean;
isItemOperations?: boolean;
isBatchOperations?: boolean;
batchOperations?: Array<any>;
itemOperations?: Array<any>;
itemOperationsAccess?: Map<string, any[]>;
batchOperations?: DataListOperation[];
itemOperations?: DataListOperation[];
itemOperationsAccess?: DataListItemOperationsAccess;
resource?: string;
primaryKey?: string;
title?: string;
itemGridLayout?: any;
itemGridLayout?: DataListItemForGridLayout;
$setting?: any;
tabs?: Array<any>;
tabs?: DataListTab[];
isConditionFormLayout?: boolean;
isTreeSider?: boolean;
treeSiderConfig?: any;
rowSelection?: any;
rowSelection?: DataListRowSelection;
}): React.JSX.Element;
/**
@@ -375,20 +502,20 @@ declare function DataListFramework({ listCode, className, layouts, dataSource, i
* @param {Object} props
* @param {string} [props.listCode] 列表标识
* @param {string} [props.className] 自定义 className
* @param {Object} [props.layouts={}] 子布局组件集合 { sider, filter, toolbar, footer }
* @param {Array<Object>} [props.dataSource] 表格数据
* @param {Array<Object>} [props.columns] 表格列配置
* @param {DataListLayouts} [props.layouts={}] 子布局组件集合 { sider, filter, toolbar, footer }
* @param {Record<string, unknown>[]} [props.dataSource] 表格数据
* @param {DataListColumn[]} [props.columns] 表格列配置
* @param {boolean} [props.isItemOperations] 是否展示行内操作按钮(结合权限计算实际是否展示操作列)
* @param {boolean} [props.isBatchOperations] 是否展示批量操作按钮
* @param {Array<Object>} [props.batchOperations] 批量操作按钮配置
* @param {Array<Object>} [props.itemOperations] 行内操作按钮配置
* @param {Map<string, Array>} [props.itemOperationsAccess] 行内操作权限映射
* @param {DataListOperation[]} [props.batchOperations] 批量操作按钮配置
* @param {DataListOperation[]} [props.itemOperations] 行内操作按钮配置
* @param {DataListItemOperationsAccess} [props.itemOperationsAccess] 行内操作权限映射
* @param {string} [props.resource] 数据嵌套的资源字段名
* @param {string} [props.primaryKey] 主键字段名
* @param {string} [props.title] 列表标题
* @param {Array<Object>} [props.tabs] tab 配置
* @param {DataListTab[]} [props.tabs] tab 配置
* @param {boolean} [props.isPaginate] 是否分页
* @param {Object} [props.rowSelection] 行选择配置
* @param {DataListRowSelection} [props.rowSelection] 行选择配置
* @param {boolean} [props.isTreeSider] 是否展示树形侧边栏
* @param {Object} [props.treeSiderConfig] 树形侧边栏配置
* @param {boolean} [props.isConditionFormLayout] 是否使用条件表单布局
@@ -396,23 +523,24 @@ declare function DataListFramework({ listCode, className, layouts, dataSource, i
declare function DataTableFramework({ listCode, className, layouts, dataSource, columns, isItemOperations, isBatchOperations, batchOperations, itemOperations, itemOperationsAccess, resource, primaryKey, title, tabs, isPaginate, rowSelection, isTreeSider, treeSiderConfig, isConditionFormLayout, ...props }: {
listCode?: string;
className?: string;
layouts?: any;
dataSource?: Array<any>;
columns?: Array<any>;
layouts?: DataListLayouts;
dataSource?: Record<string, unknown>[];
columns?: DataListColumn[];
isItemOperations?: boolean;
isBatchOperations?: boolean;
batchOperations?: Array<any>;
itemOperations?: Array<any>;
itemOperationsAccess?: Map<string, any[]>;
batchOperations?: DataListOperation[];
itemOperations?: DataListOperation[];
itemOperationsAccess?: DataListItemOperationsAccess;
resource?: string;
primaryKey?: string;
title?: string;
tabs?: Array<any>;
tabs?: DataListTab[];
isPaginate?: boolean;
rowSelection?: any;
rowSelection?: DataListRowSelection;
isTreeSider?: boolean;
treeSiderConfig?: any;
isConditionFormLayout?: boolean;
}): React.JSX.Element;
export { DataListContent, _default as DataListContext, DataListFilter, DataListFooter, DataListFramework, DataListHelper, DataListSider, DataListTable, DataListToolbar, DataTableFramework, DataList as default, useCellEditableComponents, useColumnsRender, useDataListHelper, useDataSource, useHasOperationColumn, useItemOperationsAccess, useOperationCallback, useStructure };
export { DataListContent, _default as DataListContext, DataListFilter, DataListFooter, DataListFramework, DataListHelper, DataListSider, DataListTable, DataListToolbar, DataTableFramework, useCellEditableComponents, useColumnsRender, useDataListHelper, useHasOperationColumn, useItemOperationsAccess, useOperationCallback };
export type { DataListAPI, DataListClassNames, DataListColumn, DataListContextValue, DataListHelperRef, DataListHelperState, DataListItemForGridLayout, DataListItemOperationsAccess, DataListLayouts, DataListOperation, DataListQueryParams, DataListRowSelection, DataListStructure, DataListTab };
+8 -10
View File
@@ -1,22 +1,20 @@
import { w as t, t as e, o as r, r as o, x as i, s as l, q as u, v as n, p as D, y as L, n as p, A as C, z as m, J as b, C as c, F, E as d, I as k, B as w } from "./common/main.js";
import { w as t, t as e, o, r, x as i, s as l, q as n, v as D, p as L, y as u, n as p, A as C, z as m, F as b, C as F, B as d, E as c } from "./common/main.js";
export {
t as DataListContent,
e as DataListContext,
r as DataListFilter,
o as DataListFooter,
o as DataListFilter,
r as DataListFooter,
i as DataListFramework,
l as DataListHelper,
u as DataListSider,
n as DataListTable,
D as DataListToolbar,
L as DataTableFramework,
n as DataListSider,
D as DataListTable,
L as DataListToolbar,
u as DataTableFramework,
p as default,
C as useCellEditableComponents,
m as useColumnsRender,
b as useDataListHelper,
c as useDataSource,
F as useHasOperationColumn,
d as useItemOperationsAccess,
k as useOperationCallback,
w as useStructure
c as useOperationCallback
};
+82 -117
View File
@@ -1,21 +1,12 @@
import React, { CSSProperties } from 'react';
import { FormInstance, Rule } from 'rc-field-form/es/interface';
import PropTypes from 'prop-types';
/**
* 执行一段 JS 表达式/函数并跟踪其依赖的表单字段,依赖字段变化时自动重新执行
* @param {string} fn 要执行的表达式源码,为空时直接返回 initialValue
* @param {*} initialValue 初始值/执行出错时的回退值
* @param {Object} [params] 传给表达式的额外参数
* @param {Object} [fns] 传给表达式的额外可调用函数
* @param {*} [basicForm] 表达式里 getFieldValueForBasicForm 取值用的外层表单实例
* @param {string} [resultType] 结果值的目标类型,用于类型转换
* @returns {[*, *]} [执行结果(按 resultType 转换后), 执行出错时的错误对象]
*/
declare function useFnRun(fn: string, initialValue: any, params?: any, fns?: any, basicForm?: any, resultType?: string): [any, any];
import { GridLayoutProps, LayoutField, GridLayoutItem, GridLayoutGroup, FormInstance } from './grid-layout';
export { FormInstance } from './grid-layout';
import { Rule } from 'rc-field-form/es/interface';
export { Rule } from 'rc-field-form/es/interface';
export { useFnRun } from './grid-layout';
/** useStructure 返回的表单结构数据,请求完成前为 `{ items: [], hides: [] }` */
interface FormStructure {
interface GridLayoutFormStructure extends GridLayoutProps {
/** 记录主键 */
pk?: unknown
/** 表单唯一标识 */
@@ -26,38 +17,18 @@ interface FormStructure {
resource?: string
/** 字段对齐方式 */
align?: unknown
/** 网格列数 */
cols?: number
/** 网格行高(px) */
rowHeight?: number
/** 网格水平间距(px) */
marginX?: number
/** 网格垂直间距(px) */
marginY?: number
/** 容器主题标识,对应 core.getWidgetComponent 的加载路径 */
theme?: string
/** 传给 theme 组件的 $setting 配置 */
themeProps?: Record<string, unknown>
/** 字段分组配置 */
groups?: FormGroup[]
/** 字段联动监听字段列表(字段 code 数组) */
listenChangeFields?: string[]
/** 字段联动处理函数/表达式,经 func.exec 执行 */
listenChangeFieldsFunc?: WidgetDecorator
listenChangeFieldsFunc?: GridLayoutFormWidgetDecorator
/** 可见字段列表(field.hidden 为 false) */
items?: FormItem[]
items?: GridLayoutFormItem[]
/** 隐藏字段列表(field.hidden 为 true) */
hides?: FormField[]
hides?: GridLayoutFormField[]
}
/** 表单字段定义(对应后端返回的 field 对象) */
interface FormField {
/** 字段 name,对应 rc-field-form Field.name */
code?: string
/** 字段值类型(string/number/boolean/array/bool/json 等) */
type?: string
/** 字段标签 */
label?: string
/** 表单字段定义(对应后端返回的 field 对象,继承布局通用字段) */
interface GridLayoutFormField extends LayoutField {
/** 是否必填 */
required?: boolean
/** 是否隐藏 */
@@ -71,47 +42,42 @@ interface FormField {
/** 字段提示文字 */
help?: string
/** 校验规则配置 */
validators?: FieldValidators
/** 透传给控件 $setting 的扩展配置 */
extras?: Record<string, unknown>
/** 字段初始值 */
initialValue?: unknown
/** 初始值语言(用于特定类型的取值转换) */
initialValueLanguage?: string
/** 虚拟字段,不参与表单提交 */
isVirtual?: boolean
/** 控件标识 */
widget?: string
/** 控件前缀 */
widgetPrefix?: string
validators?: GridLayoutFormFieldValidators
/** 控件切换表达式/函数 */
widgetDecorator?: WidgetDecorator
widgetDecorator?: GridLayoutFormWidgetDecorator
/** 可切换的候选子控件列表 */
subWidgets?: SubWidget[]
subWidgets?: GridLayoutFormSubWidget[]
}
/** 表单项(网格布局单元,包含字段定义与布局信息) */
interface FormItem {
/** 字段定义 */
field?: FormField
/** 网格 x 坐标 */
x?: number
/** 网格 y 坐标 */
y?: number
/** 网格宽度(列数) */
w?: number
/** 网格高度(行数) */
h?: number
[key: string]: unknown
interface GridLayoutFormItem extends GridLayoutItem {
/** 表单字段定义(收窄自 GridLayoutItem.field) */
field?: GridLayoutFormField
}
/** 字段分组配置,用于主题多分组渲染 */
interface FormGroup {
/** 分组唯一标识 */
key: string
/** 分组显示标签 */
label?: string
[key: string]: unknown
/** 字段分组配置,用于主题多分组渲染(结构等同于 GridLayoutGroup) */
type GridLayoutFormGroup = GridLayoutGroup
/** itemWidgetRender 生成的渲染函数接收的字段 props(即 GridLayoutFormField 字段在运行时的合并结果) */
type GridLayoutFormItemWidgetProps = GridLayoutFormField & Record<string, unknown>
/**
* itemWidgetRender 中实际渲染的部件组件约定接收的 props
* (由 itemWidgetRender 注入,开发者在实现自定义控件时参考此约定)
*/
interface GridLayoutFormItemWidgetComponentProps {
/** 字段值类型 */
type?: string
/** rc-field-form 表单实例 */
rcform?: unknown
/** 外层表单实例,用于字段联动/表达式求值 */
basicForm?: unknown
/** 传给 antd FormItem 的属性(label/noStyle/style/required/validateStatus/help 等) */
itemProps?: Record<string, unknown>
/** 传给实际输入控件的属性(placeholder/value/onChange 等) */
fieldProps?: Record<string, unknown>
/** 扩展配置,由 defaultProps.extras 的 key 从 props 中拆分而来 */
$setting?: Record<string, unknown>
}
/**
@@ -121,7 +87,7 @@ interface FormGroup {
type EnhancedFormInstance = FormInstance & Record<string, unknown>
/** useFormData / useFormSubmit / useFormAction 的表单配置参数 */
interface FormSetting {
interface GridLayoutFormSetting {
/** 初始化数据的请求地址,默认 `/api/{code}` */
initDataUri?: string
/** 初始化数据的请求方法,默认 `'GET'` */
@@ -143,7 +109,7 @@ interface SubmitOptions {
}
/** widgetDecorator 命中时可切换的候选子控件 */
interface SubWidget {
interface GridLayoutFormSubWidget {
/** 控件标识,规则同 GridLayoutFormWidget.widget */
widget: string
/** 控件前缀,默认同外层 widgetPrefix */
@@ -153,7 +119,16 @@ interface SubWidget {
}
/** 决定控件切换的表达式或函数,经 useFnRun 执行,返回值作为 subWidgets 下标 */
type WidgetDecorator = string | ((...args: unknown[]) => number | undefined)
type GridLayoutFormWidgetDecorator = string | ((...args: unknown[]) => number | undefined)
/**
* listenChangeFieldsFunc / validator 动态表达式可调用的表单字段 API;
* 由 GridLayoutForm 和 useRules 通过 func.exec 第三参数注入
*/
type GridLayoutFormAPI = Pick<
FormInstance,
'getFieldValue' | 'setFieldValue' | 'setFieldsValue' | 'isFieldTouched' | 'isFieldsTouched'
>
/** useFieldArray 的返回值 */
interface UseFieldArrayReturn {
@@ -185,7 +160,7 @@ interface UseFieldArrayReturn {
* GridLayoutFormWidget 字段校验规则配置
* 对应 useRules 的入参,由 validators prop 传入
*/
interface FieldValidators {
interface GridLayoutFormFieldValidators {
/** 校验类型:string 长度校验 / pattern 正则校验 / validator 自定义 */
type?: 'string' | 'pattern' | 'validator' | ''
/** 是否必填 */
@@ -205,53 +180,53 @@ interface FieldValidators {
/**
* 按表单编码(code)拉取表单结构定义,并把字段列表拆分为可见项(items)与隐藏项(hides)
* @param {string} code 表单编码,为空时不发起请求
* @returns {FormStructure} 表单结构数据,请求完成前为 `{ items: [], hides: [] }`
* @returns {GridLayoutFormStructure} 表单结构数据,请求完成前为 `{ items: [], hides: [] }`
*/
declare function useStructure(code: string): FormStructure;
declare function useStructure(code: string): GridLayoutFormStructure;
/**
* 根据字段的校验配置生成 rc-field-form 的 rules 数组;支持必填、长度限制、正则、自定义校验函数
* @param {FieldValidators} config
* @param {GridLayoutFormFieldValidators} config
* @param {string} fieldName 字段名,传给自定义 validator 表达式
* @param {string} fieldType 字段类型('number'|'string'|'array'|'bool'|'json' 等),决定必填校验的 type 及 bool/json 的映射
* @returns {Rule[]} rc-field-form 规则数组
*/
declare function useRules({ max, min, type, message, pattern, required, validator, }: FieldValidators, fieldName: string, fieldType: string): Rule[];
declare function useRules({ max, min, type, message, pattern, required, validator, }: GridLayoutFormFieldValidators, fieldName: string, fieldType: string): Rule[];
/**
* 按主键(primaryKey)拉取表单初始数据;primaryKey 为空时不请求
* @param {string} code 表单编码,用于拼接默认的请求地址 `/api/{code}`
* @param {string|number} primaryKey 记录主键,为空时不发起请求
* @param {FormSetting} [formSetting] 表单配置
* @param {GridLayoutFormSetting} [formSetting] 表单配置
* @returns {Record<string, unknown>|null} 拉取到的表单数据,请求完成前为 `null`
*/
declare function useFormData(code: string, primaryKey: string | number, formSetting?: FormSetting): Record<string, unknown> | null;
declare function useFormData(code: string, primaryKey: string | number, formSetting?: GridLayoutFormSetting): Record<string, unknown> | null;
/**
* 生成提交表单的回调函数;校验通过后按 `__RESOURCE__` 字段值裁剪数据(若存在),经 opt.serialize 序列化后提交
* @param {string} code 表单编码,用于拼接默认的请求地址 `/api/{code}`
* @param {string|number} primaryKey 记录主键,存在时拼到请求地址后面
* @param {FormSetting} [formSetting] 表单配置
* @param {GridLayoutFormSetting} [formSetting] 表单配置
* @returns {(form: FormInstance, opt?: SubmitOptions) => Promise<*>} 提交函数
*/
declare function useFormSubmit(code: string, primaryKey: string | number, formSetting?: FormSetting): (form: FormInstance, opt?: SubmitOptions) => Promise<any>;
declare function useFormSubmit(code: string, primaryKey: string | number, formSetting?: GridLayoutFormSetting): (form: FormInstance, opt?: SubmitOptions) => Promise<any>;
/**
* 组合 useFormData 与 useFormSubmit:数据拉取到后自动回填表单(否则重置),并返回已绑定 form 的提交函数
* @param {FormInstance} form rc-field-form 的表单实例
* @param {string} code 表单编码
* @param {string|number} primaryKey 记录主键
* @param {FormSetting} [formSetting] 表单配置(透传给 useFormData/useFormSubmit)
* @param {GridLayoutFormSetting} [formSetting] 表单配置(透传给 useFormData/useFormSubmit)
* @returns {(opt?: SubmitOptions) => Promise<*>} 已绑定当前 form 的提交函数
*/
declare function useFormAction(form: FormInstance, code: string, primaryKey: string | number, formSetting?: FormSetting): (opt?: SubmitOptions) => Promise<any>;
declare function useFormAction(form: FormInstance, code: string, primaryKey: string | number, formSetting?: GridLayoutFormSetting): (opt?: SubmitOptions) => Promise<any>;
/**
* 根据 widgetDecorator 表达式动态决定字段实际渲染的控件;
* widgetDecorator 执行结果为 subWidgets 的下标时,切换为对应子控件(合并其 props),
* 同时暴露 setDisabled/setRequired/getDisabled/getRequired 供 widgetDecorator 内部调用来动态调整禁用/必填状态
* @param {string} itemWidget 默认使用的控件(已归一化的 widget 路径)
* @param {WidgetDecorator} widgetDecorator 决定控件切换的表达式/函数,经 useFnRun 执行,返回值作为 subWidgets 下标
* @param {SubWidget[]} [subWidgets=[]] 可切换的候选子控件列表
* @param {GridLayoutFormWidgetDecorator} widgetDecorator 决定控件切换的表达式/函数,经 useFnRun 执行,返回值作为 subWidgets 下标
* @param {GridLayoutFormSubWidget[]} [subWidgets=[]] 可切换的候选子控件列表
* @param {FormInstance|null} [basicForm={}] 传给 widgetDecorator 执行上下文的表单实例
* @returns {[string, Object]} `[实际渲染的控件路径, 当前生效的控件 props]`
*/
declare function useWidgetDecorator(itemWidget: string, widgetDecorator: WidgetDecorator, subWidgets?: SubWidget[], basicForm?: FormInstance | null): [string, any];
declare function useWidgetDecorator(itemWidget: string, widgetDecorator: GridLayoutFormWidgetDecorator, subWidgets?: GridLayoutFormSubWidget[], basicForm?: FormInstance | null): [string, any];
/**
* 把受控的 value/onChange 与 rc-field-form 表单实例双向桥接:外部 value 变化时同步进表单
* (仅当与内部最近一次变更不同,避免循环),表单内部变化时回调 onChange;
@@ -289,8 +264,8 @@ declare function useFieldArray(value: any, onChange: (value: any[]) => void): Us
* @param {Object} props
* @param {string} [props.widget='Input'] 部件标识;以 `@` 或 `blob:` 开头时按原样使用,否则拼接 widgetPrefix 前缀
* @param {string} [props.widgetPrefix='@pkg/ff/grid-layout-forms'] widget 非绝对标识时使用的前缀
* @param {WidgetDecorator} [props.widgetDecorator] 决定控件切换的表达式/函数,详见 useWidgetDecorator
* @param {SubWidget[]} [props.subWidgets=[]] widgetDecorator 命中时可切换的候选子控件列表
* @param {GridLayoutFormWidgetDecorator} [props.widgetDecorator] 决定控件切换的表达式/函数,详见 useWidgetDecorator
* @param {GridLayoutFormSubWidget[]} [props.subWidgets=[]] widgetDecorator 命中时可切换的候选子控件列表
* @param {FormInstance|null} [props.basicForm] 表达式求值/字段联动用的外层表单实例
* @param {string} [props.code] 字段 name,对应 rc-field-form Field.name
* @param {string} [props.type] 字段值类型(string/number/boolean 等),用于取值归一化
@@ -300,7 +275,7 @@ declare function useFieldArray(value: any, onChange: (value: any[]) => void): Us
* @param {boolean} [props.noStyle] 是否隐藏 FormItem 的 label/border 等样式
* @param {Object} [props.style] FormItem 根节点行内样式
* @param {string} [props.help] 字段提示文字(tooltip)
* @param {FieldValidators} [props.validators] 校验规则配置,合并到 rc-field-form rules
* @param {GridLayoutFormFieldValidators} [props.validators] 校验规则配置,合并到 rc-field-form rules
* @param {Object} [props.extras] 透传给 ItemWidget.$setting 的扩展配置(key 由 defaultProps.extras 定义)
* @param {*} [props.initialValue] 字段初始值
* @param {string} [props.initialValueLanguage] 初始值语言(用于特定类型的取值转换)
@@ -310,8 +285,8 @@ declare function useFieldArray(value: any, onChange: (value: any[]) => void): Us
declare function GridLayoutFormWidget({ widget, widgetPrefix, widgetDecorator, subWidgets, basicForm, ...props }: {
widget?: string;
widgetPrefix?: string;
widgetDecorator?: WidgetDecorator;
subWidgets?: SubWidget[];
widgetDecorator?: GridLayoutFormWidgetDecorator;
subWidgets?: GridLayoutFormSubWidget[];
basicForm?: FormInstance | null;
code?: string;
type?: string;
@@ -321,7 +296,7 @@ declare function GridLayoutFormWidget({ widget, widgetPrefix, widgetDecorator, s
noStyle?: boolean;
style?: any;
help?: string;
validators?: FieldValidators;
validators?: GridLayoutFormFieldValidators;
extras?: any;
initialValue?: any;
initialValueLanguage?: string;
@@ -360,17 +335,17 @@ declare function GridLayoutFormHelper({ $setting, $close, extras, code, primaryK
* @param {number} [props.rowHeight=16] 栅格行高(px)
* @param {[number, number]} [props.itemMargin=[8, 16]] 字段项间距 [横向, 纵向](px)
* @param {[number, number]} [props.containerPadding=[0, 0]] 容器内边距 [纵向, 横向](px)
* @param {FormItem[]} [props.fields=[]] 可见字段配置列表(位置、尺寸、部件类型等)
* @param {FormField[]} [props.hides=[]] 隐藏字段配置列表,按 initialValueLanguage 求值后写入对应字段
* @param {GridLayoutFormItem[]} [props.fields=[]] 可见字段配置列表(位置、尺寸、部件类型等)
* @param {GridLayoutFormField[]} [props.hides=[]] 隐藏字段配置列表,按 initialValueLanguage 求值后写入对应字段
* @param {string|number} [props.primaryKey=0] 记录主键,注入为 `__PRIMARY_KEY__` 字段值
* @param {Record<string, unknown>} [props.formProps={}] 注入为 `__PROPS__` 字段值的表单级参数
* @param {FormItem[]} [props.formFields=[]] 额外注入的表单字段(与 formProps/primaryKey 一并作为初始 fields)
* @param {GridLayoutFormItem[]} [props.formFields=[]] 额外注入的表单字段(与 formProps/primaryKey 一并作为初始 fields)
* @param {string[]} [props.listenChangeFields] 触发联动表达式重新求值的字段列表
* @param {*} [props.listenChangeFieldsFunc] 字段值变化时执行的联动表达式(经 func.exec 执行)
* @param {(changedValues: Object, allValues: Object) => void} [props.onValuesChange] 表单值变化回调,先于联动表达式执行
* @param {string} [props.theme] 主题组件标识,指定时通过 GridLayoutFramework 渲染主题外壳
* @param {Object} [props.themeProps={}] 传给主题组件的额外参数
* @param {FormGroup[]} [props.groups=[{key:'default',label:'默认'}]] 字段分组配置,用于主题多分组渲染
* @param {GridLayoutFormGroup[]} [props.groups=[{key:'default',label:'默认'}]] 字段分组配置,用于主题多分组渲染
* @param {ReactNode} [props.children] 附加渲染在字段项之后的内容
*/
declare function GridLayoutForm({ name, form: initForm, basicForm, style, className, cols, rowHeight, itemMargin, containerPadding, fields, hides, primaryKey, formProps, formFields, listenChangeFields, listenChangeFieldsFunc, onValuesChange, theme, themeProps, groups, children, ...props }: {
@@ -383,29 +358,19 @@ declare function GridLayoutForm({ name, form: initForm, basicForm, style, classN
rowHeight?: number;
itemMargin?: [number, number];
containerPadding?: [number, number];
fields?: FormItem[];
hides?: FormField[];
fields?: GridLayoutFormItem[];
hides?: GridLayoutFormField[];
primaryKey?: string | number;
formProps?: Record<string, unknown>;
formFields?: FormItem[];
formFields?: GridLayoutFormItem[];
listenChangeFields?: string[];
listenChangeFieldsFunc?: any;
onValuesChange?: (changedValues: any, allValues: any) => void;
theme?: string;
themeProps?: any;
groups?: FormGroup[];
groups?: GridLayoutFormGroup[];
children?: React.ReactNode;
}): React.JSX.Element;
declare namespace GridLayoutForm {
namespace propTypes {
let fields: PropTypes.Requireable<any[]>;
let hides: PropTypes.Requireable<any[]>;
}
}
declare const _default: ({ code, isPreview, ...props }: {
[x: string]: any;
code: any;
isPreview?: boolean;
}) => React.JSX.Element;
export { GridLayoutForm, GridLayoutFormHelper, GridLayoutFormWidget, _default as default, useFieldArray, useFnRun, useFormAction, useFormData, useFormSubmit, useMergedFormValuesChange, useRules, useStructure, useWidgetDecorator };
export { GridLayoutForm, GridLayoutFormHelper, GridLayoutFormWidget, useFieldArray, useFormAction, useFormData, useFormSubmit, useMergedFormValuesChange, useRules, useStructure, useWidgetDecorator };
export type { EnhancedFormInstance, GridLayoutFormAPI, GridLayoutFormField, GridLayoutFormFieldValidators, GridLayoutFormGroup, GridLayoutFormItem, GridLayoutFormItemWidgetComponentProps, GridLayoutFormItemWidgetProps, GridLayoutFormSetting, GridLayoutFormStructure, GridLayoutFormSubWidget, GridLayoutFormWidgetDecorator, SubmitOptions, UseFieldArrayReturn };
+1 -1
View File
@@ -1,4 +1,4 @@
import { aa as s, ac as r, ab as u, a9 as o, ak as t, m, ah as d, af as i, ag as F, aj as g, ae as l, ad as c, ai as n } from "./common/main.js";
import { a8 as s, aa as r, a9 as u, a7 as o, ai as t, m, af as d, ad as i, ae as F, ah as g, ac as l, ab as c, ag as n } from "./common/main.js";
export {
s as GridLayoutForm,
r as GridLayoutFormHelper,
+179 -39
View File
@@ -1,24 +1,168 @@
import { FormInstance } from 'rc-field-form/es/interface';
export { FormInstance } from 'rc-field-form/es/interface';
import React from 'react';
/** 布局分组配置,用于主题多分组渲染 */
interface GridLayoutGroup {
/** 分组唯一标识 */
key: string
/** 分组显示标签 */
label?: string
[key: string]: unknown
}
/** 字段项盒模型配置(margin / padding / align / autoHeight) */
interface BoxStyle {
/** 是否按内容自适应高度(不再固定跨行) */
autoHeight?: boolean
/** 对齐方式,写入 `--grid-layout-box-align-items` */
alignItems?: string
/** 主轴对齐方式,写入 `--grid-layout-box-justify-content` */
justifyContent?: string
/** 外边距 - 上(px) */
marginTop?: number
/** 外边距 - 右(px) */
marginRight?: number
/** 外边距 - 下(px) */
marginBottom?: number
/** 外边距 - 左(px) */
marginLeft?: number
/** 内边距 - 上(px) */
paddingTop?: number
/** 内边距 - 右(px) */
paddingRight?: number
/** 内边距 - 下(px) */
paddingBottom?: number
/** 内边距 - 左(px) */
paddingLeft?: number
}
/**
* 字段内容配置基础类型(ff-grid-layout 与 ff-grid-layout-form 共用)
*/
interface LayoutField {
/** 字段标识,对应 rc-field-form 的 name */
code?: string
/** 字段标签 */
label?: string
/** 传给控件 $setting 的扩展配置 key 集合(key 存在时从 props 拆分为 extraProps) */
extras?: Record<string, unknown>
/** 是否虚拟字段,为 true 时不绑定表单字段(name 传 null) */
isVirtual?: boolean
/** 初始值,或 initialValueLanguage 为 'javascript' 时的表达式源码 */
initialValue?: unknown
/** 初始值类型,'javascript' 时把 initialValue 当表达式执行 */
initialValueLanguage?: string
/** 字段值目标类型(string / number / boolean / array 等),用于 toPrimitive 转换 */
type?: string
/** 部件标识;以 `@` 或 `blob:` 开头时按原样使用,否则拼接 widgetPrefix */
widget?: string
/** widget 非绝对标识时使用的前缀 */
widgetPrefix?: string
/** 盒模型配置;getNormalizeFields 渲染时从 field 中提取,不传给 ItemWidget */
boxStyle?: BoxStyle
[key: string]: unknown
}
/**
* ff-grid-layout 字段内容配置(在 LayoutField 基础上增加展示值转换配置)
*/
interface GridLayoutField extends LayoutField {
/** 展示值转换表达式(交给 DataConverter 处理) */
convertJs?: unknown
/** convertJs 表达式的附加配置 */
convertJsSetting?: unknown
}
/** 布局字段项(网格坐标 + 字段内容),对应 getNormalizeFields 入参列表的每一项 */
interface GridLayoutItem {
/** 字段唯一标识,用作 React key;优先于数组下标 */
i?: unknown
/** 网格 x 坐标(起始列,0-indexed) */
x?: number
/** 网格 y 坐标(起始行,0-indexed) */
y?: number
/** 网格宽度(列数) */
w?: number
/** 网格高度(行数) */
h?: number
/** 所属分组的 key,缺省时归入 'default' 分组 */
group?: string
/** 字段内容配置;field.boxStyle 决定盒模型,其余字段传给 ItemWidget */
field?: GridLayoutField
[key: string]: unknown
}
/** GridLayout 组件的布局配置参数(不含 form/DOM 相关 props) */
interface GridLayoutProps {
/** 栅格列数,默认 12 */
cols?: number
/** 栅格行高(px),默认 21 */
rowHeight?: number
/** 容器内边距 [纵向, 横向](px),默认 [0, 0] */
containerPadding?: [number, number]
/** 字段项间距 [纵向, 横向](px),默认 [4, 0] */
itemMargin?: [number, number]
/** 布局字段配置列表 */
fields?: GridLayoutItem[]
/** 字段分组配置,用于主题多分组渲染 */
groups?: GridLayoutGroup[]
/** 主题组件标识,通过 core.getWidgetComponent 异步加载 */
theme?: string
/** 传给主题组件的 $setting 配置 */
themeProps?: Record<string, unknown>
}
/** useStructure 返回的布局结构数据,请求完成前为 `{ items: [] }` */
interface GridLayoutStructure extends GridLayoutProps {
/** 布局唯一标识 */
uuid?: string
/** 布局编码 */
code?: string
/** 布局名称 */
name?: string
/** 关联资源标识 */
resource?: string
/** 记录主键 */
primaryKey?: unknown
/** 布局字段配置列表(API 返回名,组件侧对应 GridLayoutProps.fields) */
items?: GridLayoutItem[]
}
/** useField 返回值:[经 convertJs 转换后的展示值(未配置时等于原值), 原始字段值] */
/**
* useFnRun / useField 内 func.exec 脚本上下文中可调用的字段读取 API;
* 由 useFnRun 注入,包含当前表单与外层(basicForm)表单的只读接口
*/
type GridLayoutFieldAPI = Pick<FormInstance, 'getFieldValue' | 'isFieldTouched' | 'isFieldsTouched'> & {
/** 从外层(basicForm)表单获取字段值;无 basicForm 时返回 null */
getFieldValueForBasicForm: (name: Parameters<FormInstance['getFieldValue']>[0]) => unknown
}
type UseFieldReturn = [displayValue: unknown, rawValue: unknown]
/** useFnRun 返回值:[按 resultType 转换后的执行结果, 执行出错时的错误对象(null 表示无错误)] */
type UseFnRunReturn = [result: unknown, error: unknown]
/** rc-field-form 内部钩子的注册标识 */
declare const HOOK_MARK: "RC_FORM_INTERNAL_HOOKS";
/**
* 按布局 code 拉取布局结构定义(字段、主题、栅格设置等),code 变化时重新请求
* @param {string} code 布局的唯一编码
* @returns {Object} 布局结构数据,初始为 `{ items: [] }`
* @returns {GridLayoutStructure} 布局结构数据,请求完成前为 `{ items: [] }`
*/
declare function useStructure(code: string): any;
declare function useStructure(code: string): GridLayoutStructure;
/**
* 关联表单字段值,支持初始值表达式求值、watch 联动更新以及经 DataConverter 转换后的展示值
* @param {string} name 字段名(rc-field-form 的字段路径)
* @param {string} name 字段名(rc-field-form 的字段路径)
* @param {Object} setting 字段取值相关配置
* @param {*} [setting.initialValue] 初始值,或语言为 javascript 时的表达式源码
* @param {string} [setting.initialValueLanguage] 初始值类型,'javascript' 时把 initialValue 当表达式执行
* @param {*} [setting.convertJs] 用于生成展示值的转换表达式(交给 DataConverter 处理)
* @param {*} [setting.initialValue] 初始值,或语言为 javascript 时的表达式源码
* @param {string} [setting.initialValueLanguage] 初始值类型,'javascript' 时把 initialValue 当表达式执行
* @param {*} [setting.convertJs] 用于生成展示值的转换表达式(交给 DataConverter 处理)
* @param {*} [setting.convertJsSetting] convertJs 表达式的附加配置
* @param {string} [setting.type='string'] 字段值的目标类型,用于类型转换
* @param {string} [setting.type='string'] 字段值的目标类型,用于类型转换
* @param {*} [pContext] 表达式里 getFieldValueForBasicForm 取值用的外层表单实例
* @returns {[*, *]} [经 convertJs 转换后的展示值(未配置时等于原值), 原始字段值]
* @returns {UseFieldReturn}
*/
declare function useField(name: string, { initialValue, initialValueLanguage, convertJs, convertJsSetting, type, }: {
initialValue?: any;
@@ -26,39 +170,39 @@ declare function useField(name: string, { initialValue, initialValueLanguage, co
convertJs?: any;
convertJsSetting?: any;
type?: string;
}, pContext?: any): [any, any];
}, pContext?: any): UseFieldReturn;
/**
* 按 (y, x) 排序将字段列表归一化为渲染项列表(每项已用给定的 ItemWidget 渲染成元素)
* @param {Array} fields 字段配置列表
* @param {GridLayoutItem[]} fields 字段配置列表
* @param {Function} ItemWidget 用于渲染每个字段的组件
* @param {*} [basicForm] 传给每个字段渲染项的外层表单实例
* @returns {Array} 已排序并渲染完成的元素列表
* @returns {ReactNode[]} 已排序并渲染完成的元素列表
*/
declare function useGridLayoutFields(fields: any[], ItemWidget: Function, basicForm?: any): any[];
declare function useGridLayoutFields(fields: GridLayoutItem[], ItemWidget: Function, basicForm?: any): React.ReactNode[];
/**
* 执行一段 JS 表达式/函数并跟踪其依赖的表单字段,依赖字段变化时自动重新执行
* @param {string} fn 要执行的表达式源码,为空时直接返回 initialValue
* @param {*} initialValue 初始值/执行出错时的回退值
* @param {Object} [params] 传给表达式的额外参数
* @param {Object} [fns] 传给表达式的额外可调用函数
* @param {Partial<GridLayoutFieldAPI>} [fns] 传给表达式的额外可调用函数(useFnRun 会在此基础上注入 getFieldValue/isFieldTouched 等)
* @param {*} [basicForm] 表达式里 getFieldValueForBasicForm 取值用的外层表单实例
* @param {string} [resultType] 结果值的目标类型,用于类型转换
* @returns {[*, *]} [执行结果(按 resultType 转换后), 执行出错时的错误对象]
* @returns {UseFnRunReturn}
*/
declare function useFnRun(fn: string, initialValue: any, params?: any, fns?: any, basicForm?: any, resultType?: string): [any, any];
declare function useFnRun(fn: string, initialValue: any, params?: any, fns?: Partial<GridLayoutFieldAPI>, basicForm?: any, resultType?: string): UseFnRunReturn;
/**
* 按 widget 标识异步加载并渲染对应的部件组件,加载完成前不渲染任何内容;
* 加载出错时渲染错误信息文本
* @param {Object} props
* @param {string} [props.widget] 部件标识;以 `@` 或 `blob:` 开头时按原样使用,否则拼接 widgetPrefix 前缀
* @param {string} [props.widget] 部件标识;以 `@` 或 `blob:` 开头时按原样使用,否则拼接 widgetPrefix 前缀
* @param {string} [props.widgetPrefix='@pkg/ff/grid-layouts'] widget 非绝对标识时使用的前缀
* @param {*} [props.basicForm] 表达式求值/字段联动用的外层表单实例
* @param {FormInstance} [props.basicForm] 表达式求值/字段联动用的外层表单实例
*/
declare function GridLayoutWidget({ widget, widgetPrefix, basicForm, ...props }: {
widget?: string;
widgetPrefix?: string;
basicForm?: any;
basicForm?: FormInstance;
}): undefined;
/**
@@ -67,9 +211,9 @@ declare function GridLayoutWidget({ widget, widgetPrefix, basicForm, ...props }:
* @param {Object} props
* @param {string} [props.theme] 主题组件标识,通过 core.getWidgetComponent 加载
* @param {*} [props.basicForm] 传给主题组件及各分组内容的外层表单实例
* @param {Array} [props.items=[{key:'default',label:'默认'}]] 分组配置列表
* @param {Array} [props.fields=[]] 全部布局字段,按分组 key 过滤后分给对应 items 项
* @param {Function} [props.itemRender] 生成单个分组渲染内容的函数,签名为 (item, fields, children)
* @param {GridLayoutGroup[]} [props.items=[{key:'default',label:'默认'}]] 分组配置列表
* @param {GridLayoutItem[]} [props.fields=[]] 全部布局字段,按分组 key 过滤后分给对应 items 项
* @param {(item: GridLayoutGroup, fields: GridLayoutItem[], children: *) => *} [props.itemRender] 生成单个分组渲染内容的函数
* @param {Array} [props.chunks=[]] 额外附加在 items 之后、不参与过滤的分组项
* @param {*} [props.children] 仅附加给 key 为 'default' 的分组的内容
* @param {Object} [props.$setting={}] 传给主题组件的基础设置,会与 themeSetting 合并
@@ -77,9 +221,9 @@ declare function GridLayoutWidget({ widget, widgetPrefix, basicForm, ...props }:
declare function GridLayoutFramework({ theme, basicForm, items, fields, itemRender, chunks, children, $setting, ...themeSetting }: {
theme?: string;
basicForm?: any;
items?: any[];
fields?: any[];
itemRender?: Function;
items?: GridLayoutGroup[];
fields?: GridLayoutItem[];
itemRender?: (item: GridLayoutGroup, fields: GridLayoutItem[], children: any) => any;
chunks?: any[];
children?: any;
$setting?: any;
@@ -90,8 +234,8 @@ declare function GridLayoutFramework({ theme, basicForm, items, fields, itemRend
* 指定 theme 时委托 GridLayoutFramework 渲染主题外壳,否则直接渲染默认分组
* @param {Object} props
* @param {string} [props.name] 表单字段容器名(即 __LAYOUT_KEY__ 语义,由 GridLayoutHoc 传入)
* @param {*} [props.form] 外部传入的 rc-field-form 表单实例,不传时内部自建
* @param {*} [props.basicForm] 表达式求值/字段联动用的外层表单实例
* @param {FormInstance} [props.form] 外部传入的 rc-field-form 表单实例,不传时内部自建
* @param {FormInstance} [props.basicForm] 表达式求值/字段联动用的外层表单实例
* @param {Object} [props.style] 容器行内样式
* @param {string} [props.className] 容器额外 class 名
* @param {number} [props.cols=12] 栅格列数
@@ -100,17 +244,17 @@ declare function GridLayoutFramework({ theme, basicForm, items, fields, itemRend
* @param {[number, number]} [props.itemMargin=[4, 0]] 字段项间距 [纵向, 横向](px)
* @param {Object} [props.formProps={}] 注入为 `__PROPS__` 字段值的表单级参数
* @param {Array} [props.formFields=[]] 额外注入的表单字段(与 formProps 一并作为初始 fields)
* @param {Array} [props.fields=[]] 布局字段配置列表(位置、尺寸、部件类型等)
* @param {GridLayoutItem[]} [props.fields=[]] 布局字段配置列表(位置、尺寸、部件类型等)
* @param {Object} [props.data] 初始化/回填表单的数据
* @param {string} [props.theme] 主题组件标识,指定时通过 GridLayoutFramework 渲染主题外壳
* @param {string} [props.theme] 主题组件标识,指定时通过 GridLayoutFramework 渲染主题外壳
* @param {Object} [props.themeProps={}] 传给主题组件的额外参数
* @param {Array} [props.groups=[{key:'default',label:'默认'}]] 字段分组配置,用于主题多分组渲染
* @param {GridLayoutGroup[]} [props.groups=[{key:'default',label:'默认'}]] 字段分组配置,用于主题多分组渲染
* @param {*} [props.children] 附加渲染在字段项之后的内容
*/
declare function GridLayout({ name, form: initForm, basicForm, style, className, cols, rowHeight, containerPadding, itemMargin, formProps, formFields, fields, data, theme, themeProps, groups, children, ...props }: {
name?: string;
form?: any;
basicForm?: any;
form?: FormInstance;
basicForm?: FormInstance;
style?: any;
className?: string;
cols?: number;
@@ -119,17 +263,13 @@ declare function GridLayout({ name, form: initForm, basicForm, style, className,
itemMargin?: [number, number];
formProps?: any;
formFields?: any[];
fields?: any[];
fields?: GridLayoutItem[];
data?: any;
theme?: string;
themeProps?: any;
groups?: any[];
groups?: GridLayoutGroup[];
children?: any;
}): React.JSX.Element;
declare const _default: ({ code, data, ...props }: {
[x: string]: any;
code: any;
data: any;
}) => React.JSX.Element;
export { GridLayout, GridLayoutFramework, GridLayoutWidget, HOOK_MARK, _default as default, useField, useFnRun, useGridLayoutFields, useStructure };
export { GridLayout, GridLayoutFramework, GridLayoutWidget, HOOK_MARK, useField, useFnRun, useGridLayoutFields, useStructure };
export type { BoxStyle, GridLayoutField, GridLayoutFieldAPI, GridLayoutGroup, GridLayoutItem, GridLayoutProps, GridLayoutStructure, LayoutField, UseFieldReturn, UseFnRunReturn };
+10 -31
View File
@@ -1,46 +1,25 @@
import { GridLayoutItem, BoxStyle } from '../grid-layout';
/**
* 将布局字段配置按 (y, x) 排序并渲染为定位好的字段项元素列表
* @param {Array} [fields=[]] 布局字段配置列表,每项包含 i/x/y/w/h 及 field(可含 boxStyle)
* @param {GridLayoutItem[]} [fields=[]] 布局字段配置列表,每项包含 i/x/y/w/h 及 field(可含 boxStyle)
* @param {Function} ItemWidget 用于渲染每个字段内容的组件
* @param {*} [basicForm] 传给每个字段项的外层表单实例
* @returns {Array} 已定位、可直接渲染的字段项元素列表
*/
declare function getNormalizeFields(fields?: any[], ItemWidget: Function, basicForm?: any): any[];
declare function getNormalizeFields(fields?: GridLayoutItem[], ItemWidget: Function, basicForm?: any): any[];
/**
* 根据栅格坐标/尺寸及盒模型配置,生成布局字段项的行内样式(以 CSS 自定义属性表达)
* 根据栅格坐标/尺寸及盒模型配置,生成布局字段项的行内样式(以 CSS 自定义属性表达)
* @param {number} x 栅格列坐标
* @param {number} y 栅格行坐标
* @param {number} w 栅格宽度(列数)
* @param {number} h 栅格高度(行数)
* @param {Object} [boxStyle={}] 盒模型配置
* @param {boolean} [boxStyle.autoHeight] 是否按内容自适应高度(不再固定跨行)
* @param {string} [boxStyle.alignItems] 对齐方式,写入 `--grid-layout-box-align-items`
* @param {string} [boxStyle.justifyContent] 主轴对齐方式,写入 `--grid-layout-box-justify-content`
* @param {number} [boxStyle.marginTop] 外边距-上(px)
* @param {number} [boxStyle.marginRight] 外边距-右(px)
* @param {number} [boxStyle.marginBottom] 外边距-下(px)
* @param {number} [boxStyle.marginLeft] 外边距-左(px)
* @param {number} [boxStyle.paddingTop] 内边距-上(px)
* @param {number} [boxStyle.paddingRight] 内边距-右(px)
* @param {number} [boxStyle.paddingBottom] 内边距-下(px)
* @param {number} [boxStyle.paddingLeft] 内边距-左(px)
* @param {number} [height=0] 显式高度(px),传入时覆盖 autoHeight 计算出的 height
* @param {number} w 栅格宽度(列数)
* @param {number} h 栅格高度(行数)
* @param {BoxStyle} [boxStyle={}] 盒模型配置
* @param {number} [height=0] 显式高度(px),传入时覆盖 autoHeight 计算出的 height
* @returns {Object} 可直接用作 React style 的样式对象
*/
declare function getBoxStyle(x: number, y: number, w: number, h: number, boxStyle?: {
autoHeight?: boolean;
alignItems?: string;
justifyContent?: string;
marginTop?: number;
marginRight?: number;
marginBottom?: number;
marginLeft?: number;
paddingTop?: number;
paddingRight?: number;
paddingBottom?: number;
paddingLeft?: number;
}, height?: number): any;
declare function getBoxStyle(x: number, y: number, w: number, h: number, boxStyle?: BoxStyle, height?: number): any;
/**
* 将部件名归一化为完整标识;以 `@` 或 `blob:` 开头时按原样返回,否则拼接 widgetPrefix 前缀
* @param {string} [widget='Text'] 部件名
Vendored
+111
View File
@@ -1,3 +1,4 @@
import { WidgetType, WidgetContainerProps } from './button';
export { default as useMergedState } from 'rc-util/lib/hooks/useMergedState';
export { default as useEvent } from 'rc-util/lib/hooks/useEvent';
@@ -57,4 +58,114 @@ declare function useWidgetPropsUpdater($props: any, setLocal: (local: any) => vo
*/
declare function useWidgetProps($props: any, data?: any, fns?: any, deps?: any[]): [any, (patch: any) => void, any];
// ===== 用户数据结构(复用类型,JSDoc 无法跨文件引用,放 .d.ts) =====
interface UserRoleBinding {
user_uuid: string
role_uuid: string
created_at: string
updated_at: string
created_user: string
owned_user: string
}
interface UserInfo {
uuid: string
username: string
nickname: string
email: string
last_login_ip: string
is_active: 0 | 1
UserRole: UserRoleBinding[]
[key: string]: unknown
}
interface MenuItem {
/** 菜单唯一标识 */
uuid: string
/** 菜单显示名称 */
name: string
/** 图标 class 名 */
icon: string
/** 行为目标(组件标识 / 路由 uuid 等),含义随 widgetType 而定 */
widget: string
/** 行为类型 */
widgetType: WidgetType
/** 传给目标组件的 props 映射配置 */
widgetProps: Record<string, unknown>
/** 传给目标组件的 $setting 配置 */
widgetSetting: Record<string, unknown>
/** 弹窗容器配置 */
widgetContainerSetting: WidgetContainerProps
/** 子菜单 */
children?: MenuItem[]
}
interface RouteItem {
/** 路由唯一标识 */
uuid: string
/** 路由名称 */
name: string
/** react-router path,支持动态参数(如 /page/:id) */
uri: string
/** 是否为布局路由(外层 layout,不直接渲染页面内容) */
isLayout: boolean
/** 是否需要登录才能访问 */
isLogin: boolean
/** 是否为手机端专属路由 */
isPhone: boolean
/** 路由类型 */
type: Exclude<WidgetType, 'redirect'>
/** 是否精确匹配路径 */
exact: boolean
/** widget 标识(等同于 ButtonProps.widget),经 core.getWidgetComponent 加载 */
component: string
/** 传给页面组件的 props 映射配置 */
widgetProps: Record<string, unknown>
/** 传给页面组件的 $setting 配置 */
widgetSetting: Record<string, unknown>
/** 弹窗容器配置 */
widgetContainerSetting: WidgetContainerProps
/** 附加配置(如 layout 标识等) */
extra?: Record<string, unknown>
}
// ===== http — Proxy 模式产生交叉类型,JSDoc 无法表达 =====
/** 每次请求自动附加的请求头 */
interface HttpHeaders {
/** 客户端平台标识,固定为 'web' */
Platform: string
/** SaaS 租户标识,单租户时为 null */
SaaS: string | null
/** JWT Bearer token,未登录时为 undefined */
Authorization: string | undefined
}
// ===== func — ff-worker-pipe 无类型文件,显式声明 =====
/**
* 基于 Worker 的表达式执行引擎单例;
* exec 在独立 Worker 上下文中求值一段 JS 表达式/源码
*/
interface WorkerPipeInstance {
/**
* 在 Worker 上下文中执行一段 JS 表达式
* @param expression 要执行的表达式字符串
* @param args 传给表达式的参数(可在表达式内作为第一个参数使用)
* @param fns 注入到表达式执行作用域的额外可调用函数
* @param session 会话标识;相同 session 共享 Worker 侧工作区(this)
*/
exec: (
expression: string,
args?: Record<string, unknown>,
fns?: Record<string, Function>,
session?: string
) => Promise<unknown>
/** 清除指定 session 的 Worker 侧工作区 */
clear: (session: string) => void
}
export { useDeepEffect, useDeepEqualEffect, useOptions, useStateWithCallback, useSubscribeRequest, useUpdate, useWidgetProps, useWidgetPropsUpdater };
export type { HttpHeaders, MenuItem, RouteItem, UserInfo, UserRoleBinding, WorkerPipeInstance };
+1 -1
View File
@@ -2,7 +2,7 @@ import "lodash";
import "rc-field-form";
import "react";
import "react-use";
import { a4 as u, a3 as o, a5 as i, a2 as f, a6 as m, a1 as d, a8 as c, a7 as l } from "./common/main.js";
import { a2 as u, a1 as o, a3 as i, a0 as f, a4 as m, $ as d, a6 as c, a5 as l } from "./common/main.js";
import { default as b } from "rc-util/lib/hooks/useMergedState";
import { a as x } from "./common/vendor.js";
export {
+8 -6
View File
@@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
/**
* 渲染一个 iconfont symbol 图标(依赖 Iconfont.init 注入的 SVG symbol 脚本)
@@ -7,18 +6,21 @@ import PropTypes from 'prop-types';
* @param {string} [props.className] 额外的 class 名
* @param {string} props.type 图标名,对应 svg symbol 的 id
* @param {Object} [props.style] 行内样式
* @param {number} [props.rotate] 旋转角度(deg)
* @param {boolean} [props.spin] 是否开启旋转动画
* @param {string} [props.twoToneColor] 双色图标的第二色
* @param {boolean} [props.compact] 是否紧凑模式(去除默认间距)
*/
declare function Iconfont({ className, type, style, rotate, spin, twoToneColor, compact, ...props }: {
className?: string;
type: string;
style?: any;
rotate?: number;
spin?: boolean;
twoToneColor?: string;
compact?: boolean;
}): React.JSX.Element;
declare namespace Iconfont {
export namespace propTypes {
let className: PropTypes.Requireable<string>;
let type: PropTypes.Validator<string>;
let style: PropTypes.Requireable<object>;
}
export { createScriptUrlElements as init };
}
+1 -2
View File
@@ -1,8 +1,7 @@
import "react/jsx-runtime";
import "react";
import "prop-types";
import "classnames";
import { al as a } from "./common/main.js";
import { aj as a } from "./common/main.js";
export {
a as default
};
Vendored
+2 -75
View File
@@ -1,75 +1,2 @@
import * as axios from 'axios';
import Request from 'ff-request';
import MockAdapter from 'axios-mock-adapter';
import React from 'react';
declare const _default$3: any;
declare const _default$2: Http & Request;
/**
* 应用统一的 HTTP 客户端单例;自身只实现 init/driver/headers/mock/unmock,
* 其余属性通过 Proxy 代理到内部的 ff-request 实例(HttpRequest),
* 所以 get/post/del 等请求方法可以直接在这个单例上调用
*/
declare class Http {
static "__#private@#instance": any;
static "__#private@#core": any;
/** @returns {Http & Request} 单例实例 */
static getInstance: () => Http & Request;
appUrl: string;
/**
* 初始化(设置请求 baseURL/超时,并初始化内部 ff-request 实例)
* @param {string} appKey
* @param {string} appSecret
* @param {string} appUrl 接口请求的 baseURL
*/
init(appKey: string, appSecret: string, appUrl: string): void;
get driver(): axios.AxiosStatic;
get headers(): Readonly<{
Platform: "web";
SaaS: string;
Authorization: `Bearer ${string} `;
}>;
/**
* 开启请求 mock(基于 axios-mock-adapter),未匹配的请求会透传到真实接口
* @param {Object} [opt] 传给 MockAdapter 的选项
* @returns {MockAdapter} mock 适配器实例,用于注册具体的 mock 规则
*/
mock(opt?: any): MockAdapter;
/** 关闭并清除 mock */
unmock(): void;
#private;
}
declare class Cache {
constructor(target: any, fn: any);
get: (...args: any[]) => Promise<any>;
#private;
}
declare const _default$1: any;
declare const pipe: any;
declare const _default: any;
declare const AppContext: React.Context<{
user: {};
initUser: () => void;
initUserComplete: boolean;
}>;
declare const AppGlobalParamsContext: React.Context<{
set: () => void;
get: () => void;
assign: () => void;
currentRoute: () => void;
}>;
/**
* 判断是否是 React 组件, 大写字母开头的函数则判断为组件
*/
declare function isReactComponent(component: any): boolean;
declare function insertStyle(css: any, id: any): any;
export { AppContext, AppGlobalParamsContext, Cache as cache, _default$1 as configure, _default$3 as default, pipe as func, _default$2 as http, insertStyle, isReactComponent, _default as route };
export * from './index';
export { default } from './index';
+1 -1
View File
@@ -1,4 +1,4 @@
import { aF as t, aG as e, aB as o, aC as n, ax as p, aD as r, aA as c, az as f, ay as l, aE as u } from "./common/main.js";
import { aD as t, aE as e, az as o, aA as n, av as p, aB as r, ay as c, ax as f, aw as l, aC as u } from "./common/main.js";
export {
t as AppContext,
e as AppGlobalParamsContext,
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ff",
"version": "0.7.13",
"version": "0.7.14",
"author": "www.fsdpf.com",
"type": "module",
"main": "./index.js",
+1 -1
View File
@@ -1,4 +1,4 @@
import { L as t, K as e, M as o, N as g } from "./common/main.js";
import { J as t, I as e, K as o, N as g } from "./common/main.js";
export {
t as CustomPage,
e as DataListPage,
Vendored
+109 -25
View File
@@ -1,28 +1,112 @@
declare const _default: ResWs;
import { WidgetType, WidgetContainerProps } from './button';
/**
* 基于 SharedWorker 的资源状态 WebSocket 单例;多个页面/标签页共用同一条连接,
* 按资源 uuid 把服务端推送的状态变化分发给各自的订阅回调
*/
declare class ResWs {
/** @type {ResWs} */
static "__#private@#instance": ResWs;
/** @returns {ResWs} 单例实例 */
static getInstance: () => ResWs;
/**
* 订阅资源状态变化
* @param {(data: *) => void} cb 状态变化时的回调,收到服务端推送的原始数据
* @param {string|string[]} [res] 要订阅的资源 uuid,不传/空数组表示订阅全部('*')
* @returns {() => void} 取消订阅的函数
*/
subscribe: (cb: (data: any) => void, res?: string | string[]) => () => void;
/**
* 取消订阅
* @param {Function} cb 订阅时传入的回调
* @returns {boolean} 是否成功移除
*/
unsubscribe: (cb: Function) => boolean;
#private;
// ===== 用户数据结构(复用类型,JSDoc 无法跨文件引用,放 .d.ts) =====
interface UserRoleBinding {
user_uuid: string
role_uuid: string
created_at: string
updated_at: string
created_user: string
owned_user: string
}
export { _default as default };
interface UserInfo {
uuid: string
username: string
nickname: string
email: string
last_login_ip: string
is_active: 0 | 1
UserRole: UserRoleBinding[]
[key: string]: unknown
}
interface MenuItem {
/** 菜单唯一标识 */
uuid: string
/** 菜单显示名称 */
name: string
/** 图标 class 名 */
icon: string
/** 行为目标(组件标识 / 路由 uuid 等),含义随 widgetType 而定 */
widget: string
/** 行为类型 */
widgetType: WidgetType
/** 传给目标组件的 props 映射配置 */
widgetProps: Record<string, unknown>
/** 传给目标组件的 $setting 配置 */
widgetSetting: Record<string, unknown>
/** 弹窗容器配置 */
widgetContainerSetting: WidgetContainerProps
/** 子菜单 */
children?: MenuItem[]
}
interface RouteItem {
/** 路由唯一标识 */
uuid: string
/** 路由名称 */
name: string
/** react-router path,支持动态参数(如 /page/:id) */
uri: string
/** 是否为布局路由(外层 layout,不直接渲染页面内容) */
isLayout: boolean
/** 是否需要登录才能访问 */
isLogin: boolean
/** 是否为手机端专属路由 */
isPhone: boolean
/** 路由类型 */
type: Exclude<WidgetType, 'redirect'>
/** 是否精确匹配路径 */
exact: boolean
/** widget 标识(等同于 ButtonProps.widget),经 core.getWidgetComponent 加载 */
component: string
/** 传给页面组件的 props 映射配置 */
widgetProps: Record<string, unknown>
/** 传给页面组件的 $setting 配置 */
widgetSetting: Record<string, unknown>
/** 弹窗容器配置 */
widgetContainerSetting: WidgetContainerProps
/** 附加配置(如 layout 标识等) */
extra?: Record<string, unknown>
}
// ===== http — Proxy 模式产生交叉类型,JSDoc 无法表达 =====
/** 每次请求自动附加的请求头 */
interface HttpHeaders {
/** 客户端平台标识,固定为 'web' */
Platform: string
/** SaaS 租户标识,单租户时为 null */
SaaS: string | null
/** JWT Bearer token,未登录时为 undefined */
Authorization: string | undefined
}
// ===== func — ff-worker-pipe 无类型文件,显式声明 =====
/**
* 基于 Worker 的表达式执行引擎单例;
* exec 在独立 Worker 上下文中求值一段 JS 表达式/源码
*/
interface WorkerPipeInstance {
/**
* 在 Worker 上下文中执行一段 JS 表达式
* @param expression 要执行的表达式字符串
* @param args 传给表达式的参数(可在表达式内作为第一个参数使用)
* @param fns 注入到表达式执行作用域的额外可调用函数
* @param session 会话标识;相同 session 共享 Worker 侧工作区(this)
*/
exec: (
expression: string,
args?: Record<string, unknown>,
fns?: Record<string, Function>,
session?: string
) => Promise<unknown>
/** 清除指定 session 的 Worker 侧工作区 */
clear: (session: string) => void
}
export type { HttpHeaders, MenuItem, RouteItem, UserInfo, UserRoleBinding, WorkerPipeInstance };
Vendored
+112
View File
@@ -1,3 +1,5 @@
import { WidgetType, WidgetContainerProps } from './button';
/**
* 把任意值按目标类型做类型转换(json/array/number/integer/float/bool/string 互转)
* @param {*} data 待转换的值
@@ -112,4 +114,114 @@ declare function getUrlWithPrefix(url: string, defaultPrefix?: string): string;
*/
declare function generateUUID(): string;
// ===== 用户数据结构(复用类型,JSDoc 无法跨文件引用,放 .d.ts) =====
interface UserRoleBinding {
user_uuid: string
role_uuid: string
created_at: string
updated_at: string
created_user: string
owned_user: string
}
interface UserInfo {
uuid: string
username: string
nickname: string
email: string
last_login_ip: string
is_active: 0 | 1
UserRole: UserRoleBinding[]
[key: string]: unknown
}
interface MenuItem {
/** 菜单唯一标识 */
uuid: string
/** 菜单显示名称 */
name: string
/** 图标 class 名 */
icon: string
/** 行为目标(组件标识 / 路由 uuid 等),含义随 widgetType 而定 */
widget: string
/** 行为类型 */
widgetType: WidgetType
/** 传给目标组件的 props 映射配置 */
widgetProps: Record<string, unknown>
/** 传给目标组件的 $setting 配置 */
widgetSetting: Record<string, unknown>
/** 弹窗容器配置 */
widgetContainerSetting: WidgetContainerProps
/** 子菜单 */
children?: MenuItem[]
}
interface RouteItem {
/** 路由唯一标识 */
uuid: string
/** 路由名称 */
name: string
/** react-router path,支持动态参数(如 /page/:id) */
uri: string
/** 是否为布局路由(外层 layout,不直接渲染页面内容) */
isLayout: boolean
/** 是否需要登录才能访问 */
isLogin: boolean
/** 是否为手机端专属路由 */
isPhone: boolean
/** 路由类型 */
type: Exclude<WidgetType, 'redirect'>
/** 是否精确匹配路径 */
exact: boolean
/** widget 标识(等同于 ButtonProps.widget),经 core.getWidgetComponent 加载 */
component: string
/** 传给页面组件的 props 映射配置 */
widgetProps: Record<string, unknown>
/** 传给页面组件的 $setting 配置 */
widgetSetting: Record<string, unknown>
/** 弹窗容器配置 */
widgetContainerSetting: WidgetContainerProps
/** 附加配置(如 layout 标识等) */
extra?: Record<string, unknown>
}
// ===== http — Proxy 模式产生交叉类型,JSDoc 无法表达 =====
/** 每次请求自动附加的请求头 */
interface HttpHeaders {
/** 客户端平台标识,固定为 'web' */
Platform: string
/** SaaS 租户标识,单租户时为 null */
SaaS: string | null
/** JWT Bearer token,未登录时为 undefined */
Authorization: string | undefined
}
// ===== func — ff-worker-pipe 无类型文件,显式声明 =====
/**
* 基于 Worker 的表达式执行引擎单例;
* exec 在独立 Worker 上下文中求值一段 JS 表达式/源码
*/
interface WorkerPipeInstance {
/**
* 在 Worker 上下文中执行一段 JS 表达式
* @param expression 要执行的表达式字符串
* @param args 传给表达式的参数(可在表达式内作为第一个参数使用)
* @param fns 注入到表达式执行作用域的额外可调用函数
* @param session 会话标识;相同 session 共享 Worker 侧工作区(this)
*/
exec: (
expression: string,
args?: Record<string, unknown>,
fns?: Record<string, Function>,
session?: string
) => Promise<unknown>
/** 清除指定 session 的 Worker 侧工作区 */
clear: (session: string) => void
}
export { deepSome, generateUUID, getPkgCategory, getPkgName, getPkgOwner, getPrimitiveType, getUrlWithPrefix, getWidgetPropsData, hasUrlPrefix, hashJSON, makeUniqueIdGenerator, replaceKeys, toPrimitive, uuid };
export type { HttpHeaders, MenuItem, RouteItem, UserInfo, UserRoleBinding, WorkerPipeInstance };
+1 -1
View File
@@ -1,5 +1,5 @@
import "lodash";
import { S as r, a0 as i, W as g, V as o, X as P, P as m, $ as p, Q as U, _ as d, Y as h, Z as k, T as n, O as f, U as l } from "./common/main.js";
import { P as r, _ as i, U as g, T as o, V as P, M as m, Z as p, O as U, Y as d, W as h, X as k, Q as n, L as f, S as l } from "./common/main.js";
import "./common/vendor.js";
export {
r as deepSome,
+113 -1
View File
@@ -1,3 +1,5 @@
import { WidgetType, WidgetContainerProps } from './button';
/**
* 把 VirtualFS 里某个路径下的结构递归转换成 antd Tree 组件可用的节点结构
* (目录排在文件前面,各自按名称排序)
@@ -292,4 +294,114 @@ declare class VirtualFS {
#private;
}
export { VirtualFS as default, toTreePaths };
// ===== 用户数据结构(复用类型,JSDoc 无法跨文件引用,放 .d.ts) =====
interface UserRoleBinding {
user_uuid: string
role_uuid: string
created_at: string
updated_at: string
created_user: string
owned_user: string
}
interface UserInfo {
uuid: string
username: string
nickname: string
email: string
last_login_ip: string
is_active: 0 | 1
UserRole: UserRoleBinding[]
[key: string]: unknown
}
interface MenuItem {
/** 菜单唯一标识 */
uuid: string
/** 菜单显示名称 */
name: string
/** 图标 class 名 */
icon: string
/** 行为目标(组件标识 / 路由 uuid 等),含义随 widgetType 而定 */
widget: string
/** 行为类型 */
widgetType: WidgetType
/** 传给目标组件的 props 映射配置 */
widgetProps: Record<string, unknown>
/** 传给目标组件的 $setting 配置 */
widgetSetting: Record<string, unknown>
/** 弹窗容器配置 */
widgetContainerSetting: WidgetContainerProps
/** 子菜单 */
children?: MenuItem[]
}
interface RouteItem {
/** 路由唯一标识 */
uuid: string
/** 路由名称 */
name: string
/** react-router path,支持动态参数(如 /page/:id) */
uri: string
/** 是否为布局路由(外层 layout,不直接渲染页面内容) */
isLayout: boolean
/** 是否需要登录才能访问 */
isLogin: boolean
/** 是否为手机端专属路由 */
isPhone: boolean
/** 路由类型 */
type: Exclude<WidgetType, 'redirect'>
/** 是否精确匹配路径 */
exact: boolean
/** widget 标识(等同于 ButtonProps.widget),经 core.getWidgetComponent 加载 */
component: string
/** 传给页面组件的 props 映射配置 */
widgetProps: Record<string, unknown>
/** 传给页面组件的 $setting 配置 */
widgetSetting: Record<string, unknown>
/** 弹窗容器配置 */
widgetContainerSetting: WidgetContainerProps
/** 附加配置(如 layout 标识等) */
extra?: Record<string, unknown>
}
// ===== http — Proxy 模式产生交叉类型,JSDoc 无法表达 =====
/** 每次请求自动附加的请求头 */
interface HttpHeaders {
/** 客户端平台标识,固定为 'web' */
Platform: string
/** SaaS 租户标识,单租户时为 null */
SaaS: string | null
/** JWT Bearer token,未登录时为 undefined */
Authorization: string | undefined
}
// ===== func — ff-worker-pipe 无类型文件,显式声明 =====
/**
* 基于 Worker 的表达式执行引擎单例;
* exec 在独立 Worker 上下文中求值一段 JS 表达式/源码
*/
interface WorkerPipeInstance {
/**
* 在 Worker 上下文中执行一段 JS 表达式
* @param expression 要执行的表达式字符串
* @param args 传给表达式的参数(可在表达式内作为第一个参数使用)
* @param fns 注入到表达式执行作用域的额外可调用函数
* @param session 会话标识;相同 session 共享 Worker 侧工作区(this)
*/
exec: (
expression: string,
args?: Record<string, unknown>,
fns?: Record<string, Function>,
session?: string
) => Promise<unknown>
/** 清除指定 session 的 Worker 侧工作区 */
clear: (session: string) => void
}
export { toTreePaths };
export type { HttpHeaders, MenuItem, RouteItem, UserInfo, UserRoleBinding, WorkerPipeInstance };
+1 -1
View File
@@ -1,5 +1,5 @@
import "pathe";
import { aH as o, aI as r } from "./common/main.js";
import { aF as o, aG as r } from "./common/main.js";
export {
o as default,
r as toTreePaths