From 14fa759e8ca21c3999b8deff3011c42899293dda Mon Sep 17 00:00:00 2001 From: Kamal Qureshi Date: Mon, 21 Jul 2025 21:39:05 +0500 Subject: [PATCH] Updated styling of the tags component --- .../src/comps/comps/tagsComp/tagsCompView.tsx | 73 ++++++++++--------- .../src/comps/controls/optionsControl.tsx | 38 +++++++--- .../packages/lowcoder/src/i18n/locales/en.ts | 1 + 3 files changed, 70 insertions(+), 42 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/tagsComp/tagsCompView.tsx b/client/packages/lowcoder/src/comps/comps/tagsComp/tagsCompView.tsx index b8c475076..1f2a178c9 100644 --- a/client/packages/lowcoder/src/comps/comps/tagsComp/tagsCompView.tsx +++ b/client/packages/lowcoder/src/comps/comps/tagsComp/tagsCompView.tsx @@ -1,6 +1,5 @@ import styled from "styled-components"; import React, { useContext } from "react"; -import { trans } from "i18n"; import { Tag } from "antd"; import { EditorContext } from "comps/editorState"; import { PresetStatusColorTypes } from "antd/es/_util/colors"; @@ -23,7 +22,9 @@ const colors = PresetStatusColorTypes; function getTagColor(tagText : any, tagOptions: any[]) { const foundOption = tagOptions.find((option: { label: any; }) => option.label === tagText); if (foundOption) { - if (foundOption.colorType === "preset") { + if (foundOption.colorType === "default") { + return undefined; + } else if (foundOption.colorType === "preset") { return foundOption.presetColor; } else if (foundOption.colorType === "custom") { return undefined; @@ -36,20 +37,32 @@ function getTagColor(tagText : any, tagOptions: any[]) { const getTagStyle = (tagText: any, tagOptions: any[], baseStyle: any = {}) => { const foundOption = tagOptions.find((option: { label: any; }) => option.label === tagText); + if (foundOption) { + // If colorType is "default", use ONLY component styles + if (foundOption.colorType === "default") { + const style: any = { ...baseStyle }; + if (baseStyle.borderWidth && baseStyle.border && baseStyle.borderStyle) { + style.border = `${baseStyle.borderWidth} ${baseStyle.borderStyle} ${baseStyle.border}`; + } + return style; + } + const style: any = { ...baseStyle }; if (foundOption.colorType === "custom") { style.backgroundColor = foundOption.color; style.color = foundOption.textColor; - style.border = `1px solid ${foundOption.color}`; } - if (foundOption.border) { - style.borderColor = foundOption.border; - if (!foundOption.colorType || foundOption.colorType !== "custom") { - style.border = `1px solid ${foundOption.border}`; - } + let borderStyle = foundOption.borderStyle || "none"; + let borderWidth = foundOption.borderWidth || "0px"; + let borderColor = foundOption.border || "none"; + + if (borderStyle !== "none") { + style.border = `${borderWidth} ${borderStyle} ${borderColor}`; + } else { + style.border = "none"; } if (foundOption.radius) { @@ -64,33 +77,36 @@ const getTagStyle = (tagText: any, tagOptions: any[], baseStyle: any = {}) => { style.padding = foundOption.padding; } + if (foundOption.width) { + style.width = foundOption.width; + } + return style; } - return baseStyle; -}; -function getTagIcon(tagText: any, tagOptions: any[]) { - const foundOption = tagOptions.find(option => option.label === tagText); - return foundOption ? foundOption.icon : undefined; -} + const style: any = { ...baseStyle }; + if (baseStyle.borderWidth && baseStyle.border && baseStyle.borderStyle) { + style.border = `${baseStyle.borderWidth} ${baseStyle.borderStyle} ${baseStyle.border}`; + } + return style; +}; const multiTags = (function () { - const StyledTag = styled(Tag)<{ $style: any, $bordered: boolean, $customStyle: any }>` + const StyledTag = styled(Tag)<{ $style: any, $customStyle: any }>` display: flex; justify-content: center; align-items: center; - width: 100%; + min-width: fit-content; + width: ${(props) => props.$customStyle?.width || 'auto'}; + max-width: 100px; background: ${(props) => props.$customStyle?.backgroundColor || props.$style?.background}; color: ${(props) => props.$customStyle?.color || props.$style?.text}; border-radius: ${(props) => props.$customStyle?.borderRadius || props.$style?.borderRadius}; - border: ${(props) => { - if (props.$customStyle?.border) return props.$customStyle.border; - return props.$bordered ? `${props.$style?.borderStyle} ${props.$style?.borderWidth} ${props.$style?.border}` : 'none'; - }}; + border: ${(props) => props.$customStyle?.border || props.$style?.border || '1px solid #d9d9d9'}; padding: ${(props) => props.$customStyle?.padding || props.$style?.padding}; margin: ${(props) => props.$customStyle?.margin || props.$style?.margin}; - font-size: ${(props) => props.$style?.textSize}; + font-size: ${(props) => props.$style?.textSize || '8px'}; font-weight: ${(props) => props.$style?.fontWeight}; cursor: pointer; `; @@ -105,8 +121,6 @@ const multiTags = (function () { options: TagsCompOptionsControl, style: styleControl(InputLikeStyle, 'style'), onEvent: ButtonEventHandlerControl, - borderless: BoolCodeControl, - enableIndividualStyling: BoolCodeControl, }; return new UICompBuilder(childrenMap, (props) => { @@ -116,16 +130,14 @@ const multiTags = (function () { {props.options.map((tag, index) => { - // Use individual styling only if enableIndividualStyling is true - const tagColor = props.enableIndividualStyling ? getTagColor(tag.label, props.options) : undefined; - const tagIcon = props.enableIndividualStyling ? getTagIcon(tag.label, props.options) : tag.icon; - const tagStyle = props.enableIndividualStyling ? getTagStyle(tag.label, props.options, props.style) : {}; + const tagColor = getTagColor(tag.label, props.options); + const tagIcon = tag.icon; + const tagStyle = getTagStyle(tag.label, props.options, props.style); return ( - {children.enableIndividualStyling.propertyView({ - label: trans("style.individualStyling"), - tooltip: trans("style.individualStylingTooltip") - })} - {children.borderless.propertyView({ label: trans("style.borderless") })} {children.style.getPropertyView()} )} diff --git a/client/packages/lowcoder/src/comps/controls/optionsControl.tsx b/client/packages/lowcoder/src/comps/controls/optionsControl.tsx index 1186057d9..60f050a8e 100644 --- a/client/packages/lowcoder/src/comps/controls/optionsControl.tsx +++ b/client/packages/lowcoder/src/comps/controls/optionsControl.tsx @@ -29,7 +29,6 @@ import { IconRadius, Option, WidthIcon, - ImageCompIcon, CloseEyeIcon, } from "lowcoder-design"; import styled from "styled-components"; @@ -39,8 +38,8 @@ import { JSONObject, JSONValue } from "util/jsonTypes"; import { ButtonEventHandlerControl } from "./eventHandlerControl"; import { ControlItemCompBuilder } from "comps/generators/controlCompBuilder"; import { ColorControl } from "./colorControl"; -import { StringStateControl } from "./codeStateControl"; import { reduceInContext } from "../utils/reduceContext"; +import { BorderOuterOutlined } from "@ant-design/icons"; // Tag preset color options const TAG_PRESET_COLORS = [ @@ -786,17 +785,26 @@ let TagsCompOptions = new MultiCompBuilder( { label: StringControl, icon: IconControl, - colorType: withDefault(dropdownControl([ + colorType: dropdownControl([ + { label: "Default", value: "default"}, { label: trans("style.preset"), value: "preset" }, { label: trans("style.custom"), value: "custom" }, - ] as const, "preset"), "preset"), - presetColor: withDefault(dropdownControl(TAG_PRESET_COLORS, "blue"), "blue"), + ], "default"), + presetColor: dropdownControl(TAG_PRESET_COLORS, "default"), color: withDefault(ColorControl, "#1890ff"), textColor: withDefault(ColorControl, "#ffffff"), border: withDefault(ColorControl, ""), + borderWidth: withDefault(RadiusControl, ""), + borderStyle: withDefault(dropdownControl([ + { label: "Solid", value: "solid" }, + { label: "Dashed", value: "dashed" }, + { label: "Dotted", value: "dotted" }, + { label: "None", value: "none" }, + ], "solid"), "solid"), radius: withDefault(RadiusControl, ""), margin: withDefault(StringControl, ""), padding: withDefault(StringControl, ""), + width: withDefault(StringControl, ""), }, (props) => props ).build(); @@ -809,8 +817,7 @@ TagsCompOptions = class extends TagsCompOptions implements OptionCompProperty { {this.children.label.propertyView({ label: trans("coloredTagOptionControl.tag") })} {this.children.icon.propertyView({ label: trans("coloredTagOptionControl.icon") })} {this.children.colorType.propertyView({ - label: trans("style.colorType"), - radioButton: true + label: trans("style.styleOptions") })} {colorType === "preset" && this.children.presetColor.propertyView({ label: trans("style.presetColor") @@ -821,9 +828,17 @@ TagsCompOptions = class extends TagsCompOptions implements OptionCompProperty { {this.children.textColor.propertyView({ label: trans("style.textColor") })} )} + {this.children.borderStyle.propertyView({ + label: trans('style.borderStyle'), + preInputNode: , + })} {this.children.border.propertyView({ label: trans('style.border') })} + {this.children.borderWidth.propertyView({ + label: trans('style.borderWidth'), + preInputNode: , + })} {this.children.radius.propertyView({ label: trans('style.borderRadius'), preInputNode: , @@ -839,6 +854,11 @@ TagsCompOptions = class extends TagsCompOptions implements OptionCompProperty { preInputNode: , placeholder: '3px', })} + {this.children.width.propertyView({ + label: trans('splitLayout.width'), + preInputNode: , + placeholder: '100px', + })} ); } @@ -846,8 +866,8 @@ TagsCompOptions = class extends TagsCompOptions implements OptionCompProperty { export const TagsCompOptionsControl = optionsControl(TagsCompOptions, { initOptions: [ - { label: "Option 1", colorType: "preset", presetColor: "blue" }, - { label: "Option 2", colorType: "preset", presetColor: "green" } + { label: "Option 1", colorType: "default"}, + { label: "Option 2", colorType: "default"} ], uniqField: "label", }); diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 045518e1f..80f667288 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -476,6 +476,7 @@ export const en = { // fourth part "style": { + "styleOptions": "Style Options", "boxShadowColor": 'Shadow Color', "boxShadow": 'Box Shadow', "opacity": 'Opacity',