@wzyjs/components 0.2.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@wzyjs/components",
3
+ "version": "0.2.41",
4
+ "description": "description",
5
+ "author": "wzy",
6
+ "main": "src/index.ts",
7
+ "files": [
8
+ "src"
9
+ ],
10
+ "dependencies": {
11
+ "ali-oss": "^6.21.0",
12
+ "echarts": "^5.4.3",
13
+ "echarts-for-react": "^3.0.2",
14
+ "handlebars": "^4.7.8",
15
+ "html2canvas": "^1.4.1",
16
+ "js-beautify": "^1.14.7",
17
+ "prettier": "^3.5.3",
18
+ "prismjs": "^1.29.0",
19
+ "react": "^19.0.0",
20
+ "react-beautiful-dnd": "^13.1.1",
21
+ "react-json-view": "^1.21.3",
22
+ "react-syntax-highlighter": "^15.5.0"
23
+ },
24
+ "peerDependencies": {
25
+ "@wzyjs/antd": "^0.2.37",
26
+ "@wzyjs/hooks": "^0.2.37",
27
+ "@wzyjs/types": "^0.2.37",
28
+ "@wzyjs/utils": "^0.2.37"
29
+ },
30
+ "devDependencies": {
31
+ "@types/js-beautify": "^1.13.3",
32
+ "@types/prettier": "^2.7.2",
33
+ "@types/prismjs": "^1.26.0",
34
+ "@types/react": "^19.0.0",
35
+ "@types/react-beautiful-dnd": "^13.1.8",
36
+ "@types/react-syntax-highlighter": "^15.5.5"
37
+ },
38
+ "gitHead": "22795bdb9c670d3e37e9a6e83b544f916bab3c16",
39
+ "publishConfig": {
40
+ "access": "public"
41
+ }
42
+ }
@@ -0,0 +1,28 @@
1
+ 'use client'
2
+
3
+ import { ReactNode } from 'react'
4
+
5
+ interface BottomBarProps {
6
+ children?: ReactNode
7
+ collapsed?: boolean
8
+ }
9
+
10
+ const style = {
11
+ display: 'flex',
12
+ justifyContent: 'center',
13
+ padding: 10,
14
+ right: 0,
15
+ bottom: 0,
16
+ boxShadow: '0 0 2px 0 rgba(0, 0, 0, 0.1)',
17
+ background: '#fff',
18
+ }
19
+
20
+ export const BottomBar = (props: BottomBarProps) => {
21
+ const { children, collapsed } = props
22
+
23
+ return (
24
+ <div style={{ ...style, left: collapsed ? 64 : 256, position: 'fixed' }}>
25
+ {children}
26
+ </div>
27
+ )
28
+ }
@@ -0,0 +1,85 @@
1
+ 'use client'
2
+
3
+ import React, { CSSProperties, useEffect, useMemo, useRef } from 'react'
4
+
5
+ import Prism from 'prismjs'
6
+ import { format } from 'prettier/standalone'
7
+ import parserBabel from 'prettier/parser-babel'
8
+ import parserTs from 'prettier/parser-typescript'
9
+ import { js_beautify, html_beautify, css_beautify } from 'js-beautify'
10
+
11
+ import 'prismjs/components/prism-jsx'
12
+ import 'prismjs/components/prism-tsx'
13
+ import 'prismjs/components/prism-json'
14
+
15
+ import 'prismjs/components/prism-javascript'
16
+ import 'prismjs/components/prism-typescript'
17
+
18
+ import 'prismjs/components/prism-css'
19
+ import 'prismjs/components/prism-less'
20
+ import 'prismjs/components/prism-sass'
21
+ import 'prismjs/components/prism-scss'
22
+
23
+ import 'prismjs/components/prism-bash'
24
+ import 'prismjs/components/prism-http'
25
+ import 'prismjs/components/prism-editorconfig'
26
+ import 'prismjs/components/prism-docker'
27
+ import 'prismjs/components/prism-git'
28
+ import 'prismjs/components/prism-ignore'
29
+ import 'prismjs/components/prism-yaml'
30
+
31
+ import 'prismjs/themes/prism.css'
32
+
33
+ interface CodeViewProps {
34
+ language?: 'html' | 'jsx' | 'tsx' | 'vue' | 'json' | 'javascript' | 'typescript' | 'css' | 'less' | 'sass' | 'scss' | 'bash' | 'http' | 'editorconfig' | 'dockerfile' | 'git' | 'ignore' | 'yaml'
35
+ code?: string,
36
+ children?: any,
37
+ style?: CSSProperties,
38
+ }
39
+
40
+ export const CodeView = (props: CodeViewProps) => {
41
+ const { language = 'javascript', style, children, code = children } = props
42
+
43
+ const preRef = useRef(null)
44
+ useEffect(() => {
45
+ if (!preRef.current) {
46
+ return
47
+ }
48
+ Prism.highlightElement(preRef.current)
49
+ }, [])
50
+
51
+ const beautifydCode = useMemo(() => {
52
+ if (language === 'html') {
53
+ return html_beautify(code, { indent_size: 2 })
54
+ }
55
+ if (language === 'css') {
56
+ return css_beautify(code, { indent_size: 2 })
57
+ }
58
+ if (language === 'javascript') {
59
+ return js_beautify(code, { indent_size: 2 })
60
+ }
61
+
62
+ try {
63
+ return format(code, {
64
+ semi: false,
65
+ parser: 'babel',
66
+ singleQuote: true,
67
+ tabWidth: 2,
68
+ jsxSingleQuote: true,
69
+ plugins: [parserBabel, parserTs],
70
+ })
71
+ } catch (e) {
72
+ return code
73
+ }
74
+ }, [code])
75
+
76
+ return (
77
+ <div style={{ overflow: 'scroll', ...style }}>
78
+ <pre style={{ margin: 0, backgroundColor: 'transparent' }}>
79
+ <code ref={preRef} className={`language-${language}`}>
80
+ {beautifydCode}
81
+ </code>
82
+ </pre>
83
+ </div>
84
+ )
85
+ }
@@ -0,0 +1,26 @@
1
+ 'use client'
2
+
3
+ import { ReactNode } from 'react'
4
+ import { useBoolean } from 'ahooks'
5
+ import { RightOutlined, LeftOutlined } from '@ant-design/icons'
6
+
7
+ interface CollapseProps {
8
+ children: ReactNode
9
+ }
10
+
11
+ export const Collapse = (props: CollapseProps) => {
12
+ const { children } = props
13
+
14
+ const [collapse, { setTrue, setFalse }] = useBoolean(false)
15
+
16
+ return (
17
+ <div>
18
+ <div style={{ transform: 'translateY(100px)' }}>
19
+ {collapse ? <LeftOutlined onClick={setFalse} /> : <RightOutlined onClick={setTrue} />}
20
+ </div>
21
+ <div style={{ width: collapse ? 0 : 'auto', visibility: collapse ? 'hidden' : 'visible' }}>
22
+ {children}
23
+ </div>
24
+ </div>
25
+ )
26
+ }
@@ -0,0 +1,60 @@
1
+ 'use client'
2
+
3
+ import React, { useEffect, useRef, ReactNode } from 'react'
4
+ import html2canvas from 'html2canvas'
5
+ import { useDebounceFn } from '@wzyjs/hooks'
6
+ import { getRandomColor } from '@wzyjs/utils'
7
+
8
+ interface Com2CanvasProps {
9
+ children: ReactNode;
10
+ downloadName?: string;
11
+ onChange: (url: string) => void;
12
+ }
13
+
14
+ export const Com2Canvas = (props: Com2CanvasProps) => {
15
+ const { children, downloadName, onChange } = props
16
+
17
+ const random = useRef(getRandomColor())
18
+ const htmlId = `h2c_html_${random.current}`
19
+ const canvasId = `htc_canvas_${random.current}`
20
+
21
+ const { run } = useDebounceFn(() => {
22
+ const el = document.querySelector(`#${canvasId}`) as HTMLElement
23
+ if (!el) {
24
+ return
25
+ }
26
+
27
+ html2canvas(el, {
28
+ allowTaint: true, // 允许污染
29
+ useCORS: true, // 使用跨域(当allowTaint为true时这段代码没什么用)
30
+ scale: 2,
31
+ }).then((canvas: any) => {
32
+ el.innerHTML = ''
33
+ el.appendChild(canvas)
34
+
35
+ if (onChange) {
36
+ onChange(canvas.toDataURL('image/png'))
37
+ }
38
+
39
+ if (downloadName) {
40
+ el.onclick = () => {
41
+ const a = document.createElement('a')
42
+ a.download = downloadName
43
+ a.href = canvas.toDataURL('image/png')
44
+ document.body.appendChild(a)
45
+ a.click()
46
+ a.remove()
47
+ }
48
+ }
49
+ })
50
+ }, { wait: 500 })
51
+
52
+ useEffect(run, [children])
53
+
54
+ return (
55
+ <span style={{ position: 'relative' }}>
56
+ <span id={htmlId}>{children}</span>
57
+ <span id={canvasId} style={{ position: 'absolute', top: 0 }} />
58
+ </span>
59
+ )
60
+ }
@@ -0,0 +1,26 @@
1
+ 'use client'
2
+
3
+ import React, { useMemo } from 'react'
4
+ import Handlebars from 'handlebars'
5
+
6
+ interface Props {
7
+ template?: string
8
+ data: any
9
+ }
10
+
11
+ export default (props: Props) => {
12
+ const { template, data } = props
13
+
14
+ const html = useMemo(() => {
15
+ const html = Handlebars.compile(template || '')(data)
16
+ return html.replaceAll('\n', '').replaceAll('\t', '')
17
+ }, [template, data])
18
+
19
+ if (!html) {
20
+ return null
21
+ }
22
+
23
+ return (
24
+ <div dangerouslySetInnerHTML={{ __html: html }} />
25
+ )
26
+ }
@@ -0,0 +1,77 @@
1
+ 'use client'
2
+
3
+ import React from 'react'
4
+
5
+ import { Button } from 'antd'
6
+ import { FormPro } from '../../FormPro'
7
+
8
+ import { useUpdate } from '@wzyjs/hooks'
9
+ import { Apis, Column, ApiParams } from '../types'
10
+
11
+ interface CreateProps<I> {
12
+ name?: string,
13
+ columns: Column<I>[],
14
+ api: Apis<I>['create'],
15
+ title?: string,
16
+ layoutType?: 'ModalForm' | 'DrawerForm',
17
+ initialValues?: Partial<I>,
18
+ labelCol?: { span: number },
19
+ wrapperCol?: { span: number },
20
+ style?: React.CSSProperties,
21
+ convertValues?: (values: Partial<I>) => Partial<I>,
22
+ // 调用接口时的附加参数
23
+ apiParams?: ApiParams
24
+ }
25
+
26
+ export const Create = <I, >(props: CreateProps<I>) => {
27
+ const {
28
+ name = '',
29
+ style,
30
+ layoutType = 'ModalForm',
31
+ columns,
32
+ initialValues,
33
+ api,
34
+ title = '新建',
35
+ labelCol = { span: 4 },
36
+ wrapperCol = { span: 19 },
37
+ apiParams,
38
+ convertValues = values => values,
39
+ } = props
40
+
41
+ const update = useUpdate()
42
+
43
+ if (!api) {
44
+ return null
45
+ }
46
+
47
+ return (
48
+ <FormPro
49
+ style={style}
50
+ title={`${title}${name}`}
51
+ layout='horizontal'
52
+ layoutType={layoutType}
53
+ initialValues={initialValues as any}
54
+ labelCol={labelCol}
55
+ wrapperCol={wrapperCol}
56
+ {...({
57
+ ModalForm: {
58
+ modalProps: { destroyOnClose: true },
59
+ },
60
+ DrawerForm: {
61
+ drawerProps: { destroyOnClose: true },
62
+ },
63
+ })[layoutType]}
64
+ columns={columns.filter((column) => !column.hideInCreate) as any}
65
+ onFinish={async (formValues: Partial<I>) => {
66
+ if (!api) {
67
+ return
68
+ }
69
+ const { success } = await api(convertValues({ ...apiParams?.create, ...formValues }))
70
+ return success
71
+ }}
72
+ trigger={(
73
+ <Button onClick={() => setTimeout(update, 10)}>{title}</Button>
74
+ )}
75
+ />
76
+ )
77
+ }
@@ -0,0 +1,33 @@
1
+ 'use client'
2
+
3
+ import React from 'react'
4
+ import { ButtonPro } from '@wzyjs/antd'
5
+ import { Apis } from '../types'
6
+
7
+ interface RemoveProps<I> {
8
+ initialValues: I,
9
+ api: Apis<I>['remove'],
10
+ title?: string,
11
+ }
12
+
13
+ export default <I extends { id: string }>(props: RemoveProps<I>) => {
14
+ const { api, initialValues, title = '删除' } = props
15
+
16
+ if (!api) {
17
+ return null
18
+ }
19
+
20
+ return (
21
+ <ButtonPro.Confirm
22
+ title={`确认${title}?`}
23
+ btnProps={{
24
+ danger: true
25
+ }}
26
+ onConfirm={() => {
27
+ api(initialValues.id)
28
+ }}
29
+ >
30
+ {title}
31
+ </ButtonPro.Confirm>
32
+ )
33
+ }
@@ -0,0 +1,75 @@
1
+ 'use client'
2
+
3
+ import React from 'react'
4
+
5
+ import { Button } from 'antd'
6
+ import { FormPro } from '../../FormPro'
7
+
8
+ import { useUpdate } from '@wzyjs/hooks'
9
+ import { Apis, Column } from '../types'
10
+
11
+ interface UpdateProps<I> {
12
+ name?: string,
13
+ columns: Column<I>[],
14
+ initialValues: I,
15
+ api: Apis<I>['update'],
16
+ title?: string,
17
+ layoutType?: 'ModalForm' | 'DrawerForm',
18
+ labelCol?: { span: number },
19
+ wrapperCol?: { span: number },
20
+ style?: React.CSSProperties,
21
+ convertValues?: (values: Partial<I>) => Partial<I>,
22
+ }
23
+
24
+ export default <I extends { id: string }>(props: UpdateProps<I>) => {
25
+ const {
26
+ name = '',
27
+ style,
28
+ layoutType = 'ModalForm',
29
+ columns,
30
+ initialValues,
31
+ api,
32
+ title = '编辑',
33
+ labelCol = { span: 4 },
34
+ wrapperCol = { span: 19 },
35
+ convertValues = values => values,
36
+ } = props
37
+
38
+ const update = useUpdate()
39
+
40
+ if (!api) {
41
+ return null
42
+ }
43
+
44
+ return (
45
+ <FormPro
46
+ key={JSON.stringify(initialValues)}
47
+ style={style}
48
+ title={`${title}${name}`}
49
+ layout='horizontal'
50
+ layoutType={layoutType}
51
+ initialValues={initialValues}
52
+ labelCol={labelCol}
53
+ wrapperCol={wrapperCol}
54
+ {...({
55
+ ModalForm: {
56
+ modalProps: { destroyOnClose: true },
57
+ },
58
+ DrawerForm: {
59
+ drawerProps: { destroyOnClose: true },
60
+ },
61
+ })[layoutType]}
62
+ columns={columns.filter(column => !column.hideInUpdate) as any}
63
+ onFinish={async (formValues: Partial<I>) => {
64
+ if (!api) {
65
+ return
66
+ }
67
+ const { success } = await api(initialValues.id, convertValues(formValues))
68
+ return success
69
+ }}
70
+ trigger={(
71
+ <Button type='link' onClick={() => setTimeout(update, 10)}>{title}</Button>
72
+ )}
73
+ />
74
+ )
75
+ }
@@ -0,0 +1,144 @@
1
+ // 'use client'
2
+ //
3
+ // import React, { useRef, useImperativeHandle, useEffect } from 'react'
4
+ //
5
+ // import { Create } from './components/create'
6
+ // import { ActionType, TablePro, TableProProps } from '../TablePro'
7
+ //
8
+ // import { handleParams, dayjs } from '@wzyjs/utils'
9
+ // import { useRequestPro } from '@wzyjs/hooks'
10
+ // import { FilterParams, Pagination, SortParams } from '@wzyjs/types'
11
+ //
12
+ // import option from './powers/option'
13
+ // import validator from './powers/validator'
14
+ // import { handleColumns } from './utils'
15
+ // import { ApiParams, Apis, Column, Columns } from './types'
16
+ //
17
+ // export { getRequire, getRequireFormProps } from './utils'
18
+ //
19
+ // export * from './types'
20
+ //
21
+ // interface CrudProps<I> extends Omit<TableProProps<I, I>, 'columns'> {
22
+ // layoutType?: 'ModalForm' | 'DrawerForm',
23
+ // columns: Columns<I>,
24
+ // apis: Apis<I>,
25
+ // initialValues?: Partial<I>,
26
+ //
27
+ // // 获取到列表数据后传递给父组件
28
+ // onLoadData?: (data: I[]) => void,
29
+ // // 调用接口时的附加参数
30
+ // apiParams?: ApiParams
31
+ //
32
+ // // 转换列表数据
33
+ // convertData?: (values: I[]) => I[],
34
+ // // 处理创建或提交表单提交的数据
35
+ // convertValues?: (values: Partial<I>) => Partial<I>,
36
+ // }
37
+ //
38
+ // export const Crud = <I extends { id: string }>(props: CrudProps<I>) => {
39
+ // const {
40
+ // name = '',
41
+ // columns,
42
+ // apis,
43
+ // toolBarRender,
44
+ // initialValues,
45
+ // convertValues = values => values,
46
+ // convertData = data => data,
47
+ // onLoadData,
48
+ // apiParams,
49
+ // layoutType = 'ModalForm',
50
+ // } = props
51
+ //
52
+ // const actionRef = useRef<ActionType>()
53
+ //
54
+ // useImperativeHandle(props.actionRef, () => actionRef.current)
55
+ //
56
+ // const listState = useRequestPro(apis.list, {
57
+ // manual: true,
58
+ // })
59
+ // const createState = useRequestPro(apis.create, {
60
+ // manual: true,
61
+ // alertSuccessMessage: true,
62
+ // onSuccess: () => actionRef.current?.reload()
63
+ // })
64
+ // const updateState = useRequestPro(apis.update, {
65
+ // manual: true,
66
+ // alertSuccessMessage: true,
67
+ // onSuccess: () => actionRef.current?.reload()
68
+ // })
69
+ // const removeState = useRequestPro(apis.remove, {
70
+ // manual: true,
71
+ // alertSuccessMessage: true,
72
+ // onSuccess: () => actionRef.current?.reload()
73
+ // })
74
+ //
75
+ // const mvalidator = (columns: Column<I>[]) => validator({
76
+ // columns,
77
+ // findApi: apis.find,
78
+ // })
79
+ //
80
+ // const moption = (columns: Column<I>[]) => {
81
+ // columns.forEach(column => {
82
+ // if (column.valueType === 'dateTime') {
83
+ // column.render = (_, __) => {
84
+ // return dayjs(__?.[column.dataIndex]).format('YYYY-MM-DD HH:mm:ss')
85
+ // }
86
+ // }
87
+ // })
88
+ // return columns
89
+ // }
90
+ //
91
+ // const timeoption = (columns: Column<I>[]) => option({
92
+ // name,
93
+ // columns,
94
+ // layoutType,
95
+ // updateApi: apis.update && updateState?.runAsync,
96
+ // removeApi: apis.remove && removeState?.runAsync,
97
+ // mvalidator,
98
+ // convertValues,
99
+ // })
100
+ //
101
+ // const request = async (
102
+ // params: Pagination & I,
103
+ // sort: SortParams,
104
+ // filter: FilterParams,
105
+ // ) => {
106
+ // let { data = { data: [], total: 0 } } = await listState?.runAsync(
107
+ // handleParams(params, sort, filter, apiParams?.list),
108
+ // )
109
+ // onLoadData?.(data.data)
110
+ // return {
111
+ // data: convertData(data.data || []),
112
+ // total: data.total,
113
+ // }
114
+ // }
115
+ //
116
+ // useEffect(() => {
117
+ // actionRef.current?.reload()
118
+ // }, [JSON.stringify(apiParams?.list)])
119
+ //
120
+ // return (
121
+ // <TablePro
122
+ // {...props}
123
+ // headerTitle={`${name}列表`}
124
+ // actionRef={actionRef}
125
+ // request={request}
126
+ // columns={handleColumns(columns, { type: 'list', isList: true }, [moption, timeoption])}
127
+ // toolBarRender={(action, rows) => [
128
+ // ...(toolBarRender && toolBarRender?.(action, rows) || []),
129
+ // apis?.create && (
130
+ // <Create
131
+ // name={name}
132
+ // key='create'
133
+ // columns={handleColumns(columns, { type: 'create', isCreate: true }, [mvalidator])}
134
+ // layoutType={layoutType}
135
+ // apiParams={apiParams}
136
+ // api={createState?.runAsync}
137
+ // initialValues={initialValues}
138
+ // convertValues={convertValues}
139
+ // />
140
+ // ),
141
+ // ]}
142
+ // />
143
+ // )
144
+ // }
@@ -0,0 +1,60 @@
1
+ 'use client'
2
+
3
+ import React from 'react'
4
+ import { Space } from 'antd'
5
+ import Update from '../components/update'
6
+ import Remove from '../components/remove'
7
+ import { Apis, Column } from '../types'
8
+ import { handleColumns } from '../utils'
9
+
10
+ interface OptionProps<I> {
11
+ name?: string,
12
+ columns: Column<I>[],
13
+ layoutType?: 'ModalForm' | 'DrawerForm',
14
+ updateApi: Apis<I>['update'],
15
+ removeApi: Apis<I>['remove'],
16
+ mvalidator: (columns: Column<I>[]) => Column<I>[],
17
+ convertValues?: (values: Partial<I>) => Partial<I>,
18
+ }
19
+
20
+ export default <I extends { id: string }>(props: OptionProps<I>): Column<I>[] => {
21
+ const { name, columns, convertValues, updateApi, removeApi, mvalidator, layoutType = 'ModalForm' } = props
22
+
23
+ // 编辑和删除按钮
24
+ const optionRender = {
25
+ title: '操作',
26
+ key: 'option',
27
+ render: (dom: React.ReactNode, record: I) => (
28
+ <Space key='option'>
29
+ {updateApi && (
30
+ <Update
31
+ name={name}
32
+ columns={handleColumns(columns, { type: 'update', isUpdate: true }, [mvalidator])}
33
+ layoutType={layoutType}
34
+ initialValues={record}
35
+ api={updateApi}
36
+ convertValues={convertValues}
37
+ />
38
+ )}
39
+ {removeApi && (
40
+ <Remove
41
+ api={removeApi}
42
+ initialValues={record}
43
+ />
44
+ )}
45
+ </Space>
46
+ ),
47
+ }
48
+
49
+ const last = columns[columns.length - 1]
50
+ if (last?.key === 'option') {
51
+ const originalRender = last.render
52
+ // @ts-ignore
53
+ last.render = (dom: React.ReactNode, entity: I, index: number, action: any, schema: any) => [
54
+ (updateApi || removeApi) && optionRender.render(dom, entity),
55
+ originalRender?.(dom, entity, index, action, schema),
56
+ ].flat()
57
+ }
58
+
59
+ return columns
60
+ }