-
Notifications
You must be signed in to change notification settings - Fork 1.2k
ColorArea: add HSB and HSL support #2570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
43990a0
to
4ce326f
Compare
0e52041
to
8b8ea3a
Compare
27e9c46
to
2856bcf
Compare
/* TODO: what does a disabled color area look like? */ | ||
export let XHueYSaturationHSLisDisabled = Template.bind({}); | ||
XHueYSaturationHSLisDisabled.storyName = 'HSL xChannel="hue", yChannel="saturation", isDisabled'; | ||
XHueYSaturationHSLisDisabled.args = {...XHueYSaturationHSL.args, isDisabled: true}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question, maybe something to bring up to spectrum? I think making everything gray (like what you have) is probably easiest since we won't have to worry about if the disabled handle is too hard too see and it maybe confusing if we only change the handle style but leave the color area filled in
…ax value ColorArea: refine pageup/pagedown behaviors Omit change events when value doesn't change. useColorAreaState: fix onChangeEnd only after actual change
- Omit change events when value doesn't change. - Refine snapValueToStep for incrementing or decrementing from max.
Demonstrates controlled state and color conversion from HSL/HSB/RGB in ColorArea/ColorWheel/ColorSlider and ColorField, which is currently RGB only.
2856bcf
to
76922ca
Compare
formatMessage('colorNameAndValue', {name: state.value.getChannelName('green', locale), value: state.value.formatChannelValue('green', locale)}), | ||
formatMessage('colorNameAndValue', {name: state.value.getChannelName('blue', locale), value: state.value.formatChannelValue('blue', locale)}) | ||
].join(', '); | ||
let getValueTitle = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change going to cause issues if I'm using an app and I change my locale? I'm also curious if there could be issues with this component being used in a collaborative app where one person has their locale in one language/region and the other has it set to a different one. This code should be transforming the data for display to the user, but double checking.
let newValue = channelValue; | ||
switch (e.key) { | ||
case 'PageUp': | ||
newValue = channelValue + pageStep > maxValue ? maxValue : snapValueToStep(channelValue + pageStep, minValue, maxValue, pageStep); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would pressing PageUp ever cause the user to see the maxValue? Isn't PageUp moving upward, i.e. closer to the minValue? When I tested this pageup/pagedown seemed backwards.
Also, why does snapValueToStep have this broder issue when moving up, but not with PageDown? This feels like a bug with snapValueToStep. I noticed in useColorAreaState.ts
there was this min/max check on both values not just one like here.
break; | ||
} | ||
// remember to set this so that onChangeEnd is fired | ||
state.setThumbDragging(0, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the setThumDragging only change if the value changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to set it and then immediately unset it just so that onChangeEnd is fired
let isHue = zChannel === 'hue'; | ||
function onChange(e) { | ||
try { | ||
e = normalizeColor(e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is normalizeColor
throwing an error you need to catch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding ColorField
to the story means that parseColor
might throw an error if the string entered into the ColorField
cannot be parsed to a color.
export function normalizeColor(v: string | IColor) {
if (typeof v === 'string') {
return parseColor(v);
} else {
return v;
}
}
XLightnessYSaturation.storyName = 'HSL xChannel="lightness", yChannel="saturation"'; | ||
XLightnessYSaturation.args = {xChannel: 'lightness', yChannel: 'saturation', defaultValue: 'hsl(0, 100%, 50%)', onChange: action('onChange'), onChangeEnd: action('onChangeEnd')}; | ||
|
||
/* TODO: what does a disabled color area look like? */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this todo resolved or need to another PR or an issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we've got this pretty much resolved, I'll remove the comment, thanks
|
||
export let XSaturationYLightness = Template.bind({}); | ||
XSaturationYLightness.storyName = 'HSL xChannel="saturation", yChannel="lightness"'; | ||
XSaturationYLightness.args = {xChannel: 'saturation', yChannel: 'lightness', defaultValue: 'hsl(0, 100%, 50%)', onChange: action('onChange'), onChangeEnd: action('onChangeEnd')}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we care about the onChange and onChangeEnd events for these stories? I'm speaking to these not being on every RGB story.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they are on every rgb story in the latest on the color-area branch, they're inherited from the base one
@@ -120,3 +147,81 @@ XBlueYGreenSize3000.args = {...XBlueYGreen.args, size: 'size-3000'}; | |||
export let XBlueYGreenSize600 = Template.bind({}); | |||
XBlueYGreenSize600.storyName = 'RGB xChannel="blue", yChannel="green", size="size-600"'; | |||
XBlueYGreenSize600.args = {...XBlueYGreen.args, size: 'size-600'}; | |||
|
|||
export let XSaturationYLightness = Template.bind({}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This a lot of new stories to test. I know we are just following the pattern of the RGB stories above. Wondering if it would make more sense to add these to chromatic storybook and only having one or two examples of this or a dropdown to change a single story between all of these, or checkboxes to change toggle the examples between all these combinations?
case 'green': | ||
xChannel = 'blue'; | ||
case 'hue': | ||
xChannel = colorSpace === 'hsb' ? 'brightness' : 'lightness'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we 100% sure there will only be three color spaces in react spectrum? only hsb, rgb and hsl? If not I don't like this ternary. Never supporting YUV or CMYK?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is just for now
Closes #1732 Closes #1118
Opening this PR mainly so I don't lose track of this work.
Storybook examples:
✅ Pull Request Checklist:
📝 Test Instructions:
🧢 Your Project:
Adobe/Accessibility