Skip to content

Commit 91ca94f

Browse files
Move color area gradients inside aria hook like other color components (#2950)
Co-authored-by: Danni <[email protected]>
1 parent 2267e21 commit 91ca94f

File tree

4 files changed

+140
-133
lines changed

4 files changed

+140
-133
lines changed

packages/@react-aria/color/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,3 @@ export * from './useColorArea';
1414
export * from './useColorSlider';
1515
export * from './useColorWheel';
1616
export * from './useColorField';
17-
export * from './gradients';

packages/@react-aria/color/src/useColorArea.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {focusWithoutScrolling, isAndroid, isIOS, mergeProps, useGlobalListeners,
1616
// @ts-ignore
1717
import intlMessages from '../intl/*.json';
1818
import React, {ChangeEvent, HTMLAttributes, InputHTMLAttributes, RefObject, useCallback, useRef} from 'react';
19+
import {useColorAreaGradient} from './useColorAreaGradient';
1920
import {useKeyboard, useMove} from '@react-aria/interactions';
2021
import {useLocale, useMessageFormatter} from '@react-aria/i18n';
2122
import {useVisuallyHidden} from '@react-aria/visually-hidden';
@@ -69,7 +70,7 @@ export function useColorArea(props: ColorAreaAriaProps, state: ColorAreaState):
6970

7071
let stateRef = useRef<ColorAreaState>(null);
7172
stateRef.current = state;
72-
let {xChannel, yChannel} = stateRef.current.channels;
73+
let {xChannel, yChannel, zChannel} = stateRef.current.channels;
7374
let xChannelStep = stateRef.current.xChannelStep;
7475
let yChannelStep = stateRef.current.yChannelStep;
7576

@@ -330,17 +331,33 @@ export function useColorArea(props: ColorAreaAriaProps, state: ColorAreaState):
330331
pointerEvents: 'none'
331332
}});
332333

