From 611070edd3721f22fd0b0a79b08ff14ddbe45ee4 Mon Sep 17 00:00:00 2001 From: xzdry Date: Fri, 8 Jul 2022 18:08:48 +0800 Subject: [PATCH 1/3] feat(arco/Tag): add Tag component --- packages/arco-lib/src/components/Tag.tsx | 92 ++++++++++++++++++++ packages/arco-lib/src/generated/types/Tag.ts | 40 +++++++++ 2 files changed, 132 insertions(+) create mode 100644 packages/arco-lib/src/components/Tag.tsx create mode 100644 packages/arco-lib/src/generated/types/Tag.ts diff --git a/packages/arco-lib/src/components/Tag.tsx b/packages/arco-lib/src/components/Tag.tsx new file mode 100644 index 00000000..6f12c3dd --- /dev/null +++ b/packages/arco-lib/src/components/Tag.tsx @@ -0,0 +1,92 @@ +import { Tag as BaseTag } from '@arco-design/web-react'; +import { implementRuntimeComponent } from '@sunmao-ui/runtime'; +import { css } from '@emotion/css'; +import { Type, Static } from '@sinclair/typebox'; +import { FALLBACK_METADATA, getComponentProps } from '../sunmao-helper'; +import { TagPropsSpec as BaseTagPropsSpec } from '../generated/types/Tag'; +import { useEffect, useState } from 'react'; + +const TagPropsSpec = Type.Object(BaseTagPropsSpec); +const TagStateSpec = Type.Object({ + checked: Type.Boolean(), +}); + +const exampleProperties: Static = { + content: 'tag', + closable: false, + checkable: false, + defaultChecked: false, + color: '', + size: 'large', + bordered: false, + defaultVisible: true, +}; + +export const Tag = implementRuntimeComponent({ + version: 'arco/v1', + metadata: { + ...FALLBACK_METADATA, + name: 'tag', + displayName: 'Tag', + exampleProperties, + annotations: { + category: 'Data Display', + }, + }, + spec: { + properties: TagPropsSpec, + state: TagStateSpec, + methods: {}, + slots: { + content: { + slotProps: Type.Object({}), + }, + icon: { + slotProps: Type.Object({}), + }, + }, + styleSlots: ['content'], + events: ['onCheck', 'onClose'], + }, +})(props => { + const { content, defaultChecked, defaultVisible, checkable, ...cProps } = + getComponentProps(props); + const { slotsElements, customStyle, elementRef, callbackMap, mergeState } = props; + + const [checked, setChecked] = useState(defaultChecked); + const [visible, setVisible] = useState(defaultVisible); + useEffect(() => { + if (!checkable) { + setChecked(undefined); + mergeState({ checked: undefined }); + } else { + setChecked(defaultChecked); + mergeState({ checked: defaultChecked }); + } + }, [checkable, defaultChecked, mergeState, setChecked]); + + return ( + { + setChecked(prev => !prev); + mergeState({ checked: !checked }); + callbackMap?.onCheck?.(); + }} + onClose={() => { + setVisible(false); + setChecked(undefined); + mergeState({ checked: undefined }); + callbackMap?.onClose?.(); + }} + icon={slotsElements.icon ? slotsElements.icon({}) : null} + {...cProps} + > + {(slotsElements.content && slotsElements.content({})) || content} + + ); +}); diff --git a/packages/arco-lib/src/generated/types/Tag.ts b/packages/arco-lib/src/generated/types/Tag.ts new file mode 100644 index 00000000..3151d7e1 --- /dev/null +++ b/packages/arco-lib/src/generated/types/Tag.ts @@ -0,0 +1,40 @@ +import { Type } from '@sinclair/typebox'; +import { Category } from '../../constants/category'; +import { StringUnion } from '../../sunmao-helper'; + +export const TagPropsSpec = { + content: Type.String({ + title: 'Content', + category: Category.Basic, + }), + closable: Type.Boolean({ + title: 'Closable', + category: Category.Behavior, + }), + checkable: Type.Boolean({ + title: 'Checkable', + category: Category.Behavior, + }), + defaultChecked: Type.Boolean({ + title: 'Default Checked', + category: Category.Behavior, + conditions: [{ key: 'checkable', value: true }], + }), + defaultVisible: Type.Boolean({ + title: 'Default Visible', + category: Category.Behavior, + }), + color: Type.String({ + title: 'Color', + category: Category.Style, + widget: 'core/v1/color', + }), + size: StringUnion(['large', 'medium', 'default', 'small'], { + title: 'Size', + category: Category.Style, + }), + bordered: Type.Boolean({ + title: 'Bordered', + category: Category.Style, + }), +}; From 350a149a3a9b9967697ec25dfa85d4bc64a9481a Mon Sep 17 00:00:00 2001 From: xzdry Date: Fri, 8 Jul 2022 18:10:11 +0800 Subject: [PATCH 2/3] feat(arco/Carousel): add Carousel component --- packages/arco-lib/src/components/Carousel.tsx | 90 +++++++++++++++++++ .../arco-lib/src/generated/types/Carousel.ts | 62 +++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 packages/arco-lib/src/components/Carousel.tsx create mode 100644 packages/arco-lib/src/generated/types/Carousel.ts diff --git a/packages/arco-lib/src/components/Carousel.tsx b/packages/arco-lib/src/components/Carousel.tsx new file mode 100644 index 00000000..9354e3d5 --- /dev/null +++ b/packages/arco-lib/src/components/Carousel.tsx @@ -0,0 +1,90 @@ +import { Carousel as BaseCarousel } from '@arco-design/web-react'; +import { implementRuntimeComponent } from '@sunmao-ui/runtime'; +import { css } from '@emotion/css'; +import { Type, Static } from '@sinclair/typebox'; +import { FALLBACK_METADATA, getComponentProps } from '../sunmao-helper'; +import { CarouselPropsSpec as BaseCarouselPropsSpec } from '../generated/types/Carousel'; +import { useRef, useEffect } from 'react'; +import { CarouselHandle } from '@arco-design/web-react/es/Carousel/interface'; + +const InputPropsSpec = Type.Object({ + ...BaseCarouselPropsSpec, +}); +const InputStateSpec = Type.Object({ + value: Type.Number(), +}); + +const defaultCarouselStyle = css` + height: 240px; +`; + +const exampleProperties: Static = { + imageSrc: [ + '//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/cd7a1aaea8e1c5e3d26fe2591e561798.png~tplv-uwbnlip3yd-webp.webp', + '//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/6480dbc69be1b5de95010289787d64f1.png~tplv-uwbnlip3yd-webp.webp', + '//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/0265a04fddbd77a19602a15d9d55d797.png~tplv-uwbnlip3yd-webp.webp', + '//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/24e0dd27418d2291b65db1b21aa62254.png~tplv-uwbnlip3yd-webp.webp', + ], + indicatorPosition: 'bottom', + indicatorType: 'dot', + showArrow: 'always', + direction: 'horizontal', + animation: 'slide', + autoPlay: false, + autoPlayInterval: 3000, + autoPlayHoverToPause: true, + moveSpeed: 500, + timingFunc: 'cubic-bezier(0.34, 0.69, 0.1, 1)', +}; + +export const Carousel = implementRuntimeComponent({ + version: 'arco/v1', + metadata: { + ...FALLBACK_METADATA, + name: 'carousel', + displayName: 'Carousel', + exampleProperties, + annotations: { + category: 'Data Display', + }, + }, + spec: { + properties: InputPropsSpec, + state: InputStateSpec, + methods: {}, + slots: {}, + styleSlots: ['carousel', 'image'], + events: ['onChange', 'onBlur', 'onFocus'], + }, +})(props => { + const { getElement, customStyle } = props; + const { imageSrc, autoPlay, autoPlayHoverToPause, autoPlayInterval, ...cProps } = + getComponentProps(props); + const ref = useRef(null as any); + + useEffect(() => { + const ele = ref.current?.dom; + if (getElement && ele) { + getElement(ele); + } + }, [getElement, ref]); + + return ( + + {imageSrc.map((src, idx) => { + return ( +
+ +
+ ); + })} +
+ ); +}); diff --git a/packages/arco-lib/src/generated/types/Carousel.ts b/packages/arco-lib/src/generated/types/Carousel.ts new file mode 100644 index 00000000..9d91abd3 --- /dev/null +++ b/packages/arco-lib/src/generated/types/Carousel.ts @@ -0,0 +1,62 @@ +import { Type } from '@sinclair/typebox'; +import { Category } from '../../constants/category'; +import { StringUnion } from '../../sunmao-helper'; + +export const CarouselPropsSpec = { + imageSrc: Type.Array(Type.String(), { + title: 'Image Src', + category: Category.Basic, + }), + indicatorType: StringUnion(['dot', 'line', 'slider'], { + title: 'Indicator Type', + category: Category.Basic, + }), + indicatorPosition: StringUnion(['left', 'right', 'top', 'bottom', 'outer'], { + title: 'Indicator Type', + category: Category.Basic, + }), + direction: StringUnion(['vertical', 'horizontal'], { + title: 'Direction', + category: Category.Basic, + }), + showArrow: StringUnion(['always', 'hover', 'never'], { + title: 'Show Arrow', + category: Category.Behavior, + }), + animation: StringUnion(['slide', 'card', 'fade'], { + title: 'Animation', + category: Category.Behavior, + }), + moveSpeed: Type.Number({ + title: 'Move Speed', + category: Category.Behavior, + }), + trigger: Type.Optional( + StringUnion(['click', 'hover'], { + title: 'Trigger', + category: Category.Behavior, + }) + ), + autoPlay: Type.Boolean({ + title: 'Auto Play', + category: Category.Behavior, + }), + autoPlayInterval: Type.Optional( + Type.Number({ + title: 'Auto Play Interval', + category: Category.Behavior, + conditions: [{ key: 'autoPlay', value: true }], + }) + ), + autoPlayHoverToPause: Type.Optional( + Type.Boolean({ + title: 'Auto Play Hover To Pause', + category: Category.Behavior, + conditions: [{ key: 'autoPlay', value: true }], + }) + ), + timingFunc: Type.String({ + title: 'Timing Func', + category: Category.Behavior, + }), +}; From 89ff09c6ea0bf5645654ed0a9e0a1bb8ae22ef62 Mon Sep 17 00:00:00 2001 From: xzdry Date: Fri, 8 Jul 2022 18:13:26 +0800 Subject: [PATCH 3/3] feat(arco/NumberInput): add NumberInput component --- .../arco-lib/src/components/NumberInput.tsx | 97 +++++++++++++++++++ .../src/generated/types/NumberInput.ts | 54 +++++++++++ packages/arco-lib/src/lib.ts | 6 ++ 3 files changed, 157 insertions(+) create mode 100644 packages/arco-lib/src/components/NumberInput.tsx create mode 100644 packages/arco-lib/src/generated/types/NumberInput.ts diff --git a/packages/arco-lib/src/components/NumberInput.tsx b/packages/arco-lib/src/components/NumberInput.tsx new file mode 100644 index 00000000..ac244a88 --- /dev/null +++ b/packages/arco-lib/src/components/NumberInput.tsx @@ -0,0 +1,97 @@ +import { InputNumber } from '@arco-design/web-react'; +import { implementRuntimeComponent } from '@sunmao-ui/runtime'; +import { css } from '@emotion/css'; +import { Type, Static } from '@sinclair/typebox'; +import { FALLBACK_METADATA, getComponentProps } from '../sunmao-helper'; +import { NumberInputPropsSpec as BaseNumberInputPropsSpec } from '../generated/types/NumberInput'; +import { useEffect, useRef } from 'react'; +import { RefInputType } from '@arco-design/web-react/es/Input/interface'; +import { useStateValue } from 'src/hooks/useStateValue'; + +const InputPropsSpec = Type.Object({ + ...BaseNumberInputPropsSpec, +}); +const InputStateSpec = Type.Object({ + value: Type.Number(), +}); + +const exampleProperties: Static = { + defaultValue: 1, + disabled: false, + placeholder: 'please input', + error: false, + size: 'default', + buttonMode: false, + min: 0, + max: 5, + readOnly: false, + step: 1, + precision: 1, + updateWhenDefaultValueChanges: false, +}; + +export const NumberInput = implementRuntimeComponent({ + version: 'arco/v1', + metadata: { + ...FALLBACK_METADATA, + name: 'numberInput', + displayName: 'Number Input', + exampleProperties, + annotations: { + category: 'Data Entry', + }, + }, + spec: { + properties: InputPropsSpec, + state: InputStateSpec, + methods: {}, + slots: { + prefix: { slotProps: Type.Object({}) }, + suffix: { slotProps: Type.Object({}) }, + }, + styleSlots: ['input'], + events: ['onChange', 'onBlur', 'onFocus'], + }, +})(props => { + const { getElement, slotsElements, customStyle, callbackMap, mergeState } = props; + const { buttonMode, defaultValue, updateWhenDefaultValueChanges, ...cProps } = + getComponentProps(props); + const [value, setValue] = useStateValue( + defaultValue, + mergeState, + updateWhenDefaultValueChanges + ); + const ref = useRef(null); + + useEffect(() => { + const ele = ref.current?.dom; + if (getElement && ele) { + getElement(ele); + } + }, [getElement, ref]); + + return ( + { + setValue(value); + mergeState({ + value, + }); + callbackMap?.onChange?.(); + }} + onBlur={() => { + callbackMap?.onBlur?.(); + }} + onFocus={() => { + callbackMap?.onFocus?.(); + }} + value={value} + {...cProps} + prefix={slotsElements.prefix ? slotsElements.prefix({}) : null} + suffix={slotsElements.suffix ? slotsElements.suffix({}) : null} + mode={buttonMode ? 'button' : 'embed'} + /> + ); +}); diff --git a/packages/arco-lib/src/generated/types/NumberInput.ts b/packages/arco-lib/src/generated/types/NumberInput.ts new file mode 100644 index 00000000..2a5d1272 --- /dev/null +++ b/packages/arco-lib/src/generated/types/NumberInput.ts @@ -0,0 +1,54 @@ +import { Type } from '@sinclair/typebox'; +import { StringUnion } from '../../sunmao-helper'; +import { Category } from '../../constants/category'; + +export const NumberInputPropsSpec = { + defaultValue: Type.Number({ + title: 'Default Value', + category: Category.Basic, + }), + updateWhenDefaultValueChanges: Type.Boolean({ + title: 'Update When Default Value Changes', + category: Category.Basic, + }), + min: Type.Number({ + title: 'Min', + category: Category.Basic, + }), + max: Type.Number({ + title: 'Max', + category: Category.Basic, + }), + placeholder: Type.String({ + title: 'Placeholder', + category: Category.Behavior, + }), + disabled: Type.Boolean({ + title: 'Disabled', + category: Category.Behavior, + }), + buttonMode: Type.Boolean({ + title: 'Button Mode', + category: Category.Behavior, + }), + precision: Type.Number({ + title: 'Precision', + category: Category.Behavior, + }), + step: Type.Number({ + title: 'Step', + category: Category.Behavior, + }), + size: StringUnion(['default', 'mini', 'small', 'large'], { + title: 'Size', + category: Category.Style, + }), + readOnly: Type.Boolean({ + title: 'Read Only', + category: Category.Behavior, + }), + error: Type.Boolean({ + title: 'Error', + category: Category.Behavior, + }), +}; diff --git a/packages/arco-lib/src/lib.ts b/packages/arco-lib/src/lib.ts index b3f68a6a..8a694aa2 100644 --- a/packages/arco-lib/src/lib.ts +++ b/packages/arco-lib/src/lib.ts @@ -31,6 +31,7 @@ import { Alert } from './components/Alert'; import { Link } from './components/Link'; import { Switch } from './components/Switch'; import { PasswordInput } from './components/PasswordInput'; +import { NumberInput } from './components/NumberInput'; import { TextArea } from './components/TextArea'; import { Tabs } from './components/Tabs'; import { FormControl } from './components/Form/FormControl'; @@ -39,11 +40,14 @@ import { Row, Col } from './components/Grid'; import { Slider } from './components/Slider'; import { DatePicker } from './components/DatePicker'; import { TimePicker } from './components/TimePicker'; +import { Carousel } from './components/Carousel'; +import { Tag } from './components/Tag'; import './style.css'; import { MessageUtilMethodFactory } from './methods/Message'; export const components: SunmaoLib['components'] = [ + Tag, Table, Pagination, Steps, @@ -86,6 +90,8 @@ export const components: SunmaoLib['components'] = [ Slider, DatePicker, TimePicker, + NumberInput, + Carousel, ]; export const traits: SunmaoLib['traits'] = []; export const modules: SunmaoLib['modules'] = [];