@react-spectrum/color 3.0.0-nightly.4567 → 3.0.0-nightly.4582
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/ColorArea.main.js +11 -10
- package/dist/ColorArea.main.js.map +1 -1
- package/dist/ColorArea.mjs +12 -11
- package/dist/ColorArea.module.js +12 -11
- package/dist/ColorArea.module.js.map +1 -1
- package/dist/ColorEditor.32e497e8.css +20 -0
- package/dist/ColorEditor.32e497e8.css.map +1 -0
- package/dist/ColorEditor.main.js +116 -0
- package/dist/ColorEditor.main.js.map +1 -0
- package/dist/ColorEditor.mjs +111 -0
- package/dist/ColorEditor.module.js +111 -0
- package/dist/ColorEditor.module.js.map +1 -0
- package/dist/ColorField.main.js +44 -6
- package/dist/ColorField.main.js.map +1 -1
- package/dist/ColorField.mjs +46 -8
- package/dist/ColorField.module.js +46 -8
- package/dist/ColorField.module.js.map +1 -1
- package/dist/ColorPicker.ab9f47c0.css +204 -0
- package/dist/ColorPicker.ab9f47c0.css.map +1 -0
- package/dist/ColorPicker.main.js +125 -0
- package/dist/ColorPicker.main.js.map +1 -0
- package/dist/ColorPicker.mjs +116 -0
- package/dist/ColorPicker.module.js +116 -0
- package/dist/ColorPicker.module.js.map +1 -0
- package/dist/ColorSlider.main.js +8 -4
- package/dist/ColorSlider.main.js.map +1 -1
- package/dist/ColorSlider.mjs +9 -5
- package/dist/ColorSlider.module.js +9 -5
- package/dist/ColorSlider.module.js.map +1 -1
- package/dist/ColorSwatch.f6e6f811.css +260 -0
- package/dist/ColorSwatch.f6e6f811.css.map +1 -0
- package/dist/ColorSwatch.main.js +94 -0
- package/dist/ColorSwatch.main.js.map +1 -0
- package/dist/ColorSwatch.mjs +84 -0
- package/dist/ColorSwatch.module.js +84 -0
- package/dist/ColorSwatch.module.js.map +1 -0
- package/dist/ColorSwatchPicker.1575be06.css +356 -0
- package/dist/ColorSwatchPicker.1575be06.css.map +1 -0
- package/dist/ColorSwatchPicker.main.js +115 -0
- package/dist/ColorSwatchPicker.main.js.map +1 -0
- package/dist/ColorSwatchPicker.mjs +106 -0
- package/dist/ColorSwatchPicker.module.js +106 -0
- package/dist/ColorSwatchPicker.module.js.map +1 -0
- package/dist/ColorThumb.main.js +57 -7
- package/dist/ColorThumb.main.js.map +1 -1
- package/dist/ColorThumb.mjs +59 -9
- package/dist/ColorThumb.module.js +59 -9
- package/dist/ColorThumb.module.js.map +1 -1
- package/dist/ColorWheel.main.js +6 -2
- package/dist/ColorWheel.main.js.map +1 -1
- package/dist/ColorWheel.mjs +7 -3
- package/dist/ColorWheel.module.js +7 -3
- package/dist/ColorWheel.module.js.map +1 -1
- package/dist/colorarea_vars_css.main.js +0 -3
- package/dist/colorarea_vars_css.main.js.map +1 -1
- package/dist/colorarea_vars_css.mjs +0 -3
- package/dist/colorarea_vars_css.module.js +0 -3
- package/dist/colorarea_vars_css.module.js.map +1 -1
- package/dist/en-US.main.js +10 -0
- package/dist/en-US.main.js.map +1 -0
- package/dist/en-US.mjs +12 -0
- package/dist/en-US.module.js +12 -0
- package/dist/en-US.module.js.map +1 -0
- package/dist/import.mjs +11 -1
- package/dist/intlStrings.main.js +9 -0
- package/dist/intlStrings.main.js.map +1 -0
- package/dist/intlStrings.mjs +11 -0
- package/dist/intlStrings.module.js +11 -0
- package/dist/intlStrings.module.js.map +1 -0
- package/dist/main.js +16 -0
- package/dist/main.js.map +1 -1
- package/dist/module.js +11 -1
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +75 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/{vars.08ba4b4c.css → vars.53b417c1.css} +2 -3
- package/dist/vars.53b417c1.css.map +1 -0
- package/dist/{vars.6f3d3943.css → vars.6fa9fa04.css} +6 -18
- package/dist/vars.6fa9fa04.css.map +1 -0
- package/dist/{vars.571f903e.css → vars.aa07b6d2.css} +2 -2
- package/dist/{vars.571f903e.css.map → vars.aa07b6d2.css.map} +1 -1
- package/dist/{vars.ef2c01b8.css → vars.cc682729.css} +4 -4
- package/dist/{vars.ef2c01b8.css.map → vars.cc682729.css.map} +1 -1
- package/package.json +23 -17
- package/src/ColorArea.tsx +7 -6
- package/src/ColorEditor.tsx +63 -0
- package/src/ColorField.tsx +67 -14
- package/src/ColorPicker.tsx +122 -0
- package/src/ColorSlider.tsx +6 -4
- package/src/ColorSwatch.tsx +102 -0
- package/src/ColorSwatchPicker.tsx +118 -0
- package/src/ColorThumb.tsx +72 -25
- package/src/ColorWheel.tsx +5 -2
- package/src/index.ts +10 -0
- package/dist/vars.08ba4b4c.css.map +0 -1
- package/dist/vars.6f3d3943.css.map +0 -1
@@ -4,8 +4,8 @@
|
|
4
4
|
transform: translate(0, var(--spectrum-global-dimension-static-size-100, 8px));
|
5
5
|
opacity: 0;
|
6
6
|
transform-origin: bottom;
|
7
|
-
|
8
|
-
left: calc(
|
7
|
+
margin-top: calc(calc(var(--spectrum-colorloupe-height, var(--spectrum-global-dimension-static-size-800)) + var(--spectrum-colorhandle-inner-border-size, var(--spectrum-global-dimension-static-size-25)) * 2) * -1 - var(--spectrum-global-dimension-static-size-200, 16px));
|
8
|
+
margin-left: calc(calc(calc(var(--spectrum-colorloupe-width, var(--spectrum-global-dimension-static-size-600)) + var(--spectrum-colorhandle-inner-border-size, var(--spectrum-global-dimension-static-size-25)) * 2) / -2));
|
9
9
|
pointer-events: none;
|
10
10
|
transition: transform .1s ease-in-out, opacity .125s ease-in-out;
|
11
11
|
position: absolute;
|
@@ -28,7 +28,7 @@
|
|
28
28
|
}
|
29
29
|
|
30
30
|
.HpWpfq_spectrum-ColorLoupe-inner-checker {
|
31
|
-
fill:
|
31
|
+
fill: #e6e6e6;
|
32
32
|
}
|
33
33
|
|
34
34
|
@media (forced-colors: active) {
|
@@ -38,4 +38,4 @@
|
|
38
38
|
--spectrum-colorloupe-outer-border-color: ButtonFace;
|
39
39
|
}
|
40
40
|
}
|
41
|
-
/*# sourceMappingURL=vars.
|
41
|
+
/*# sourceMappingURL=vars.cc682729.css.map */
|
@@ -1 +1 @@
|
|
1
|
-
{"mappings":"AAYA;;;;;;;;;;;;;
|
1
|
+
{"mappings":"AAYA;;;;;;;;;;;;;AA0BE;;;;;;AAOF;;;;;;AASA;;;;AAIA;;;;AAIA;EACE","sources":["packages/@adobe/spectrum-css-temp/components/colorloupe/vars.css"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n@import './index.css';\n@import './skin.css';\n"],"names":[],"version":3,"file":"vars.cc682729.css.map"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@react-spectrum/color",
|
3
|
-
"version": "3.0.0-nightly.
|
3
|
+
"version": "3.0.0-nightly.4582+e352bda0c",
|
4
4
|
"description": "Spectrum UI components in React",
|
5
5
|
"license": "Apache-2.0",
|
6
6
|
"main": "dist/main.js",
|
@@ -36,23 +36,29 @@
|
|
36
36
|
"url": "https://github.com/adobe/react-spectrum"
|
37
37
|
},
|
38
38
|
"dependencies": {
|
39
|
-
"@react-aria/color": "3.0.0-nightly.
|
40
|
-
"@react-aria/focus": "3.0.0-nightly.
|
41
|
-
"@react-aria/i18n": "3.0.0-nightly.
|
42
|
-
"@react-aria/interactions": "3.0.0-nightly.
|
43
|
-
"@react-aria/utils": "3.0.0-nightly.
|
44
|
-
"@react-spectrum/
|
45
|
-
"@react-spectrum/
|
46
|
-
"@react-spectrum/
|
47
|
-
"@react-spectrum/
|
48
|
-
"@react-
|
49
|
-
"@react-
|
50
|
-
"@react-
|
51
|
-
"@react-
|
52
|
-
"@
|
39
|
+
"@react-aria/color": "3.0.0-nightly.4582+e352bda0c",
|
40
|
+
"@react-aria/focus": "3.0.0-nightly.2870+e352bda0c",
|
41
|
+
"@react-aria/i18n": "3.0.0-nightly.2870+e352bda0c",
|
42
|
+
"@react-aria/interactions": "3.0.0-nightly.2870+e352bda0c",
|
43
|
+
"@react-aria/utils": "3.0.0-nightly.2870+e352bda0c",
|
44
|
+
"@react-spectrum/dialog": "3.0.0-nightly.2870+e352bda0c",
|
45
|
+
"@react-spectrum/form": "3.0.0-nightly.2870+e352bda0c",
|
46
|
+
"@react-spectrum/label": "3.16.5-nightly.4582+e352bda0c",
|
47
|
+
"@react-spectrum/overlays": "3.0.0-nightly.2870+e352bda0c",
|
48
|
+
"@react-spectrum/picker": "3.14.4-nightly.4582+e352bda0c",
|
49
|
+
"@react-spectrum/textfield": "3.0.0-nightly.2870+e352bda0c",
|
50
|
+
"@react-spectrum/utils": "3.0.0-nightly.2870+e352bda0c",
|
51
|
+
"@react-spectrum/view": "3.0.0-nightly.2870+e352bda0c",
|
52
|
+
"@react-stately/color": "3.5.4-nightly.4582+e352bda0c",
|
53
|
+
"@react-types/color": "3.0.0-nightly.4582+e352bda0c",
|
54
|
+
"@react-types/shared": "3.0.0-nightly.2870+e352bda0c",
|
55
|
+
"@react-types/textfield": "3.0.0-nightly.2870+e352bda0c",
|
56
|
+
"@swc/helpers": "^0.5.0",
|
57
|
+
"react-aria-components": "1.1.2-nightly.4582+e352bda0c"
|
53
58
|
},
|
54
59
|
"devDependencies": {
|
55
|
-
"@adobe/spectrum-css-temp": "3.0.0-nightly.
|
60
|
+
"@adobe/spectrum-css-temp": "3.0.0-nightly.2870+e352bda0c",
|
61
|
+
"@react-spectrum/style-macro-s1": "1.0.0-nightly.4582+e352bda0c"
|
56
62
|
},
|
57
63
|
"peerDependencies": {
|
58
64
|
"@react-spectrum/provider": "^3.0.0",
|
@@ -62,5 +68,5 @@
|
|
62
68
|
"publishConfig": {
|
63
69
|
"access": "public"
|
64
70
|
},
|
65
|
-
"gitHead": "
|
71
|
+
"gitHead": "e352bda0c6a25ce09950f5b6780d2a3763b02ffb"
|
66
72
|
}
|
package/src/ColorArea.tsx
CHANGED
@@ -11,6 +11,7 @@
|
|
11
11
|
*/
|
12
12
|
|
13
13
|
import {classNames, dimensionValue, useFocusableRef, useStyleProps} from '@react-spectrum/utils';
|
14
|
+
import {ColorAreaContext, useContextProps} from 'react-aria-components';
|
14
15
|
import {ColorThumb} from './ColorThumb';
|
15
16
|
import {FocusableRef} from '@react-types/shared';
|
16
17
|
import {mergeProps} from '@react-aria/utils';
|
@@ -24,20 +25,20 @@ import {useProviderProps} from '@react-spectrum/provider';
|
|
24
25
|
|
25
26
|
function ColorArea(props: SpectrumColorAreaProps, ref: FocusableRef<HTMLDivElement>) {
|
26
27
|
props = useProviderProps(props);
|
28
|
+
let inputXRef = useRef(null);
|
29
|
+
let inputYRef = useRef(null);
|
30
|
+
let containerRef = useFocusableRef(ref, inputXRef);
|
31
|
+
[props, containerRef] = useContextProps(props, containerRef, ColorAreaContext);
|
27
32
|
|
28
33
|
let {isDisabled} = props;
|
29
34
|
let size = props.size && dimensionValue(props.size);
|
30
35
|
let {styleProps} = useStyleProps(props);
|
31
36
|
|
32
|
-
let inputXRef = useRef(null);
|
33
|
-
let inputYRef = useRef(null);
|
34
|
-
let containerRef = useFocusableRef(ref, inputXRef);
|
35
37
|
|
36
38
|
let state = useColorAreaState(props);
|
37
39
|
|
38
40
|
let {
|
39
41
|
colorAreaProps,
|
40
|
-
gradientProps,
|
41
42
|
xInputProps,
|
42
43
|
yInputProps,
|
43
44
|
thumbProps
|
@@ -59,18 +60,18 @@ function ColorArea(props: SpectrumColorAreaProps, ref: FocusableRef<HTMLDivEleme
|
|
59
60
|
}
|
60
61
|
ref={containerRef}
|
61
62
|
style={{
|
62
|
-
...colorAreaProps.style,
|
63
|
+
...(isDisabled ? {} : colorAreaProps.style),
|
63
64
|
...styleProps.style,
|
64
65
|
// Workaround around https://github.com/adobe/spectrum-css/issues/1032
|
65
66
|
width: size,
|
66
67
|
height: size
|
67
68
|
}}>
|
68
|
-
<div {...gradientProps} className={classNames(styles, 'spectrum-ColorArea-gradient')} />
|
69
69
|
<ColorThumb
|
70
70
|
value={state.getDisplayColor()}
|
71
71
|
isFocused={isFocusVisible}
|
72
72
|
isDisabled={isDisabled}
|
73
73
|
isDragging={state.isDragging}
|
74
|
+
containerRef={containerRef}
|
74
75
|
className={classNames(styles, 'spectrum-ColorArea-handle')}
|
75
76
|
{...thumbProps}>
|
76
77
|
<div role="presentation">
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import {ColorArea} from './ColorArea';
|
2
|
+
import {ColorField} from './ColorField';
|
3
|
+
import {ColorSlider} from './ColorSlider';
|
4
|
+
import {ColorSpace} from '@react-types/color';
|
5
|
+
import {DOMRef} from '@react-types/shared';
|
6
|
+
import {getColorChannels} from '@react-stately/color';
|
7
|
+
// @ts-ignore
|
8
|
+
import intlMessages from '../intl/*.json';
|
9
|
+
import {Item, Picker} from '@react-spectrum/picker';
|
10
|
+
import React, {CSSProperties, useState} from 'react';
|
11
|
+
import {style} from '@react-spectrum/style-macro-s1' with {type: 'macro'};
|
12
|
+
import {useDOMRef} from '@react-spectrum/utils';
|
13
|
+
import {useLocalizedStringFormatter} from '@react-aria/i18n';
|
14
|
+
|
15
|
+
export interface SpectrumColorEditorProps {
|
16
|
+
/** Whether to hide the alpha channel color slider and color field. */
|
17
|
+
hideAlphaChannel?: boolean
|
18
|
+
}
|
19
|
+
|
20
|
+
function ColorEditor(props: SpectrumColorEditorProps, ref: DOMRef<HTMLDivElement>) {
|
21
|
+
let [format, setFormat] = useState<ColorSpace | 'hex'>('hex');
|
22
|
+
let domRef = useDOMRef(ref);
|
23
|
+
let formatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/color');
|
24
|
+
|
25
|
+
return (
|
26
|
+
<div className={style({display: 'flex', flexDirection: 'column', gap: 4})()} ref={domRef}>
|
27
|
+
<div className={style({display: 'flex', gap: 4})()}>
|
28
|
+
<ColorArea colorSpace="hsb" xChannel="saturation" yChannel="brightness" />
|
29
|
+
<ColorSlider colorSpace="hsb" channel="hue" orientation="vertical" />
|
30
|
+
{!props.hideAlphaChannel &&
|
31
|
+
<ColorSlider channel="alpha" orientation="vertical" />
|
32
|
+
}
|
33
|
+
</div>
|
34
|
+
<div className={style({display: 'flex', gap: 4})()}>
|
35
|
+
<Picker
|
36
|
+
aria-label={formatter.format('colorFormat')}
|
37
|
+
isQuiet
|
38
|
+
width="size-700"
|
39
|
+
menuWidth="size-1000"
|
40
|
+
selectedKey={format}
|
41
|
+
onSelectionChange={f => setFormat(f as typeof format)}>
|
42
|
+
<Item key="hex">{formatter.format('hex')}</Item>
|
43
|
+
<Item key="rgb">{formatter.format('rgb')}</Item>
|
44
|
+
<Item key="hsl">{formatter.format('hsl')}</Item>
|
45
|
+
<Item key="hsb">{formatter.format('hsb')}</Item>
|
46
|
+
</Picker>
|
47
|
+
{format === 'hex'
|
48
|
+
? <ColorField isQuiet width="size-1000" aria-label={formatter.format('hex')} />
|
49
|
+
: getColorChannels(format).map(channel => (
|
50
|
+
<ColorField key={channel} colorSpace={format === 'hex' ? 'rgb' : format} channel={channel} isQuiet width="size-400" flex UNSAFE_style={{'--spectrum-textfield-min-width': 0} as CSSProperties} />
|
51
|
+
))}
|
52
|
+
{!props.hideAlphaChannel &&
|
53
|
+
<ColorField channel="alpha" isQuiet width="size-400" flex UNSAFE_style={{'--spectrum-textfield-min-width': 0} as CSSProperties} />}
|
54
|
+
</div>
|
55
|
+
</div>
|
56
|
+
);
|
57
|
+
}
|
58
|
+
|
59
|
+
/**
|
60
|
+
* ColorEditor provides a default UI for editing colors within a ColorPicker.
|
61
|
+
*/
|
62
|
+
let _ColorEditor = React.forwardRef(ColorEditor);
|
63
|
+
export {_ColorEditor as ColorEditor};
|
package/src/ColorField.tsx
CHANGED
@@ -11,46 +11,99 @@
|
|
11
11
|
*/
|
12
12
|
|
13
13
|
import {classNames} from '@react-spectrum/utils';
|
14
|
+
import {ColorChannel, SpectrumColorFieldProps} from '@react-types/color';
|
15
|
+
import {ColorFieldContext, useContextProps} from 'react-aria-components';
|
14
16
|
import React, {Ref, useRef} from 'react';
|
15
|
-
import {SpectrumColorFieldProps} from '@react-types/color';
|
16
17
|
import styles from './colorfield.css';
|
17
18
|
import {TextFieldBase} from '@react-spectrum/textfield';
|
18
19
|
import {TextFieldRef} from '@react-types/textfield';
|
19
|
-
import {useColorField} from '@react-aria/color';
|
20
|
-
import {useColorFieldState} from '@react-stately/color';
|
20
|
+
import {useColorChannelField, useColorField} from '@react-aria/color';
|
21
|
+
import {useColorChannelFieldState, useColorFieldState} from '@react-stately/color';
|
21
22
|
import {useFormProps} from '@react-spectrum/form';
|
23
|
+
import {useLocale} from '@react-aria/i18n';
|
22
24
|
import {useProviderProps} from '@react-spectrum/provider';
|
23
25
|
|
24
26
|
function ColorField(props: SpectrumColorFieldProps, ref: Ref<TextFieldRef>) {
|
25
27
|
props = useProviderProps(props);
|
26
28
|
props = useFormProps(props);
|
29
|
+
[props] = useContextProps(props, null, ColorFieldContext);
|
30
|
+
if (props.placeholder) {
|
31
|
+
console.warn('Placeholders are deprecated due to accessibility issues. Please use help text instead. See the docs for details: https://react-spectrum.adobe.com/react-spectrum/ColorField.html#help-text');
|
32
|
+
}
|
33
|
+
|
34
|
+
if (props.channel) {
|
35
|
+
return <ColorChannelField {...props} channel={props.channel} forwardedRef={ref} />;
|
36
|
+
} else {
|
37
|
+
return <HexColorField {...props} forwardedRef={ref} />;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* A color field allows users to edit a hex color or individual color channel value.
|
43
|
+
*/
|
44
|
+
const _ColorField = React.forwardRef(ColorField);
|
45
|
+
export {_ColorField as ColorField};
|
46
|
+
|
47
|
+
interface ColorChannelFieldProps extends Omit<SpectrumColorFieldProps, 'channel'> {
|
48
|
+
channel: ColorChannel,
|
49
|
+
forwardedRef: Ref<TextFieldRef>
|
50
|
+
}
|
51
|
+
|
52
|
+
function ColorChannelField(props: ColorChannelFieldProps) {
|
27
53
|
let {
|
28
54
|
// These disabled props are handled by the state hook
|
29
55
|
value, // eslint-disable-line @typescript-eslint/no-unused-vars
|
30
56
|
defaultValue, // eslint-disable-line @typescript-eslint/no-unused-vars
|
31
57
|
onChange, // eslint-disable-line @typescript-eslint/no-unused-vars
|
58
|
+
validate, // eslint-disable-line @typescript-eslint/no-unused-vars
|
59
|
+
forwardedRef,
|
60
|
+
...otherProps
|
61
|
+
} = props;
|
62
|
+
let {locale} = useLocale();
|
63
|
+
let state = useColorChannelFieldState({
|
64
|
+
...props,
|
65
|
+
locale
|
66
|
+
});
|
67
|
+
|
68
|
+
let inputRef = useRef<HTMLInputElement & HTMLTextAreaElement>(null);
|
69
|
+
let result = useColorChannelField(otherProps, state, inputRef);
|
70
|
+
|
71
|
+
return (
|
72
|
+
<>
|
73
|
+
<TextFieldBase
|
74
|
+
{...otherProps}
|
75
|
+
ref={forwardedRef}
|
76
|
+
inputRef={inputRef}
|
77
|
+
{...result}
|
78
|
+
inputClassName={classNames(styles, 'react-spectrum-ColorField-input')} />
|
79
|
+
{props.name && <input type="hidden" name={props.name} value={isNaN(state.numberValue) ? '' : state.numberValue} />}
|
80
|
+
</>
|
81
|
+
);
|
82
|
+
}
|
83
|
+
|
84
|
+
interface HexColorFieldProps extends SpectrumColorFieldProps {
|
85
|
+
forwardedRef: Ref<TextFieldRef>
|
86
|
+
}
|
87
|
+
|
88
|
+
function HexColorField(props: HexColorFieldProps) {
|
89
|
+
let {
|
90
|
+
// These disabled props are handled by the state hook
|
91
|
+
value, // eslint-disable-line @typescript-eslint/no-unused-vars
|
92
|
+
defaultValue, // eslint-disable-line @typescript-eslint/no-unused-vars
|
93
|
+
onChange, // eslint-disable-line @typescript-eslint/no-unused-vars
|
94
|
+
forwardedRef,
|
32
95
|
...otherProps
|
33
96
|
} = props;
|
34
97
|
let state = useColorFieldState(props);
|
35
98
|
let inputRef = useRef<HTMLInputElement & HTMLTextAreaElement>(null);
|
36
99
|
let result = useColorField(otherProps, state, inputRef);
|
37
100
|
|
38
|
-
if (props.placeholder) {
|
39
|
-
console.warn('Placeholders are deprecated due to accessibility issues. Please use help text instead. See the docs for details: https://react-spectrum.adobe.com/react-spectrum/ColorField.html#help-text');
|
40
|
-
}
|
41
|
-
|
42
101
|
return (
|
43
102
|
<TextFieldBase
|
44
103
|
{...otherProps}
|
45
|
-
ref={
|
104
|
+
ref={forwardedRef}
|
46
105
|
inputRef={inputRef}
|
47
106
|
{...result}
|
48
107
|
inputClassName={classNames(styles, 'react-spectrum-ColorField-input')} />
|
49
108
|
);
|
50
109
|
}
|
51
|
-
|
52
|
-
/**
|
53
|
-
* ColorFields allow users to enter a color in #rrggbb hexadecimal format.
|
54
|
-
*/
|
55
|
-
const _ColorField = React.forwardRef(ColorField);
|
56
|
-
export {_ColorField as ColorField};
|
@@ -0,0 +1,122 @@
|
|
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 {ColorPicker as AriaColorPicker, Button, Color} from 'react-aria-components';
|
14
|
+
import {AriaLabelingProps, FocusableRef, ValueBase} from '@react-types/shared';
|
15
|
+
import {ColorSwatch} from './ColorSwatch';
|
16
|
+
import {Content} from '@react-spectrum/view';
|
17
|
+
import {Dialog, DialogTrigger} from '@react-spectrum/dialog';
|
18
|
+
import React, {ReactNode, useRef} from 'react';
|
19
|
+
import {style} from '@react-spectrum/style-macro-s1' with {type: 'macro'};
|
20
|
+
import {unwrapDOMRef, useFocusableRef} from '@react-spectrum/utils';
|
21
|
+
import {useId} from '@react-aria/utils';
|
22
|
+
|
23
|
+
export interface SpectrumColorPickerProps extends ValueBase<string | Color, Color>, AriaLabelingProps {
|
24
|
+
/** A visual label for the color picker. */
|
25
|
+
label?: ReactNode,
|
26
|
+
/** The contents of the color picker popover, e.g. `<ColorEditor />`. */
|
27
|
+
children?: ReactNode,
|
28
|
+
/**
|
29
|
+
* The size of the color swatch.
|
30
|
+
* @default "M"
|
31
|
+
*/
|
32
|
+
size?: 'XS' | 'S' | 'M' | 'L',
|
33
|
+
/**
|
34
|
+
* The corner rounding of the color swatch.
|
35
|
+
* @default "default"
|
36
|
+
*/
|
37
|
+
rounding?: 'default' | 'none' | 'full'
|
38
|
+
}
|
39
|
+
|
40
|
+
function ColorPicker(props: SpectrumColorPickerProps, ref: FocusableRef<HTMLButtonElement>) {
|
41
|
+
let swatchRef = useRef(null);
|
42
|
+
let domRef = useFocusableRef(ref);
|
43
|
+
let labelId = useId();
|
44
|
+
return (
|
45
|
+
<AriaColorPicker {...props}>
|
46
|
+
<DialogTrigger type="popover" mobileType="tray" targetRef={unwrapDOMRef(swatchRef)}>
|
47
|
+
<Button
|
48
|
+
ref={domRef}
|
49
|
+
className={style({
|
50
|
+
backgroundColor: 'transparent',
|
51
|
+
borderStyle: 'none',
|
52
|
+
padding: 0,
|
53
|
+
display: 'flex',
|
54
|
+
alignItems: 'center',
|
55
|
+
gap: 'text-to-control',
|
56
|
+
outlineStyle: 'none',
|
57
|
+
fontFamily: 'sans',
|
58
|
+
color: 'body',
|
59
|
+
fontSize: {
|
60
|
+
size: {
|
61
|
+
XS: 'xs',
|
62
|
+
S: 'sm',
|
63
|
+
M: 'base',
|
64
|
+
L: 'lg'
|
65
|
+
}
|
66
|
+
}
|
67
|
+
})({size: props.size || 'M'})}>
|
68
|
+
{({isFocusVisible}) => (
|
69
|
+
<>
|
70
|
+
<div
|
71
|
+
className={style({
|
72
|
+
outlineStyle: {
|
73
|
+
default: 'none',
|
74
|
+
isFocusVisible: 'solid'
|
75
|
+
},
|
76
|
+
outlineColor: 'focus-ring',
|
77
|
+
outlineWidth: 2,
|
78
|
+
outlineOffset: 2,
|
79
|
+
borderRadius: 'default'
|
80
|
+
})({isFocusVisible})}>
|
81
|
+
<ColorSwatch
|
82
|
+
ref={swatchRef}
|
83
|
+
size={props.size}
|
84
|
+
rounding={props.rounding}
|
85
|
+
aria-label={props['aria-label']}
|
86
|
+
aria-labelledby={props['aria-labelledby']}
|
87
|
+
aria-describedby={props['aria-describedby']}
|
88
|
+
aria-details={props['aria-details']} />
|
89
|
+
</div>
|
90
|
+
{props.label &&
|
91
|
+
<span id={labelId}>{props.label}</span>
|
92
|
+
}
|
93
|
+
</>
|
94
|
+
)}
|
95
|
+
</Button>
|
96
|
+
<Dialog
|
97
|
+
aria-labelledby={props.label ? labelId : props['aria-labelledby']}
|
98
|
+
aria-label={props['aria-label']}
|
99
|
+
UNSAFE_style={{
|
100
|
+
width: 'fit-content',
|
101
|
+
minWidth: 0,
|
102
|
+
margin: '0 auto' // Center within tray.
|
103
|
+
}}>
|
104
|
+
<Content
|
105
|
+
UNSAFE_style={{
|
106
|
+
position: 'relative',
|
107
|
+
margin: 'calc(var(--spectrum-dialog-padding) * -1)',
|
108
|
+
padding: 'var(--spectrum-global-dimension-size-200)'
|
109
|
+
}}>
|
110
|
+
{props.children}
|
111
|
+
</Content>
|
112
|
+
</Dialog>
|
113
|
+
</DialogTrigger>
|
114
|
+
</AriaColorPicker>
|
115
|
+
);
|
116
|
+
}
|
117
|
+
|
118
|
+
/**
|
119
|
+
* A ColorPicker combines a swatch with a customizable popover for editing a color.
|
120
|
+
*/
|
121
|
+
let _ColorPicker = React.forwardRef(ColorPicker);
|
122
|
+
export {_ColorPicker as ColorPicker};
|
package/src/ColorSlider.tsx
CHANGED
@@ -11,6 +11,7 @@
|
|
11
11
|
*/
|
12
12
|
|
13
13
|
import {classNames, SlotProvider, useFocusableRef, useStyleProps} from '@react-spectrum/utils';
|
14
|
+
import {ColorSliderContext, useContextProps} from 'react-aria-components';
|
14
15
|
import {ColorThumb} from './ColorThumb';
|
15
16
|
import {FocusableRef} from '@react-types/shared';
|
16
17
|
import {Label} from '@react-spectrum/label';
|
@@ -25,6 +26,10 @@ import {useProviderProps} from '@react-spectrum/provider';
|
|
25
26
|
|
26
27
|
function ColorSlider(props: SpectrumColorSliderProps, ref: FocusableRef<HTMLDivElement>) {
|
27
28
|
props = useProviderProps(props);
|
29
|
+
let inputRef = useRef(null);
|
30
|
+
let trackRef = useRef(null);
|
31
|
+
let domRef = useFocusableRef(ref, inputRef);
|
32
|
+
[props, domRef] = useContextProps(props, domRef, ColorSliderContext);
|
28
33
|
|
29
34
|
let {
|
30
35
|
isDisabled,
|
@@ -39,10 +44,6 @@ function ColorSlider(props: SpectrumColorSliderProps, ref: FocusableRef<HTMLDivE
|
|
39
44
|
let {styleProps} = useStyleProps(props);
|
40
45
|
let {locale} = useLocale();
|
41
46
|
|
42
|
-
let inputRef = useRef(null);
|
43
|
-
let trackRef = useRef(null);
|
44
|
-
let domRef = useFocusableRef(ref, inputRef);
|
45
|
-
|
46
47
|
let state = useColorSliderState({...props, locale});
|
47
48
|
|
48
49
|
// If vertical and a label is provided, use it as an aria-label instead.
|
@@ -126,6 +127,7 @@ function ColorSlider(props: SpectrumColorSliderProps, ref: FocusableRef<HTMLDivE
|
|
126
127
|
isFocused={isFocused && isFocusVisible}
|
127
128
|
isDisabled={isDisabled}
|
128
129
|
isDragging={state.isThumbDragging(0)}
|
130
|
+
containerRef={trackRef}
|
129
131
|
className={classNames(styles, 'spectrum-ColorSlider-handle')}
|
130
132
|
{...thumbProps}>
|
131
133
|
<input {...inputProps} {...focusProps} ref={inputRef} className={classNames(styles, 'spectrum-ColorSlider-slider')} />
|
@@ -0,0 +1,102 @@
|
|
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 {AriaColorSwatchProps, useColorSwatch} from '@react-aria/color';
|
14
|
+
import {Color} from '@react-types/color';
|
15
|
+
import {ColorSwatchContext, useContextProps} from 'react-aria-components';
|
16
|
+
import {DOMRef, StyleProps} from '@react-types/shared';
|
17
|
+
import React, {createContext, forwardRef, JSX, ReactElement, useContext} from 'react';
|
18
|
+
import {style} from '@react-spectrum/style-macro-s1' with {type: 'macro'};
|
19
|
+
import {useDOMRef, useStyleProps} from '@react-spectrum/utils';
|
20
|
+
|
21
|
+
export interface SpectrumColorSwatchProps extends AriaColorSwatchProps, StyleProps {
|
22
|
+
/**
|
23
|
+
* The size of the ColorSwatch.
|
24
|
+
* @default "M"
|
25
|
+
*/
|
26
|
+
size?: 'XS' | 'S' | 'M' | 'L',
|
27
|
+
/**
|
28
|
+
* The corner rounding of the ColorSwatch.
|
29
|
+
* @default "default"
|
30
|
+
*/
|
31
|
+
rounding?: 'default' | 'none' | 'full'
|
32
|
+
}
|
33
|
+
|
34
|
+
interface SpectrumColorSwatchContextValue extends Pick<SpectrumColorSwatchProps, 'size' | 'rounding'> {
|
35
|
+
useWrapper: (swatch: ReactElement, color: Color, rounding: SpectrumColorSwatchProps['rounding']) => JSX.Element
|
36
|
+
}
|
37
|
+
|
38
|
+
export const SpectrumColorSwatchContext = createContext<SpectrumColorSwatchContextValue | null>(null);
|
39
|
+
|
40
|
+
function ColorSwatch(props: SpectrumColorSwatchProps, ref: DOMRef<HTMLDivElement>): JSX.Element {
|
41
|
+
let domRef = useDOMRef(ref);
|
42
|
+
[props, domRef] = useContextProps(props, domRef, ColorSwatchContext);
|
43
|
+
let {colorSwatchProps, color} = useColorSwatch(props);
|
44
|
+
let {styleProps} = useStyleProps(props);
|
45
|
+
let ctx = useContext(SpectrumColorSwatchContext);
|
46
|
+
let {
|
47
|
+
size = ctx?.size || 'M',
|
48
|
+
rounding = ctx?.rounding || 'default'
|
49
|
+
} = props;
|
50
|
+
|
51
|
+
let swatch = (
|
52
|
+
<div
|
53
|
+
{...colorSwatchProps}
|
54
|
+
{...styleProps}
|
55
|
+
ref={domRef}
|
56
|
+
style={{
|
57
|
+
...styleProps.style,
|
58
|
+
// TODO: should there be a distinction between transparent and no value (e.g. null)?
|
59
|
+
background: color.getChannelValue('alpha') > 0
|
60
|
+
? `linear-gradient(${color}, ${color}), repeating-conic-gradient(#e6e6e6 0% 25%, white 0% 50%) 0% 50% / 16px 16px`
|
61
|
+
// Red slash to indicate there is no selected color.
|
62
|
+
: 'linear-gradient(to bottom right, transparent calc(50% - 2px), var(--spectrum-red-900) calc(50% - 2px) calc(50% + 2px), transparent calc(50% + 2px)) no-repeat'
|
63
|
+
}}
|
64
|
+
className={style({
|
65
|
+
size: {
|
66
|
+
size: {
|
67
|
+
XS: 4,
|
68
|
+
S: 6,
|
69
|
+
M: 8,
|
70
|
+
L: 10
|
71
|
+
}
|
72
|
+
},
|
73
|
+
borderRadius: {
|
74
|
+
rounding: {
|
75
|
+
default: 'default',
|
76
|
+
none: 'none',
|
77
|
+
full: 'full'
|
78
|
+
}
|
79
|
+
},
|
80
|
+
// Trick to create a partially transparent color from a variable.
|
81
|
+
// Ideally we'd use relative color syntax for this but it's not in Firefox yet.
|
82
|
+
borderColor: '[color-mix(in srgb, var(--spectrum-gray-900), transparent 49%)]',
|
83
|
+
borderWidth: 1,
|
84
|
+
borderStyle: 'solid',
|
85
|
+
boxSizing: 'border-box',
|
86
|
+
forcedColorAdjust: 'none'
|
87
|
+
})({size, rounding})} />
|
88
|
+
);
|
89
|
+
|
90
|
+
// ColorSwatchPicker needs to wrap the swatch in a ListBoxItem.
|
91
|
+
if (ctx) {
|
92
|
+
return ctx.useWrapper(swatch, color, rounding);
|
93
|
+
}
|
94
|
+
|
95
|
+
return swatch;
|
96
|
+
}
|
97
|
+
|
98
|
+
/**
|
99
|
+
* A ColorSwatch displays a preview of a selected color.
|
100
|
+
*/
|
101
|
+
let _ColorSwatch = forwardRef(ColorSwatch);
|
102
|
+
export {_ColorSwatch as ColorSwatch};
|