@fe-free/core 2.8.12 → 2.8.13

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @fe-free/core
2
2
 
3
+ ## 2.8.13
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: add DataViewer and PageLayout equalParts
8
+ - @fe-free/tool@2.8.13
9
+
3
10
  ## 2.8.12
4
11
 
5
12
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fe-free/core",
3
- "version": "2.8.12",
3
+ "version": "2.8.13",
4
4
  "description": "",
5
5
  "main": "./src/index.ts",
6
6
  "author": "",
@@ -41,7 +41,7 @@
41
41
  "safe-stable-stringify": "^2.5.0",
42
42
  "vanilla-jsoneditor": "^0.23.1",
43
43
  "zustand": "^4.5.4",
44
- "@fe-free/tool": "2.8.12"
44
+ "@fe-free/tool": "2.8.13"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@ant-design/pro-components": "2.8.9",
@@ -0,0 +1,54 @@
1
+ import type { DataViewerProps } from '@fe-free/core';
2
+ import { DataViewer } from '@fe-free/core';
3
+ import type { Meta, StoryObj } from '@storybook/react-vite';
4
+
5
+ const meta: Meta<typeof DataViewer> = {
6
+ title: '@fe-free/core/DataViewer',
7
+ component: DataViewer,
8
+ tags: ['autodocs'],
9
+ };
10
+
11
+ export default meta;
12
+ type Story = StoryObj<typeof DataViewer>;
13
+
14
+ const BasicDemo = (props: DataViewerProps) => {
15
+ return (
16
+ <div style={{ width: '500px', height: '500px' }}>
17
+ <DataViewer {...props} />
18
+ </div>
19
+ );
20
+ };
21
+
22
+ // 基础用法
23
+ export const Basic: Story = {
24
+ args: {
25
+ data: 'hello world!',
26
+ title: '输入',
27
+ enableMaximize: true,
28
+ },
29
+ render: (props) => <BasicDemo {...props} />,
30
+ };
31
+
32
+ export const ForJSON: Story = {
33
+ args: {
34
+ data: JSON.stringify({ action: 'hello', data: 'world' }, null, 2),
35
+ },
36
+ render: (props) => <BasicDemo {...props} />,
37
+ };
38
+
39
+ export const Markdown: Story = {
40
+ args: {
41
+ data: `# Hello, World!
42
+
43
+ This is a markdown file.
44
+
45
+ ## Title2
46
+
47
+ ### Title 3
48
+
49
+ - Item 1
50
+ - Item 2
51
+ - Item 3`,
52
+ },
53
+ render: (props) => <BasicDemo {...props} />,
54
+ };
@@ -0,0 +1,70 @@
1
+ import { ArrowsAltOutlined } from '@ant-design/icons';
2
+ import { Button, Modal, Select } from 'antd';
3
+ import { useState } from 'react';
4
+ import { Editor } from '../editor';
5
+ import { PageLayout } from '../page_layout';
6
+
7
+ interface DataViewerProps {
8
+ data: string;
9
+ title?: string | React.ReactNode;
10
+ enableMaximize?: boolean;
11
+ }
12
+
13
+ type DataViewerLanguage = 'json' | 'markdown' | 'text';
14
+
15
+ const options = [
16
+ { label: 'Text', value: 'text' },
17
+ { label: 'JSON', value: 'json' },
18
+ { label: 'Markdown', value: 'markdown' },
19
+ ];
20
+
21
+ function DataViewer({ data, title, enableMaximize }: DataViewerProps) {
22
+ const [maximize, setMaximize] = useState(false);
23
+ const [language, setLanguage] = useState<DataViewerLanguage>(
24
+ options[0].value as DataViewerLanguage,
25
+ );
26
+
27
+ return (
28
+ <>
29
+ <PageLayout
30
+ direction="vertical"
31
+ start={
32
+ <div className="flex items-center justify-between gap-2 py-2">
33
+ <div className="flex-1">{title}</div>
34
+ <Select
35
+ options={options}
36
+ value={language}
37
+ onChange={(value) => setLanguage(value)}
38
+ className="w-[110px]"
39
+ />
40
+ {enableMaximize && (
41
+ <Button icon={<ArrowsAltOutlined />} onClick={() => setMaximize(!maximize)} />
42
+ )}
43
+ </div>
44
+ }
45
+ >
46
+ <div className="relative h-full">
47
+ <Editor
48
+ value={data}
49
+ language={language === 'text' ? undefined : language}
50
+ editable={false}
51
+ />
52
+ </div>
53
+ </PageLayout>
54
+ {maximize && (
55
+ <Modal title="查看" open width={'80vw'} onCancel={() => setMaximize(false)} footer={null}>
56
+ <div className="h-[80vh]">
57
+ <Editor
58
+ value={data}
59
+ language={language === 'text' ? undefined : language}
60
+ editable={false}
61
+ />
62
+ </div>
63
+ </Modal>
64
+ )}
65
+ </>
66
+ );
67
+ }
68
+
69
+ export { DataViewer };
70
+ export type { DataViewerProps };
package/src/index.ts CHANGED
@@ -12,6 +12,8 @@ export { CRUDOfList } from './crud_of_list';
12
12
  export type { CRUDOfListProps } from './crud_of_list';
