-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Feat] add color picker to single color selector (#2699)
* [Feat] add color picker to single color selector Signed-off-by: Ihor Dykhta <[email protected]>
- Loading branch information
1 parent
b258e8a
commit 2d8161e
Showing
7 changed files
with
198 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
src/components/src/side-panel/layer-panel/color-palette-preset.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// SPDX-License-Identifier: MIT | ||
// Copyright contributors to the kepler.gl project | ||
|
||
import React from 'react'; | ||
import styled from 'styled-components'; | ||
import {range} from 'd3-array'; | ||
|
||
import {ColorsByTheme} from '@kepler.gl/constants'; | ||
import {HexColor} from '@kepler.gl/types'; | ||
|
||
const PALETTE_HEIGHT = '8px'; | ||
const ROWS = 22; | ||
|
||
const StyledColorPalette = styled.div` | ||
display: flex; | ||
flex-direction: row; | ||
justify-content: space-between; | ||
padding: 12px; | ||
:hover { | ||
cursor: pointer; | ||
} | ||
`; | ||
|
||
const StyledColorColumn = styled.div` | ||
display: flex; | ||
flex-grow: 1; | ||
flex-direction: column; | ||
justify-content: space-between; | ||
`; | ||
|
||
type StyledColorBlockProps = { | ||
selected?: boolean; | ||
}; | ||
|
||
const StyledColorBlock = styled.div<StyledColorBlockProps>` | ||
flex-grow: 1; | ||
height: ${PALETTE_HEIGHT}; | ||
border-width: 1px; | ||
border-style: solid; | ||
`; | ||
|
||
export type PresetColorPaletteProps = { | ||
themes: string[]; | ||
selectedColor: HexColor; | ||
onSelectColor: (c: HexColor, e?: React.MouseEvent<HTMLDivElement, MouseEvent>) => void; | ||
}; | ||
|
||
const PresetColorPalette: React.FC<PresetColorPaletteProps> = ({ | ||
themes, | ||
onSelectColor, | ||
selectedColor | ||
}: PresetColorPaletteProps) => ( | ||
<StyledColorPalette> | ||
{themes.map(theme => ( | ||
<StyledColorColumn key={theme} className="single-color-palette__column"> | ||
{range(1, ROWS + 1, 1).map((key, i) => ( | ||
<StyledColorBlock | ||
className="single-color-palette__block" | ||
style={{ | ||
backgroundColor: ColorsByTheme[theme][key], | ||
borderColor: | ||
selectedColor === ColorsByTheme[theme][key].toUpperCase() | ||
? 'white' | ||
: ColorsByTheme[theme][key] | ||
}} | ||
key={`${theme}_${key}`} | ||
selected={selectedColor === ColorsByTheme[theme][key].toUpperCase()} | ||
onClick={e => onSelectColor(ColorsByTheme[theme][key], e)} | ||
/> | ||
))} | ||
</StyledColorColumn> | ||
))} | ||
</StyledColorPalette> | ||
); | ||
|
||
export default PresetColorPalette; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 76 additions & 51 deletions
127
src/components/src/side-panel/layer-panel/single-color-palette.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,95 @@ | ||
// SPDX-License-Identifier: MIT | ||
// Copyright contributors to the kepler.gl project | ||
|
||
import React, {MouseEvent} from 'react'; | ||
import {range} from 'd3-array'; | ||
import React, {MouseEvent, useCallback, useState} from 'react'; | ||
import styled from 'styled-components'; | ||
import classnames from 'classnames'; | ||
|
||
import {hexToRgb} from '@kepler.gl/utils'; | ||
import {FormattedMessage} from '@kepler.gl/localization'; | ||
import {Themes, ColorRange} from '@kepler.gl/constants'; | ||
import {RGBColor, HexColor} from '@kepler.gl/types'; | ||
|
||
import CustomPicker from './custom-picker'; | ||
import PresetColorPalette from './color-palette-preset'; | ||
|
||
import {ColorsByTheme, Themes, ColorRange} from '@kepler.gl/constants'; | ||
import {RGBColor} from '@kepler.gl/types'; | ||
const MODE = { | ||
preset: 'preset', | ||
picker: 'picker' | ||
}; | ||
|
||
export type SingleColorPaletteProps = { | ||
selectedColor: HexColor; | ||
onSelectColor: (color: RGBColor | ColorRange, e: MouseEvent) => void; | ||
// hex value | ||
selectedColor: string; | ||
}; | ||
|
||
const PALETTE_HEIGHT = '8px'; | ||
const ROWS = 22; | ||
|
||
const StyledColorPalette = styled.div` | ||
const StyledColorPickerTop = styled.div` | ||
border-bottom: 1px solid ${({theme}) => theme.dropdownListBorderTop}; | ||
display: flex; | ||
flex-direction: row; | ||
justify-content: space-between; | ||
padding: 12px; | ||
:hover { | ||
cursor: pointer; | ||
padding-top: 2px 4px 0 4px; | ||
.color-palette-tab { | ||
padding: 8px 0; | ||
margin: 0 8px; | ||
color: ${({theme}) => theme.subtextColor}; | ||
border-bottom: 2px; | ||
border-bottom-style: solid; | ||
border-bottom-color: transparent; | ||
&.active { | ||
color: ${({theme}) => theme.textColorHl}; | ||
border-bottom-color: ${({theme}) => theme.panelToggleBorderColor}; | ||
} | ||
:hover { | ||
cursor: pointer; | ||
color: ${props => props.theme.textColorHl}; | ||
} | ||
} | ||
`; | ||
|
||
const StyledColorColumn = styled.div` | ||
display: flex; | ||
flex-grow: 1; | ||
flex-direction: column; | ||
justify-content: space-between; | ||
`; | ||
|
||
const StyledColorBlock = styled.div<{selected: boolean}>` | ||
flex-grow: 1; | ||
height: ${PALETTE_HEIGHT}; | ||
border-width: 1px; | ||
border-style: solid; | ||
`; | ||
|
||
const SingleColorPalette: React.FC<SingleColorPaletteProps> = ({selectedColor, onSelectColor}) => ( | ||
<StyledColorPalette className="single-color-palette"> | ||
{Themes.map(theme => ( | ||
<StyledColorColumn key={theme} className="single-color-palette__column"> | ||
{range(1, ROWS + 1, 1).map(key => ( | ||
<StyledColorBlock | ||
className="single-color-palette__block" | ||
style={{ | ||
backgroundColor: ColorsByTheme[theme][key], | ||
borderColor: | ||
selectedColor === ColorsByTheme[theme][key].toUpperCase() | ||
? 'white' | ||
: ColorsByTheme[theme][key] | ||
}} | ||
key={`${theme}_${key}`} | ||
selected={selectedColor === ColorsByTheme[theme][key].toUpperCase()} | ||
onClick={e => onSelectColor(hexToRgb(ColorsByTheme[theme][key]), e)} | ||
/> | ||
))} | ||
</StyledColorColumn> | ||
const ColorPickerTop = ({setMode, mode}) => ( | ||
<StyledColorPickerTop> | ||
{Object.keys(MODE).map(modeId => ( | ||
<div | ||
onClick={() => setMode(modeId)} | ||
key={modeId} | ||
className={classnames('color-palette-tab', {active: mode === modeId})} | ||
> | ||
<FormattedMessage id={`color.${modeId}`} /> | ||
</div> | ||
))} | ||
</StyledColorPalette> | ||
</StyledColorPickerTop> | ||
); | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-empty-function | ||
const nop = () => {}; | ||
|
||
const SingleColorPalette: React.FC<SingleColorPaletteProps> = ({ | ||
selectedColor, | ||
onSelectColor | ||
}: SingleColorPaletteProps) => { | ||
const [mode, setMode] = useState(MODE.preset); | ||
const onSetColor = useCallback( | ||
(color, e) => { | ||
// color picker return an object, with color.hex | ||
const hex = color.hex || color; | ||
onSelectColor(hexToRgb(hex), e); | ||
}, | ||
[onSelectColor] | ||
); | ||
return ( | ||
<div className="single-color-palette"> | ||
<ColorPickerTop mode={mode} setMode={setMode} /> | ||
{mode === MODE.preset ? ( | ||
<PresetColorPalette | ||
themes={Themes} | ||
onSelectColor={onSetColor} | ||
selectedColor={selectedColor} | ||
/> | ||
) : null} | ||
{mode === MODE.picker ? ( | ||
<CustomPicker color={selectedColor} onChange={onSetColor} onSwatchClose={nop} /> | ||
) : null} | ||
</div> | ||
); | ||
}; | ||
|
||
export default SingleColorPalette; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters