add-cms
This commit is contained in:
225
source/admin/packages/decap-cms-widget-number/CHANGELOG.md
Normal file
225
source/admin/packages/decap-cms-widget-number/CHANGELOG.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [3.2.0](https://github.com/decaporg/decap-cms/compare/decap-cms-widget-number@3.1.3...decap-cms-widget-number@3.2.0) (2025-06-26)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
## [3.1.3](https://github.com/decaporg/decap-cms/compare/decap-cms-widget-number@3.1.2...decap-cms-widget-number@3.1.3) (2024-08-13)
|
||||
|
||||
### Reverts
|
||||
|
||||
- Revert "Update dependencies (#7264)" ([22d483a](https://github.com/decaporg/decap-cms/commit/22d483a5b0c654071ae05735ac4f49abdc13d38c)), closes [#7264](https://github.com/decaporg/decap-cms/issues/7264)
|
||||
|
||||
## [3.1.2](https://github.com/decaporg/decap-cms/compare/decap-cms-widget-number@3.1.1...decap-cms-widget-number@3.1.2) (2024-08-13)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
## [3.1.1](https://github.com/decaporg/decap-cms/compare/decap-cms-widget-number@3.1.0-beta.2...decap-cms-widget-number@3.1.1) (2024-03-21)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
# [3.1.0](https://github.com/decaporg/decap-cms/compare/decap-cms-widget-number@3.1.0-beta.2...decap-cms-widget-number@3.1.0) (2024-02-01)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
# [3.1.0-beta.2](https://github.com/decaporg/decap-cms/compare/decap-cms-widget-number@3.1.0-beta.1...decap-cms-widget-number@3.1.0-beta.2) (2024-01-31)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
# [3.1.0-beta.1](https://github.com/decaporg/decap-cms/compare/decap-cms-widget-number@3.1.0-beta.0...decap-cms-widget-number@3.1.0-beta.1) (2024-01-16)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
# [3.1.0-beta.0](https://github.com/decaporg/decap-cms/compare/decap-cms-widget-number@3.1.0...decap-cms-widget-number@3.1.0-beta.0) (2023-10-20)
|
||||
|
||||
### Reverts
|
||||
|
||||
- Revert "chore(release): publish" ([b89fc89](https://github.com/decaporg/decap-cms/commit/b89fc894dfbb5f4136b2e5427fd25a29378a58c6))
|
||||
|
||||
## [3.0.1](https://github.com/decaporg/decap-cms/compare/decap-cms-widget-number@3.0.0...decap-cms-widget-number@3.0.1) (2023-08-25)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- update peer dependencies ([#6886](https://github.com/decaporg/decap-cms/issues/6886)) ([e580ce5](https://github.com/decaporg/decap-cms/commit/e580ce52ce5f80fa040e8fbcab7fed0744f4f695))
|
||||
|
||||
# [3.0.0](https://github.com/decaporg/decap-cms/compare/decap-cms-widget-number@2.6.0...decap-cms-widget-number@3.0.0) (2023-08-18)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
# [2.6.0](https://github.com/decaporg/decap-cms/compare/decap-cms-widget-number@2.6.0-beta.0...decap-cms-widget-number@2.6.0) (2023-08-18)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
# 2.6.0-beta.0 (2023-08-18)
|
||||
|
||||
### Features
|
||||
|
||||
- rename packages ([#6863](https://github.com/decaporg/decap-cms/issues/6863)) ([d515e7b](https://github.com/decaporg/decap-cms/commit/d515e7bd33216a775d96887b08c4f7b1962941bb))
|
||||
|
||||
## [2.5.1-beta.0](https://github.com/decaporg/decap-cms/compare/decap-cms-widget-number@2.5.0...decap-cms-widget-number@2.5.1-beta.0) (2023-07-27)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
# [2.5.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.4.7...decap-cms-widget-number@2.5.0) (2021-05-04)
|
||||
|
||||
### Features
|
||||
|
||||
- added react 17 as peer dependency in packages ([#5316](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/5316)) ([9e42380](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/9e423805707321396eec137f5b732a5b07a0dd3f))
|
||||
|
||||
## [2.4.7](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.4.6...decap-cms-widget-number@2.4.7) (2021-02-23)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
## [2.4.6](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.4.5...decap-cms-widget-number@2.4.6) (2021-02-10)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
## [2.4.5](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.4.4...decap-cms-widget-number@2.4.5) (2020-09-15)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
## 2.4.4 (2020-09-08)
|
||||
|
||||
### Reverts
|
||||
|
||||
- Revert "chore(release): publish" ([828bb16](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae))
|
||||
|
||||
## 2.4.3 (2020-08-20)
|
||||
|
||||
### Reverts
|
||||
|
||||
- Revert "chore(release): publish" ([8262487](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/82624879ccbcb16610090041db28f00714d924c8))
|
||||
|
||||
## 2.4.2 (2020-07-27)
|
||||
|
||||
### Reverts
|
||||
|
||||
- Revert "chore(release): publish" ([118d50a](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/118d50a7a70295f25073e564b5161aa2b9883056))
|
||||
|
||||
## [2.4.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.4.0...decap-cms-widget-number@2.4.1) (2020-07-01)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **widget-number:** use number instead of integer in schema ([#3931](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/3931)) ([3a53873](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/3a5387346925cb7a579ef199c261d7c7de4a3423))
|
||||
|
||||
# [2.4.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.3.5...decap-cms-widget-number@2.4.0) (2020-06-18)
|
||||
|
||||
### Features
|
||||
|
||||
- add widgets schema validation ([#3841](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/3841)) ([2b46608](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/2b46608f86d22c8ad34f75e396be7c34462d9e99))
|
||||
- commit media with post ([#2851](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/2851)) ([6515dee](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/6515dee8715d8571ea19484a7dfab7cfd0cc40be))
|
||||
|
||||
## [2.3.5](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.3.4...decap-cms-widget-number@2.3.5) (2019-11-07)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- don't enforce min max when number value is empty ([#2792](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/2792)) ([6b11367](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/6b113673130389aba1ee00fd614501668fad7596))
|
||||
|
||||
## [2.3.4](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.3.3...decap-cms-widget-number@2.3.4) (2019-07-24)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
## [2.3.3](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.3.3-beta.0...decap-cms-widget-number@2.3.3) (2019-04-10)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
## [2.3.3-beta.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.3.2...decap-cms-widget-number@2.3.3-beta.0) (2019-04-05)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
## [2.3.2](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.3.1...decap-cms-widget-number@2.3.2) (2019-04-02)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **widget-number:** allow zero as value ([#2261](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/2261)) ([800c3ee](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/800c3ee))
|
||||
|
||||
## [2.3.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.3.1-beta.2...decap-cms-widget-number@2.3.1) (2019-03-29)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
## [2.3.1-beta.2](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.3.1-beta.1...decap-cms-widget-number@2.3.1-beta.2) (2019-03-28)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
## [2.3.1-beta.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.3.1-beta.0...decap-cms-widget-number@2.3.1-beta.1) (2019-03-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- export on decap-cms and maps on esm ([#2244](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/2244)) ([6ffd13b](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/6ffd13b))
|
||||
|
||||
## [2.3.1-beta.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.3.0...decap-cms-widget-number@2.3.1-beta.0) (2019-03-25)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- update peer dep versions ([#2234](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/2234)) ([7987091](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/7987091))
|
||||
|
||||
# [2.3.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.2.0...decap-cms-widget-number@2.3.0) (2019-03-22)
|
||||
|
||||
### Features
|
||||
|
||||
- add ES module builds ([#2215](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/2215)) ([d142b32](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/d142b32))
|
||||
|
||||
# [2.2.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.2.0-beta.0...decap-cms-widget-number@2.2.0) (2019-03-22)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
# [2.2.0-beta.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.1.2-beta.0...decap-cms-widget-number@2.2.0-beta.0) (2019-03-21)
|
||||
|
||||
### Features
|
||||
|
||||
- provide usable UMD builds for all packages ([#2141](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/2141)) ([82cc794](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/82cc794))
|
||||
|
||||
## [2.1.2-beta.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.1.1...decap-cms-widget-number@2.1.2-beta.0) (2019-03-15)
|
||||
|
||||
### Features
|
||||
|
||||
- upgrade to Emotion 10 ([#2166](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/2166)) ([ccef446](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/ccef446))
|
||||
|
||||
## [2.1.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.1.0...decap-cms-widget-number@2.1.1) (2019-02-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **widget-number:** fix empty value handling for number input ([#2077](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/2077)) ([be15015](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/be15015))
|
||||
|
||||
# [2.1.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.0.5...decap-cms-widget-number@2.1.0) (2019-02-08)
|
||||
|
||||
### Features
|
||||
|
||||
- **widget-number:** add range validation ([#2049](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/issues/2049)) ([dc44cac](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/commit/dc44cac))
|
||||
|
||||
<a name="2.0.5"></a>
|
||||
|
||||
## [2.0.5](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.0.4...decap-cms-widget-number@2.0.5) (2018-08-27)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
<a name="2.0.4"></a>
|
||||
|
||||
## [2.0.4](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.0.3...decap-cms-widget-number@2.0.4) (2018-08-24)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
<a name="2.0.3"></a>
|
||||
|
||||
## [2.0.3](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.0.2...decap-cms-widget-number@2.0.3) (2018-08-01)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
<a name="2.0.2"></a>
|
||||
|
||||
## [2.0.2](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number/compare/decap-cms-widget-number@2.0.1...decap-cms-widget-number@2.0.2) (2018-07-28)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
|
||||
<a name="2.0.1"></a>
|
||||
|
||||
## 2.0.1 (2018-07-26)
|
||||
|
||||
<a name="2.0.0"></a>
|
||||
|
||||
# 2.0.0 (2018-07-26)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-widget-number
|
||||
9
source/admin/packages/decap-cms-widget-number/README.md
Normal file
9
source/admin/packages/decap-cms-widget-number/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Docs coming soon!
|
||||
|
||||
Decap CMS was converted from a single npm package to a "monorepo" of over 20 packages.
|
||||
We haven't created a README for this package yet, but you can:
|
||||
|
||||
1. Check out the [main readme](https://github.com/decaporg/decap-cms/#readme) or the [documentation
|
||||
site](https://www.decapcms.org) for more info.
|
||||
2. Reach out to the [community chat](https://decapcms.org/chat/) if you need help.
|
||||
3. Help out and [write the readme yourself](https://github.com/decaporg/decap-cms/edit/main/packages/decap-cms-widget-number/README.md)!
|
||||
27
source/admin/packages/decap-cms-widget-number/package.json
Normal file
27
source/admin/packages/decap-cms-widget-number/package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "decap-cms-widget-number",
|
||||
"description": "Widget for editing numeric values in Decap CMS.",
|
||||
"version": "3.2.0",
|
||||
"homepage": "https://www.decapcms.org/docs/widgets/#number",
|
||||
"repository": "https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-number",
|
||||
"bugs": "https://github.com/decaporg/decap-cms/issues",
|
||||
"module": "dist/esm/index.js",
|
||||
"main": "dist/decap-cms-widget-number.js",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"decap-cms",
|
||||
"widget",
|
||||
"number"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"develop": "npm run 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"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"decap-cms-ui-default": "^3.0.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^19.1.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
const ValidationErrorTypes = {
|
||||
PRESENCE: 'PRESENCE',
|
||||
PATTERN: 'PATTERN',
|
||||
RANGE: 'RANGE',
|
||||
CUSTOM: 'CUSTOM',
|
||||
};
|
||||
|
||||
export function validateMinMax(value, min, max, field, t) {
|
||||
let error;
|
||||
|
||||
switch (true) {
|
||||
case value !== '' && min !== false && max !== false && (value < min || value > max):
|
||||
error = {
|
||||
type: ValidationErrorTypes.RANGE,
|
||||
message: t('editor.editorControlPane.widget.range', {
|
||||
fieldLabel: field.get('label', field.get('name')),
|
||||
minValue: min,
|
||||
maxValue: max,
|
||||
}),
|
||||
};
|
||||
break;
|
||||
case value !== '' && min !== false && value < min:
|
||||
error = {
|
||||
type: ValidationErrorTypes.RANGE,
|
||||
message: t('editor.editorControlPane.widget.min', {
|
||||
fieldLabel: field.get('label', field.get('name')),
|
||||
minValue: min,
|
||||
}),
|
||||
};
|
||||
break;
|
||||
case value !== '' && max !== false && value > max:
|
||||
error = {
|
||||
type: ValidationErrorTypes.RANGE,
|
||||
message: t('editor.editorControlPane.widget.max', {
|
||||
fieldLabel: field.get('label', field.get('name')),
|
||||
maxValue: max,
|
||||
}),
|
||||
};
|
||||
break;
|
||||
default:
|
||||
error = null;
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
export default class NumberControl extends React.Component {
|
||||
static propTypes = {
|
||||
field: ImmutablePropTypes.map.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
classNameWrapper: PropTypes.string.isRequired,
|
||||
setActiveStyle: PropTypes.func.isRequired,
|
||||
setInactiveStyle: PropTypes.func.isRequired,
|
||||
value: PropTypes.node,
|
||||
forID: PropTypes.string,
|
||||
valueType: PropTypes.string,
|
||||
step: PropTypes.number,
|
||||
min: PropTypes.number,
|
||||
max: PropTypes.number,
|
||||
t: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
value: '',
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
// Manually validate PropTypes - React 19 breaking change
|
||||
PropTypes.checkPropTypes(NumberControl.propTypes, this.props, 'prop', 'NumberControl');
|
||||
}
|
||||
|
||||
handleChange = e => {
|
||||
const valueType = this.props.field.get('value_type');
|
||||
const { onChange } = this.props;
|
||||
const value = valueType === 'float' ? parseFloat(e.target.value) : parseInt(e.target.value, 10);
|
||||
|
||||
if (!isNaN(value)) {
|
||||
onChange(value);
|
||||
} else {
|
||||
onChange('');
|
||||
}
|
||||
};
|
||||
|
||||
isValid = () => {
|
||||
const { field, value, t } = this.props;
|
||||
const hasPattern = !!field.get('pattern', false);
|
||||
const min = field.get('min', false);
|
||||
const max = field.get('max', false);
|
||||
|
||||
// Pattern overrides min/max logic always:
|
||||
if (hasPattern) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const error = validateMinMax(value, min, max, field, t);
|
||||
return error ? { error } : true;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { field, value, classNameWrapper, forID, setActiveStyle, setInactiveStyle } = this.props;
|
||||
const min = field.get('min', '');
|
||||
const max = field.get('max', '');
|
||||
const step = field.get('step', field.get('value_type') === 'int' ? 1 : '');
|
||||
return (
|
||||
<input
|
||||
type="number"
|
||||
id={forID}
|
||||
className={classNameWrapper}
|
||||
onFocus={setActiveStyle}
|
||||
onBlur={setInactiveStyle}
|
||||
value={value || (value === 0 ? value : '')}
|
||||
step={step}
|
||||
min={min}
|
||||
max={max}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { WidgetPreviewContainer } from 'decap-cms-ui-default';
|
||||
|
||||
function NumberPreview({ value }) {
|
||||
return <WidgetPreviewContainer>{value}</WidgetPreviewContainer>;
|
||||
}
|
||||
|
||||
NumberPreview.propTypes = {
|
||||
value: PropTypes.node,
|
||||
};
|
||||
|
||||
export default NumberPreview;
|
||||
@@ -0,0 +1,214 @@
|
||||
import React from 'react';
|
||||
import { fromJS } from 'immutable';
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
|
||||
import { DecapCmsWidgetNumber } from '../';
|
||||
import { validateMinMax } from '../NumberControl';
|
||||
|
||||
const NumberControl = DecapCmsWidgetNumber.controlComponent;
|
||||
|
||||
const fieldSettings = {
|
||||
min: -20,
|
||||
max: 20,
|
||||
step: 1,
|
||||
value_type: 'int',
|
||||
};
|
||||
|
||||
class NumberController extends React.Component {
|
||||
state = {
|
||||
value: this.props.defaultValue,
|
||||
};
|
||||
|
||||
handleOnChange = jest.fn(value => {
|
||||
this.setState({ value });
|
||||
});
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onStateChange(this.state);
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.props.children({
|
||||
value: this.state.value,
|
||||
handleOnChange: this.handleOnChange,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function setup({ field, defaultValue }) {
|
||||
let renderArgs;
|
||||
const stateChangeSpy = jest.fn();
|
||||
const setActiveSpy = jest.fn();
|
||||
const setInactiveSpy = jest.fn();
|
||||
|
||||
const helpers = render(
|
||||
<NumberController defaultValue={defaultValue} onStateChange={stateChangeSpy}>
|
||||
{({ value, handleOnChange }) => {
|
||||
renderArgs = { value, onChangeSpy: handleOnChange };
|
||||
return (
|
||||
<NumberControl
|
||||
field={field}
|
||||
value={value}
|
||||
onChange={handleOnChange}
|
||||
forID="test-number"
|
||||
classNameWrapper=""
|
||||
setActiveStyle={setActiveSpy}
|
||||
setInactiveStyle={setInactiveSpy}
|
||||
t={jest.fn()}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</NumberController>,
|
||||
);
|
||||
|
||||
const input = helpers.container.querySelector('input');
|
||||
|
||||
return {
|
||||
...helpers,
|
||||
...renderArgs,
|
||||
stateChangeSpy,
|
||||
setActiveSpy,
|
||||
setInactiveSpy,
|
||||
input,
|
||||
};
|
||||
}
|
||||
|
||||
describe('Number widget', () => {
|
||||
it('should call onChange when input changes', () => {
|
||||
const field = fromJS(fieldSettings);
|
||||
const testValue = Math.floor(Math.random() * (20 - -20 + 1)) + -20;
|
||||
const { input, onChangeSpy } = setup({ field });
|
||||
|
||||
fireEvent.focus(input);
|
||||
fireEvent.change(input, { target: { value: String(testValue) } });
|
||||
|
||||
expect(onChangeSpy).toHaveBeenCalledTimes(1);
|
||||
expect(onChangeSpy).toHaveBeenCalledWith(testValue);
|
||||
});
|
||||
|
||||
it('should call onChange with empty string when no value is set', () => {
|
||||
const field = fromJS(fieldSettings);
|
||||
const { input, onChangeSpy } = setup({ field, defaultValue: 20 });
|
||||
|
||||
fireEvent.focus(input);
|
||||
fireEvent.change(input, { target: { value: '' } });
|
||||
|
||||
expect(onChangeSpy).toHaveBeenCalledTimes(1);
|
||||
expect(onChangeSpy).toHaveBeenCalledWith('');
|
||||
});
|
||||
|
||||
it('should call onChange with empty string when a non numeric value is set', () => {
|
||||
const field = fromJS(fieldSettings);
|
||||
const { input, onChangeSpy } = setup({ field, defaultValue: 20 });
|
||||
|
||||
fireEvent.focus(input);
|
||||
fireEvent.change(input, { target: { value: 'invalid' } });
|
||||
|
||||
expect(onChangeSpy).toHaveBeenCalledTimes(1);
|
||||
expect(onChangeSpy).toHaveBeenCalledWith('');
|
||||
});
|
||||
|
||||
it('should parse float numbers as integers', () => {
|
||||
const field = fromJS(fieldSettings);
|
||||
const testValue = (Math.random() * (20 - -20 + 1) + -20).toFixed(2);
|
||||
const { input, onChangeSpy } = setup({ field });
|
||||
|
||||
fireEvent.focus(input);
|
||||
fireEvent.change(input, { target: { value: String(testValue) } });
|
||||
|
||||
expect(onChangeSpy).toHaveBeenCalledTimes(1);
|
||||
expect(onChangeSpy).toHaveBeenCalledWith(parseInt(testValue, 10));
|
||||
});
|
||||
|
||||
it('should parse float numbers as float', () => {
|
||||
const field = fromJS({ ...fieldSettings, value_type: 'float' });
|
||||
const testValue = (Math.random() * (20 - -20 + 1) + -20).toFixed(2);
|
||||
const { input, onChangeSpy } = setup({ field });
|
||||
|
||||
fireEvent.focus(input);
|
||||
fireEvent.change(input, { target: { value: String(testValue) } });
|
||||
|
||||
expect(onChangeSpy).toHaveBeenCalledTimes(1);
|
||||
expect(onChangeSpy).toHaveBeenCalledWith(parseFloat(testValue));
|
||||
});
|
||||
|
||||
it('should allow 0 as a value', () => {
|
||||
const field = fromJS(fieldSettings);
|
||||
const testValue = 0;
|
||||
const { input } = setup({ field });
|
||||
|
||||
fireEvent.focus(input);
|
||||
fireEvent.change(input, { target: { value: String(testValue) } });
|
||||
|
||||
expect(input.value).toBe('0');
|
||||
});
|
||||
|
||||
describe('validateMinMax', () => {
|
||||
const field = { get: jest.fn() };
|
||||
field.get.mockReturnValue('label');
|
||||
const t = jest.fn();
|
||||
t.mockImplementation((_, params) => params);
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should return error when min max are defined and value is out of range', () => {
|
||||
const error = validateMinMax(5, 0, 1, field, t);
|
||||
const expectedMessage = {
|
||||
fieldLabel: 'label',
|
||||
minValue: 0,
|
||||
maxValue: 1,
|
||||
};
|
||||
expect(error).not.toBeNull();
|
||||
expect(error).toEqual({
|
||||
type: 'RANGE',
|
||||
message: expectedMessage,
|
||||
});
|
||||
expect(t).toHaveBeenCalledTimes(1);
|
||||
expect(t).toHaveBeenCalledWith('editor.editorControlPane.widget.range', expectedMessage);
|
||||
});
|
||||
|
||||
it('should return error when min is defined and value is out of range', () => {
|
||||
const error = validateMinMax(5, 6, false, field, t);
|
||||
const expectedMessage = {
|
||||
fieldLabel: 'label',
|
||||
minValue: 6,
|
||||
};
|
||||
expect(error).not.toBeNull();
|
||||
expect(error).toEqual({
|
||||
type: 'RANGE',
|
||||
message: expectedMessage,
|
||||
});
|
||||
expect(t).toHaveBeenCalledTimes(1);
|
||||
expect(t).toHaveBeenCalledWith('editor.editorControlPane.widget.min', expectedMessage);
|
||||
});
|
||||
|
||||
it('should return error when max is defined and value is out of range', () => {
|
||||
const error = validateMinMax(5, false, 3, field, t);
|
||||
const expectedMessage = {
|
||||
fieldLabel: 'label',
|
||||
maxValue: 3,
|
||||
};
|
||||
expect(error).not.toBeNull();
|
||||
expect(error).toEqual({
|
||||
type: 'RANGE',
|
||||
message: expectedMessage,
|
||||
});
|
||||
expect(t).toHaveBeenCalledTimes(1);
|
||||
expect(t).toHaveBeenCalledWith('editor.editorControlPane.widget.max', expectedMessage);
|
||||
});
|
||||
|
||||
it('should not return error when min max are defined and value is empty', () => {
|
||||
const error = validateMinMax('', 0, 1, field, t);
|
||||
|
||||
expect(error).toBeNull();
|
||||
});
|
||||
|
||||
it('should not return error when min max are defined and value is in range', () => {
|
||||
const error = validateMinMax(0, -1, 1, field, t);
|
||||
|
||||
expect(error).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
16
source/admin/packages/decap-cms-widget-number/src/index.js
Normal file
16
source/admin/packages/decap-cms-widget-number/src/index.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import controlComponent from './NumberControl';
|
||||
import previewComponent from './NumberPreview';
|
||||
import schema from './schema';
|
||||
|
||||
function Widget(opts = {}) {
|
||||
return {
|
||||
name: 'number',
|
||||
controlComponent,
|
||||
previewComponent,
|
||||
schema,
|
||||
...opts,
|
||||
};
|
||||
}
|
||||
|
||||
export const DecapCmsWidgetNumber = { Widget, controlComponent, previewComponent };
|
||||
export default DecapCmsWidgetNumber;
|
||||
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
properties: {
|
||||
step: { type: 'number' },
|
||||
value_type: { type: 'string' },
|
||||
min: { type: 'number' },
|
||||
max: { type: 'number' },
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
const { getConfig } = require('../../scripts/webpack.js');
|
||||
|
||||
module.exports = getConfig();
|
||||
Reference in New Issue
Block a user