Skip to content

Enhance color palette generation with saturation curve options#3942

Open
ZivSa1 wants to merge 4 commits intomasterfrom
feat/new-lightness-and-saturation-logic
Open

Enhance color palette generation with saturation curve options#3942
ZivSa1 wants to merge 4 commits intomasterfrom
feat/new-lightness-and-saturation-logic

Conversation

@ZivSa1
Copy link
Collaborator

@ZivSa1 ZivSa1 commented Feb 26, 2026

Description

  • Updated GeneratePaletteOptions to include saturationCurve, saturationThreshold, and saturationFloor for improved saturation adjustments.
  • Refactored adjustSaturation function to utilize the new saturation curve logic.
  • Modified color tint tests to match the changes + added tests for new logic.

Changelog

Colors: ColorPalette new Lightness and Saturation logic

Additional info

Ticket 4308

- Updated GeneratePaletteOptions to include saturationCurve, saturationThreshold, and saturationFloor for improved saturation adjustments.
- Refactored adjustSaturation function to utilize the new saturation curve logic.
- Modified color tint tests to reflect new expected values based on saturation adjustments.
- Added tests to ensure saturation curve behavior respects thresholds and custom floor values.
@github-actions
Copy link
Contributor

github-actions bot commented Feb 26, 2026

✅ PR Description Validation Passed

All required sections are properly filled out:

  • Description
  • Changelog
  • Additional info

Your PR is good for review! 🚀


This validation ensures all sections from the PR template are properly filled.

Copy link
Collaborator

@lidord-wix lidord-wix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some comments, also maybe worth going over it together to make sure I understand the changes

adjustSaturation?: boolean;
/** Array of saturation adjustments to apply on the color's tints array (from darkest to lightest).
* The 'adjustSaturation' option must be true */
saturationLevels?: number[];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if someone is passing saturationLevels?
it seems like a breaking change..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I asked Alexey and Yulia, we do want to change the logic entirely.
If I'm not mistaken, at Wix this logic is passed only via the private, so it should break our modules, but it is breaking change for public users. what do we want to do? still allow the public users use the old logic, or make them adjust to the new logic?

const sliced = tints.slice(start, end);

const adjusted = options?.adjustSaturation && adjustSaturation(sliced, color, options?.saturationLevels);
const adjusted = options?.adjustSaturation && adjustSaturationWithCurve(sliced, color, options);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function expect to get CurveOptions but gets GeneratePaletteOptions

const sliced = tints.slice(start, end);

const adjusted = options?.adjustSaturation && adjustSaturation(sliced, color, options?.saturationLevels);
const adjusted = options?.adjustSaturation && adjustSaturationWithCurve(sliced, color, options);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When adjustSaturation is false (or not provided), adjustSaturationWithCurve is never called.
However, defaultPaletteOptions sets adjustSaturation: true, so calling generateColorPalette without options always applies the curve. This is a behavior change from before where the old fallback adjustSaturation function only modified colors when lightness > 80 && saturation > 60. Now the curve is applied to all colors with baseSaturation > 50.

This means previously unaffected palettes (e.g., colors with lightness < 80 but saturation > 50) will now get
modified. This widens the blast radius of the change.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we want the saturation curve to be applied as default, and only if the user decides to - they can still turn it off by sending false in the options. The curve also wont be applied if the base saturation is below 50 - it's part of the logic.

const hsl = Color(hex).hsl();
const distance = Math.abs(i - baseIndex);
const percentage = curve[Math.min(distance, curve.length - 1)];
const newSaturation = Math.max(floor, Math.ceil(baseSaturation * percentage));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why using Math.ceil here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to round 🙏

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please also cover the new logic where the addDarkestTints: true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants