From e9c3a9ed5d273b6c048f655eac48b7208459196a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=C4=83ng=20T=C3=BA?= <68631458+ngdangtu-vn@users.noreply.github.com> Date: Sat, 21 Oct 2023 22:59:04 +0700 Subject: [PATCH] chore(3 widgets): add prefix & suffix labels Those 3 widgets are Boolean, Number, String - update 3 widgets UI to display prefix & suffix - refactor BooleanControl.js code structure - update document for 3 widgets - update demo config `dev-test/` --- dev-test/config.yml | 26 +++++++- .../src/BooleanControl.js | 59 +++++++++++-------- .../src/NumberControl.js | 41 +++++++++---- .../src/StringControl.js | 43 ++++++++++---- packages/decap-server/package.json | 4 +- website/content/docs/widgets/boolean.md | 9 ++- website/content/docs/widgets/number.md | 3 + website/content/docs/widgets/string.md | 2 + 8 files changed, 132 insertions(+), 55 deletions(-) diff --git a/dev-test/config.yml b/dev-test/config.yml index 561295095e35..68b49550fe13 100644 --- a/dev-test/config.yml +++ b/dev-test/config.yml @@ -140,11 +140,31 @@ collections: # A list of collections the CMS should be able to edit display_fields: ['title', 'datetime'] search_fields: ['title', 'body'] value_field: 'title' - - { label: 'Title', name: 'title', widget: 'string' } - - { label: 'Boolean', name: 'boolean', widget: 'boolean', default: true } + - { + label: 'Title', + name: 'title', + widget: 'string', + prefix: 'This string:', + suffix: 'is a title' + } + - { + label: 'Boolean', + name: 'boolean', + widget: 'boolean', + prefix: 'OFF', + suffix: 'ON', + hint: 'Toggle this to switch on/off', + default: true + } - { label: 'Map', name: 'map', widget: 'map' } - { label: 'Text', name: 'text', widget: 'text', hint: 'Plain text, not markdown' } - - { label: 'Number', name: 'number', widget: 'number', hint: 'To infinity and beyond!' } + - { + label: 'Number', + name: 'number', + widget: 'number', + suffix: 'px', + hint: 'To infinity and beyond!' + } - { label: 'Markdown', name: 'markdown', widget: 'markdown' } - { label: 'Datetime', name: 'datetime', widget: 'datetime' } - { label: 'Image', name: 'image', widget: 'image' } diff --git a/packages/decap-cms-widget-boolean/src/BooleanControl.js b/packages/decap-cms-widget-boolean/src/BooleanControl.js index 3667c1bd372a..31a679854be9 100644 --- a/packages/decap-cms-widget-boolean/src/BooleanControl.js +++ b/packages/decap-cms-widget-boolean/src/BooleanControl.js @@ -4,6 +4,11 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import { css } from '@emotion/react'; import { Toggle, ToggleBackground, colors } from 'decap-cms-ui-default'; +const innerWrapper = css` + display: flex; + align-items: center; +` + function BooleanBackground({ isActive, ...props }) { return ( - +
+ {prefix && ({prefix} )} + + {suffix && ( {suffix})} +
); } } - -BooleanControl.propTypes = { - field: ImmutablePropTypes.map.isRequired, - onChange: PropTypes.func.isRequired, - classNameWrapper: PropTypes.string.isRequired, - setActiveStyle: PropTypes.func.isRequired, - setInactiveStyle: PropTypes.func.isRequired, - forID: PropTypes.string, - value: PropTypes.bool, -}; - -BooleanControl.defaultProps = { - value: false, -}; diff --git a/packages/decap-cms-widget-number/src/NumberControl.js b/packages/decap-cms-widget-number/src/NumberControl.js index 35606d9e4211..9e69dd54e186 100644 --- a/packages/decap-cms-widget-number/src/NumberControl.js +++ b/packages/decap-cms-widget-number/src/NumberControl.js @@ -1,6 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; +import { css } from '@emotion/core'; + const ValidationErrorTypes = { PRESENCE: 'PRESENCE', PATTERN: 'PATTERN', @@ -8,6 +10,11 @@ const ValidationErrorTypes = { CUSTOM: 'CUSTOM', }; +const innerWrapper = css` + display: flex; + align-items: baseline; +` + export function validateMinMax(value, min, max, field, t) { let error; @@ -100,19 +107,29 @@ export default class NumberControl extends React.Component { const min = field.get('min', ''); const max = field.get('max', ''); const step = field.get('step', field.get('value_type') === 'int' ? 1 : ''); + + const prefix = field.get('prefix', false); + const suffix = field.get('suffix', false); + return ( - +
+
+ {prefix && ({prefix} )} + + {suffix && ( {suffix})} +
+
); } } diff --git a/packages/decap-cms-widget-string/src/StringControl.js b/packages/decap-cms-widget-string/src/StringControl.js index bcb8dd14c2b0..28b3f54d7ab0 100644 --- a/packages/decap-cms-widget-string/src/StringControl.js +++ b/packages/decap-cms-widget-string/src/StringControl.js @@ -1,8 +1,16 @@ import React from 'react'; import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { css } from '@emotion/core'; + +const innerWrapper = css` + display: flex; + align-items: baseline; +` export default class StringControl extends React.Component { static propTypes = { + field: ImmutablePropTypes.map.isRequired, onChange: PropTypes.func.isRequired, forID: PropTypes.string, value: PropTypes.node, @@ -41,21 +49,30 @@ export default class StringControl extends React.Component { }; render() { - const { forID, value, classNameWrapper, setActiveStyle, setInactiveStyle } = this.props; + const { field, forID, value, classNameWrapper, setActiveStyle, setInactiveStyle } = this.props; + + const prefix = field.get('prefix', false); + const suffix = field.get('suffix', false); return ( - { - this._el = el; - }} - type="text" - id={forID} - className={classNameWrapper} - value={value || ''} - onChange={this.handleChange} - onFocus={setActiveStyle} - onBlur={setInactiveStyle} - /> +
+
+ {prefix && ({prefix} )} + { + this._el = el; + }} + type="text" + id={forID} + value={value || ''} + onChange={this.handleChange} + onFocus={setActiveStyle} + onBlur={setInactiveStyle} + css={css`flex-grow: 1`} + /> + {suffix && ( {suffix})} +
+
); } } diff --git a/packages/decap-server/package.json b/packages/decap-server/package.json index 990788031a07..e1de754df273 100644 --- a/packages/decap-server/package.json +++ b/packages/decap-server/package.json @@ -52,7 +52,5 @@ "engines": { "node": ">=v10.22.1" }, - "bin": { - "decap-server": "./dist/index.js" - } + "bin": "./dist/index.js" } diff --git a/website/content/docs/widgets/boolean.md b/website/content/docs/widgets/boolean.md index 30b71349faac..903f493d518c 100644 --- a/website/content/docs/widgets/boolean.md +++ b/website/content/docs/widgets/boolean.md @@ -10,7 +10,14 @@ The boolean widget translates a toggle switch input to a true/false value. - **Data type:** boolean - **Options:** - `default`: accepts `true` or `false`; defaults to `false` when `required` is set to `false` + - `prefix`: display a message before the toggle; accepts a string; defaults to an empty string + - `suffix`: display a message after the toggle; accepts a string; defaults to an empty string - **Example:** ```yaml - - {label: "Draft", name: "draft", widget: "boolean", default: true} + - label: "Draft" + name: "draft" + widget: "boolean" + prefix: "OFF" + default: true + suffix: "ON" ``` diff --git a/website/content/docs/widgets/number.md b/website/content/docs/widgets/number.md index e0ea666e4678..5d82b4a02c09 100644 --- a/website/content/docs/widgets/number.md +++ b/website/content/docs/widgets/number.md @@ -14,6 +14,8 @@ The number widget uses an HTML number input, saving the value as a string, integ - `min`: accepts a number for minimum value accepted; unset by default - `max`: accepts a number for maximum value accepted; unset by default - `step`: accepts a number for stepping up/down values in the input; 1 by default + - `prefix`: display a message before the number input; accepts a string; defaults to an empty string + - `suffix`: display a message after the number input; accepts a string; defaults to an empty string - **Example:** ```yaml - label: "Puppy Count" @@ -24,4 +26,5 @@ The number widget uses an HTML number input, saving the value as a string, integ min: 1 max: 101 step: 2 + suffix: puppies ``` diff --git a/website/content/docs/widgets/string.md b/website/content/docs/widgets/string.md index fdffbfd4a33b..8bbeaf3be388 100644 --- a/website/content/docs/widgets/string.md +++ b/website/content/docs/widgets/string.md @@ -10,6 +10,8 @@ The string widget translates a basic text input to a string value. For larger te - **Data type:** string - **Options:** - `default`: accepts a string; defaults to an empty string + - `prefix`: display a message before the string input; accepts a string; defaults to an empty string + - `suffix`: display a message after the string input; accepts a string; defaults to an empty string - **Example:** ```yaml - {label: "Title", name: "title", widget: "string"}