@react-aria/color 3.0.0-nightly.4569 → 3.0.0-nightly.4578
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ar-AE.main.js +3 -1
- package/dist/ar-AE.main.js.map +1 -1
- package/dist/ar-AE.mjs +3 -1
- package/dist/ar-AE.module.js +3 -1
- package/dist/ar-AE.module.js.map +1 -1
- package/dist/bg-BG.main.js +3 -1
- package/dist/bg-BG.main.js.map +1 -1
- package/dist/bg-BG.mjs +3 -1
- package/dist/bg-BG.module.js +3 -1
- package/dist/bg-BG.module.js.map +1 -1
- package/dist/cs-CZ.main.js +3 -1
- package/dist/cs-CZ.main.js.map +1 -1
- package/dist/cs-CZ.mjs +3 -1
- package/dist/cs-CZ.module.js +3 -1
- package/dist/cs-CZ.module.js.map +1 -1
- package/dist/da-DK.main.js +3 -1
- package/dist/da-DK.main.js.map +1 -1
- package/dist/da-DK.mjs +3 -1
- package/dist/da-DK.module.js +3 -1
- package/dist/da-DK.module.js.map +1 -1
- package/dist/de-DE.main.js +3 -1
- package/dist/de-DE.main.js.map +1 -1
- package/dist/de-DE.mjs +3 -1
- package/dist/de-DE.module.js +3 -1
- package/dist/de-DE.module.js.map +1 -1
- package/dist/el-GR.main.js +3 -1
- package/dist/el-GR.main.js.map +1 -1
- package/dist/el-GR.mjs +3 -1
- package/dist/el-GR.module.js +3 -1
- package/dist/el-GR.module.js.map +1 -1
- package/dist/en-US.main.js +3 -1
- package/dist/en-US.main.js.map +1 -1
- package/dist/en-US.mjs +3 -1
- package/dist/en-US.module.js +3 -1
- package/dist/en-US.module.js.map +1 -1
- package/dist/es-ES.main.js +3 -1
- package/dist/es-ES.main.js.map +1 -1
- package/dist/es-ES.mjs +3 -1
- package/dist/es-ES.module.js +3 -1
- package/dist/es-ES.module.js.map +1 -1
- package/dist/et-EE.main.js +3 -1
- package/dist/et-EE.main.js.map +1 -1
- package/dist/et-EE.mjs +3 -1
- package/dist/et-EE.module.js +3 -1
- package/dist/et-EE.module.js.map +1 -1
- package/dist/fi-FI.main.js +3 -1
- package/dist/fi-FI.main.js.map +1 -1
- package/dist/fi-FI.mjs +3 -1
- package/dist/fi-FI.module.js +3 -1
- package/dist/fi-FI.module.js.map +1 -1
- package/dist/fr-FR.main.js +3 -1
- package/dist/fr-FR.main.js.map +1 -1
- package/dist/fr-FR.mjs +3 -1
- package/dist/fr-FR.module.js +3 -1
- package/dist/fr-FR.module.js.map +1 -1
- package/dist/he-IL.main.js +3 -1
- package/dist/he-IL.main.js.map +1 -1
- package/dist/he-IL.mjs +3 -1
- package/dist/he-IL.module.js +3 -1
- package/dist/he-IL.module.js.map +1 -1
- package/dist/hr-HR.main.js +3 -1
- package/dist/hr-HR.main.js.map +1 -1
- package/dist/hr-HR.mjs +3 -1
- package/dist/hr-HR.module.js +3 -1
- package/dist/hr-HR.module.js.map +1 -1
- package/dist/hu-HU.main.js +3 -1
- package/dist/hu-HU.main.js.map +1 -1
- package/dist/hu-HU.mjs +3 -1
- package/dist/hu-HU.module.js +3 -1
- package/dist/hu-HU.module.js.map +1 -1
- package/dist/import.mjs +5 -1
- package/dist/it-IT.main.js +3 -1
- package/dist/it-IT.main.js.map +1 -1
- package/dist/it-IT.mjs +3 -1
- package/dist/it-IT.module.js +3 -1
- package/dist/it-IT.module.js.map +1 -1
- package/dist/ja-JP.main.js +3 -1
- package/dist/ja-JP.main.js.map +1 -1
- package/dist/ja-JP.mjs +3 -1
- package/dist/ja-JP.module.js +3 -1
- package/dist/ja-JP.module.js.map +1 -1
- package/dist/ko-KR.main.js +3 -1
- package/dist/ko-KR.main.js.map +1 -1
- package/dist/ko-KR.mjs +3 -1
- package/dist/ko-KR.module.js +3 -1
- package/dist/ko-KR.module.js.map +1 -1
- package/dist/lt-LT.main.js +3 -1
- package/dist/lt-LT.main.js.map +1 -1
- package/dist/lt-LT.mjs +3 -1
- package/dist/lt-LT.module.js +3 -1
- package/dist/lt-LT.module.js.map +1 -1
- package/dist/lv-LV.main.js +3 -1
- package/dist/lv-LV.main.js.map +1 -1
- package/dist/lv-LV.mjs +3 -1
- package/dist/lv-LV.module.js +3 -1
- package/dist/lv-LV.module.js.map +1 -1
- package/dist/main.js +6 -0
- package/dist/main.js.map +1 -1
- package/dist/module.js +5 -1
- package/dist/module.js.map +1 -1
- package/dist/nb-NO.main.js +3 -1
- package/dist/nb-NO.main.js.map +1 -1
- package/dist/nb-NO.mjs +3 -1
- package/dist/nb-NO.module.js +3 -1
- package/dist/nb-NO.module.js.map +1 -1
- package/dist/nl-NL.main.js +3 -1
- package/dist/nl-NL.main.js.map +1 -1
- package/dist/nl-NL.mjs +3 -1
- package/dist/nl-NL.module.js +3 -1
- package/dist/nl-NL.module.js.map +1 -1
- package/dist/pl-PL.main.js +3 -1
- package/dist/pl-PL.main.js.map +1 -1
- package/dist/pl-PL.mjs +3 -1
- package/dist/pl-PL.module.js +3 -1
- package/dist/pl-PL.module.js.map +1 -1
- package/dist/pt-BR.main.js +3 -1
- package/dist/pt-BR.main.js.map +1 -1
- package/dist/pt-BR.mjs +3 -1
- package/dist/pt-BR.module.js +3 -1
- package/dist/pt-BR.module.js.map +1 -1
- package/dist/pt-PT.main.js +3 -1
- package/dist/pt-PT.main.js.map +1 -1
- package/dist/pt-PT.mjs +3 -1
- package/dist/pt-PT.module.js +3 -1
- package/dist/pt-PT.module.js.map +1 -1
- package/dist/ro-RO.main.js +3 -1
- package/dist/ro-RO.main.js.map +1 -1
- package/dist/ro-RO.mjs +3 -1
- package/dist/ro-RO.module.js +3 -1
- package/dist/ro-RO.module.js.map +1 -1
- package/dist/ru-RU.main.js +3 -1
- package/dist/ru-RU.main.js.map +1 -1
- package/dist/ru-RU.mjs +3 -1
- package/dist/ru-RU.module.js +3 -1
- package/dist/ru-RU.module.js.map +1 -1
- package/dist/sk-SK.main.js +3 -1
- package/dist/sk-SK.main.js.map +1 -1
- package/dist/sk-SK.mjs +3 -1
- package/dist/sk-SK.module.js +3 -1
- package/dist/sk-SK.module.js.map +1 -1
- package/dist/sl-SI.main.js +3 -1
- package/dist/sl-SI.main.js.map +1 -1
- package/dist/sl-SI.mjs +3 -1
- package/dist/sl-SI.module.js +3 -1
- package/dist/sl-SI.module.js.map +1 -1
- package/dist/sr-SP.main.js +3 -1
- package/dist/sr-SP.main.js.map +1 -1
- package/dist/sr-SP.mjs +3 -1
- package/dist/sr-SP.module.js +3 -1
- package/dist/sr-SP.module.js.map +1 -1
- package/dist/sv-SE.main.js +3 -1
- package/dist/sv-SE.main.js.map +1 -1
- package/dist/sv-SE.mjs +3 -1
- package/dist/sv-SE.module.js +3 -1
- package/dist/sv-SE.module.js.map +1 -1
- package/dist/tr-TR.main.js +3 -1
- package/dist/tr-TR.main.js.map +1 -1
- package/dist/tr-TR.mjs +3 -1
- package/dist/tr-TR.module.js +3 -1
- package/dist/tr-TR.module.js.map +1 -1
- package/dist/types.d.ts +41 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/uk-UA.main.js +3 -1
- package/dist/uk-UA.main.js.map +1 -1
- package/dist/uk-UA.mjs +3 -1
- package/dist/uk-UA.module.js +3 -1
- package/dist/uk-UA.module.js.map +1 -1
- package/dist/useColorArea.main.js +7 -7
- package/dist/useColorArea.main.js.map +1 -1
- package/dist/useColorArea.mjs +7 -7
- package/dist/useColorArea.module.js +7 -7
- package/dist/useColorArea.module.js.map +1 -1
- package/dist/useColorAreaGradient.main.js +65 -171
- package/dist/useColorAreaGradient.main.js.map +1 -1
- package/dist/useColorAreaGradient.mjs +65 -171
- package/dist/useColorAreaGradient.module.js +65 -171
- package/dist/useColorAreaGradient.module.js.map +1 -1
- package/dist/useColorChannelField.main.js +36 -0
- package/dist/useColorChannelField.main.js.map +1 -0
- package/dist/useColorChannelField.mjs +31 -0
- package/dist/useColorChannelField.module.js +31 -0
- package/dist/useColorChannelField.module.js.map +1 -0
- package/dist/useColorField.main.js +3 -2
- package/dist/useColorField.main.js.map +1 -1
- package/dist/useColorField.mjs +3 -2
- package/dist/useColorField.module.js +3 -2
- package/dist/useColorField.module.js.map +1 -1
- package/dist/useColorSlider.main.js +29 -2
- package/dist/useColorSlider.main.js.map +1 -1
- package/dist/useColorSlider.mjs +29 -2
- package/dist/useColorSlider.module.js +29 -2
- package/dist/useColorSlider.module.js.map +1 -1
- package/dist/useColorSwatch.main.js +67 -0
- package/dist/useColorSwatch.main.js.map +1 -0
- package/dist/useColorSwatch.mjs +62 -0
- package/dist/useColorSwatch.module.js +62 -0
- package/dist/useColorSwatch.module.js.map +1 -0
- package/dist/useColorWheel.main.js +18 -4
- package/dist/useColorWheel.main.js.map +1 -1
- package/dist/useColorWheel.mjs +18 -4
- package/dist/useColorWheel.module.js +18 -4
- package/dist/useColorWheel.module.js.map +1 -1
- package/dist/zh-CN.main.js +3 -1
- package/dist/zh-CN.main.js.map +1 -1
- package/dist/zh-CN.mjs +3 -1
- package/dist/zh-CN.module.js +3 -1
- package/dist/zh-CN.module.js.map +1 -1
- package/dist/zh-TW.main.js +3 -1
- package/dist/zh-TW.main.js.map +1 -1
- package/dist/zh-TW.mjs +3 -1
- package/dist/zh-TW.module.js +3 -1
- package/dist/zh-TW.module.js.map +1 -1
- package/package.json +14 -13
- package/src/index.ts +4 -0
- package/src/useColorArea.ts +6 -9
- package/src/useColorAreaGradient.ts +66 -189
- package/src/useColorChannelField.ts +37 -0
- package/src/useColorField.ts +18 -14
- package/src/useColorSlider.ts +21 -3
- package/src/useColorSwatch.ts +74 -0
- package/src/useColorWheel.ts +18 -4
|
@@ -10,205 +10,89 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
import {Color} from '@react-types/color';
|
|
13
14
|
import {CSSProperties, useMemo} from 'react';
|
|
15
|
+
import {parseColor} from '@react-stately/color';
|
|
14
16
|
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
let result = {
|
|
18
|
-
colorAreaStyles: {
|
|
19
|
-
backgroundImage: `linear-gradient(to ${orientation[Number(dir)]},rgb(${zValue},0,0),rgb(${zValue},255,0))`
|
|
20
|
-
},
|
|
21
|
-
gradientStyles: {
|
|
22
|
-
backgroundImage: `linear-gradient(to ${orientation[Number(dir)]},rgb(${zValue},0,255),rgb(${zValue},255,255))`,
|
|
23
|
-
'WebkitMaskImage': maskImage,
|
|
24
|
-
maskImage
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
return result;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const generateRGB_G = (orientation, dir: boolean, zValue: number) => {
|
|
31
|
-
let maskImage = `linear-gradient(to ${orientation[Number(!dir)]}, transparent, #000)`;
|
|
32
|
-
let result = {
|
|
33
|
-
colorAreaStyles: {
|
|
34
|
-
backgroundImage: `linear-gradient(to ${orientation[Number(dir)]},rgb(0,${zValue},0),rgb(255,${zValue},0))`
|
|
35
|
-
},
|
|
36
|
-
gradientStyles: {
|
|
37
|
-
backgroundImage: `linear-gradient(to ${orientation[Number(dir)]},rgb(0,${zValue},255),rgb(255,${zValue},255))`,
|
|
38
|
-
'WebkitMaskImage': maskImage,
|
|
39
|
-
maskImage
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
return result;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const generateRGB_B = (orientation, dir: boolean, zValue: number) => {
|
|
46
|
-
let maskImage = `linear-gradient(to ${orientation[Number(!dir)]}, transparent, #000)`;
|
|
47
|
-
let result = {
|
|
48
|
-
colorAreaStyles: {
|
|
49
|
-
backgroundImage: `linear-gradient(to ${orientation[Number(dir)]},rgb(0,0,${zValue}),rgb(255,0,${zValue}))`
|
|
50
|
-
},
|
|
51
|
-
gradientStyles: {
|
|
52
|
-
backgroundImage: `linear-gradient(to ${orientation[Number(dir)]},rgb(0,255,${zValue}),rgb(255,255,${zValue}))`,
|
|
53
|
-
'WebkitMaskImage': maskImage,
|
|
54
|
-
maskImage
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
return result;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const generateHSL_H = (orientation, dir: boolean, zValue: number) => {
|
|
62
|
-
let result = {
|
|
63
|
-
colorAreaStyles: {},
|
|
64
|
-
gradientStyles: {
|
|
65
|
-
background: [
|
|
66
|
-
`linear-gradient(to ${orientation[Number(dir)]}, hsla(0,0%,0%,1) 0%, hsla(0,0%,0%,0) 50%, hsla(0,0%,100%,0) 50%, hsla(0,0%,100%,1) 100%)`,
|
|
67
|
-
`linear-gradient(to ${orientation[Number(!dir)]},hsl(0,0%,50%),hsla(0,0%,50%,0))`,
|
|
68
|
-
`hsl(${zValue}, 100%, 50%)`
|
|
69
|
-
].join(',')
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
return result;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const generateHSL_S = (orientation, dir: boolean, alphaValue: number) => {
|
|
76
|
-
let result = {
|
|
77
|
-
colorAreaStyles: {},
|
|
78
|
-
gradientStyles: {
|
|
79
|
-
background: [
|
|
80
|
-
`linear-gradient(to ${orientation[Number(!dir)]}, hsla(0,0%,0%,${alphaValue}) 0%, hsla(0,0%,0%,0) 50%, hsla(0,0%,100%,0) 50%, hsla(0,0%,100%,${alphaValue}) 100%)`,
|
|
81
|
-
`linear-gradient(to ${orientation[Number(dir)]},hsla(0,100%,50%,${alphaValue}),hsla(60,100%,50%,${alphaValue}),hsla(120,100%,50%,${alphaValue}),hsla(180,100%,50%,${alphaValue}),hsla(240,100%,50%,${alphaValue}),hsla(300,100%,50%,${alphaValue}),hsla(359,100%,50%,${alphaValue}))`,
|
|
82
|
-
'hsl(0, 0%, 50%)'
|
|
83
|
-
].join(',')
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
return result;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const generateHSL_L = (orientation, dir: boolean, zValue: number) => {
|
|
90
|
-
let result = {
|
|
91
|
-
colorAreaStyles: {},
|
|
92
|
-
gradientStyles: {
|
|
93
|
-
backgroundImage: [
|
|
94
|
-
`linear-gradient(to ${orientation[Number(!dir)]},hsl(0,0%,${zValue}%),hsla(0,0%,${zValue}%,0))`,
|
|
95
|
-
`linear-gradient(to ${orientation[Number(dir)]},hsl(0,100%,${zValue}%),hsl(60,100%,${zValue}%),hsl(120,100%,${zValue}%),hsl(180,100%,${zValue}%),hsl(240,100%,${zValue}%),hsl(300,100%,${zValue}%),hsl(360,100%,${zValue}%))`
|
|
96
|
-
].join(',')
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
return result;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const generateHSB_H = (orientation, dir: boolean, zValue: number) => {
|
|
104
|
-
let result = {
|
|
105
|
-
colorAreaStyles: {},
|
|
106
|
-
gradientStyles: {
|
|
107
|
-
background: [
|
|
108
|
-
`linear-gradient(to ${orientation[Number(dir)]},hsl(0,0%,0%),hsla(0,0%,0%,0))`,
|
|
109
|
-
`linear-gradient(to ${orientation[Number(!dir)]},hsl(0,0%,100%),hsla(0,0%,100%,0))`,
|
|
110
|
-
`hsl(${zValue}, 100%, 50%)`
|
|
111
|
-
].join(',')
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
return result;
|
|
115
|
-
};
|
|
17
|
+
const hue = (color: Color) => [0, 60, 120, 180, 240, 300, 360].map(hue => color.withChannelValue('hue', hue).toString('css')).join(', ');
|
|
18
|
+
const saturation = (color: Color) => `${color.withChannelValue('saturation', 0)}, transparent`;
|
|
116
19
|
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
background: [
|
|
122
|
-
`linear-gradient(to ${orientation[Number(!dir)]},hsla(0,0%,0%,${alphaValue}),hsla(0,0%,0%,0))`,
|
|
123
|
-
`linear-gradient(to ${orientation[Number(dir)]},hsla(0,100%,50%,${alphaValue}),hsla(60,100%,50%,${alphaValue}),hsla(120,100%,50%,${alphaValue}),hsla(180,100%,50%,${alphaValue}),hsla(240,100%,50%,${alphaValue}),hsla(300,100%,50%,${alphaValue}),hsla(359,100%,50%,${alphaValue}))`,
|
|
124
|
-
`linear-gradient(to ${orientation[Number(!dir)]},hsl(0,0%,0%),hsl(0,0%,100%))`
|
|
125
|
-
].join(',')
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
return result;
|
|
20
|
+
const hslChannels = {
|
|
21
|
+
hue,
|
|
22
|
+
saturation,
|
|
23
|
+
lightness: () => 'black, transparent, white'
|
|
129
24
|
};
|
|
130
25
|
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
background: [
|
|
136
|
-
`linear-gradient(to ${orientation[Number(!dir)]},hsla(0,0%,100%,${alphaValue}),hsla(0,0%,100%,0))`,
|
|
137
|
-
`linear-gradient(to ${orientation[Number(dir)]},hsla(0,100%,50%,${alphaValue}),hsla(60,100%,50%,${alphaValue}),hsla(120,100%,50%,${alphaValue}),hsla(180,100%,50%,${alphaValue}),hsla(240,100%,50%,${alphaValue}),hsla(300,100%,50%,${alphaValue}),hsla(359,100%,50%,${alphaValue}))`,
|
|
138
|
-
'#000'
|
|
139
|
-
].join(',')
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
return result;
|
|
26
|
+
const hsbChannels = {
|
|
27
|
+
hue,
|
|
28
|
+
saturation,
|
|
29
|
+
brightness: () => 'black, transparent'
|
|
143
30
|
};
|
|
144
31
|
|
|
145
|
-
|
|
146
32
|
interface Gradients {
|
|
147
33
|
colorAreaStyleProps: {
|
|
148
34
|
style: CSSProperties
|
|
149
35
|
},
|
|
150
|
-
gradientStyleProps: {
|
|
151
|
-
style: CSSProperties
|
|
152
|
-
},
|
|
153
36
|
thumbStyleProps: {
|
|
154
37
|
style: CSSProperties
|
|
155
38
|
}
|
|
156
39
|
}
|
|
157
40
|
|
|
158
|
-
export function useColorAreaGradient({direction, state, zChannel, xChannel,
|
|
41
|
+
export function useColorAreaGradient({direction, state, zChannel, xChannel, yChannel}): Gradients {
|
|
159
42
|
let returnVal = useMemo<Gradients>(() => {
|
|
160
|
-
let
|
|
161
|
-
let
|
|
162
|
-
let background = {colorAreaStyles: {}, gradientStyles: {}};
|
|
43
|
+
let end = direction === 'rtl' ? 'left' : 'right';
|
|
44
|
+
let colorAreaStyles = {};
|
|
163
45
|
let zValue = state.value.getChannelValue(zChannel);
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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;
|
|
46
|
+
|
|
47
|
+
switch (state.value.getColorSpace()) {
|
|
48
|
+
case 'rgb': {
|
|
49
|
+
let rgb = parseColor('rgb(0, 0, 0)');
|
|
50
|
+
colorAreaStyles = {
|
|
51
|
+
background: [
|
|
52
|
+
// The screen blend mode multiplies the inverse of each channel, e.g. 1 - (1 - a) * (1 - b).
|
|
53
|
+
// Create a layer for each channel, with the other channels as 0. After blending, this should
|
|
54
|
+
// result in the gradients being combined channel by channel.
|
|
55
|
+
`linear-gradient(to ${end}, ${rgb.withChannelValue(xChannel, 0)}, ${rgb.withChannelValue(xChannel, 255)})`,
|
|
56
|
+
`linear-gradient(to top, ${rgb.withChannelValue(yChannel, 0)}, ${rgb.withChannelValue(yChannel, 255)})`,
|
|
57
|
+
rgb.withChannelValue(zChannel, zValue)
|
|
58
|
+
].join(','),
|
|
59
|
+
backgroundBlendMode: 'screen'
|
|
60
|
+
};
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case 'hsl': {
|
|
64
|
+
let channels = state.value.getColorChannels();
|
|
65
|
+
let value = parseColor('hsl(0, 100%, 50%)').withChannelValue(zChannel, zValue);
|
|
66
|
+
|
|
67
|
+
let bg = channels
|
|
68
|
+
.filter(c => c !== zChannel)
|
|
69
|
+
.map(c => `linear-gradient(to ${c === xChannel ? end : 'top'}, ${hslChannels[c](value)})`)
|
|
70
|
+
.reverse();
|
|
71
|
+
if (zChannel === 'hue') {
|
|
72
|
+
bg.push(value.toString('css'));
|
|
206
73
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
background
|
|
210
|
-
|
|
74
|
+
|
|
75
|
+
colorAreaStyles = {
|
|
76
|
+
background: bg.join(', ')
|
|
77
|
+
};
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
case 'hsb': {
|
|
81
|
+
let channels = state.value.getColorChannels();
|
|
82
|
+
let value = parseColor('hsb(0, 100%, 100%)').withChannelValue(zChannel, zValue);
|
|
83
|
+
|
|
84
|
+
let bg = channels
|
|
85
|
+
.filter(c => c !== zChannel)
|
|
86
|
+
.map(c => `linear-gradient(to ${c === xChannel ? end : 'top'}, ${hsbChannels[c](value)})`)
|
|
87
|
+
.reverse();
|
|
88
|
+
if (zChannel === 'hue') {
|
|
89
|
+
bg.push(value.toString('css'));
|
|
211
90
|
}
|
|
91
|
+
|
|
92
|
+
colorAreaStyles = {
|
|
93
|
+
background: bg.join(', ')
|
|
94
|
+
};
|
|
95
|
+
break;
|
|
212
96
|
}
|
|
213
97
|
}
|
|
214
98
|
|
|
@@ -226,14 +110,7 @@ export function useColorAreaGradient({direction, state, zChannel, xChannel, isDi
|
|
|
226
110
|
position: 'relative',
|
|
227
111
|
touchAction: 'none',
|
|
228
112
|
...forcedColorAdjustNoneStyle,
|
|
229
|
-
...
|
|
230
|
-
}
|
|
231
|
-
},
|
|
232
|
-
gradientStyleProps: {
|
|
233
|
-
style: {
|
|
234
|
-
touchAction: 'none',
|
|
235
|
-
...forcedColorAdjustNoneStyle,
|
|
236
|
-
...background.gradientStyles
|
|
113
|
+
...colorAreaStyles
|
|
237
114
|
}
|
|
238
115
|
},
|
|
239
116
|
thumbStyleProps: {
|
|
@@ -241,13 +118,13 @@ export function useColorAreaGradient({direction, state, zChannel, xChannel, isDi
|
|
|
241
118
|
position: 'absolute',
|
|
242
119
|
left: `${x * 100}%`,
|
|
243
120
|
top: `${y * 100}%`,
|
|
244
|
-
transform: 'translate(
|
|
121
|
+
transform: 'translate(-50%, -50%)',
|
|
245
122
|
touchAction: 'none',
|
|
246
123
|
...forcedColorAdjustNoneStyle
|
|
247
124
|
}
|
|
248
125
|
}
|
|
249
126
|
};
|
|
250
|
-
}, [direction, state, zChannel, xChannel,
|
|
127
|
+
}, [direction, state, zChannel, xChannel, yChannel]);
|
|
251
128
|
|
|
252
129
|
return returnVal;
|
|
253
130
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {AriaLabelingProps} from '@react-types/shared';
|
|
14
|
+
import {ColorChannelFieldProps, ColorChannelFieldState} from '@react-stately/color';
|
|
15
|
+
import {NumberFieldAria, useNumberField} from '@react-aria/numberfield';
|
|
16
|
+
import {RefObject} from 'react';
|
|
17
|
+
import {useLocale} from '@react-aria/i18n';
|
|
18
|
+
|
|
19
|
+
export interface AriaColorChannelFieldProps extends ColorChannelFieldProps, AriaLabelingProps {}
|
|
20
|
+
export interface ColorChannelFieldAria extends NumberFieldAria {}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Provides the behavior and accessibility implementation for a color channel field, allowing users to edit the
|
|
24
|
+
* value of an individual color channel.
|
|
25
|
+
*/
|
|
26
|
+
export function useColorChannelField(props: AriaColorChannelFieldProps, state: ColorChannelFieldState, inputRef: RefObject<HTMLInputElement>): ColorChannelFieldAria {
|
|
27
|
+
let {locale} = useLocale();
|
|
28
|
+
return useNumberField({
|
|
29
|
+
...props,
|
|
30
|
+
value: undefined,
|
|
31
|
+
defaultValue: undefined,
|
|
32
|
+
onChange: undefined,
|
|
33
|
+
validate: undefined,
|
|
34
|
+
// Provide a default aria-label if no other label is provided.
|
|
35
|
+
'aria-label': props['aria-label'] || (props.label || props['aria-labelledby'] ? undefined : state.colorValue.getChannelName(props.channel, locale))
|
|
36
|
+
}, state, inputRef);
|
|
37
|
+
}
|
package/src/useColorField.ts
CHANGED
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
|
|
13
13
|
import {AriaColorFieldProps} from '@react-types/color';
|
|
14
14
|
import {ColorFieldState} from '@react-stately/color';
|
|
15
|
+
import {DOMAttributes, ValidationResult} from '@react-types/shared';
|
|
15
16
|
import {
|
|
16
|
-
|
|
17
|
+
InputHTMLAttributes,
|
|
17
18
|
LabelHTMLAttributes,
|
|
18
19
|
RefObject,
|
|
19
20
|
useCallback,
|
|
@@ -24,13 +25,16 @@ import {privateValidationStateProp} from '@react-stately/form';
|
|
|
24
25
|
import {useFocusWithin, useScrollWheel} from '@react-aria/interactions';
|
|
25
26
|
import {useFormattedTextField} from '@react-aria/textfield';
|
|
26
27
|
import {useSpinButton} from '@react-aria/spinbutton';
|
|
27
|
-
import {ValidationResult} from '@react-types/shared';
|
|
28
28
|
|
|
29
29
|
export interface ColorFieldAria extends ValidationResult {
|
|
30
30
|
/** Props for the label element. */
|
|
31
31
|
labelProps: LabelHTMLAttributes<HTMLLabelElement>,
|
|
32
32
|
/** Props for the input element. */
|
|
33
|
-
inputProps:
|
|
33
|
+
inputProps: InputHTMLAttributes<HTMLInputElement>,
|
|
34
|
+
/** Props for the text field's description element, if any. */
|
|
35
|
+
descriptionProps: DOMAttributes,
|
|
36
|
+
/** Props for the text field's error message element, if any. */
|
|
37
|
+
errorMessageProps: DOMAttributes
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
/**
|
|
@@ -100,17 +104,17 @@ export function useColorField(
|
|
|
100
104
|
}
|
|
101
105
|
};
|
|
102
106
|
|
|
103
|
-
let {inputProps, ...otherProps} = useFormattedTextField(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
107
|
+
let {inputProps, ...otherProps} = useFormattedTextField({
|
|
108
|
+
...props,
|
|
109
|
+
id: inputId,
|
|
110
|
+
value: inputValue,
|
|
111
|
+
defaultValue: undefined,
|
|
112
|
+
validate: undefined,
|
|
113
|
+
[privateValidationStateProp]: state,
|
|
114
|
+
type: 'text',
|
|
115
|
+
autoComplete: 'off',
|
|
116
|
+
onChange
|
|
117
|
+
}, state, ref);
|
|
114
118
|
|
|
115
119
|
inputProps = mergeProps(inputProps, spinButtonProps, focusWithinProps, {
|
|
116
120
|
role: 'textbox',
|
package/src/useColorSlider.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {InputHTMLAttributes, RefObject} from 'react';
|
|
|
17
17
|
import {mergeProps} from '@react-aria/utils';
|
|
18
18
|
import {useLocale} from '@react-aria/i18n';
|
|
19
19
|
import {useSlider, useSliderThumb} from '@react-aria/slider';
|
|
20
|
+
import {useVisuallyHidden} from '@react-aria/visually-hidden';
|
|
20
21
|
|
|
21
22
|
export interface AriaColorSliderOptions extends AriaColorSliderProps {
|
|
22
23
|
/** A ref for the track element. */
|
|
@@ -74,8 +75,10 @@ export function useColorSlider(props: AriaColorSliderOptions, state: ColorSlider
|
|
|
74
75
|
to = 'left';
|
|
75
76
|
}
|
|
76
77
|
switch (channel) {
|
|
77
|
-
case 'hue':
|
|
78
|
-
|
|
78
|
+
case 'hue': {
|
|
79
|
+
let stops = [0, 60, 120, 180, 240, 300, 360].map(hue => value.withChannelValue('hue', hue).toString('css')).join(', ');
|
|
80
|
+
return `linear-gradient(to ${to}, ${stops})`;
|
|
81
|
+
}
|
|
79
82
|
case 'lightness': {
|
|
80
83
|
// We have to add an extra color stop in the middle so that the hue shows up at all.
|
|
81
84
|
// Otherwise it will always just be black to white.
|
|
@@ -109,6 +112,15 @@ export function useColorSlider(props: AriaColorSliderOptions, state: ColorSlider
|
|
|
109
112
|
inputProps['aria-valuetext'] += `, ${value.getColorName(locale)}`;
|
|
110
113
|
}
|
|
111
114
|
|
|
115
|
+
let {visuallyHiddenProps} = useVisuallyHidden({
|
|
116
|
+
style: {
|
|
117
|
+
opacity: '0.0001',
|
|
118
|
+
width: '100%',
|
|
119
|
+
height: '100%',
|
|
120
|
+
pointerEvents: 'none'
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
112
124
|
return {
|
|
113
125
|
trackProps: {
|
|
114
126
|
...mergeProps(groupProps, trackProps),
|
|
@@ -118,7 +130,13 @@ export function useColorSlider(props: AriaColorSliderOptions, state: ColorSlider
|
|
|
118
130
|
background: generateBackground()
|
|
119
131
|
}
|
|
120
132
|
},
|
|
121
|
-
inputProps
|
|
133
|
+
inputProps: {
|
|
134
|
+
...inputProps,
|
|
135
|
+
style: {
|
|
136
|
+
...inputProps.style,
|
|
137
|
+
...visuallyHiddenProps.style
|
|
138
|
+
}
|
|
139
|
+
},
|
|
122
140
|
thumbProps: {
|
|
123
141
|
...thumbProps,
|
|
124
142
|
style: {
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {AriaLabelingProps, DOMProps} from '@react-types/shared';
|
|
14
|
+
import {Color} from '@react-types/color';
|
|
15
|
+
import {filterDOMProps, useId} from '@react-aria/utils';
|
|
16
|
+
import {HTMLAttributes, useMemo} from 'react';
|
|
17
|
+
// @ts-ignore
|
|
18
|
+
import intlMessages from '../intl/*.json';
|
|
19
|
+
import {parseColor} from '@react-stately/color';
|
|
20
|
+
import {useLocale, useLocalizedStringFormatter} from '@react-aria/i18n';
|
|
21
|
+
|
|
22
|
+
export interface AriaColorSwatchProps extends AriaLabelingProps, DOMProps {
|
|
23
|
+
/** The color value to display in the swatch. */
|
|
24
|
+
color?: string | Color | null,
|
|
25
|
+
/**
|
|
26
|
+
* A localized accessible name for the color.
|
|
27
|
+
* By default, a description is generated from the color value,
|
|
28
|
+
* but this can be overridden if you have a more specific color
|
|
29
|
+
* name (e.g. Pantone colors).
|
|
30
|
+
*/
|
|
31
|
+
colorName?: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface ColorSwatchAria {
|
|
35
|
+
/** Props for the color swatch element. */
|
|
36
|
+
colorSwatchProps: HTMLAttributes<HTMLElement>,
|
|
37
|
+
/** The parsed color value of the swatch. */
|
|
38
|
+
color: Color
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Provides the accessibility implementation for a color swatch component.
|
|
43
|
+
* A color swatch displays a preview of a selected color.
|
|
44
|
+
*/
|
|
45
|
+
export function useColorSwatch(props: AriaColorSwatchProps): ColorSwatchAria {
|
|
46
|
+
let {color: value, colorName} = props;
|
|
47
|
+
let nonNullValue = value || '#fff0';
|
|
48
|
+
let color = useMemo(() => typeof nonNullValue === 'string' ? parseColor(nonNullValue) : nonNullValue, [nonNullValue]);
|
|
49
|
+
let {locale} = useLocale();
|
|
50
|
+
let DOMProps = filterDOMProps(props, {labelable: true});
|
|
51
|
+
let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/color');
|
|
52
|
+
let id = useId(props.id);
|
|
53
|
+
|
|
54
|
+
if (!colorName) {
|
|
55
|
+
colorName = color.getChannelValue('alpha') === 0 ? stringFormatter.format('transparent') : color.getColorName(locale);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
colorSwatchProps: {
|
|
60
|
+
...DOMProps,
|
|
61
|
+
role: 'img',
|
|
62
|
+
'aria-roledescription': stringFormatter.format('colorSwatch'),
|
|
63
|
+
'aria-label': [colorName, props['aria-label'] || ''].filter(Boolean).join(', '),
|
|
64
|
+
'aria-labelledby': props['aria-labelledby'] ? `${id} ${props['aria-labelledby']}` : undefined,
|
|
65
|
+
id,
|
|
66
|
+
style: {
|
|
67
|
+
backgroundColor: color.toString('css'),
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
forcedColorAdjust: 'none'
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
color: color || null
|
|
73
|
+
};
|
|
74
|
+
}
|
package/src/useColorWheel.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {focusWithoutScrolling, mergeProps, useFormReset, useGlobalListeners, use
|
|
|
17
17
|
import React, {ChangeEvent, InputHTMLAttributes, RefObject, useCallback, useRef} from 'react';
|
|
18
18
|
import {useKeyboard, useMove} from '@react-aria/interactions';
|
|
19
19
|
import {useLocale} from '@react-aria/i18n';
|
|
20
|
+
import {useVisuallyHidden} from '@react-aria/visually-hidden';
|
|
20
21
|
|
|
21
22
|
export interface AriaColorWheelOptions extends AriaColorWheelProps {
|
|
22
23
|
/** The outer radius of the color wheel. */
|
|
@@ -263,6 +264,15 @@ export function useColorWheel(props: AriaColorWheelOptions, state: ColorWheelSta
|
|
|
263
264
|
forcedColorAdjust: 'none'
|
|
264
265
|
};
|
|
265
266
|
|
|
267
|
+
let {visuallyHiddenProps} = useVisuallyHidden({
|
|
268
|
+
style: {
|
|
269
|
+
opacity: '0.0001',
|
|
270
|
+
width: '100%',
|
|
271
|
+
height: '100%',
|
|
272
|
+
pointerEvents: 'none'
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
|
|
266
276
|
return {
|
|
267
277
|
trackProps: {
|
|
268
278
|
...trackInteractions,
|
|
@@ -297,9 +307,9 @@ export function useColorWheel(props: AriaColorWheelOptions, state: ColorWheelSta
|
|
|
297
307
|
...thumbInteractions,
|
|
298
308
|
style: {
|
|
299
309
|
position: 'absolute',
|
|
300
|
-
left:
|
|
301
|
-
top:
|
|
302
|
-
transform:
|
|
310
|
+
left: outerRadius + x,
|
|
311
|
+
top: outerRadius + y,
|
|
312
|
+
transform: 'translate(-50%, -50%)',
|
|
303
313
|
touchAction: 'none',
|
|
304
314
|
...forcedColorAdjustNoneStyle
|
|
305
315
|
}
|
|
@@ -317,7 +327,11 @@ export function useColorWheel(props: AriaColorWheelOptions, state: ColorWheelSta
|
|
|
317
327
|
name,
|
|
318
328
|
onChange: (e: ChangeEvent<HTMLInputElement>) => {
|
|
319
329
|
state.setHue(parseFloat(e.target.value));
|
|
320
|
-
}
|
|
330
|
+
},
|
|
331
|
+
style: visuallyHiddenProps.style,
|
|
332
|
+
'aria-errormessage': props['aria-errormessage'],
|
|
333
|
+
'aria-describedby': props['aria-describedby'],
|
|
334
|
+
'aria-details': props['aria-details']
|
|
321
335
|
}
|
|
322
336
|
)
|
|
323
337
|
};
|