|
| 1 | +/* |
| 2 | + * Copyright 2022 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 {ColorArea, ColorField, ColorSlider, ColorWheel} from '../'; |
| 14 | +import {Flex} from '@adobe/react-spectrum'; |
| 15 | +import {Meta, Story} from '@storybook/react'; |
| 16 | +import {parseColor} from '@react-stately/color'; |
| 17 | +import React, {useState} from 'react'; |
| 18 | +import {SpectrumColorAreaProps} from '@react-types/color'; |
| 19 | + |
| 20 | + |
| 21 | +const meta: Meta<SpectrumColorAreaProps> = { |
| 22 | + title: 'ColorArea', |
| 23 | + component: ColorArea |
| 24 | +}; |
| 25 | + |
| 26 | +export default meta; |
| 27 | + |
| 28 | +const Template: Story<SpectrumColorAreaProps> = (args) => ( |
| 29 | + <ColorAreaExample {...args} /> |
| 30 | +); |
| 31 | + |
| 32 | +function ColorAreaExample(props: SpectrumColorAreaProps) { |
| 33 | + let {xChannel, yChannel, isDisabled} = props; |
| 34 | + let defaultValue = typeof props.defaultValue === 'string' ? parseColor(props.defaultValue) : props.defaultValue; |
| 35 | + let [color, setColor] = useState(defaultValue || parseColor('#ff00ff')); |
| 36 | + let xyChannels = {xChannel, yChannel}; |
| 37 | + let colorSpace = color.getColorSpace(); |
| 38 | + let {zChannel} = color.getColorSpaceAxes(xyChannels); |
| 39 | + let isHue = zChannel === 'hue'; |
| 40 | + |
| 41 | + function onChange(e) { |
| 42 | + const newColor = (e || color).toFormat(colorSpace); |
| 43 | + if (props.onChange) { |
| 44 | + props.onChange(newColor); |
| 45 | + } |
| 46 | + setColor(newColor); |
| 47 | + } |
| 48 | + |
| 49 | + return ( |
| 50 | + <div role="group" aria-label={`${colorSpace.toUpperCase()} Color Picker`}> |
| 51 | + <Flex gap="size-500" alignItems="start"> |
| 52 | + <Flex direction="column" gap={isHue ? 0 : 'size-50'} alignItems="center"> |
| 53 | + <ColorArea |
| 54 | + size={isHue ? 'size-1200' : null} |
| 55 | + {...props} |
| 56 | + value={color} |
| 57 | + onChange={onChange} |
| 58 | + onChangeEnd={props.onChangeEnd} /> |
| 59 | + {isHue ? ( |
| 60 | + <ColorWheel |
| 61 | + value={color} |
| 62 | + onChange={onChange} |
| 63 | + onChangeEnd={props.onChangeEnd} |
| 64 | + isDisabled={isDisabled} |
| 65 | + size={'size-2400'} |
| 66 | + UNSAFE_style={{ |
| 67 | + marginTop: 'calc( -.75 * var(--spectrum-global-dimension-size-2400))' |
| 68 | + }} /> |
| 69 | + ) : ( |
| 70 | + <ColorSlider |
| 71 | + value={color} |
| 72 | + onChange={onChange} |
| 73 | + onChangeEnd={props.onChangeEnd} |
| 74 | + channel={zChannel} |
| 75 | + isDisabled={isDisabled} /> |
| 76 | + )} |
| 77 | + </Flex> |
| 78 | + <Flex direction="column" alignItems="center" gap="size-100" minWidth="size-1200"> |
| 79 | + <div |
| 80 | + role="img" |
| 81 | + aria-label={`color swatch: ${color.toString('rgb')}`} |
| 82 | + title={`${color.toString('hex')}`} |
| 83 | + style={{width: '96px', height: '96px', background: color.toString('css')}} /> |
| 84 | + <ColorField |
| 85 | + label="HEX Color" |
| 86 | + value={color} |
| 87 | + onChange={onChange} |
| 88 | + onKeyDown={event => |
| 89 | + event.key === 'Enter' && |
| 90 | + onChange((event.target as HTMLInputElement).value) |
| 91 | + } |
| 92 | + isDisabled={isDisabled} |
| 93 | + width="size-1200" /> |
| 94 | + </Flex> |
| 95 | + </Flex> |
| 96 | + </div> |
| 97 | + ); |
| 98 | +} |
| 99 | + |
| 100 | +export let XBlueYGreen = Template.bind({}); |
| 101 | +XBlueYGreen.storyName = 'RGB xChannel="blue", yChannel="green"'; |
| 102 | +XBlueYGreen.args = {xChannel: 'blue', yChannel: 'green'}; |
| 103 | + |
| 104 | +export let XGreenYBlue = Template.bind({}); |
| 105 | +XGreenYBlue.storyName = 'RGB xChannel="green", yChannel="blue"'; |
| 106 | +XGreenYBlue.args = {...XBlueYGreen.args, xChannel: 'green', yChannel: 'blue'}; |
| 107 | + |
| 108 | +export let XBlueYRed = Template.bind({}); |
| 109 | +XBlueYRed.storyName = 'RGB xChannel="blue", yChannel="red"'; |
| 110 | +XBlueYRed.args = {...XBlueYGreen.args, xChannel: 'blue', yChannel: 'red'}; |
| 111 | + |
| 112 | +export let XRedYBlue = Template.bind({}); |
| 113 | +XRedYBlue.storyName = 'RGB xChannel="red", yChannel="blue"'; |
| 114 | +XRedYBlue.args = {...XBlueYGreen.args, xChannel: 'red', yChannel: 'blue'}; |
| 115 | + |
| 116 | +export let XRedYGreen = Template.bind({}); |
| 117 | +XRedYGreen.storyName = 'RGB xChannel="red", yChannel="green"'; |
| 118 | +XRedYGreen.args = {...XBlueYGreen.args, xChannel: 'red', yChannel: 'green'}; |
| 119 | + |
| 120 | +export let XGreenYRed = Template.bind({}); |
| 121 | +XGreenYRed.storyName = 'RGB xChannel="green", yChannel="red"'; |
| 122 | +XGreenYRed.args = {...XBlueYGreen.args, xChannel: 'green', yChannel: 'red'}; |
| 123 | + |
| 124 | +export let XBlueYGreenisDisabled = Template.bind({}); |
| 125 | +XBlueYGreenisDisabled.storyName = 'RGB xChannel="blue", yChannel="green", isDisabled'; |
| 126 | +XBlueYGreenisDisabled.args = {...XBlueYGreen.args, isDisabled: true}; |
| 127 | + |
| 128 | +export let XBlueYGreenSize3000 = Template.bind({}); |
| 129 | +XBlueYGreenSize3000.storyName = 'RGB xChannel="blue", yChannel="green", size="size-3000"'; |
| 130 | +XBlueYGreenSize3000.args = {...XBlueYGreen.args, size: 'size-3000'}; |
| 131 | + |
| 132 | +export let XBlueYGreenSize600 = Template.bind({}); |
| 133 | +XBlueYGreenSize600.storyName = 'RGB xChannel="blue", yChannel="green", size="size-600"'; |
| 134 | +XBlueYGreenSize600.args = {...XBlueYGreen.args, size: 'size-600'}; |
| 135 | + |
| 136 | +export let XSaturationYLightness = Template.bind({}); |
| 137 | +XSaturationYLightness.storyName = 'HSL xChannel="saturation", yChannel="lightness"'; |
| 138 | +XSaturationYLightness.args = {...XBlueYGreen.args, xChannel: 'saturation', yChannel: 'lightness', defaultValue: 'hsl(0, 100%, 50%)'}; |
| 139 | + |
| 140 | +export let XLightnessYSaturation = Template.bind({}); |
| 141 | +XLightnessYSaturation.storyName = 'HSL xChannel="lightness", yChannel="saturation"'; |
| 142 | +XLightnessYSaturation.args = {...XBlueYGreen.args, xChannel: 'lightness', yChannel: 'saturation', defaultValue: 'hsl(0, 100%, 50%)'}; |
| 143 | + |
| 144 | +export let XHueYSaturationHSL = Template.bind({}); |
| 145 | +XHueYSaturationHSL.storyName = 'HSL xChannel="hue", yChannel="saturation"'; |
| 146 | +XHueYSaturationHSL.args = {...XSaturationYLightness.args, xChannel: 'hue', yChannel: 'saturation', defaultValue: 'hsl(0, 100%, 50%)'}; |
| 147 | + |
| 148 | +export let XSaturationYHueHSL = Template.bind({}); |
| 149 | +XSaturationYHueHSL.storyName = 'HSL xChannel="saturation", yChannel="hue"'; |
| 150 | +XSaturationYHueHSL.args = {...XSaturationYLightness.args, xChannel: 'saturation', yChannel: 'hue', defaultValue: 'hsl(0, 100%, 50%)'}; |
| 151 | + |
| 152 | +export let XHueYLightnessHSL = Template.bind({}); |
| 153 | +XHueYLightnessHSL.storyName = 'HSL xChannel="hue", yChannel="lightness"'; |
| 154 | +XHueYLightnessHSL.args = {...XHueYSaturationHSL.args, xChannel: 'hue', yChannel: 'lightness', defaultValue: 'hsl(0, 100%, 50%)'}; |
| 155 | + |
| 156 | +export let XLightnessYHueHSL = Template.bind({}); |
| 157 | +XLightnessYHueHSL.storyName = 'HSL xChannel="lightness", yChannel="hue"'; |
| 158 | +XLightnessYHueHSL.args = {...XHueYSaturationHSL.args, xChannel: 'lightness', yChannel: 'hue', defaultValue: 'hsl(0, 100%, 50%)'}; |
| 159 | + |
| 160 | +export let XSaturationYBrightness = Template.bind({}); |
| 161 | +XSaturationYBrightness.storyName = 'HSB xChannel="saturation", yChannel="brightness"'; |
| 162 | +XSaturationYBrightness.args = {...XHueYSaturationHSL.args, xChannel: 'saturation', yChannel: 'brightness', defaultValue: 'hsb(0, 100%, 100%)'}; |
| 163 | + |
| 164 | +export let XBrightnessYSaturation = Template.bind({}); |
| 165 | +XBrightnessYSaturation.storyName = 'HSB xChannel="brightness", yChannel="saturation"'; |
| 166 | +XBrightnessYSaturation.args = {...XHueYSaturationHSL.args, xChannel: 'brightness', yChannel: 'saturation', defaultValue: 'hsb(0, 100%, 100%)'}; |
| 167 | + |
| 168 | +export let XSaturationYBrightnessisDisabled = Template.bind({}); |
| 169 | +XSaturationYBrightnessisDisabled.storyName = 'HSB xChannel="saturation", yChannel="brightness", isDisabled'; |
| 170 | +XSaturationYBrightnessisDisabled.args = {...XSaturationYBrightness.args, isDisabled: true}; |
| 171 | + |
| 172 | +export let XHueYSaturationHSB = Template.bind({}); |
| 173 | +XHueYSaturationHSB.storyName = 'HSB xChannel="hue", yChannel="saturation"'; |
| 174 | +XHueYSaturationHSB.args = {...XSaturationYBrightness.args, xChannel: 'hue', yChannel: 'saturation', defaultValue: 'hsb(0, 100%, 100%)'}; |
| 175 | + |
| 176 | +export let XSaturationYHueHSB = Template.bind({}); |
| 177 | +XSaturationYHueHSB.storyName = 'HSB xChannel="saturation", yChannel="hue"'; |
| 178 | +XSaturationYHueHSB.args = {...XSaturationYBrightness.args, xChannel: 'saturation', yChannel: 'hue', defaultValue: 'hsb(0, 100%, 100%)'}; |
| 179 | + |
| 180 | +export let XHueYBrightnessHSB = Template.bind({}); |
| 181 | +XHueYBrightnessHSB.storyName = 'HSB xChannel="hue", yChannel="brightness"'; |
| 182 | +XHueYBrightnessHSB.args = {...XHueYSaturationHSB.args, xChannel: 'hue', yChannel: 'brightness', defaultValue: 'hsb(0, 100%, 100%)'}; |
| 183 | + |
| 184 | +export let XBrightnessYHueHSB = Template.bind({}); |
| 185 | +XBrightnessYHueHSB.storyName = 'HSB xChannel="brightness", yChannel="hue"'; |
| 186 | +XBrightnessYHueHSB.args = {...XHueYSaturationHSB.args, xChannel: 'brightness', yChannel: 'hue', defaultValue: 'hsb(0, 100%, 100%)'}; |
0 commit comments