1.2.6 • Published 2 years ago

@perrychi/editable-sortable-tree v1.2.6

Weekly downloads
-
License
ISC
Repository
github
Last release
2 years ago

@perrychi/editable-sortable-tree

A react editable and sortable tree component based on antd tree

Interaction

demo demo

📦 Install

npm install @perrychi/editable-sortable-tree --save
yarn add @perrychi/editable-sortable-tree

This component is based on antd. If antd is not installed in your project, please install antd first

npm install antd --save

🔨 Usage

A simple example

import React from 'react';
import EditableSortableTree from '@perrychi/editable-sortable-tree';

const App = () => {
  const treeData = [
    {
      title: '中国',
      code: 'china',
      children: [
        {
          title: '浙江',
          code: 'zhejiang',
          children: [
            {
              title: '杭州',
              code: 'hangzhou',
            },
            {
              title: '宁波',
              code: 'ningbo',
            },
          ]
        }
      ]
    },
    {
      title: 'America',
      code: 'USA',
    }
  ]
  return <EditableSortableTree treeData={treeData} />
}

export default App;

A complex example

src/FormComponent.js

import React, { useState, useEffect } from 'react';
import { Form, Input, Radio } from 'antd';
import { trimNull } from '@perrychi/editable-sortable-tree';

const { TextArea } = Input;

const FormComponent = props => {
  const { currentNodeContent, treeNodeFormAPI } = props;
    // console.log('15 currentNodeContent', currentNodeContent);
    // console.log('11 treeNodeFormAPI', treeNodeFormAPI);
    const {
      key = '',
      title: name = '',
      indexRoute = '',
      component = '',
      iframeUrl = '',
      hideInMenu = false,
      icon = '',
      moreConfig = '',
    } = trimNull(currentNodeContent || {});

    const [componentValue, setComponentInputValue] = useState(component);
    const [iframeUrlValue, setIframeUrlInputValue] = useState(iframeUrl);

    // 当左侧菜单树节点切换时,要在右侧表单中回显菜单节点的各个字段
    // When the left menu tree node is switched, each field of the menu node is to be echoed in the right form
    useEffect(() => {
      treeNodeFormAPI.setFieldsValue({
        indexRoute,
        component,
        iframeUrl,
        hideInMenu,
        icon,
        moreConfig,
      });
      /**
       * 更新component和iframeUrl的状态,来控制这两个输入框的disabled的互斥关系
       * 对于同一个菜单节点,component和iframeUrl只能一个有值
       * 也就是说每个菜单要么引用前端项目中的组件,要么用iframe嵌入第三方页面
       */
      setComponentInputValue(component);
      setIframeUrlInputValue(iframeUrl);
    }, [key, name]);

    return (
      <Form form={treeNodeFormAPI} labelAlign="right" labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
        <Form.Item
          label="IndexRoute"
          name="indexRoute"
          rules={[{ required: false, message: 'Please enter index router' }]}
          initialValue=""
        >
          <Input placeholder="Please enter index router" />
        </Form.Item>
        <Form.Item
          label="Component"
          name="component"
          rules={[{ required: false, message: 'Please enter component directory' }]}
          initialValue=""
        >
          <Input
            placeholder={`${iframeUrlValue ? 'component and url are mutually exclusive' : 'Please enter component directory'}`}
            disabled={!!iframeUrlValue}
            onChange={(event) => {
              setComponentInputValue(event.target.value);
            }}
          />
        </Form.Item>
        <Form.Item
          label="Third-party URL"
          name="iframeUrl"
          rules={[{ required: false, message: 'Please enter Third-party url' }]}
          initialValue=""
        >
          <Input
            placeholder={`${componentValue ? 'Component and url are mutually exclusive' : 'Please enter component url'}`}
            disabled={!!componentValue}
            onChange={(event) => {
              setIframeUrlInputValue(event.target.value);
            }}
          />
        </Form.Item>
        <Form.Item
          label="Whether to hide"
          name="hideInMenu"
          rules={[{ required: false, message: 'Please choose' }]}
          initialValue={false}
        >
          <Radio.Group>
            <Radio value={false}>Yes</Radio>
            <Radio value={true}>No</Radio>
          </Radio.Group>
        </Form.Item>
        <Form.Item
          label="Menu icon"
          name="icon"
          rules={[{ required: false, message: 'Please enter menu icon name' }]}
          initialValue=""
        >
          <Input placeholder="Please enter menu icon name" />
        </Form.Item>
        <Form.Item
          label="More config"
          name="moreConfig"
          rules={[{ required: false, message: 'Please enter extended JSON' }]}
          initialValue=""
        >
          <TextArea placeholder="Please enter extended JSON" />
        </Form.Item>
      </Form>
    )
  }

export default FormComponent;

src/App.js

import React, { useRef } from 'react';
import EditableSortableTree, { handleRouteData } from './EditableSortableTree';
import { Form, Button } from 'antd';
import FormComponent from './FormComponent';

const App = () => {
  const getTreeData = useRef();

  const [treeNodeFormAPI] = Form.useForm();

  const onChange = (treeData) => {
    console.log('This is the latest tree data: ', treeData);
  }

  const props = {
    treeData: handleRouteData([]),
    treeNodeFormAPI,
    FormComponent,
    leftWidth: 40,
    getTreeData,
    onChange,
    // needClear: When in a popup, whether to clear the form data when closing the popup
    needClear: false,
  };

  return (
    <div className="App">
      <EditableSortableTree {...props} />
      <div style={{
        height: '80px',
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center'
      }}>
        <Button type='primary' onClick={() => {
          getTreeData.current().then(finalData => {
            console.log('This is the data you want: ', finalData);
          })
        }}>
          Get data
        </Button>
      </div>
    </div>
  );
}

export default App;

UI display

demo demo

Props

PropDescriptionTypeDefault
treeDataThe treeNodes data Arrayarray<{ key, title, children, disabled, selectable }>[]
FormComponentUser-defined node information editing form component, this component is best to use antd's Form form(currentNodeContent, treeNodeFormAPI) => ReactNode-
treeNodeFormAPIform API of Antd Form in FormComponentobject-
leftWidthThe width of the left tree component blocknumber40
getTreeDataA object generated by useRefobject-
onChangeThe callback when the tree data changes, the latest tree data will be passed to the callback(treeData) => {}-
needClearIf the component is in the modal box, whether to clear the data of the tree component and the content of the form when the modal box is closedbooleanfalse
1.2.6

2 years ago

1.2.5

2 years ago

1.2.4

2 years ago

1.2.0

2 years ago

1.2.3

2 years ago

1.2.2

2 years ago

1.2.1

2 years ago

1.1.4

2 years ago

1.1.3

2 years ago

1.1.2

2 years ago

1.1.1

2 years ago

1.1.0

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago