diff --git a/packages/gbeata/.dumirc.ts b/packages/gbeata/.dumirc.ts index 9be6427d..d7c362de 100644 --- a/packages/gbeata/.dumirc.ts +++ b/packages/gbeata/.dumirc.ts @@ -5,6 +5,11 @@ export default defineConfig({ themeConfig: { name: 'gbeata', mfsu: false, + footer: false, + footerConfig: { + copyright: 'Copyright © 2022-present Gbeata', + theme: 'dark', + }, // 单语言时配置数组即可 // features: [{ title: '开箱即用'}, { description: '接入简单,安装即使用,全面融入 Ant Design 5.0 风格。'}] // 多语言时配置对象,key 为语言名 diff --git a/packages/gbeata/package.json b/packages/gbeata/package.json index 45b7e4c7..0e382f82 100644 --- a/packages/gbeata/package.json +++ b/packages/gbeata/package.json @@ -69,6 +69,7 @@ "pre-commit": "lint-staged" }, "dependencies": { + "classnames": "^2.3.2", "dumi-theme-antd-style": "^0.29.7" } } diff --git a/packages/gbeata/src/GButton/g-button.d.ts b/packages/gbeata/src/GButton/g-button.d.ts new file mode 100644 index 00000000..5e010cdc --- /dev/null +++ b/packages/gbeata/src/GButton/g-button.d.ts @@ -0,0 +1,23 @@ +import { ButtonProps } from 'antd/lib/button'; + +// 设置权限列表 +export declare function setPermissionList(list: Array): void; + +export interface GButtonProps extends ButtonProps { + /** true 会有确认,false: 无确认 */ + confirm?: boolean; + /** 确认事件 */ + onConfirm?(): void; + /** 是否只在表格扩展显示 */ + tableFooterExtraOnly?: boolean; + /** 自定义确认消息 */ + confirmMsg?: React.ReactNode; + /** 权限 */ + permission?: string; + /** 悬浮提示 */ + tooltip?: React.ReactNode; + /** 是否用次级字体 */ + sub?: boolean; + __simple?: boolean; + [key: string]: any; +} diff --git a/packages/gbeata/src/GButton/index.d.ts b/packages/gbeata/src/GButton/index.d.ts new file mode 100644 index 00000000..7583ac59 --- /dev/null +++ b/packages/gbeata/src/GButton/index.d.ts @@ -0,0 +1,7 @@ +import { GButtonProps } from './g-button'; + +declare const MwButton: React.ForwardRefExoticComponent< + GButtonProps & React.RefAttributes +>; + +export default MwButton; diff --git a/packages/gbeata/src/GButton/index.less b/packages/gbeata/src/GButton/index.less new file mode 100644 index 00000000..cb79104a --- /dev/null +++ b/packages/gbeata/src/GButton/index.less @@ -0,0 +1,21 @@ +.mw-button { + &.simple { + width: 100%; + } + + &.sub { + padding: 0; + height: unset; + line-height: 1em; + border: unset; + box-shadow: unset; + background-color: unset; + color: #00000073; + + &:hover, + &:focus { + color: #000000d9; + background-color: unset; + } + } +} diff --git a/packages/gbeata/src/GButton/index.md b/packages/gbeata/src/GButton/index.md new file mode 100644 index 00000000..e65e5af5 --- /dev/null +++ b/packages/gbeata/src/GButton/index.md @@ -0,0 +1,101 @@ +--- +nav: + path: /components +title: '按钮' +group: + title: 组件 + order: 1 +--- + +# GButton 0.0.5 + +```tsx +import React, { useState } from 'react'; +import { GButton } from 'gbeata'; + +export default function Demo() { + return alert('阿米娅')}>gbeata; +} +``` + +# 次级按钮 + +会去除按钮的颜色、边框、内边距、高度等属性。 + +```tsx +import React from 'react'; +import { GButton } from 'gbeata'; + +export default function Demo() { + return ( + alert('阿米娅')}> + gbeata + + ); +} +``` + +## confirm + +可以在按钮点击时进行确认,同时 onClick 方法要换成 onConfirm 方法。 + +```tsx +import React from 'react'; +import { GButton } from 'gbeata'; + +export default function Demo() { + return ( + alert('确定')} + > + 删除 + + ); +} +``` + +### tooltip + +```tsx +import React from 'react'; +import { GButton } from 'gbeata'; + +export default function Demo() { + return ( + alert('阿米娅')}> + 悬浮提示 + + ); +} +``` + +## 权限 + +```tsx +import React from 'react'; +import { GButton } from 'gbeata'; + +// 注释掉此行,将不会展示相关按钮 +// setPermissionList(['delete']); + +export default function Demo() { + return 删除; +} +``` + +权限控制可以看[这里](../global/set-permission-list) + +## 参数 + +| 参数名 | 说明 | 参数类型 | 默认值 | +| ---------- | ---------------------------------------------- | -------- | ------ | +| confirm | 是否需要确认 | boolean | false | +| confirmMsg | 确认框提示文字,需要先设置 confirm 属性为 true | string | - | +| onConfirm | 确认完成事件,需要先设置 confirm 属性为 true | Function | - | +| onClick | 点击事件 | Function | - | +| permission | 权限 | string | - | + +其它属性保持跟 antd Button 属性一致。 diff --git a/packages/gbeata/src/GButton/index.tsx b/packages/gbeata/src/GButton/index.tsx new file mode 100644 index 00000000..dce1105e --- /dev/null +++ b/packages/gbeata/src/GButton/index.tsx @@ -0,0 +1,153 @@ +import { Button, Modal, Popconfirm, Tooltip } from 'antd'; +import classNames from 'classnames'; +import React, { useEffect, useState } from 'react'; +import { omitObj } from '../utils'; +import { GButtonProps } from './g-button'; + +interface AnyKeyProps { + [key: string]: any; +} + +const refreshList: Array = []; + +export const addRefresh = (setRefresh: any) => { + refreshList.push(setRefresh); +}; + +export const removeRefresh = (setRefresh: any) => { + let refreshIndex = refreshList.findIndex((item) => item === setRefresh); + if (refreshIndex >= 0) { + refreshList.splice(refreshIndex, 1); + } +}; + +// 权限列表 +let permissionList: Array = []; + +export const setPermissionList = (list: Array) => { + permissionList = list; + refreshList.forEach((setRefresh) => { + setRefresh(Math.random()); + }); +}; + +export const hasPermission = (permission: string) => { + if (!permission) { + return true; + } + if (permissionList.includes(permission)) { + return true; + } + return false; +}; + +let keys = [ + 'confirm', + 'onConfirm', + 'confirmMsg', + 'tableFooterExtraOnly', + 'action', + 'api', + 'onFinish', + '__simple', + 'deleteApi', + 'detailApi', + 'detailParams', + 'detailApiFilter', + 'permission', + 'extra', + 'record', + 'confirmVisible', + 'sub', + 'omitKeys', +]; +export default function GButton(props: GButtonProps) { + const [, setRefresh] = useState(0); + let params: AnyKeyProps = { + ...props, + }; + + useEffect(() => { + addRefresh(setRefresh); + return () => { + removeRefresh(setRefresh); + }; + }, []); + + // 权限控制 + if (params.permission && !permissionList.includes(params.permission)) { + return null; + } + + // 控制样式 + let className: string[] | string = [`mw-button`]; + + // 是否在折叠按钮里面 + if (props.__simple) { + className.push('simple'); + } + + // 是否是次级按钮 + if (props.sub) { + className.push('sub'); + } + + // 是否有自定义样式 + if (props.className) { + className.push(props.className); + } + + className = classNames(className); + + // 删除一些没有用到的属性 + if (props.omitKeys) { + params = omitObj(params, props.omitKeys); + } + + params = omitObj(params, keys); + + // 基础按钮 + let btn = ( + + ); + + // 带悬浮提示 + if (props.tooltip) { + btn = {btn}; + } + + // 带确认提示 + if (props.confirm && !props.disabled) { + if (!props.__simple) { + return ( + props.onConfirm && props.onConfirm()} + > + {btn} + + ); + } else { + return ( + + ); + } + } + + return btn; +} + +GButton.componentName = 'GButton'; diff --git a/packages/gbeata/src/constant.ts b/packages/gbeata/src/constant.ts new file mode 100755 index 00000000..ad5afb8f --- /dev/null +++ b/packages/gbeata/src/constant.ts @@ -0,0 +1,206 @@ +export const TRUE = '1' +export const FALSE = '0' + +/** 主页地址 */ +export const HOME_PATH = '/home' + +/** 默认侧边宽度 */ +export const LAYOUT_SIDE_WIDTH = 270 + +/** 标签页 loading 时间 */ +export const TAB_LOADING_TIME = 1000 + +/** MwCtrl 默认数量 */ +export const CTRL_DEFAULT_MAX = 3 + +/** MwCtrl 默认数量 */ +export const CTRL_DEFAULT_MORE_TEXT = '更多' + +// -------------------------------------------------------------- +// ------------------------ table 默认配置 ----------------------- +// -------------------------------------------------------------- +/** 表格默认页数 */ +export const TABLE_PAGESIZE = 10 + +/** 表格初始第 N 页开始 */ +export const TABLE_START_PAGE = 1 + +/** 表格控制列的 key */ +export const TABLE_CTRL_KEY = 'ctrl' + +/** 昨天 */ +export const TABLE_YESTODAY = '0' + +/** 今天 */ +export const TABLE_TODAY = '1' + +/** 本周 */ +export const TABLE_THISWEEK = '2' + +/** 本月 */ +export const TABLE_THISMONTH = '3' + +/** 下月 */ +export const TABLE_LASTMONTH = '4' + +/** 表格默认 RowKey */ +export const TABLE_DEFAULT_ROW_KEY = 'id' + +// -------------------------------------------------------------- +// ------------------------ form 其它默认值 ----------------------- +// -------------------------------------------------------------- +/** 输入框默认字符长度 */ +export const INPUT_DEFAULT_MAXLENGTH = 30 + +/** 多行文本框默认字符长度 */ +export const TEXTAREA_DEFAULT_MAXLENGTH = 200 + +/** 数字框默认最小 */ +export const NUMBER_DEFAULT_MIN = 0 + +/** 数字框默认最大*/ +export const NUMBER_DEFAULT_MAX = 99999999 + +/** 百分比框默认最大*/ +export const PERCENT_DEFAULT_MAX = 100 + +/** form 默认是否有清空按钮 */ +export const FORM_DEFAULT_ALLOW_CLEAR = true + +// -------------------------------------------------------------- +// ------------------------ form 表单类型 ------------------------ +// -------------------------------------------------------------- +/** 表单类型: 输入框 */ +export const FORM_TYPE_INPUT = 'input' + +/** 表单类型: 搜索框 */ +export const FORM_TYPE_SEARCH = 'search' + +/** 表单类型: 数字 */ +export const FORM_TYPE_NUMBER = 'number' + +/** 表单类型: 百分比 */ +export const FORM_TYPE_PERCENT = 'percent' + +/** 表单类型: 密码框 */ +export const FORM_TYPE_PASSWORD = 'password' + +/** 表单类型: 多行输入框 */ +export const FORM_TYPE_TEXTAREA = 'textarea' + +/** 表单类型: 选择框 */ +export const FORM_TYPE_SELECT = 'select' + +/** 表单类型: 开关 */ +export const FORM_TYPE_SWITCH = 'switch' + +/** 表单类型: 多选框 */ +export const FORM_TYPE_CHECKBOX = 'checkbox' + +/** 表单类型: 多选组 */ +export const FORM_TYPE_CHECKBOX_GROUP = 'checkbox-group' + +/** 表单类型: 单选组 */ +export const FORM_TYPE_RADIO_GROUP = 'radio-group' + +/** 表单类型: 日期 */ +export const FORM_TYPE_DATE = 'date' + +/** 表单类型: 日期区间 */ +export const FORM_TYPE_DATE_RANGE = 'date-range' + +/** 表单类型: 空白框 */ +export const FORM_TYPE_EMPTY = 'empty' + +/** 表单类型: 自定义 */ +export const FORM_TYPE_CUSTOM = 'custom' + +/** 表单类型: 卡片表单 */ +export const FORM_TYPE_CARD = 'card' + +/** 表单类型: 组合表单 */ +export const FORM_TYPE_GROUP = 'group' + +/** 表单类型: 组合输入框 */ +export const FORM_TYPE_INPUT_GROUP = 'input-group' + +/** 表单类型: 评分 */ +export const FORM_TYPE_RATE = 'rate' + +/** 表单类型: 滑动输入条 */ +export const FORM_TYPE_SLIDER = 'slider' + +/** 表单类型: 标签组选择 */ +export const FORM_TYPE_TAG_GROUP = 'tag-group' + +/** 表单类型: 卡片选择 */ +export const FORM_TYPE_CARD_GROUP = 'card-group' + +/** 表单类型: HTML */ +export const FORM_TYPE_HTML = 'html' + +/** 表单类型: 列表 */ +export const FORM_TYPE_LIST = 'list' + +// -------------------------------------------------------------- +// ------------------------ form 表单默认值 ----------------------- +// -------------------------------------------------------------- +/** 表单默认值: 输入框默认值 */ +export const FORM_DEFAULT_VALUE_INPUT = '' + +/** 表单默认值: 搜索框默认值 */ +export const FORM_DEFAULT_VALUE_SEARCH = '' + +/** 表单默认值: 数字框默认值 */ +export const FORM_DEFAULT_VALUE_NUMBER = null + +/** 表单默认值: 数字框默认值 */ +export const FORM_DEFAULT_VALUE_PERCENT = null + +/** 表单默认值: 密码框默认值 */ +export const FORM_DEFAULT_VALUE_PASSWORD = '' + +/** 表单默认值: 多行输入框默认值 */ +export const FORM_DEFAULT_VALUE_TEXTAREA = '' + +/** 表单默认值: 选择框默认值 */ +export const FORM_DEFAULT_VALUE_SELECT = undefined + +/** 表单默认值: 开关默认值 */ +export const FORM_DEFAULT_VALUE_SWITCH = false + +/** 表单默认值: 多选框默认值 */ +export const FORM_DEFAULT_VALUE_CHECKBOX = false + +/** 表单默认值: 多选组默认值 */ +export const FORM_DEFAULT_VALUE_CHECKBOX_GROUP = [] + +/** 表单默认值: 单选组默认值 */ +export const FORM_DEFAULT_VALUE_RADIO_GROUP = null + +/** 表单默认值: 日期默认值 */ +export const FORM_DEFAULT_VALUE_DATE = undefined + +/** 表单默认值: 日期区间默认值 */ +export const FORM_DEFAULT_VALUE_DATE_RANGE = [] + +/** 表单默认值: 空白框 */ +export const FORM_DEFAULT_VALUE_EMPTY = '' + +/** 表单默认值: 评分 */ +export const FORM_DEFAULT_VALUE_RATE = null + +/** 表单默认值: 滑动输入条 */ +export const FORM_DEFAULT_VALUE_SLIDER = 0 + +/** 表单默认值: 标签组选择 */ +export const FORM_DEFAULT_VALUE_TAG_GROUP = undefined + +/** 表单默认值: 标签组选择 */ +export const FORM_DEFAULT_VALUE_CARD_GROUP = undefined + +/** 表单默认值: HTML */ +export const FORM_DEFAULT_VALUE_HTML = undefined + +/** 表单 readonly 值 */ +export const FORM_READONLY_EMPTY = '-' diff --git a/packages/gbeata/src/index.ts b/packages/gbeata/src/index.ts index 0ae99e4e..82e9b6fc 100644 --- a/packages/gbeata/src/index.ts +++ b/packages/gbeata/src/index.ts @@ -1,6 +1,7 @@ +import { default as GButton } from './GButton'; import { error, info, success, warning } from './GMessage'; import { default as GTagGroup } from './GTagGroup'; -export { GTagGroup, error, info, success, warning }; +export { GButton, GTagGroup, error, info, success, warning }; export default { success, @@ -8,4 +9,5 @@ export default { error, warning, GTagGroup, + GButton, }; diff --git a/packages/gbeata/src/types/AnyKeyProps.d.ts b/packages/gbeata/src/types/AnyKeyProps.d.ts new file mode 100755 index 00000000..a3a0ef29 --- /dev/null +++ b/packages/gbeata/src/types/AnyKeyProps.d.ts @@ -0,0 +1,3 @@ +export interface AnyKeyProps { + [key: string]: any +} diff --git a/packages/gbeata/src/types/FormValues.d.ts b/packages/gbeata/src/types/FormValues.d.ts new file mode 100644 index 00000000..e6cdf789 --- /dev/null +++ b/packages/gbeata/src/types/FormValues.d.ts @@ -0,0 +1,3 @@ +export interface FormValues { + [key: string]: any +} diff --git a/packages/gbeata/src/types/Record.d.ts b/packages/gbeata/src/types/Record.d.ts new file mode 100644 index 00000000..1bb4486c --- /dev/null +++ b/packages/gbeata/src/types/Record.d.ts @@ -0,0 +1,3 @@ +export interface Record { + [key: string]: any +} diff --git a/packages/gbeata/src/utils.tsx b/packages/gbeata/src/utils.tsx new file mode 100755 index 00000000..70e3625f --- /dev/null +++ b/packages/gbeata/src/utils.tsx @@ -0,0 +1,252 @@ +import React from 'react'; +import { AnyKeyProps } from './types/AnyKeyProps'; +// import { Option } from './MwForm/mw-form' +// import { Badge, Tag } from 'antd' +import { TABLE_DEFAULT_ROW_KEY } from './constant'; + +/** + * 拷贝对象 + * @param obj + */ +export const copy = (obj: AnyKeyProps) => { + return JSON.parse(JSON.stringify(obj)); +}; + +/** + * 获取随机数 + * @param min 最小随机数 + * @param max 最大随机数 + */ +export const getRandom = (min: number, max: number) => { + return min + Math.random() * (max - min); +}; + +/** + * 获取随机数(带小数) + * @param min 最小随机数 + * @param max 最大随机数 + */ +export const getRandomFloor = (min: number, max: number) => { + return min + Math.floor(Math.random() * (max - min + 1)); +}; + +/** + * 是否是对象 + * @param obj 判断对象 + */ +export const isObj = (obj: any): boolean => { + return Object.prototype.toString.call(obj) === '[object Object]'; +}; + +/** + * 是否是方法 + * @param func 判断对象 + */ +export const isFunc = (func: any): boolean => { + return typeof func === 'function'; +}; + +/** + * 清空对象的 undefined 和 null + * @param params 要清空的对象 + */ +export const clearEmpty = (params: AnyKeyProps): AnyKeyProps => { + let result: AnyKeyProps = {}; + + for (let key in params) { + if (params[key] !== undefined) { + result[key] = params[key]; + } + } + return result; +}; + +interface ListToTreeProps { + /** 数据源 */ + data: Array; + /** 父节点 key */ + parentKey?: string; + /** 标题 key */ + labelKey?: string; + /** 子节点 key */ + childrenKey?: string; + /** 值 key */ + valueKey?: string; + /** 跟节点值 */ + rootValue?: string | null; + /** 是否拥有 children */ + keepLeaf?: boolean; +} + +/** + * 列表转树结构 + * @param props 配置参数 + */ +export const listToTree = (props: ListToTreeProps) => { + const { + data = [], + parentKey = 'parentId', + childrenKey = 'children', + valueKey = 'id', + rootValue = null, + keepLeaf = false, + } = props; + let list = copy(data); + let map: AnyKeyProps = {}; + let roots: Array = []; + list.forEach((item: any, i: number) => { + map[item[valueKey]] = i; + item[childrenKey] = []; + }); + list.forEach((node: AnyKeyProps) => { + let target = node[parentKey]; + if (target === rootValue) { + roots.push(node); + } else { + if (map[target] !== undefined) { + list[map[target]].children.push(node); + } else { + roots.push(node); + } + } + }); + if (!keepLeaf) { + list.forEach((item: AnyKeyProps) => { + if (!item.children.length) { + delete item.children; + } + }); + } + return roots; +}; + +// 根据充值类型 id 获取对应的中文描述 +export const getLabelByValue = (type: number = 1, options: AnyKeyProps) => { + return options.find((option: AnyKeyProps) => option.value === type).label; +}; + +/** + * 数字转金额 + * @param value 金额 + */ +export const getCurrencyValue = (value: any) => { + if (typeof value !== 'number') { + return '0'; + } + return value.toLocaleString(); +}; + +/** + * 通过选项列表把 value 变成 label + * @param value 当前值 + * @param options 选项列表 + */ +// export const getValueByOptions = (value: any, options: Array