Skip to content

Commit e9c3a9e

Browse files
committed
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/`
1 parent 26f650b commit e9c3a9e

File tree

8 files changed

+132
-55
lines changed

8 files changed

+132
-55
lines changed

dev-test/config.yml

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,31 @@ collections: # A list of collections the CMS should be able to edit
140140
display_fields: ['title', 'datetime']
141141
search_fields: ['title', 'body']
142142
value_field: 'title'
143-
- { label: 'Title', name: 'title', widget: 'string' }
144-
- { label: 'Boolean', name: 'boolean', widget: 'boolean', default: true }
143+
- {
144+
label: 'Title',
145+
name: 'title',
146+
widget: 'string',
147+
prefix: 'This string:',
148+
suffix: 'is a title'
149+
}
150+
- {
151+
label: 'Boolean',
152+
name: 'boolean',
153+
widget: 'boolean',
154+
prefix: 'OFF',
155+
suffix: 'ON',
156+
hint: 'Toggle this to switch on/off',
157+
default: true
158+
}
145159
- { label: 'Map', name: 'map', widget: 'map' }
146160
- { label: 'Text', name: 'text', widget: 'text', hint: 'Plain text, not markdown' }
147-
- { label: 'Number', name: 'number', widget: 'number', hint: 'To infinity and beyond!' }
161+
- {
162+
label: 'Number',
163+
name: 'number',
164+
widget: 'number',
165+
suffix: 'px',
166+
hint: 'To infinity and beyond!'
167+
}
148168
- { label: 'Markdown', name: 'markdown', widget: 'markdown' }
149169
- { label: 'Datetime', name: 'datetime', widget: 'datetime' }
150170
- { label: 'Image', name: 'image', widget: 'image' }

packages/decap-cms-widget-boolean/src/BooleanControl.js

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
44
import { css } from '@emotion/react';
55
import { Toggle, ToggleBackground, colors } from 'decap-cms-ui-default';
66

7+
const innerWrapper = css`
8+
display: flex;
9+
align-items: center;
10+
`
11+
712
function BooleanBackground({ isActive, ...props }) {
813
return (
914
<ToggleBackground
@@ -16,34 +21,42 @@ function BooleanBackground({ isActive, ...props }) {
1621
}
1722

1823
export default class BooleanControl extends React.Component {
24+
static propTypes = {
25+
field: ImmutablePropTypes.map.isRequired,
26+
onChange: PropTypes.func.isRequired,
27+
classNameWrapper: PropTypes.string.isRequired,
28+
setActiveStyle: PropTypes.func.isRequired,
29+
setInactiveStyle: PropTypes.func.isRequired,
30+
forID: PropTypes.string,
31+
value: PropTypes.bool,
32+
}
33+
34+
static defaultProps = {
35+
value: false,
36+
}
37+
1938
render() {
20-
const { value, forID, onChange, classNameWrapper, setActiveStyle, setInactiveStyle } =
39+
const { value, forID, onChange, classNameWrapper, setActiveStyle, setInactiveStyle, field } =
2140
this.props;
41+
42+
const prefix = field.get('prefix', false);
43+
const suffix = field.get('suffix', false);
44+
2245
return (
2346
<div className={classNameWrapper}>
24-
<Toggle
25-
id={forID}
26-
active={value}
27-
onChange={onChange}
28-
onFocus={setActiveStyle}
29-
onBlur={setInactiveStyle}
30-
Background={BooleanBackground}
31-
/>
47+
<div css={innerWrapper}>
48+
{prefix && (<span>{prefix}&nbsp;</span>)}
49+
<Toggle
50+
id={forID}
51+
active={value}
52+
onChange={onChange}
53+
onFocus={setActiveStyle}
54+
onBlur={setInactiveStyle}
55+
Background={BooleanBackground}
56+
/>
57+
{suffix && (<span>&nbsp;{suffix}</span>)}
58+
</div>
3259
</div>
3360
);
3461
}
3562
}
36-
37-
BooleanControl.propTypes = {
38-
field: ImmutablePropTypes.map.isRequired,
39-
onChange: PropTypes.func.isRequired,
40-
classNameWrapper: PropTypes.string.isRequired,
41-
setActiveStyle: PropTypes.func.isRequired,
42-
setInactiveStyle: PropTypes.func.isRequired,
43-
forID: PropTypes.string,
44-
value: PropTypes.bool,
45-
};
46-
47-
BooleanControl.defaultProps = {
48-
value: false,
49-
};

packages/decap-cms-widget-number/src/NumberControl.js

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33
import ImmutablePropTypes from 'react-immutable-proptypes';
4+
import { css } from '@emotion/core';
5+
46
const ValidationErrorTypes = {
57
PRESENCE: 'PRESENCE',
68
PATTERN: 'PATTERN',
79
RANGE: 'RANGE',
810
CUSTOM: 'CUSTOM',
911
};
1012

13+
const innerWrapper = css`
14+
display: flex;
15+
align-items: baseline;
16+
`
17+
1118
export function validateMinMax(value, min, max, field, t) {
1219
let error;
1320

@@ -100,19 +107,29 @@ export default class NumberControl extends React.Component {
100107
const min = field.get('min', '');
101108
const max = field.get('max', '');
102109
const step = field.get('step', field.get('value_type') === 'int' ? 1 : '');
110+
111+
const prefix = field.get('prefix', false);
112+
const suffix = field.get('suffix', false);
113+
103114
return (
104-
<input
105-
type="number"
106-
id={forID}
107-
className={classNameWrapper}
108-
onFocus={setActiveStyle}
109-
onBlur={setInactiveStyle}
110-
value={value || (value === 0 ? value : '')}
111-
step={step}
112-
min={min}
113-
max={max}
114-
onChange={this.handleChange}
115-
/>
115+
<div className={classNameWrapper}>
116+
<div css={innerWrapper}>
117+
{prefix && (<span>{prefix}&nbsp;</span>)}
118+
<input
119+
type="number"
120+
id={forID}
121+
onFocus={setActiveStyle}
122+
onBlur={setInactiveStyle}
123+
value={value || (value === 0 ? value : '')}
124+
step={step}
125+
min={min}
126+
max={max}
127+
onChange={this.handleChange}
128+
css={css`flex-grow: 1`}
129+
/>
130+
{suffix && (<span>&nbsp;{suffix}</span>)}
131+
</div>
132+
</div>
116133
);
117134
}
118135
}

packages/decap-cms-widget-string/src/StringControl.js

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3+
import ImmutablePropTypes from 'react-immutable-proptypes';
4+
import { css } from '@emotion/core';
5+
6+
const innerWrapper = css`
7+
display: flex;
8+
align-items: baseline;
9+
`
310

411
export default class StringControl extends React.Component {
512
static propTypes = {
13+
field: ImmutablePropTypes.map.isRequired,
614
onChange: PropTypes.func.isRequired,
715
forID: PropTypes.string,
816
value: PropTypes.node,
@@ -41,21 +49,30 @@ export default class StringControl extends React.Component {
4149
};
4250

4351
render() {
44-
const { forID, value, classNameWrapper, setActiveStyle, setInactiveStyle } = this.props;
52+
const { field, forID, value, classNameWrapper, setActiveStyle, setInactiveStyle } = this.props;
53+
54+
const prefix = field.get('prefix', false);
55+
const suffix = field.get('suffix', false);
4556

4657
return (
47-
<input
48-
ref={el => {
49-
this._el = el;
50-
}}
51-
type="text"
52-
id={forID}
53-
className={classNameWrapper}
54-
value={value || ''}
55-
onChange={this.handleChange}
56-
onFocus={setActiveStyle}
57-
onBlur={setInactiveStyle}
58-
/>
58+
<div className={classNameWrapper}>
59+
<div css={innerWrapper}>
60+
{prefix && (<span>{prefix}&nbsp;</span>)}
61+
<input
62+
ref={el => {
63+
this._el = el;
64+
}}
65+
type="text"
66+
id={forID}
67+
value={value || ''}
68+
onChange={this.handleChange}
69+
onFocus={setActiveStyle}
70+
onBlur={setInactiveStyle}
71+
css={css`flex-grow: 1`}
72+
/>
73+
{suffix && (<span>&nbsp;{suffix}</span>)}
74+
</div>
75+
</div>
5976
);
6077
}
6178
}

packages/decap-server/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,5 @@
5252
"engines": {
5353
"node": ">=v10.22.1"
5454
},
55-
"bin": {
56-
"decap-server": "./dist/index.js"
57-
}
55+
"bin": "./dist/index.js"
5856
}

website/content/docs/widgets/boolean.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ The boolean widget translates a toggle switch input to a true/false value.
1010
- **Data type:** boolean
1111
- **Options:**
1212
- `default`: accepts `true` or `false`; defaults to `false` when `required` is set to `false`
13+
- `prefix`: display a message before the toggle; accepts a string; defaults to an empty string
14+
- `suffix`: display a message after the toggle; accepts a string; defaults to an empty string
1315
- **Example:**
1416
```yaml
15-
- {label: "Draft", name: "draft", widget: "boolean", default: true}
17+
- label: "Draft"
18+
name: "draft"
19+
widget: "boolean"
20+
prefix: "OFF"
21+
default: true
22+
suffix: "ON"
1623
```

website/content/docs/widgets/number.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ The number widget uses an HTML number input, saving the value as a string, integ
1414
- `min`: accepts a number for minimum value accepted; unset by default
1515
- `max`: accepts a number for maximum value accepted; unset by default
1616
- `step`: accepts a number for stepping up/down values in the input; 1 by default
17+
- `prefix`: display a message before the number input; accepts a string; defaults to an empty string
18+
- `suffix`: display a message after the number input; accepts a string; defaults to an empty string
1719
- **Example:**
1820
```yaml
1921
- label: "Puppy Count"
@@ -24,4 +26,5 @@ The number widget uses an HTML number input, saving the value as a string, integ
2426
min: 1
2527
max: 101
2628
step: 2
29+
suffix: puppies
2730
```

website/content/docs/widgets/string.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ The string widget translates a basic text input to a string value. For larger te
1010
- **Data type:** string
1111
- **Options:**
1212
- `default`: accepts a string; defaults to an empty string
13+
- `prefix`: display a message before the string input; accepts a string; defaults to an empty string
14+
- `suffix`: display a message after the string input; accepts a string; defaults to an empty string
1315
- **Example:**
1416
```yaml
1517
- {label: "Title", name: "title", widget: "string"}

0 commit comments

Comments
 (0)