diff --git a/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx b/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx
index b2070c7c2..e4e70a632 100644
--- a/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx
@@ -3,16 +3,21 @@ import { styleControl } from "comps/controls/styleControl";
import { AnimationStyle, AnimationStyleType, CircleProgressStyle, CircleProgressType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import styled, { css } from "styled-components";
import { Section, sectionNames } from "lowcoder-design";
-import { numberExposingStateControl } from "../controls/codeStateControl";
+import { numberExposingStateControl, stringExposingStateControl } from "../controls/codeStateControl";
import { UICompBuilder } from "../generators";
import { NameConfig, NameConfigHidden, withExposingConfigs } from "../generators/withExposing";
import { hiddenPropertyView } from "comps/utils/propertyUtils";
import { trans } from "i18n";
-
+import { BoolControl } from "../controls/boolControl";
+import { dropdownControl } from "../controls/dropdownControl";
+import { NumberControl } from "../controls/codeControl";
import { useContext } from "react";
import { EditorContext } from "comps/editorState";
-
-// TODO: after Update of ANTd, introduce Size attribute to ProgressCircle
+import {
+ ProgressTypeOptions,
+ StrokeLinecapOptions,
+ GapPositionOptions
+} from "./progressCircleConstants";
const getStyle = (style: CircleProgressType) => {
return css`
@@ -20,13 +25,13 @@ const getStyle = (style: CircleProgressType) => {
height: ${heightCalculator(style.margin)};
margin: ${style.margin};
padding: ${style.padding};
- border-radius:${style.radius};
+ border-radius: ${style.radius};
.ant-progress-text {
color: ${style.text} !important;
- font-family:${style.fontFamily};
- font-style:${style.fontStyle};
- font-size:${style.textSize} !important;
- font-weight:${style.textWeight};
+ font-family: ${style.fontFamily};
+ font-style: ${style.fontStyle};
+ font-size: ${style.textSize} !important;
+ font-weight: ${style.textWeight};
}
.ant-progress-circle-trail {
stroke: ${style.track};
@@ -68,21 +73,54 @@ export const StyledProgressCircle = styled(Progress)<{
let ProgressCircleTmpComp = (function () {
const childrenMap = {
value: numberExposingStateControl("value", 60),
- // borderRadius property hidden as it's not valid for progress circle
+ progressType: dropdownControl(ProgressTypeOptions, "circle"),
+ showInfo: BoolControl.DEFAULT_TRUE,
+ strokeWidth: NumberControl,
+ strokeLinecap: dropdownControl(StrokeLinecapOptions, "round"),
+ gapDegree: NumberControl,
+ gapPosition: dropdownControl(GapPositionOptions, "bottom"),
+ customFormat: stringExposingStateControl("customFormat", ""),
+ // Steps configuration for segmented progress
+ stepsEnabled: BoolControl,
+ stepsCount: NumberControl,
+ stepsGap: NumberControl,
+ // Style controls
style: styleControl(CircleProgressStyle, 'style'),
animationStyle: styleControl(AnimationStyle, 'animationStyle'),
};
+
return new UICompBuilder(childrenMap, (props) => {
+ const percent = Math.round(props.value.value);
+ const customFormatValue = props.customFormat.value?.trim();
+
+ // Simple format function - just returns the custom text if provided
+ const formatFunction = customFormatValue ? () => customFormatValue : undefined;
+
+ // Build steps configuration if enabled
+ const stepsConfig = props.stepsEnabled && props.stepsCount > 0
+ ? { count: props.stepsCount, gap: props.stepsGap || 2 }
+ : undefined;
+
return (
);
})
.setPropertyViewFn((children) => {
+ const progressType = children.progressType.getView();
+ const stepsEnabled = children.stepsEnabled.getView();
+
return (
<>
@@ -90,8 +128,62 @@ let ProgressCircleTmpComp = (function () {
label: trans("progress.value"),
tooltip: trans("progress.valueTooltip"),
})}
+ {children.progressType.propertyView({
+ label: trans("progressCircle.progressType"),
+ tooltip: trans("progressCircle.progressTypeTooltip"),
+ })}
+
+
+
+ {children.showInfo.propertyView({
+ label: trans("progress.showInfo"),
+ })}
+ {children.customFormat.propertyView({
+ label: trans("progressCircle.customFormat"),
+ tooltip: trans("progressCircle.customFormatTooltip"),
+ })}
+ {children.strokeWidth.propertyView({
+ label: trans("progressCircle.strokeWidth"),
+ tooltip: trans("progressCircle.strokeWidthTooltip"),
+ placeholder: "6",
+ })}
+ {children.strokeLinecap.propertyView({
+ label: trans("progressCircle.strokeLinecap"),
+ tooltip: trans("progressCircle.strokeLinecapTooltip"),
+ })}
+
+
+
+ {children.stepsEnabled.propertyView({
+ label: trans("progressCircle.stepsEnabled"),
+ tooltip: trans("progressCircle.stepsEnabledTooltip"),
+ })}
+ {stepsEnabled && children.stepsCount.propertyView({
+ label: trans("progressCircle.stepsCount"),
+ tooltip: trans("progressCircle.stepsCountTooltip"),
+ placeholder: "5",
+ })}
+ {stepsEnabled && children.stepsGap.propertyView({
+ label: trans("progressCircle.stepsGap"),
+ tooltip: trans("progressCircle.stepsGapTooltip"),
+ placeholder: "2",
+ })}
+ {progressType === "dashboard" && (
+
+ {children.gapDegree.propertyView({
+ label: trans("progressCircle.gapDegree"),
+ tooltip: trans("progressCircle.gapDegreeTooltip"),
+ placeholder: "75",
+ })}
+ {children.gapPosition.propertyView({
+ label: trans("progressCircle.gapPosition"),
+ tooltip: trans("progressCircle.gapPositionTooltip"),
+ })}
+
+ )}
+
{["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && (
{hiddenPropertyView(children)}
@@ -101,12 +193,12 @@ let ProgressCircleTmpComp = (function () {
{["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && (
<>
- {children.style.getPropertyView()}
+ {children.style.getPropertyView()}
- {children.animationStyle.getPropertyView()}
+ {children.animationStyle.getPropertyView()}
- >
+ >
)}
>
);
@@ -122,5 +214,6 @@ ProgressCircleTmpComp = class extends ProgressCircleTmpComp {
export const ProgressCircleComp = withExposingConfigs(ProgressCircleTmpComp, [
new NameConfig("value", trans("progress.valueDesc")),
+ new NameConfig("customFormat", trans("progressCircle.customFormatDesc")),
NameConfigHidden,
]);
diff --git a/client/packages/lowcoder/src/comps/comps/progressCircleConstants.ts b/client/packages/lowcoder/src/comps/comps/progressCircleConstants.ts
new file mode 100644
index 000000000..31a5bb112
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/progressCircleConstants.ts
@@ -0,0 +1,22 @@
+import { trans } from "i18n";
+
+// Progress type options (circle or dashboard)
+export const ProgressTypeOptions = [
+ { label: trans("progressCircle.circle"), value: "circle" },
+ { label: trans("progressCircle.dashboard"), value: "dashboard" },
+] as const;
+
+// Stroke linecap options (line ending style)
+export const StrokeLinecapOptions = [
+ { label: trans("progressCircle.round"), value: "round" },
+ { label: trans("progressCircle.butt"), value: "butt" },
+ { label: trans("progressCircle.square"), value: "square" },
+] as const;
+
+// Gap position options (for dashboard type)
+export const GapPositionOptions = [
+ { label: trans("progressCircle.top"), value: "top" },
+ { label: trans("progressCircle.bottom"), value: "bottom" },
+ { label: trans("progressCircle.left"), value: "left" },
+ { label: trans("progressCircle.right"), value: "right" },
+] as const;
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index e9dcf1268..95488cc8c 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -2257,6 +2257,39 @@ export const en = {
"valueDesc": "Current Progress Value, Ranging from 0 to 100",
"showInfoDesc": "Whether to Display the Current Progress Value"
},
+ "progressCircle": {
+ "circle": "Circle",
+ "dashboard": "Dashboard",
+ "progressType": "Type",
+ "progressTypeTooltip": "Choose between a full circle or dashboard (semi-circle) style",
+ "appearance": "Appearance",
+ "customFormat": "Custom Text",
+ "customFormatTooltip": "Custom text to display instead of the percentage",
+ "customFormatDesc": "Custom text displayed in the progress circle",
+ "strokeWidth": "Stroke Width",
+ "strokeWidthTooltip": "The width of the progress stroke line (default: 6)",
+ "strokeLinecap": "Line Cap Style",
+ "strokeLinecapTooltip": "The shape of the progress line endings",
+ "round": "Round",
+ "butt": "Flat",
+ "square": "Square",
+ "dashboardSettings": "Dashboard Settings",
+ "gapDegree": "Gap Degree",
+ "gapDegreeTooltip": "The gap degree of the dashboard, 0-295 (default: 75)",
+ "gapPosition": "Gap Position",
+ "gapPositionTooltip": "The position of the gap in the dashboard",
+ "top": "Top",
+ "bottom": "Bottom",
+ "left": "Left",
+ "right": "Right",
+ "segments": "Segments",
+ "stepsEnabled": "Enable Steps",
+ "stepsEnabledTooltip": "Display progress as segmented steps instead of continuous",
+ "stepsCount": "Step Count",
+ "stepsCountTooltip": "The total number of steps/segments to display",
+ "stepsGap": "Step Gap",
+ "stepsGapTooltip": "The gap between each step in pixels (default: 2)"
+ },
"fileViewer": {
"invalidURL": "Please Enter a Valid URL or Base64 String",
"src": "File URI",