Skip to content

Tags component Styling Updated #1885

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 40 additions & 33 deletions client/packages/lowcoder/src/comps/comps/tagsComp/tagsCompView.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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;
Expand All @@ -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) {
Expand All @@ -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;
`;
Expand All @@ -105,8 +121,6 @@ const multiTags = (function () {
options: TagsCompOptionsControl,
style: styleControl(InputLikeStyle, 'style'),
onEvent: ButtonEventHandlerControl,
borderless: BoolCodeControl,
enableIndividualStyling: BoolCodeControl,
};

return new UICompBuilder(childrenMap, (props) => {
Expand All @@ -116,16 +130,14 @@ const multiTags = (function () {
<StyledTagContainer>
{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 (
<StyledTag
key={`tag-${index}`}
$style={props.style}
$bordered={!props.borderless}
$customStyle={tagStyle}
icon={tagIcon}
color={tagColor}
Expand Down Expand Up @@ -157,11 +169,6 @@ const multiTags = (function () {
useContext(EditorContext).editorModeStatus
) && (
<Section name={sectionNames.style}>
{children.enableIndividualStyling.propertyView({
label: trans("style.individualStyling"),
tooltip: trans("style.individualStylingTooltip")
})}
{children.borderless.propertyView({ label: trans("style.borderless") })}
{children.style.getPropertyView()}
</Section>
)}
Expand Down
38 changes: 29 additions & 9 deletions client/packages/lowcoder/src/comps/controls/optionsControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import {
IconRadius,
Option,
WidthIcon,
ImageCompIcon,
CloseEyeIcon,
} from "lowcoder-design";
import styled from "styled-components";
Expand All @@ -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 = [
Expand Down Expand Up @@ -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();
Expand All @@ -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")
Expand All @@ -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: <StyledIcon as={BorderOuterOutlined} title="" />,
})}
{this.children.border.propertyView({
label: trans('style.border')
})}
{this.children.borderWidth.propertyView({
label: trans('style.borderWidth'),
preInputNode: <StyledIcon as={WidthIcon} title="" />,
})}
{this.children.radius.propertyView({
label: trans('style.borderRadius'),
preInputNode: <StyledIcon as={IconRadius} title="" />,
Expand All @@ -839,15 +854,20 @@ TagsCompOptions = class extends TagsCompOptions implements OptionCompProperty {
preInputNode: <StyledIcon as={CompressIcon} title="" />,
placeholder: '3px',
})}
{this.children.width.propertyView({
label: trans('splitLayout.width'),
preInputNode: <StyledIcon as={WidthIcon} title="" />,
placeholder: '100px',
})}
</>
);
}
};

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",
});
Expand Down
1 change: 1 addition & 0 deletions client/packages/lowcoder/src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ export const en = {
// fourth part

"style": {
"styleOptions": "Style Options",
"boxShadowColor": 'Shadow Color',
"boxShadow": 'Box Shadow',
"opacity": 'Opacity',
Expand Down
Loading