334+
let {
335+
colorAreaStyleProps,
336+
gradientStyleProps,
337+
thumbStyleProps
338+
} = useColorAreaGradient({
339+
direction,
340+
state,
341+
xChannel,
342+
zChannel,
343+
isDisabled: props.isDisabled
344+
});
345+
346+
333347
return {
334348
colorAreaProps: {
335349
...colorAriaLabellingProps,
336350
...colorAreaInteractions,
351+
...colorAreaStyleProps,
337352
role: 'group'
338353
},
339354
gradientProps: {
355+
...gradientStyleProps,
340356
role: 'presentation'
341357
},
342358
thumbProps: {
343359
...thumbInteractions,
360+
...thumbStyleProps,
344361
role: 'presentation'
345362
},
346363
xInputProps: {

packages/@react-aria/color/src/gradients.ts renamed to packages/@react-aria/color/src/useColorAreaGradient.ts

Lines changed: 117 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
export const generateRGB_R = (orientation, dir: boolean, zValue: number) => {
13+
import {CSSProperties, useMemo} from 'react';
14+
15+
const generateRGB_R = (orientation, dir: boolean, zValue: number) => {
1416
let maskImage = `linear-gradient(to ${orientation[Number(!dir)]}, transparent, #000)`;
1517
let result = {
1618
colorAreaStyles: {
@@ -25,7 +27,7 @@ export const generateRGB_R = (orientation, dir: boolean, zValue: number) => {
2527
return result;
2628
};
2729

28-
export const generateRGB_G = (orientation, dir: boolean, zValue: number) => {
30+
const generateRGB_G = (orientation, dir: boolean, zValue: number) => {
2931
let maskImage = `linear-gradient(to ${orientation[Number(!dir)]}, transparent, #000)`;
3032
let result = {
3133
colorAreaStyles: {
@@ -40,7 +42,7 @@ export const generateRGB_G = (orientation, dir: boolean, zValue: number) => {
4042
return result;
4143
};
4244

43-
export const generateRGB_B = (orientation, dir: boolean, zValue: number) => {
45+
const generateRGB_B = (orientation, dir: boolean, zValue: number) => {
4446
let maskImage = `linear-gradient(to ${orientation[Number(!dir)]}, transparent, #000)`;
4547
let result = {
4648
colorAreaStyles: {
@@ -56,7 +58,7 @@ export const generateRGB_B = (orientation, dir: boolean, zValue: number) => {
5658
};
5759

5860

59-
export const generateHSL_H = (orientation, dir: boolean, zValue: number) => {
61+
const generateHSL_H = (orientation, dir: boolean, zValue: number) => {
6062
let result = {
6163
colorAreaStyles: {},
6264
gradientStyles: {
@@ -70,7 +72,7 @@ export const generateHSL_H = (orientation, dir: boolean, zValue: number) => {
7072
return result;
7173
};
7274

73-
export const generateHSL_S = (orientation, dir: boolean, alphaValue: number) => {
75+
const generateHSL_S = (orientation, dir: boolean, alphaValue: number) => {
7476
let result = {
7577
colorAreaStyles: {},
7678
gradientStyles: {
@@ -84,7 +86,7 @@ export const generateHSL_S = (orientation, dir: boolean, alphaValue: number) =>
8486
return result;
8587
};
8688

87-
export const generateHSL_L = (orientation, dir: boolean, zValue: number) => {
89+
const generateHSL_L = (orientation, dir: boolean, zValue: number) => {
8890
let result = {
8991
colorAreaStyles: {},
9092
gradientStyles: {
@@ -98,7 +100,7 @@ export const generateHSL_L = (orientation, dir: boolean, zValue: number) => {
98100
};
99101

100102

101-
export const generateHSB_H = (orientation, dir: boolean, zValue: number) => {
103+
const generateHSB_H = (orientation, dir: boolean, zValue: number) => {
102104
let result = {
103105
colorAreaStyles: {},
104106
gradientStyles: {
@@ -112,7 +114,7 @@ export const generateHSB_H = (orientation, dir: boolean, zValue: number) => {
112114
return result;
113115
};
114116

115-
export const generateHSB_S = (orientation, dir: boolean, alphaValue: number) => {
117+
const generateHSB_S = (orientation, dir: boolean, alphaValue: number) => {
116118
let result = {
117119
colorAreaStyles: {},
118120
gradientStyles: {
@@ -126,7 +128,7 @@ export const generateHSB_S = (orientation, dir: boolean, alphaValue: number) =>
126128
return result;
127129
};
128130

129-
export const generateHSB_B = (orientation, dir: boolean, alphaValue: number) => {
131+
const generateHSB_B = (orientation, dir: boolean, alphaValue: number) => {
130132
let result = {
131133
colorAreaStyles: {},
132134
gradientStyles: {
@@ -139,3 +141,109 @@ export const generateHSB_B = (orientation, dir: boolean, alphaValue: number) =>
139141
};
140142
return result;
141143
};
144+
145+
146+
interface Gradients {
147+
colorAreaStyleProps: {
148+
style: CSSProperties
149+
},
150+
gradientStyleProps: {
151+
style: CSSProperties
152+
},
153+
thumbStyleProps: {
154+
style: CSSProperties
155+
}
156+
}
157+
158+
export function useColorAreaGradient({direction, state, zChannel, xChannel, isDisabled}): Gradients {
159+
let returnVal = useMemo<Gradients>(() => {
160+
let orientation = ['top', direction === 'rtl' ? 'left' : 'right'];
161+
let dir = false;
162+
let background = {colorAreaStyles: {}, gradientStyles: {}};
163+
let zValue = state.value.getChannelValue(zChannel);
164+
let {minValue: zMin, maxValue: zMax} = state.value.getChannelRange(zChannel);
165+
let alphaValue = (zValue - zMin) / (zMax - zMin);
166+
let isHSL = state.value.getColorSpace() === 'hsl';
167+
if (!isDisabled) {
168+
switch (zChannel) {
169+
case 'red': {
170+
dir = xChannel === 'green';
171+
background = generateRGB_R(orientation, dir, zValue);
172+
break;
173+
}
174+
case 'green': {
175+
dir = xChannel === 'red';
176+
background = generateRGB_G(orientation, dir, zValue);
177+
break;
178+
}
179+
case 'blue': {
180+
dir = xChannel === 'red';
181+
background = generateRGB_B(orientation, dir, zValue);
182+
break;
183+
}
184+
case 'hue': {
185+
dir = xChannel !== 'saturation';
186+
if (isHSL) {
187+
background = generateHSL_H(orientation, dir, zValue);
188+
} else {
189+
background = generateHSB_H(orientation, dir, zValue);
190+
}
191+
break;
192+
}
193+
case 'saturation': {
194+
dir = xChannel === 'hue';
195+
if (isHSL) {
196+
background = generateHSL_S(orientation, dir, alphaValue);
197+
} else {
198+
background = generateHSB_S(orientation, dir, alphaValue);
199+
}
200+
break;
201+
}
202+
case 'brightness': {
203+
dir = xChannel === 'hue';
204+
background = generateHSB_B(orientation, dir, alphaValue);
205+
break;
206+
}
207+
case 'lightness': {
208+
dir = xChannel === 'hue';
209+
background = generateHSL_L(orientation, dir, zValue);
210+
break;
211+
}
212+
}
213+
}
214+
215+
let {x, y} = state.getThumbPosition();
216+
217+
if (direction === 'rtl') {
218+
x = 1 - x;
219+
}
220+
221+
return {
222+
colorAreaStyleProps: {
223+
style: {
224+
position: 'relative',
225+
touchAction: 'none',
226+
...background.colorAreaStyles
227+
}
228+
},
229+
gradientStyleProps: {
230+
style: {
231+
touchAction: 'none',
232+
...background.gradientStyles
233+
}
234+
},
235+
thumbStyleProps: {
236+
style: {
237+
position: 'absolute',
238+
left: `${x * 100}%`,
239+
top: `${y * 100}%`,
240+
transform: 'translate(0%, 0%)',
241+
touchAction: 'none'
242+
}
243+
}
244+
};
245+
}, [direction, state, zChannel, xChannel, isDisabled]);
246+
247+
return returnVal;
248+
}
249+

0 commit comments

Comments
 (0)