import { observer, connect, useField, RecursionField } from '@formily/react'; import React from 'react'; import { Button, Tabs as AntdTabs, Dropdown, Menu, Switch, Space } from 'antd'; import { findPropertyByPath, getSchemaPath, SchemaField, useDesignable, } from '../../components/schema-renderer'; import { Schema, SchemaKey } from '@formily/react'; import { PlusOutlined, MenuOutlined } from '@ant-design/icons'; import { useState } from 'react'; import cls from 'classnames'; import { createSchema, removeSchema, updateSchema } from '..'; import './style.less'; import { uid } from '@formily/shared'; import { DragHandle, SortableItem } from '../../components/Sortable'; import { DndContext, DragOverlay } from '@dnd-kit/core'; import { FormDialog, FormLayout } from '@formily/antd'; import IconPicker from '../../components/icon-picker'; const useTabs = ({ singleton }) => { const tabsField = useField(); const { schema } = useDesignable(); const tabs: { name: SchemaKey; props: any; schema: Schema }[] = []; schema.mapProperties((schema, name) => { const field = tabsField.query(tabsField.address.concat(name)).take(); if (field?.display === 'none' || field?.display === 'hidden') return; if (schema['x-component']?.indexOf('TabPane') > -1) { tabs.push({ name, props: { key: schema?.['x-component-props']?.key || name, ...schema?.['x-component-props'], }, schema, }); } }); if (singleton) { return [tabs.shift()].filter(Boolean); } return tabs; }; export const Tabs: any = observer((props: any) => { const { singleton, ...others } = props; const { designable, schema, DesignableBar, appendChild, root, remove, insertAfter, } = useDesignable(); const tabs = useTabs({ singleton }); const [dragOverlayContent, setDragOverlayContent] = useState(''); const moveToAfter = (path1, path2) => { if (!path1 || !path2) { return; } if (path1.join('.') === path2.join('.')) { return; } const data = findPropertyByPath(root, path1); if (!data) { return; } remove(path1); return insertAfter(data.toJSON(), path2); }; if (singleton) { return (
{tabs.map(({ props, schema, name }, key) => ( ))}
); } return (
{ setDragOverlayContent(event.active.data?.current?.title || ''); }} onDragEnd={async (event) => { const path1 = event.active?.data?.current?.path; const path2 = event.over?.data?.current?.path; const data = moveToAfter(path1, path2); await updateSchema(data); }} > {dragOverlayContent} } onClick={async () => { const values = await FormDialog('新增标签页', () => { return ( ); }).open({ initialValues: { title: schema['title'], icon: schema['x-component-props']?.['icon'], }, }); const data = appendChild({ type: 'void', name: uid(), title: values.title, 'x-component': 'Tabs.TabPane', 'x-designable-bar': 'Tabs.TabPane.DesignableBar', 'x-component-props': { icon: values.icon, }, properties: { [uid()]: { type: 'void', 'x-component': 'Grid', 'x-component-props': { addNewComponent: 'AddNew.PaneItem', }, }, }, }); await createSchema(data); }} > 新增标签页 ) } > {tabs.map(({ props, schema, name }, key) => ( } key={key} > ))}
); }); Tabs.TabPane = observer((props: any) => { const { schema, DesignableBar } = useDesignable(); return (
{schema.title}
); }); Tabs.DesignableBar = () => { const { schema, remove, refresh, insertAfter } = useDesignable(); const [visible, setVisible] = useState(false); const field = useField(); return (
{ e.stopPropagation(); }} className={cls('designable-bar-actions', { active: visible })} > { setVisible(visible); }} overlay={ { const singleton = !field.componentProps.singleton; schema['x-component-props'] = schema['x-component-props'] || {}; schema['x-component-props'].singleton = singleton; field.componentProps.singleton = singleton; updateSchema(schema); }} > 禁用标签页 {' '} } >
); }; Tabs.TabPane.DesignableBar = () => { const { schema, remove, refresh, insertAfter } = useDesignable(); const [visible, setVisible] = useState(false); const field = useField(); return (
{ e.stopPropagation(); }} className={cls('designable-bar-actions', { active: visible })} > {' '} { setVisible(visible); }} overlay={ { const values = await FormDialog('修改名称和图标', () => { return ( ); }).open({ initialValues: { title: schema['title'], icon: schema['x-component-props']?.['icon'], }, }); field.componentProps.icon = values.icon; schema.title = values.title; schema['x-component-props'] = schema['x-component-props'] || {}; schema['x-component-props']['icon'] = values.icon; refresh(); updateSchema(schema); }} > 修改名称和图标 { const data = remove(); await removeSchema(data); setVisible(false); }} > 移除 } >
); };