forked from decaporg/decap-cms
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(widget-color): add color widget (decaporg#4437)
- Loading branch information
Showing
12 changed files
with
324 additions
and
1 deletion.
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
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
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,4 @@ | ||
# Change Log | ||
|
||
All notable changes to this project will be documented in this file. | ||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. |
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,11 @@ | ||
# Docs coming soon! | ||
|
||
Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. | ||
That's over 20 Readme's! We haven't created one for this package yet, but we will soon. | ||
|
||
In the meantime, you can: | ||
|
||
1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation | ||
site](https://www.netlifycms.org) for more info. | ||
2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. | ||
3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-string/README.md)! |
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,34 @@ | ||
{ | ||
"name": "netlify-cms-widget-color", | ||
"description": "Widget for editing color strings in Netlify CMS.", | ||
"version": "1.0.0", | ||
"homepage": "https://www.netlifycms.org/docs/widgets/#color", | ||
"repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-color", | ||
"bugs": "https://github.com/netlify/netlify-cms/issues", | ||
"module": "dist/esm/index.js", | ||
"main": "dist/netlify-cms-widget-color.js", | ||
"license": "MIT", | ||
"keywords": [ | ||
"netlify", | ||
"netlify-cms", | ||
"widget", | ||
"color" | ||
], | ||
"sideEffects": false, | ||
"scripts": { | ||
"develop": "yarn build:esm --watch", | ||
"build": "cross-env NODE_ENV=production webpack", | ||
"build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" | ||
}, | ||
"dependencies": { | ||
"react-color": "^2.18.1", | ||
"validate-color": "^2.1.0" | ||
}, | ||
"peerDependencies": { | ||
"@emotion/core": "^10.0.35", | ||
"@emotion/styled": "^10.0.27", | ||
"netlify-cms-ui-default": "^2.6.0", | ||
"prop-types": "^15.7.2", | ||
"react": "^16.8.4" | ||
} | ||
} |
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,176 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import styled from '@emotion/styled'; | ||
import ChromePicker from 'react-color'; | ||
import validateColor from 'validate-color'; | ||
import { zIndex } from 'netlify-cms-ui-default'; | ||
|
||
const ClearIcon = () => ( | ||
<svg height="20" width="20" viewBox="0 0 20 20" aria-hidden="true" focusable="false"> | ||
<path | ||
fill="rgb(122, 130, 145)" | ||
d="M14.348 14.849c-0.469 0.469-1.229 0.469-1.697 0l-2.651-3.030-2.651 3.029c-0.469 0.469-1.229 0.469-1.697 0-0.469-0.469-0.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-0.469-0.469-0.469-1.228 0-1.697s1.228-0.469 1.697 0l2.652 3.031 2.651-3.031c0.469-0.469 1.228-0.469 1.697 0s0.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c0.469 0.469 0.469 1.229 0 1.698z" | ||
></path> | ||
</svg> | ||
); | ||
|
||
const ClearButton = styled.div` | ||
position: absolute; | ||
right: 6px; | ||
z-index: ${zIndex.zIndex1000}; | ||
padding: 8px; | ||
margin-top: 11px; | ||
`; | ||
|
||
const ClearButtonWrapper = styled.div` | ||
position: relative; | ||
width: 100%; | ||
`; | ||
|
||
// color swatch background with checkerboard to display behind transparent colors | ||
const ColorSwatchBackground = styled.div` | ||
position: absolute; | ||
z-index: ${zIndex.zIndex1}; | ||
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg=='); | ||
height: 38px; | ||
width: 48px; | ||
margin-top: 10px; | ||
margin-left: 10px; | ||
border-radius: 5px; | ||
`; | ||
|
||
const ColorSwatch = styled.div` | ||
position: absolute; | ||
z-index: ${zIndex.zIndex2}; | ||
background: ${props => props.background}; | ||
cursor: pointer; | ||
height: 38px; | ||
width: 48px; | ||
margin-top: 10px; | ||
margin-left: 10px; | ||
border-radius: 5px; | ||
border: 2px solid rgb(223, 223, 227); | ||
text-align: center; | ||
font-size: 27px; | ||
line-height: 1; | ||
padding-top: 4px; | ||
user-select: none; | ||
color: ${props => props.color}; | ||
`; | ||
|
||
const ColorPickerContainer = styled.div` | ||
position: absolute; | ||
z-index: ${zIndex.zIndex1000}; | ||
margin-top: 48px; | ||
margin-left: 12px; | ||
`; | ||
|
||
// fullscreen div to close color picker when clicking outside of picker | ||
const ClickOutsideDiv = styled.div` | ||
position: fixed; | ||
top: 0px; | ||
right: 0px; | ||
bottom: 0px; | ||
left: 0px; | ||
`; | ||
|
||
export default class ColorControl extends React.Component { | ||
static propTypes = { | ||
onChange: PropTypes.func.isRequired, | ||
forID: PropTypes.string, | ||
value: PropTypes.node, | ||
classNameWrapper: PropTypes.string.isRequired, | ||
setActiveStyle: PropTypes.func.isRequired, | ||
setInactiveStyle: PropTypes.func.isRequired, | ||
}; | ||
|
||
static defaultProps = { | ||
value: '', | ||
}; | ||
|
||
state = { | ||
showColorPicker: false, | ||
}; | ||
// show/hide color picker | ||
handleClick = () => { | ||
this.setState({ showColorPicker: !this.state.showColorPicker }); | ||
}; | ||
handleClear = () => { | ||
this.props.onChange(''); | ||
}; | ||
handleClose = () => { | ||
this.setState({ showColorPicker: false }); | ||
}; | ||
handleChange = color => { | ||
const formattedColor = | ||
color.rgb.a < 1 | ||
? `rgba(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b}, ${color.rgb.a})` | ||
: color.hex; | ||
this.props.onChange(formattedColor); | ||
}; | ||
render() { | ||
const { | ||
forID, | ||
value, | ||
field, | ||
onChange, | ||
classNameWrapper, | ||
setActiveStyle, | ||
setInactiveStyle, | ||
} = this.props; | ||
|
||
const allowInput = field.get('allowInput', false); | ||
|
||
// clear button is not displayed if allowInput: true | ||
const showClearButton = !allowInput && value; | ||
|
||
return ( | ||
<> | ||
{' '} | ||
{showClearButton && ( | ||
<ClearButtonWrapper> | ||
<ClearButton onClick={this.handleClear}> | ||
<ClearIcon /> | ||
</ClearButton> | ||
</ClearButtonWrapper> | ||
)} | ||
<ColorSwatchBackground /> | ||
<ColorSwatch | ||
background={validateColor(this.props.value) ? this.props.value : '#fff'} | ||
color={validateColor(this.props.value) ? 'rgba(255, 255, 255, 0)' : 'rgb(223, 223, 227)'} | ||
onClick={this.handleClick} | ||
> | ||
? | ||
</ColorSwatch> | ||
{this.state.showColorPicker && ( | ||
<ColorPickerContainer> | ||
<ClickOutsideDiv onClick={this.handleClose} /> | ||
<ChromePicker | ||
color={value || ''} | ||
onChange={this.handleChange} | ||
disableAlpha={!field.get('enableAlpha', false)} | ||
/> | ||
</ColorPickerContainer> | ||
)} | ||
<input | ||
// text input with padding left for the color swatch | ||
type="text" | ||
id={forID} | ||
className={classNameWrapper} | ||
value={value || ''} | ||
onChange={e => onChange(e.target.value)} | ||
onFocus={setActiveStyle} | ||
onBlur={setInactiveStyle} | ||
style={{ | ||
paddingLeft: '75px', | ||
paddingRight: '70px', | ||
color: !allowInput && '#bbb', | ||
}} | ||
// make readonly and open color picker on click if set to allowInput: false | ||
onClick={!allowInput ? this.handleClick : undefined} | ||
readOnly={!allowInput} | ||
/> | ||
</> | ||
); | ||
} | ||
} |
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,11 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; | ||
|
||
const ColorPreview = ({ value }) => <WidgetPreviewContainer>{value}</WidgetPreviewContainer>; | ||
|
||
ColorPreview.propTypes = { | ||
value: PropTypes.node, | ||
}; | ||
|
||
export default ColorPreview; |
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,12 @@ | ||
import controlComponent from './ColorControl'; | ||
import previewComponent from './ColorPreview'; | ||
|
||
const Widget = (opts = {}) => ({ | ||
name: 'color', | ||
controlComponent, | ||
previewComponent, | ||
...opts, | ||
}); | ||
|
||
export const NetlifyCmsWidgetColor = { Widget, controlComponent, previewComponent }; | ||
export default NetlifyCmsWidgetColor; |
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,3 @@ | ||
const { getConfig } = require('../../scripts/webpack.js'); | ||
|
||
module.exports = getConfig(); |
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,22 @@ | ||
--- | ||
label: 'Color' | ||
title: color | ||
--- | ||
|
||
The color widget translates a color picker to a color string. | ||
|
||
- **Name:** `color` | ||
- **UI:** color picker | ||
- **Data type:** string | ||
- **Options:** | ||
- `default`: accepts a string; defaults to an empty string. Sets the default value | ||
- `allowInput`: accepts a boolean, defaults to `false`. Allows manual editing of the color input value | ||
- `enableAlpha`: accepts a boolean, defaults to `false`. Enables Alpha editing | ||
- **Example:** | ||
```yaml | ||
- { label: 'Color', name: 'color', widget: 'color' } | ||
``` | ||
- **Example:** | ||
```yaml | ||
- { label: 'Color', name: 'color', widget: 'color', enableAlpha: true, allowInput: true } | ||
``` |
Oops, something went wrong.