Skip to content

Commit b6ef073

Browse files
committed
change the way to set palette presets, now ColorField works also with all other type of color sets as selectable options, fix/remove useEffect usage
1 parent b7d5717 commit b6ef073

6 files changed

Lines changed: 86 additions & 106 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
2424
- `<RadioButton />`
2525
- `hideIndicator` property: hide the radio inout indicator but click on children can be processed via `onChange` event
2626
- `<ColorField />`
27-
- input component for colors, uses the configured palette by default, but it also allows to enter custom colors
27+
- input component for colors
28+
- uses a subset from the configured color palette by default, but it also allows to enter custom colors
2829
- CSS custom properties
2930
- beside the color palette we now mirror the most important layout configuration variables as CSS custom properties
3031
- new icons:

src/common/utils/CssCustomProperties.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export default class CssCustomProperties {
2828

2929
// Methods
3030

31-
customProperties = (props: getCustomPropertiesProps = {}): string[][] | Record<string, string> => {
31+
customProperties = (props: getCustomPropertiesProps = {}): [string, string][] | Record<string, string> => {
3232
// FIXME:
3333
// in case of performance issues results should get saved at least into intern variables
3434
// other cache strategies could be also tested
@@ -104,7 +104,9 @@ export default class CssCustomProperties {
104104
});
105105
};
106106

107-
static listCustomProperties = (props: getCustomPropertiesProps = {}): string[][] | Record<string, string> => {
107+
static listCustomProperties = (
108+
props: getCustomPropertiesProps = {}
109+
): [string, string][] | Record<string, string> => {
108110
const { removeDashPrefix = true, returnObject = true, filterName = () => true, ...filterProps } = props;
109111

110112
const customProperties = CssCustomProperties.listLocalCssStyleRuleProperties({
@@ -123,6 +125,6 @@ export default class CssCustomProperties {
123125

124126
return returnObject
125127
? (Object.fromEntries(customProperties) as Record<string, string>)
126-
: (customProperties as string[][]);
128+
: (customProperties as [string, string][]);
127129
};
128130
}

src/common/utils/colorHash.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ type ColorOrFalse = Color | false;
99
export type ColorWeight = 100 | 300 | 500 | 700 | 900;
1010
export type PaletteGroup = "identity" | "semantic" | "layout" | "extra";
1111

12-
interface getEnabledColorsProps {
12+
export interface getEnabledColorsProps {
1313
/** Specify the palette groups used to define the set of colors. */
1414
includePaletteGroup?: PaletteGroup[];
1515
/** Use only some weights of a color tint. */
@@ -21,7 +21,7 @@ interface getEnabledColorsProps {
2121
}
2222

2323
const getEnabledColorsFromPaletteCache = new Map<string, Color[]>();
24-
const getEnabledColorPropertiesFromPaletteCache = new Map<string, string[][]>();
24+
const getEnabledColorPropertiesFromPaletteCache = new Map<string, [string, string][]>();
2525

2626
export function getEnabledColorsFromPalette(props: getEnabledColorsProps): Color[] {
2727
const configId = JSON.stringify({
@@ -50,7 +50,7 @@ export function getEnabledColorPropertiesFromPalette({
5050
includeColorWeight = [100, 300, 500, 700, 900],
5151
// (planned for later): includeMixedColors = false,
5252
minimalColorDistance = COLORMINDISTANCE,
53-
}: getEnabledColorsProps): string[][] {
53+
}: getEnabledColorsProps): [string, string][] {
5454
const configId = JSON.stringify({
5555
includePaletteGroup,
5656
includeColorWeight,
@@ -166,7 +166,7 @@ export function textToColorHash({
166166
}
167167

168168
function stringToIntegerHash(inputString: string): number {
169-
/* this function is idempotend, meaning it retrieves the same result for the same input
169+
/* this function is idempotent, meaning it retrieves the same result for the same input
170170
no matter how many times it's called */
171171
// Convert the string to a hash code
172172
let hashCode = 0;

src/components/ColorField/ColorField.stories.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from "react";
22
import { Meta, StoryFn } from "@storybook/react";
33

4+
import { getEnabledColorsProps } from "../../common/utils/colorHash";
45
import textFieldTest from "../TextField/stories/TextField.stories";
56

67
import { ColorField, ColorFieldProps } from "./ColorField";
@@ -25,21 +26,22 @@ Default.args = {
2526
export const NoPalettePresets = Template.bind({});
2627
NoPalettePresets.args = {
2728
...Default.args,
28-
includeColorWeight: [],
29-
includePaletteGroup: [],
3029
allowCustomColor: true,
3130
};
3231

33-
interface TemplateColorHashProps
34-
extends Pick<ColorFieldProps, "onChange" | "allowCustomColor" | "includeColorWeight" | "includePaletteGroup"> {
35-
stringForColorHashValue: string;
36-
}
32+
type TemplateColorHashProps = { stringForColorHashValue: string } & Pick<
33+
ColorFieldProps,
34+
"onChange" | "allowCustomColor"
35+
> &
36+
Pick<getEnabledColorsProps, "includeColorWeight" | "includePaletteGroup">;
3737

3838
const TemplateColorHash: StoryFn<TemplateColorHashProps> = (args: TemplateColorHashProps) => (
3939
<ColorField
4040
allowCustomColor={args.allowCustomColor}
41-
includeColorWeight={args.includeColorWeight}
42-
includePaletteGroup={args.includePaletteGroup}
41+
colorPresets={ColorField.listColorPalettePresets({
42+
includeColorWeight: args.includeColorWeight,
43+
includePaletteGroup: args.includePaletteGroup,
44+
})}
4345
value={ColorField.calculateColorHashValue(args.stringForColorHashValue, {
4446
allowCustomColor: args.allowCustomColor,
4547
includeColorWeight: args.includeColorWeight,

src/components/ColorField/ColorField.test.tsx

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,88 +17,71 @@ describe("ColorField", () => {
1717
});
1818

1919
it("renders a color input by default (no palette presets)", () => {
20-
const { container } = render(
21-
<ColorField includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={true} />
22-
);
20+
const { container } = render(<ColorField colorPresets={[]} allowCustomColor={true} />);
2321
expect(container.querySelector("input[type='color']")).toBeInTheDocument();
2422
});
2523

26-
// Jest cannot test this because it does not (cannot) load Styles where the palette isconfigured
27-
/*
2824
it("renders a readonly text input when palette colors are configured, and custom picker CSS class is applied", () => {
29-
const { container } = render(<ColorField className="my-custom-class" />);
25+
const { container } = render(
26+
<ColorField
27+
className="my-custom-class"
28+
colorPresets={[
29+
["my-black", "#000000"],
30+
["my-white", "#ffffff"],
31+
]}
32+
/>
33+
);
3034
// With default palette settings, a text input with readOnly is shown
3135
expect(container.querySelector("input[type='text']")).toBeInTheDocument();
3236
expect(container.querySelector("input[readonly]")).toBeInTheDocument();
3337
expect(container.querySelector(`.${eccgui}-colorfield--custom-picker`)).toBeInTheDocument();
3438
});
35-
*/
3639

3740
it("applies additional className", () => {
38-
render(
39-
<ColorField
40-
className="my-custom-class"
41-
includePaletteGroup={[]}
42-
includeColorWeight={[]}
43-
allowCustomColor={true}
44-
/>
45-
);
41+
render(<ColorField className="my-custom-class" colorPresets={[]} allowCustomColor={true} />);
4642
expect(document.querySelector(".my-custom-class")).toBeInTheDocument();
4743
});
4844
});
4945

5046
describe("value handling", () => {
5147
it("uses defaultValue as initial color", () => {
52-
render(
53-
<ColorField
54-
defaultValue="#ff0000"
55-
includePaletteGroup={[]}
56-
includeColorWeight={[]}
57-
allowCustomColor={true}
58-
/>
59-
);
48+
render(<ColorField defaultValue="#ff0000" colorPresets={[]} allowCustomColor={true} />);
6049
const input = document.querySelector("input") as HTMLInputElement;
6150
expect(input.value).toBe("#ff0000");
6251
});
6352

6453
it("uses value prop as initial color", () => {
65-
render(
66-
<ColorField value="#00ff00" includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={true} />
67-
);
54+
render(<ColorField value="#00ff00" colorPresets={[]} allowCustomColor={true} />);
6855
const input = document.querySelector("input") as HTMLInputElement;
6956
expect(input.value).toBe("#00ff00");
7057
});
7158

7259
it("falls back to #000000 when no value or defaultValue is provided", () => {
73-
render(<ColorField includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={true} />);
60+
render(<ColorField colorPresets={[]} allowCustomColor={true} />);
7461
const input = document.querySelector("input") as HTMLInputElement;
7562
expect(input.value).toBe("#000000");
7663
});
7764

7865
it("updates displayed value when value prop changes", () => {
79-
const { rerender } = render(
80-
<ColorField value="#ff0000" includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={true} />
81-
);
66+
const { rerender } = render(<ColorField value="#ff0000" colorPresets={[]} allowCustomColor={true} />);
8267
let input = document.querySelector("input") as HTMLInputElement;
8368
expect(input.value).toBe("#ff0000");
8469

85-
rerender(
86-
<ColorField value="#0000ff" includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={true} />
87-
);
70+
rerender(<ColorField value="#0000ff" colorPresets={[]} allowCustomColor={true} />);
8871
input = document.querySelector("input") as HTMLInputElement;
8972
expect(input.value).toBe("#0000ff");
9073
});
9174
});
9275

9376
describe("disabled state", () => {
9477
it("is disabled when disabled prop is true", () => {
95-
render(<ColorField disabled includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={true} />);
78+
render(<ColorField disabled colorPresets={[]} allowCustomColor={true} />);
9679
const input = document.querySelector("input") as HTMLInputElement;
9780
expect(input).toBeDisabled();
9881
});
9982

10083
it("is disabled when no palette colors and allowCustomColor is false", () => {
101-
render(<ColorField includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={false} />);
84+
render(<ColorField colorPresets={[]} allowCustomColor={false} />);
10285
const input = document.querySelector("input") as HTMLInputElement;
10386
expect(input).toBeDisabled();
10487
});
@@ -108,14 +91,7 @@ describe("ColorField", () => {
10891
it("calls onChange when native color input changes", async () => {
10992
const user = userEvent.setup();
11093
const onChange = jest.fn();
111-
render(
112-
<ColorField
113-
onChange={onChange}
114-
includePaletteGroup={[]}
115-
includeColorWeight={[]}
116-
allowCustomColor={true}
117-
/>
118-
);
94+
render(<ColorField onChange={onChange} colorPresets={[]} allowCustomColor={true} />);
11995
const input = document.querySelector("input[type='color']") as HTMLInputElement;
12096
input.type = "text"; // for unknown reasons Jest seems not able to test it on color inputs
12197
await user.type(input, "#123456");

0 commit comments

Comments
 (0)