13
13
  export { CRUDOfPure } from './crud_of_pure';
14
14
  export type { CRUDOfPureProps } from './crud_of_pure';
15
+ export { DataViewer } from './data_viewer';
16
+ export type { DataViewerProps } from './data_viewer';
15
17
  export { Editor } from './editor';
16
18
  export type { EditorProps } from './editor';
17
19
  export { EditorJSON } from './editor_json';
@@ -1,4 +1,4 @@
1
- import cn from 'classnames';
1
+ import classNames from 'classnames';
2
2
  import { Fragment, useMemo } from 'react';
3
3
  import { useSearchParams } from 'react-router-dom';
4
4
  import type { TabsProps } from '../tabs';
@@ -9,6 +9,8 @@ interface PageLayoutProps {
9
9
  start?: React.ReactNode;
10
10
  children?: React.ReactNode;
11
11
  end?: React.ReactNode;
12
+ /** beta equalParts */
13
+ equalParts?: boolean;
12
14
  className?: string;
13
15
  startClassName?: string;
14
16
  childrenClassName?: string;
@@ -20,6 +22,7 @@ function PageLayout({
20
22
  start,
21
23
  children,
22
24
  end,
25
+ equalParts,
23
26
  className,
24
27
  startClassName,
25
28
  childrenClassName,
@@ -27,7 +30,7 @@ function PageLayout({
27
30
  }: PageLayoutProps) {
28
31
  return (
29
32
  <div
30
- className={cn(
33
+ className={classNames(
31
34
  'flex h-full w-full',
32
35
  {
33
36
  'flex-row': direction === 'horizontal',
@@ -36,9 +39,45 @@ function PageLayout({
36
39
  className,
37
40
  )}
38
41
  >
39
- <div className={cn('flex-none', startClassName)}>{start}</div>
40
- <div className={cn('flex-1 overflow-auto', childrenClassName)}>{children}</div>
41
- <div className={cn('flex-none', endClassName)}>{end}</div>
42
+ {start && (
43
+ <div
44
+ className={classNames(
45
+ {
46
+ 'flex-none': !equalParts,
47
+ 'min-w-0 flex-1 flex-shrink-0 overflow-auto': equalParts,
48
+ },
49
+ startClassName,
50
+ )}
51
+ >
52
+ {start}
53
+ </div>
54
+ )}
55
+ {children && (
56
+ <div
57
+ className={classNames(
58
+ 'flex-1 overflow-auto',
59
+ {
60
+ 'min-w-0 flex-shrink-0': equalParts,
61
+ },
62
+ childrenClassName,
63
+ )}
64
+ >
65
+ {children}
66
+ </div>
67
+ )}
68
+ {end && (
69
+ <div
70
+ className={classNames(
71
+ {
72
+ 'flex-none': !equalParts,
73
+ 'min-w-0 flex-1 flex-shrink-0 overflow-auto': equalParts,
74
+ },
75
+ endClassName,
76
+ )}
77
+ >
78
+ {end}
79
+ </div>
80
+ )}
42
81
  </div>
43
82
  );
44
83
  }
@@ -27,6 +27,15 @@ export const DirectionVertical: Story = {
27
27
  },
28
28
  };
29
29
 
30
+ export const EqualParts: Story = {
31
+ args: {
32
+ className: '!w-[800px] !h-[200px] bg-gray-200',
33
+ equalParts: true,
34
+ // start: <div className="h-[100px] bg-red-500">start</div>,
35
+ children: <div className="h-[100px] bg-blue-500">children</div>,
36
+ end: <div className="h-[100px] w-[600px] bg-green-500">end</div>,
37
+ },
38
+ };
30
39
  export const ClassName: Story = {
31
40
  args: {
32
41
  className: '!w-[500px] !h-[500px]',