Skip to content

Commit 2dedc8f

Browse files
Merge pull request #1749 from iamfaran/feat/1578-tags
[Feat]: #1578 Add Tags Presets and custom margin paddings borders
2 parents a00e634 + 45bdd9b commit 2dedc8f

File tree

2 files changed

+154
-14
lines changed

2 files changed

+154
-14
lines changed

client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnTagsComp.tsx

Lines changed: 87 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,58 @@ const TagsControl = codeControl<Array<string> | string>(
5858

5959
function getTagColor(tagText : any, tagOptions: any[]) {
6060
const foundOption = tagOptions.find((option: { label: any; }) => option.label === tagText);
61-
return foundOption ? foundOption.color : (function() {
62-
const index = Math.abs(hashToNum(tagText)) % colors.length;
63-
return colors[index];
64-
})();
61+
if (foundOption) {
62+
if (foundOption.colorType === "preset") {
63+
return foundOption.presetColor;
64+
} else if (foundOption.colorType === "custom") {
65+
return undefined; // For custom colors, we'll use style instead
66+
}
67+
// Backward compatibility - if no colorType specified, assume it's the old color field
68+
return foundOption.color;
69+
}
70+
// Default fallback
71+
const index = Math.abs(hashToNum(tagText)) % colors.length;
72+
return colors[index];
73+
}
74+
75+
function getTagStyle(tagText: any, tagOptions: any[]) {
76+
const foundOption = tagOptions.find((option: { label: any; }) => option.label === tagText);
77+
if (foundOption) {
78+
const style: any = {};
79+
80+
// Handle color styling
81+
if (foundOption.colorType === "custom") {
82+
style.backgroundColor = foundOption.color;
83+
style.color = foundOption.textColor;
84+
style.border = `1px solid ${foundOption.color}`;
85+
}
86+
87+
// Add border styling if specified
88+
if (foundOption.border) {
89+
style.borderColor = foundOption.border;
90+
if (!foundOption.colorType || foundOption.colorType !== "custom") {
91+
style.border = `1px solid ${foundOption.border}`;
92+
}
93+
}
94+
95+
// Add border radius if specified
96+
if (foundOption.radius) {
97+
style.borderRadius = foundOption.radius;
98+
}
99+
100+
// Add margin if specified
101+
if (foundOption.margin) {
102+
style.margin = foundOption.margin;
103+
}
104+
105+
// Add padding if specified
106+
if (foundOption.padding) {
107+
style.padding = foundOption.padding;
108+
}
109+
110+
return style;
111+
}
112+
return {};
65113
}
66114

67115
function getTagIcon(tagText: any, tagOptions: any[]) {
@@ -286,13 +334,32 @@ const TagEdit = React.memo((props: TagEditPropsType) => {
286334
{tags.map((value, index) => (
287335
<CustomSelect.Option value={value} key={index}>
288336
{value.split(",")[1] ? (
289-
value.split(",").map((item, i) => (
290-
<Tag color={getTagColor(item, memoizedTagOptions)} icon={getTagIcon(item, memoizedTagOptions)} key={i} style={{ marginRight: "8px" }}>
291-
{item}
292-
</Tag>
293-
))
337+
value.split(",").map((item, i) => {
338+
const tagColor = getTagColor(item, memoizedTagOptions);
339+
const tagIcon = getTagIcon(item, memoizedTagOptions);
340+
const tagStyle = getTagStyle(item, memoizedTagOptions);
341+
342+
return (
343+
<Tag
344+
color={tagColor}
345+
icon={tagIcon}
346+
key={i}
347+
style={{
348+
marginRight: tagStyle.margin ? undefined : "8px",
349+
...tagStyle
350+
}}
351+
>
352+
{item}
353+
</Tag>
354+
);
355+
})
294356
) : (
295-
<Tag color={getTagColor(value, memoizedTagOptions)} icon={getTagIcon(value, memoizedTagOptions)} key={index}>
357+
<Tag
358+
color={getTagColor(value, memoizedTagOptions)}
359+
icon={getTagIcon(value, memoizedTagOptions)}
360+
key={index}
361+
style={getTagStyle(value, memoizedTagOptions)}
362+
>
296363
{value}
297364
</Tag>
298365
)}
@@ -316,9 +383,18 @@ export const ColumnTagsComp = (function () {
316383
const view = tags.map((tag, index) => {
317384
// The actual eval value is of type number or boolean
318385
const tagText = String(tag);
386+
const tagColor = getTagColor(tagText, tagOptions);
387+
const tagIcon = getTagIcon(tagText, tagOptions);
388+
const tagStyle = getTagStyle(tagText, tagOptions);
389+
319390
return (
320391
<div key={`${tag.split(' ').join('_')}-${index}`}>
321-
<TagStyled color={getTagColor(tagText, tagOptions)} icon={getTagIcon(tagText, tagOptions)} key={index} >
392+
<TagStyled
393+
color={tagColor}
394+
icon={tagIcon}
395+
key={index}
396+
style={tagStyle}
397+
>
322398
{tagText}
323399
</TagStyled>
324400
</div>

client/packages/lowcoder/src/comps/controls/optionsControl.tsx

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,26 @@ import { ColorControl } from "./colorControl";
4141
import { StringStateControl } from "./codeStateControl";
4242
import { reduceInContext } from "../utils/reduceContext";
4343

44+
// Tag preset color options
45+
const TAG_PRESET_COLORS = [
46+
{ label: "Magenta", value: "magenta" },
47+
{ label: "Red", value: "red" },
48+
{ label: "Volcano", value: "volcano" },
49+
{ label: "Orange", value: "orange" },
50+
{ label: "Gold", value: "gold" },
51+
{ label: "Lime", value: "lime" },
52+
{ label: "Green", value: "green" },
53+
{ label: "Cyan", value: "cyan" },
54+
{ label: "Blue", value: "blue" },
55+
{ label: "Geek Blue", value: "geekblue" },
56+
{ label: "Purple", value: "purple" },
57+
{ label: "Success", value: "success" },
58+
{ label: "Processing", value: "processing" },
59+
{ label: "Error", value: "error" },
60+
{ label: "Warning", value: "warning" },
61+
{ label: "Default", value: "default" },
62+
] as const;
63+
4464
const OptionTypes = [
4565
{
4666
label: trans("prop.manual"),
@@ -729,24 +749,68 @@ let ColoredTagOption = new MultiCompBuilder(
729749
{
730750
label: StringControl,
731751
icon: IconControl,
732-
color: withDefault(ColorControl, ""),
752+
colorType: withDefault(dropdownControl([
753+
{ label: "Preset", value: "preset" },
754+
{ label: "Custom", value: "custom" },
755+
] as const, "preset"), "preset"),
756+
presetColor: withDefault(dropdownControl(TAG_PRESET_COLORS, "blue"), "blue"),
757+
color: withDefault(ColorControl, "#1890ff"),
758+
textColor: withDefault(ColorControl, "#ffffff"),
759+
border: withDefault(ColorControl, ""),
760+
radius: withDefault(RadiusControl, ""),
761+
margin: withDefault(StringControl, ""),
762+
padding: withDefault(StringControl, ""),
733763
},
734764
(props) => props
735765
).build();
736766

737767
ColoredTagOption = class extends ColoredTagOption implements OptionCompProperty {
738768
propertyView(param: { autoMap?: boolean }) {
769+
const colorType = this.children.colorType.getView();
739770
return (
740771
<>
741772
{this.children.label.propertyView({ label: trans("coloredTagOptionControl.tag") })}
742773
{this.children.icon.propertyView({ label: trans("coloredTagOptionControl.icon") })}
743-
{this.children.color.propertyView({ label: trans("coloredTagOptionControl.color") })}
774+
{this.children.colorType.propertyView({
775+
label: "Color Type",
776+
radioButton: true
777+
})}
778+
{colorType === "preset" && this.children.presetColor.propertyView({
779+
label: "Preset Color"
780+
})}
781+
{colorType === "custom" && (
782+
<>
783+
{this.children.color.propertyView({ label: trans("coloredTagOptionControl.color") })}
784+
{this.children.textColor.propertyView({ label: "Text Color" })}
785+
</>
786+
)}
787+
{this.children.border.propertyView({
788+
label: trans('style.border')
789+
})}
790+
{this.children.radius.propertyView({
791+
label: trans('style.borderRadius'),
792+
preInputNode: <StyledIcon as={IconRadius} title="" />,
793+
placeholder: '3px',
794+
})}
795+
{this.children.margin.propertyView({
796+
label: trans('style.margin'),
797+
preInputNode: <StyledIcon as={ExpandIcon} title="" />,
798+
placeholder: '3px',
799+
})}
800+
{this.children.padding.propertyView({
801+
label: trans('style.padding'),
802+
preInputNode: <StyledIcon as={CompressIcon} title="" />,
803+
placeholder: '3px',
804+
})}
744805
</>
745806
);
746807
}
747808
};
748809

749810
export const ColoredTagOptionControl = optionsControl(ColoredTagOption, {
750-
initOptions: [{ label: "Tag1", icon: "/icon:solid/tag", color: "#f50" }, { label: "Tag2", icon: "/icon:solid/tag", color: "#2db7f5" }],
811+
initOptions: [
812+
{ label: "Tag1", icon: "/icon:solid/tag", colorType: "preset", presetColor: "blue" },
813+
{ label: "Tag2", icon: "/icon:solid/tag", colorType: "preset", presetColor: "green" }
814+
],
751815
uniqField: "label",
752816
});

0 commit comments

Comments
 (0)