Skip to content
Open
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
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@
},
"patchedDependencies": {
"react-native-gesture-handler@2.31.2": "patches/react-native-gesture-handler+2.31.2.patch",
"react-native-slider@0.11.0": "patches/react-native-slider+0.11.0.patch",
"react-native-snap-carousel@3.9.1": "patches/react-native-snap-carousel+3.9.1.patch",
"@mendix/pluggable-widgets-tools": "patches/@mendix__pluggable-widgets-tools.patch"
}
Expand Down
9 changes: 6 additions & 3 deletions packages/pluggableWidgets/color-picker-native/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

### Changed

- We updated deprecated-react-native-prop-types to 4.2.3.
- We pinned react-native-color to 0.0.10.
- We pinned react-native-slider to 0.11.0.
- We updated tinycolor2 to 1.6.0.
- We replaced react-native-slider and react-native-color with built-in components, and removed deprecated-react-native-prop-types.

### Fixed

- We fixed the sliders not announcing their value to screen readers. They can now also be adjusted with VoiceOver and TalkBack.
- We fixed the other sliders moving slightly while one slider is dragged, and hue and saturation being lost when the color becomes black or white.

## [2.1.0] - 2024-12-3

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "color-picker-native",
"widgetName": "ColorPicker",
"version": "2.3.0",
"version": "2.4.0",
"license": "Apache-2.0",
"repository": {
"type": "git",
Expand All @@ -21,9 +21,6 @@
"dependencies": {
"@mendix/piw-native-utils-internal": "*",
"@mendix/piw-utils-internal": "*",
"deprecated-react-native-prop-types": "4.2.3",
"react-native-color": "0.0.10",
"react-native-slider": "0.11.0",
"tinycolor2": "1.6.0"
},
"devDependencies": {
Expand Down
49 changes: 29 additions & 20 deletions packages/pluggableWidgets/color-picker-native/src/ColorPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import { flattenStyles } from "@mendix/piw-native-utils-internal";
import { ValueStatus } from "mendix";
import { Component, ReactElement, ReactNode } from "react";
import { View, ViewStyle } from "react-native";

import { HueGradient, LightnessGradient, SaturationGradient } from "react-native-color";
import tinycolor from "tinycolor2";
import { ColorPickerProps } from "../typings/ColorPickerProps";
import { PickerSlider } from "./components/PickerSlider";
import { AlphaGradient } from "./components/AlphaGradient";
import { DisabledHueGradient } from "./components/DisabledHueGradient";
import { HueGradient, LightnessGradient, SaturationGradient } from "./components/Gradients";
import { ColorPickerStyle, defaultColorPickerStyle } from "./ui/Styles";
import HSLA = tinycolor.ColorFormats.HSLA;
import { executeAction } from "@mendix/piw-utils-internal";
Expand All @@ -27,6 +26,8 @@ export class ColorPicker extends Component<Props, State> {
private readonly onChangeCompleteHandler = this.onChangeComplete.bind(this);
private readonly styles = flattenStyles(defaultColorPickerStyle, this.props.style);
private readonly defaultSteps = 80;
// Screen reader actions change and complete in one event, before the state update is applied
private pendingColor?: HSLA;
readonly state: State = {
color: undefined
};
Expand All @@ -36,8 +37,7 @@ export class ColorPicker extends Component<Props, State> {
return null;
}

const colorHex = this.state.color ? this.getColor() : this.props.color.value;
const color = tinycolor(colorHex).toHsl();
const color = this.getCurrentColor();

return (
<View style={this.styles.container} testID={`${this.props.name}`}>
Expand All @@ -51,45 +51,54 @@ export class ColorPicker extends Component<Props, State> {
}

componentDidUpdate(prevProps: Readonly<Props>, prevState: Readonly<State>): void {
if (this.props.color.value !== prevProps.color.value && this.state.color === prevState.color) {
// Keep the unrounded color while it still matches the value, so the other sliders don't jump when it is
// stored with 8-bit precision or hue and saturation are lost at black and white
if (
this.props.color.value !== prevProps.color.value &&
this.state.color === prevState.color &&
this.state.color &&
this.getColor() !== this.props.color.value
) {
this.setState({ color: undefined });
}
}

private onChangeHue(value: number): void {
const color = tinycolor(this.props.color.value).toHsl();
color.h = value;
this.setState({ color });
this.setColor({ ...this.getCurrentColor(), h: value });
}

private onChangeSaturation(value: number): void {
const color = tinycolor(this.props.color.value).toHsl();
color.s = value;
this.setState({ color });
this.setColor({ ...this.getCurrentColor(), s: value });
}

private onChangeLightness(value: number): void {
const color = tinycolor(this.props.color.value).toHsl();
color.l = value;
this.setState({ color });
this.setColor({ ...this.getCurrentColor(), l: value });
}

private onChangeAlpha(value: number): void {
const color = tinycolor(this.props.color.value).toHsl();
color.a = value;
this.setColor({ ...this.getCurrentColor(), a: value });
}

private getCurrentColor(): HSLA {
return this.pendingColor ?? this.state.color ?? tinycolor(this.props.color.value).toHsl();
}

private setColor(color: HSLA): void {
this.pendingColor = color;
this.setState({ color });
}

private onChangeComplete(): void {
if (this.state.color && this.props.color.value !== this.getColor()) {
this.props.color.setValue(this.getColor());
if (this.pendingColor && this.props.color.value !== this.getColor(this.pendingColor)) {
this.props.color.setValue(this.getColor(this.pendingColor));
}
this.pendingColor = undefined;

executeAction(this.props.onChange);
}

private getColor(): string {
const color = tinycolor(this.state.color);
private getColor(hsla = this.state.color): string {
const color = tinycolor(hsla);
switch (this.props.format) {
case "hex":
return color.toHexString();
Expand Down
Loading
Loading