Skip to content

Commit 2e3ae01

Browse files
committed
fix: improve overall user experience with onChange action, fix buggy logic
1 parent 36fbc91 commit 2e3ae01

2 files changed

Lines changed: 39 additions & 15 deletions

File tree

packages/pluggableWidgets/color-picker-web/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
### Fixed
10+
11+
- We fixed an issue with On change action not triggering in some cases.
12+
913
## [2.1.5] - 2026-03-06
1014

1115
### Fixed

packages/pluggableWidgets/color-picker-web/src/components/ColorPicker.tsx

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { ReactElement, useCallback, useEffect, useState } from "react";
2-
import { Alert } from "@mendix/widget-plugin-component-kit/Alert";
3-
import { DefaultColorsType, FormatEnum, ModeEnum, TypeEnum } from "../../typings/ColorPickerProps";
1+
import classNames from "classnames";
2+
import { ReactElement, useCallback, useEffect, useMemo, useState, useRef } from "react";
43
import {
54
BlockPickerProps,
65
ChromePickerProps,
@@ -15,10 +14,12 @@ import {
1514
SwatchesPickerProps,
1615
TwitterPickerProps
1716
} from "react-color";
18-
import classNames from "classnames";
17+
import { Alert } from "@mendix/widget-plugin-component-kit/Alert";
18+
import { debounce } from "@mendix/widget-plugin-platform/utils/debounce";
19+
import { DefaultColorsType, FormatEnum, ModeEnum, TypeEnum } from "../../typings/ColorPickerProps";
1920
import { getColorPicker, parseColor, validateColorFormat, validateProps } from "../utils";
20-
import { Input } from "./Input";
2121
import { Button } from "./Button";
22+
import { Input } from "./Input";
2223

2324
export interface ColorPickerProps {
2425
id: string;
@@ -53,18 +54,33 @@ export const ColorPicker = (props: ColorPickerProps): ReactElement => {
5354
rgb: "rgb(255,255,255)",
5455
rgba: "rgb(255,255,255,1)"
5556
};
56-
const { type, mode, disabled, defaultColors, color, format, invalidFormatMessage, onColorChange } = props;
57+
const {
58+
type,
59+
mode,
60+
disabled,
61+
defaultColors,
62+
color,
63+
format,
64+
invalidFormatMessage,
65+
onColorChange,
66+
onChange: onColorChangeComplete
67+
} = props;
5768
const ColorElement = getColorPicker(type);
5869
const [hidden, setHidden] = useState(mode !== "inline");
59-
const [currentColor, setCurrentColor] = useState<string | undefined>(color);
70+
const currentColor = useRef<string>(color);
6071
const [alertMessage, setAlertMessage] = useState<string | undefined>();
6172

73+
const [completeColorChange, abortCompleteColorChange] = useMemo(() => {
74+
return debounce(onColorChangeComplete, 500);
75+
}, [onColorChangeComplete]);
76+
6277
const submitColor = useCallback(
6378
(color: string): void => {
64-
setCurrentColor(color);
79+
currentColor.current = color;
6580
onColorChange(color);
81+
abortCompleteColorChange();
6682
},
67-
[onColorChange]
83+
[onColorChange, abortCompleteColorChange]
6884
);
6985

7086
const validateColor = (colorValue: string): void => {
@@ -93,7 +109,7 @@ export const ColorPicker = (props: ColorPickerProps): ReactElement => {
93109
);
94110

95111
const renderInput = (): ReactElement => {
96-
const colorValue = currentColor || color;
112+
const colorValue = currentColor.current || color;
97113
return (
98114
<Input
99115
color={colorValue}
@@ -108,11 +124,15 @@ export const ColorPicker = (props: ColorPickerProps): ReactElement => {
108124
</Input>
109125
);
110126
};
111-
const onChangeComplete = (color: ColorState): void => {
112-
if (currentColor !== parseColor(color, format)) {
113-
props.onChange();
114-
}
115-
};
127+
const onChangeComplete = useCallback(
128+
(color: ColorState): void => {
129+
if (currentColor.current === parseColor(color, format)) {
130+
completeColorChange();
131+
}
132+
},
133+
[format, completeColorChange]
134+
);
135+
116136
const renderButton = (): ReactElement => {
117137
return <Button mode={mode} disabled={disabled} onClick={() => setColorPickerHidden(!hidden)} color={color} />;
118138
};

0 commit comments

Comments
 (0)