diff --git a/packages/pluggableWidgets/color-picker-web/CHANGELOG.md b/packages/pluggableWidgets/color-picker-web/CHANGELOG.md index a405a1dade..358d2b7c22 100644 --- a/packages/pluggableWidgets/color-picker-web/CHANGELOG.md +++ b/packages/pluggableWidgets/color-picker-web/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Fixed + +- We fixed an issue with On change action not triggering in some cases. + ## [2.1.5] - 2026-03-06 ### Fixed diff --git a/packages/pluggableWidgets/color-picker-web/src/ColorPicker.editorConfig.ts b/packages/pluggableWidgets/color-picker-web/src/ColorPicker.editorConfig.ts index 57e08ad70c..2a936ce277 100644 --- a/packages/pluggableWidgets/color-picker-web/src/ColorPicker.editorConfig.ts +++ b/packages/pluggableWidgets/color-picker-web/src/ColorPicker.editorConfig.ts @@ -1,3 +1,4 @@ +import { hidePropertiesIn, hidePropertyIn, Properties, transformGroupsIntoTabs } from "@mendix/pluggable-widgets-tools"; import { ContainerProps, ImageProps, @@ -5,11 +6,10 @@ import { StructurePreviewProps, TextProps } from "@mendix/widget-plugin-platform/preview/structure-preview-api"; -import { hidePropertiesIn, hidePropertyIn, Properties, transformGroupsIntoTabs } from "@mendix/pluggable-widgets-tools"; import { ColorPickerPreviewProps } from "../typings/ColorPickerProps"; -import StructurePreviewSvg from "./assets/structure-preview.svg"; import StructurePreviewSvgDark from "./assets/structure-preview-dark.svg"; +import StructurePreviewSvg from "./assets/structure-preview.svg"; const defaultColorTypes = ["block", "sketch", "circle", "compact", "twitter"]; diff --git a/packages/pluggableWidgets/color-picker-web/src/components/Button.tsx b/packages/pluggableWidgets/color-picker-web/src/components/Button.tsx index 2ec254a8a3..fb4d6ccf19 100644 --- a/packages/pluggableWidgets/color-picker-web/src/components/Button.tsx +++ b/packages/pluggableWidgets/color-picker-web/src/components/Button.tsx @@ -1,5 +1,5 @@ -import { ReactElement } from "react"; import classNames from "classnames"; +import { ReactElement } from "react"; import { ModeEnum } from "../../typings/ColorPickerProps"; export interface ButtonProps { diff --git a/packages/pluggableWidgets/color-picker-web/src/components/ColorPicker.tsx b/packages/pluggableWidgets/color-picker-web/src/components/ColorPicker.tsx index db296cc164..6c88656f7a 100644 --- a/packages/pluggableWidgets/color-picker-web/src/components/ColorPicker.tsx +++ b/packages/pluggableWidgets/color-picker-web/src/components/ColorPicker.tsx @@ -1,6 +1,5 @@ -import { ReactElement, useCallback, useEffect, useState } from "react"; -import { Alert } from "@mendix/widget-plugin-component-kit/Alert"; -import { DefaultColorsType, FormatEnum, ModeEnum, TypeEnum } from "../../typings/ColorPickerProps"; +import classNames from "classnames"; +import { ReactElement, useCallback, useEffect, useMemo, useState, useRef } from "react"; import { BlockPickerProps, ChromePickerProps, @@ -15,10 +14,12 @@ import { SwatchesPickerProps, TwitterPickerProps } from "react-color"; -import classNames from "classnames"; +import { Alert } from "@mendix/widget-plugin-component-kit/Alert"; +import { debounce } from "@mendix/widget-plugin-platform/utils/debounce"; +import { DefaultColorsType, FormatEnum, ModeEnum, TypeEnum } from "../../typings/ColorPickerProps"; import { getColorPicker, parseColor, validateColorFormat, validateProps } from "../utils"; -import { Input } from "./Input"; import { Button } from "./Button"; +import { Input } from "./Input"; export interface ColorPickerProps { id: string; @@ -53,18 +54,33 @@ export const ColorPicker = (props: ColorPickerProps): ReactElement => { rgb: "rgb(255,255,255)", rgba: "rgb(255,255,255,1)" }; - const { type, mode, disabled, defaultColors, color, format, invalidFormatMessage, onColorChange } = props; + const { + type, + mode, + disabled, + defaultColors, + color, + format, + invalidFormatMessage, + onColorChange, + onChange: onColorChangeComplete + } = props; const ColorElement = getColorPicker(type); const [hidden, setHidden] = useState(mode !== "inline"); - const [currentColor, setCurrentColor] = useState(color); + const currentColor = useRef(color); const [alertMessage, setAlertMessage] = useState(); + const [completeColorChange, abortCompleteColorChange] = useMemo(() => { + return debounce(onColorChangeComplete, 500); + }, [onColorChangeComplete]); + const submitColor = useCallback( (color: string): void => { - setCurrentColor(color); + currentColor.current = color; onColorChange(color); + abortCompleteColorChange(); }, - [onColorChange] + [onColorChange, abortCompleteColorChange] ); const validateColor = (colorValue: string): void => { @@ -93,7 +109,7 @@ export const ColorPicker = (props: ColorPickerProps): ReactElement => { ); const renderInput = (): ReactElement => { - const colorValue = currentColor || color; + const colorValue = currentColor.current || color; return ( { ); }; - const onChangeComplete = (color: ColorState): void => { - if (currentColor !== parseColor(color, format)) { - props.onChange(); - } - }; + const onChangeComplete = useCallback( + (color: ColorState): void => { + if (currentColor.current === parseColor(color, format)) { + completeColorChange(); + } + }, + [format, completeColorChange] + ); + const renderButton = (): ReactElement => { return