From 644a5d412a7f1c5323ce6141e8e6ded7a0d578bc Mon Sep 17 00:00:00 2001 From: "Water.Li" Date: Wed, 11 Jan 2023 10:44:52 +0800 Subject: [PATCH] can set background image --- src/expamples/ant5/components/Hero/style.less | 4 - .../components/{ => layouts}/Hero/index.tsx | 11 +- src/expamples/ant5/materials/index.ts | 2 + .../ant5/materials/layouts/Hero/icon.tsx | 3 + .../ant5/materials/layouts/Hero/index.ts | 28 ++++ .../ant5/materials/layouts/Hero/locales.ts | 23 +++ .../ant5/materials/layouts/Hero/schema.ts | 4 + .../css-background-parser.d.ts | 1 - .../components/BackgroundImageInput/index.tsx | 133 +++++++++++++----- .../components/ImageSelect/index.tsx | 88 ++++++++++++ src/react-shells/ant5/SettingsForm/index.tsx | 5 +- .../SettingsForm/locales/settingLocales.ts | 4 + .../SettingsForm/schemas/backgroundSetter.ts | 33 ++++- .../ant5/components/ImageView/index.tsx | 47 +++++++ 14 files changed, 334 insertions(+), 52 deletions(-) delete mode 100644 src/expamples/ant5/components/Hero/style.less rename src/expamples/ant5/components/{ => layouts}/Hero/index.tsx (85%) create mode 100644 src/expamples/ant5/materials/layouts/Hero/icon.tsx create mode 100644 src/expamples/ant5/materials/layouts/Hero/index.ts create mode 100644 src/expamples/ant5/materials/layouts/Hero/locales.ts create mode 100644 src/expamples/ant5/materials/layouts/Hero/schema.ts delete mode 100644 src/react-shells/ant5/SettingsForm/components/BackgroundImageInput/css-background-parser.d.ts create mode 100644 src/react-shells/ant5/SettingsForm/components/ImageSelect/index.tsx create mode 100644 src/react-shells/ant5/components/ImageView/index.tsx diff --git a/src/expamples/ant5/components/Hero/style.less b/src/expamples/ant5/components/Hero/style.less deleted file mode 100644 index 839116264..000000000 --- a/src/expamples/ant5/components/Hero/style.less +++ /dev/null @@ -1,4 +0,0 @@ -.rx-hero{ - padding: 8px 24px 32px 24px; - border-radius: 8px; -} \ No newline at end of file diff --git a/src/expamples/ant5/components/Hero/index.tsx b/src/expamples/ant5/components/layouts/Hero/index.tsx similarity index 85% rename from src/expamples/ant5/components/Hero/index.tsx rename to src/expamples/ant5/components/layouts/Hero/index.tsx index 8f0ee6dd9..30e4177f2 100644 --- a/src/expamples/ant5/components/Hero/index.tsx +++ b/src/expamples/ant5/components/layouts/Hero/index.tsx @@ -1,6 +1,7 @@ import { ConfigProvider, theme } from "antd" import { ConfigContext } from "antd/es/config-provider"; import { forwardRef, memo, CSSProperties, useContext, useMemo } from "react" +import styled from "styled-components"; export type HeroProps = { themeMode?: 'dark' | 'light' | 'inherit' @@ -9,6 +10,11 @@ export type HeroProps = { closeable?: boolean, } +const HeroInner = styled.div` + padding: 8px 24px 32px 24px; + border-radius: 8px; +` + export const Hero = memo(forwardRef((props: HeroProps, ref) => { const { themeMode = 'inherit', children, ...other } = props const config = useContext(ConfigContext) @@ -29,13 +35,12 @@ export const Hero = memo(forwardRef((props: HeroProps, ref) => { algorithm: algorithm }} > -
{children} -
+ ) })) \ No newline at end of file diff --git a/src/expamples/ant5/materials/index.ts b/src/expamples/ant5/materials/index.ts index f51cebfc1..1773839bd 100644 --- a/src/expamples/ant5/materials/index.ts +++ b/src/expamples/ant5/materials/index.ts @@ -48,6 +48,7 @@ import { PopconfirmMaterial } from "./popups/Popconfirm"; import { PopoverMaterial } from "./popups/Popover"; import { TooltipMaterial } from "./popups/Tooltip"; import { BadgeMaterial } from "./displays/Badge"; +import { HeroMaterial } from "./layouts/Hero"; export const inputMaterials: IComponentMaterial[] = [ ButtonMaterial, @@ -104,6 +105,7 @@ export const layoutMaterials: IComponentMaterial[] = [ PaperMaterial, DividerMaterial, BreadcrumbMaterial, + HeroMaterial, ] export const businessMaterials: IComponentMaterial[] = [ diff --git a/src/expamples/ant5/materials/layouts/Hero/icon.tsx b/src/expamples/ant5/materials/layouts/Hero/icon.tsx new file mode 100644 index 000000000..7e5464171 --- /dev/null +++ b/src/expamples/ant5/materials/layouts/Hero/icon.tsx @@ -0,0 +1,3 @@ +export const icon = + + diff --git a/src/expamples/ant5/materials/layouts/Hero/index.ts b/src/expamples/ant5/materials/layouts/Hero/index.ts new file mode 100644 index 000000000..efdb195fc --- /dev/null +++ b/src/expamples/ant5/materials/layouts/Hero/index.ts @@ -0,0 +1,28 @@ +import { IComponentMaterial } from "core-react"; +import { icon } from "./icon"; +import { boxLocales, boxResourceLocales } from "./locales"; +import { boxSchema } from "./schema"; +import { Hero } from "expamples/ant5/components/layouts/Hero"; + +const name = "Hero" +export const HeroMaterial: IComponentMaterial = { + componentName: name, + component: Hero, + designer: Hero, + designerLocales: boxLocales, + designerSchema: boxSchema, + resource: { + name: name, + icon: icon, + color: "#dfa324", + resourceLocales: boxResourceLocales, + elements: [ + { + componentName: name, + } + ] + }, + behaviorRule: { + droppable: true, + } +} diff --git a/src/expamples/ant5/materials/layouts/Hero/locales.ts b/src/expamples/ant5/materials/layouts/Hero/locales.ts new file mode 100644 index 000000000..4c5fa1d11 --- /dev/null +++ b/src/expamples/ant5/materials/layouts/Hero/locales.ts @@ -0,0 +1,23 @@ +export const boxLocales = { + "zh-CN": { + title: "大块屏", + settings: { + } + + }, + 'en-US': { + title: "Hero", + settings: { + } + } +} + + +export const boxResourceLocales = { + "zh-CN": { + "Hero": "大块屏", + }, + 'en-US': { + "Hero": "Hero", + } +} diff --git a/src/expamples/ant5/materials/layouts/Hero/schema.ts b/src/expamples/ant5/materials/layouts/Hero/schema.ts new file mode 100644 index 000000000..56c386bb4 --- /dev/null +++ b/src/expamples/ant5/materials/layouts/Hero/schema.ts @@ -0,0 +1,4 @@ +import { INodeSchema } from "core"; +import { createSchema } from "react-shells/ant5/shared/createSchema"; + +export const boxSchema: INodeSchema = createSchema() \ No newline at end of file diff --git a/src/react-shells/ant5/SettingsForm/components/BackgroundImageInput/css-background-parser.d.ts b/src/react-shells/ant5/SettingsForm/components/BackgroundImageInput/css-background-parser.d.ts deleted file mode 100644 index ae78eb734..000000000 --- a/src/react-shells/ant5/SettingsForm/components/BackgroundImageInput/css-background-parser.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'css-background-parser' \ No newline at end of file diff --git a/src/react-shells/ant5/SettingsForm/components/BackgroundImageInput/index.tsx b/src/react-shells/ant5/SettingsForm/components/BackgroundImageInput/index.tsx index 6fdf81696..2de369bfa 100644 --- a/src/react-shells/ant5/SettingsForm/components/BackgroundImageInput/index.tsx +++ b/src/react-shells/ant5/SettingsForm/components/BackgroundImageInput/index.tsx @@ -1,7 +1,8 @@ -import { memo, useCallback, useState } from "react" +import { memo, useCallback } from "react" import { FoldExtraItem } from "../Fold/FoldExtraItem" import { Button, Input, Select } from "antd" import { createSpecialSizeOption, createUnitType, PolyInput } from "../PolyInput" +import { ImageSelect } from "../ImageSelect" export const imageIcon = @@ -21,51 +22,107 @@ const sizeOptions = [ createUnitType('vh'), createUnitType('em'), ] + export const BackgroundImageInput = memo(( props: { - imageTitle?: string, - imageSizeTitle?: string, - repeatTitle?: string, - positionTitle?: string, + title?: string, value?: string, onChange?: (value?: string) => void, + marginTop?: number, + span?: number, } ) => { - const { imageTitle, imageSizeTitle, repeatTitle, positionTitle, value, onChange } = props - const [image, setImage] = useState() - const [size, setSize] = useState() + const { title, value, onChange, marginTop, span = 24 } = props + const handleSelectChange = useCallback((imageUrl?: string) => { + if (imageUrl) { + onChange?.(`url(${imageUrl})`) + } else { + onChange?.(undefined) + } + }, [onChange]) + + const handleChange = (e: React.ChangeEvent) => { + onChange?.(e.target.value) + } + return ( + + + + + + + + + ) +}) - const handleSizeChange = useCallback((size?: string | null) => { +export const BackgroundSizeInput = memo(( + props: { + title?: string, + value?: string, + onChange?: (value?: string | null) => void + marginTop?: number, + span?: number, + } +) => { + const { title, value, onChange, marginTop = 8, span = 12 } = props + return ( + + + + ) +}) - }, []) +export const BackgroundRepeatInput = memo(( + props: { + title?: string, + value?: string, + onChange?: (value?: string | null) => void + marginTop?: number, + span?: number, + } +) => { + const { title, value, onChange, marginTop = 8, span = 12 } = props + return ( + + - - - - - - - - - - + + + ) -}) \ No newline at end of file +}) diff --git a/src/react-shells/ant5/SettingsForm/components/ImageSelect/index.tsx b/src/react-shells/ant5/SettingsForm/components/ImageSelect/index.tsx new file mode 100644 index 000000000..c03e2b0c7 --- /dev/null +++ b/src/react-shells/ant5/SettingsForm/components/ImageSelect/index.tsx @@ -0,0 +1,88 @@ +import { Col, Modal, Row } from "antd" +import { useToken } from "antd/es/theme/internal" +import { useToolsTranslate } from "core-react/hooks/useToolsTranslate" +import React, { useCallback, useEffect } from "react" +import { memo, useState } from "react" +import { ImageView } from "react-shells/ant5/components/ImageView" +import styled from "styled-components" + +const ImageContainer = styled.div.attrs((props: { actived?: boolean, borderColor?: string }) => ({ + ...props, +}))` + width: 100%; + border-radius: 8px; + overflow: hidden; + padding:2px; + outline: ${props => props.actived ? props.borderColor + " solid 1px" : undefined}; +` + +const images = [ + "/imgs/hero.png", + "/imgs/ad.jpg", +] + +export const ImageSelect = memo(( + props: { + children: React.ReactElement, + value?: string, + onChange?: (value?: string) => void, + } +) => { + const { children, value, onChange } = props + const [open, setOpen] = useState(false) + const [selected, setSelected] = useState() + const t = useToolsTranslate() + const [, token] = useToken() + + useEffect(()=>{ + setSelected(value) + }, [value]) + + const handleClick = useCallback(() => { + setOpen(true) + }, []) + + const handleOk = useCallback(() => { + setOpen(false); + onChange?.(selected) + }, [onChange, selected]); + + const handleCancel = useCallback(() => { + setOpen(false); + }, []); + + return ( + <> + {React.cloneElement(children, { onClick: handleClick })} + + + { + images.map((img, index) => { + return ( + + setSelected(img)} + > + + + + ) + }) + } + + + + ) +}) \ No newline at end of file diff --git a/src/react-shells/ant5/SettingsForm/index.tsx b/src/react-shells/ant5/SettingsForm/index.tsx index 33cb47666..6da7013d1 100644 --- a/src/react-shells/ant5/SettingsForm/index.tsx +++ b/src/react-shells/ant5/SettingsForm/index.tsx @@ -33,7 +33,7 @@ import { DisplaySetter } from "./components/DisplaySetter"; import IconInput from "./components/IconInput"; import { GutterInput } from "./components/GutterInput"; import { ColInput } from "./components/ColInput"; -import { BackgroundImageInput } from "./components/BackgroundImageInput"; +import { BackgroundImageInput, BackgroundPositionInput, BackgroundRepeatInput, BackgroundSizeInput } from "./components/BackgroundImageInput"; const propertiesStyle: CSSProperties = { flex: 1, @@ -116,6 +116,9 @@ export const SettingsForm = memo((props: SettingsFormProps) => { "Checkbox.Group": Checkbox.Group, ColInput, BackgroundImageInput, + BackgroundSizeInput, + BackgroundRepeatInput, + BackgroundPositionInput }} > diff --git a/src/react-shells/ant5/SettingsForm/locales/settingLocales.ts b/src/react-shells/ant5/SettingsForm/locales/settingLocales.ts index 5041cc268..55a5be0e6 100644 --- a/src/react-shells/ant5/SettingsForm/locales/settingLocales.ts +++ b/src/react-shells/ant5/SettingsForm/locales/settingLocales.ts @@ -46,6 +46,8 @@ export const settingLocales = { repeat:"重复", position:"定位", + selectImage:"选择图片", + IconInput: { DialogTitle: "选择图标", "Outlined": "线框风格", @@ -106,6 +108,8 @@ export const settingLocales = { repeat:"Repeat", position:"Positioin", + selectImage:"Select image", + IconInput: { DialogTitle: "Select Icon", "Outlined": "Outlined", diff --git a/src/react-shells/ant5/SettingsForm/schemas/backgroundSetter.ts b/src/react-shells/ant5/SettingsForm/schemas/backgroundSetter.ts index 07df7522b..664530d5d 100644 --- a/src/react-shells/ant5/SettingsForm/schemas/backgroundSetter.ts +++ b/src/react-shells/ant5/SettingsForm/schemas/backgroundSetter.ts @@ -24,16 +24,39 @@ export const backgroundSetter: INodeSchema = { { componentName: "BackgroundImageInput", props: { - title: "$backgroundImage", - imageTitle: "$image", - imageSizeTitle: "$imageSize", - repeatTitle: "$repeat", - positionTitle: "$position", + title: "$image", }, "x-field": { name: "backgroundImage" } }, + { + componentName: "BackgroundSizeInput", + props: { + title: "$imageSize", + }, + "x-field": { + name: "backgroundSize" + } + }, + { + componentName: "BackgroundRepeatInput", + props: { + title: "$repeat", + }, + "x-field": { + name: "backgroundRepeat" + } + }, + { + componentName: "BackgroundPositionInput", + props: { + title: "$position", + }, + "x-field": { + name: "backgroundPosition" + } + }, ] } ] diff --git a/src/react-shells/ant5/components/ImageView/index.tsx b/src/react-shells/ant5/components/ImageView/index.tsx new file mode 100644 index 000000000..f63acfd0a --- /dev/null +++ b/src/react-shells/ant5/components/ImageView/index.tsx @@ -0,0 +1,47 @@ +import { CSSProperties, memo } from "react" +import styled from "styled-components"; + +export interface IImageProps { + empertyIconSize?: number, + value?: string, + style?: CSSProperties, + height?: string, +} + +const ImageShell = styled.div` + width: 100%; + padding-bottom: 61.8%; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + font-size: 16px; + position: relative; + overflow: hidden; +` + +const ImageMask = styled.div` + position:absolute; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + background-color: #eee; + color: #ddd; +` + +export const ImageView = memo((props: IImageProps) => { + const { empertyIconSize = 120, value, style, height = '61.8%', ...other } = props; + return ( + + { + !value && + + + + + + } + + ) +}) \ No newline at end of file