From d04d3d063915772fa77619ec4c131d9c2549cbe4 Mon Sep 17 00:00:00 2001 From: semmy Date: Thu, 20 Jan 2022 15:16:12 +0800 Subject: [PATCH] feat: add IconPicker component into schema components --- packages/client/src/components/icon/Icon.tsx | 51 +++++++++++++ packages/client/src/components/icon/index.ts | 1 + packages/client/src/components/index.ts | 1 + .../antd/icon-picker/IconPicker.tsx | 71 +++++++++++++++++++ .../antd/icon-picker/demos/demo1.tsx | 41 +++++++++++ .../antd/icon-picker/index.md | 6 ++ .../antd/icon-picker/index.ts | 1 + .../client/src/schema-component/antd/index.ts | 5 +- 8 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 packages/client/src/components/icon/Icon.tsx create mode 100644 packages/client/src/components/icon/index.ts create mode 100644 packages/client/src/components/index.ts create mode 100644 packages/client/src/schema-component/antd/icon-picker/IconPicker.tsx create mode 100644 packages/client/src/schema-component/antd/icon-picker/demos/demo1.tsx create mode 100644 packages/client/src/schema-component/antd/icon-picker/index.ts diff --git a/packages/client/src/components/icon/Icon.tsx b/packages/client/src/components/icon/Icon.tsx new file mode 100644 index 000000000..012eec51e --- /dev/null +++ b/packages/client/src/components/icon/Icon.tsx @@ -0,0 +1,51 @@ +import * as antIcons from '@ant-design/icons'; +import { createFromIconfontCN } from '@ant-design/icons'; +import React from 'react'; + +export const IconFont = createFromIconfontCN({ + scriptUrl: ['//at.alicdn.com/t/font_2261954_u9jzwc44ug.js'], +}); + +export const icons = new Map(); + +export function registerIcon(type: string, icon: any = IconFont) { + icons.set(type.toLowerCase(), icon); +} + +export function hasIcon(type: string) { + if (!type) { + return false; + } + return icons.has(type.toLowerCase()); +} + +export function registerIcons(components) { + Object.keys(components).forEach((type) => { + registerIcon(type, components[type]); + }); +} + +Object.keys(antIcons).forEach((name) => { + if (name.endsWith('Outlined')) { + registerIcon(name, antIcons[name]); + } +}); + +interface IconProps { + type: string; + [key: string]: any; +} + +export function Icon(props: IconProps) { + const { type = '', ...restProps } = props; + if (type && icons.has(type.toLowerCase())) { + const IconComponent = icons.get(type.toLowerCase()); + if (IconComponent === IconFont) { + return ; + } + return ; + } + return null; +} + +export default Icon; diff --git a/packages/client/src/components/icon/index.ts b/packages/client/src/components/icon/index.ts new file mode 100644 index 000000000..e263cc0e6 --- /dev/null +++ b/packages/client/src/components/icon/index.ts @@ -0,0 +1 @@ +export * from './Icon'; diff --git a/packages/client/src/components/index.ts b/packages/client/src/components/index.ts new file mode 100644 index 000000000..af77d84ef --- /dev/null +++ b/packages/client/src/components/index.ts @@ -0,0 +1 @@ +export * from './icon'; diff --git a/packages/client/src/schema-component/antd/icon-picker/IconPicker.tsx b/packages/client/src/schema-component/antd/icon-picker/IconPicker.tsx new file mode 100644 index 000000000..1a79c7df4 --- /dev/null +++ b/packages/client/src/schema-component/antd/icon-picker/IconPicker.tsx @@ -0,0 +1,71 @@ +import { CloseOutlined, LoadingOutlined } from '@ant-design/icons'; +import { connect, mapProps, mapReadPretty } from '@formily/react'; +import { isValid } from '@formily/shared'; +import { Button, Input, Popover } from 'antd'; +import React, { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { hasIcon, Icon, icons } from '../../../components/icon'; + +function IconField(props: any) { + const { value, onChange } = props; + const [visible, setVisible] = useState(false); + const { t } = useTranslation(); + return ( +
+ + { + setVisible(val); + }} + content={ +
+ {[...icons.keys()].map((key) => ( + { + onChange(key); + setVisible(false); + }} + > + + + ))} +
+ } + title={t('Icon')} + trigger="click" + > + +
+ {value && ( + + )} +
+
+ ); +} + +export const IconPicker = connect( + IconField, + mapProps((props, field) => { + return { + ...props, + suffix: {field?.['loading'] || field?.['validating'] ? : props.suffix}, + }; + }), + mapReadPretty((props) => { + if (!isValid(props.value)) { + return
; + } + return ; + }), +); + +export default IconPicker; diff --git a/packages/client/src/schema-component/antd/icon-picker/demos/demo1.tsx b/packages/client/src/schema-component/antd/icon-picker/demos/demo1.tsx new file mode 100644 index 000000000..d22088891 --- /dev/null +++ b/packages/client/src/schema-component/antd/icon-picker/demos/demo1.tsx @@ -0,0 +1,41 @@ +/** + * title: IconPicker + */ +import { FormItem } from '@formily/antd'; +import { IconPicker, SchemaComponent, SchemaComponentProvider } from '@nocobase/client'; +import React from 'react'; + +const schema = { + type: 'object', + properties: { + input: { + type: 'boolean', + title: `Editable`, + 'x-decorator': 'FormItem', + 'x-component': 'IconPicker', + 'x-reactions': { + target: 'read', + fulfill: { + state: { + value: '{{$self.value}}', + }, + }, + }, + }, + read: { + type: 'boolean', + title: `Read pretty`, + 'x-read-pretty': true, + 'x-decorator': 'FormItem', + 'x-component': 'IconPicker', + }, + }, +}; + +export default () => { + return ( + + + + ); +}; diff --git a/packages/client/src/schema-component/antd/icon-picker/index.md b/packages/client/src/schema-component/antd/icon-picker/index.md index 9780ff7bf..39ff77661 100644 --- a/packages/client/src/schema-component/antd/icon-picker/index.md +++ b/packages/client/src/schema-component/antd/icon-picker/index.md @@ -6,3 +6,9 @@ group: --- # IconPicker + +## Examples + +### IconPicker usage + + diff --git a/packages/client/src/schema-component/antd/icon-picker/index.ts b/packages/client/src/schema-component/antd/icon-picker/index.ts new file mode 100644 index 000000000..30dda5250 --- /dev/null +++ b/packages/client/src/schema-component/antd/icon-picker/index.ts @@ -0,0 +1 @@ +export * from './IconPicker'; diff --git a/packages/client/src/schema-component/antd/index.ts b/packages/client/src/schema-component/antd/index.ts index e2e05de79..f69926756 100644 --- a/packages/client/src/schema-component/antd/index.ts +++ b/packages/client/src/schema-component/antd/index.ts @@ -7,9 +7,10 @@ export * from './dnd-context'; export * from './form'; export * from './form-item'; export * from './grid'; +export * from './icon-picker'; export * from './input'; export * from './input-number'; -export * from './password'; -export * from './radio'; export * from './menu'; export * from './page'; +export * from './password'; +export * from './radio';