@contentful/field-editor-checkbox 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/CheckboxEditor.js +164 -0
- package/dist/cjs/CheckboxEditor.spec.js +219 -0
- package/dist/cjs/index.js +11 -0
- package/dist/cjs/styles.js +44 -0
- package/dist/esm/CheckboxEditor.js +112 -0
- package/dist/esm/CheckboxEditor.spec.js +176 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/styles.js +15 -0
- package/dist/{CheckboxEditor.d.ts → types/CheckboxEditor.d.ts} +22 -22
- package/dist/types/CheckboxEditor.spec.d.ts +1 -0
- package/dist/{index.d.ts → types/index.d.ts} +1 -1
- package/dist/{styles.d.ts → types/styles.d.ts} +4 -4
- package/package.json +26 -13
- package/CHANGELOG.md +0 -204
- package/dist/field-editor-checkbox.cjs.development.js +0 -130
- package/dist/field-editor-checkbox.cjs.development.js.map +0 -1
- package/dist/field-editor-checkbox.cjs.production.min.js +0 -2
- package/dist/field-editor-checkbox.cjs.production.min.js.map +0 -1
- package/dist/field-editor-checkbox.esm.js +0 -124
- package/dist/field-editor-checkbox.esm.js.map +0 -1
- package/dist/index.js +0 -8
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "CheckboxEditor", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return CheckboxEditor;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _react = _interop_require_wildcard(require("react"));
|
|
12
|
+
const _f36components = require("@contentful/f36-components");
|
|
13
|
+
const _fieldeditorshared = require("@contentful/field-editor-shared");
|
|
14
|
+
const _emotion = require("emotion");
|
|
15
|
+
const _get = _interop_require_default(require("lodash/get"));
|
|
16
|
+
const _nanoid = require("nanoid");
|
|
17
|
+
const _styles = _interop_require_wildcard(require("./styles"));
|
|
18
|
+
function _interop_require_default(obj) {
|
|
19
|
+
return obj && obj.__esModule ? obj : {
|
|
20
|
+
default: obj
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
24
|
+
if (typeof WeakMap !== "function") return null;
|
|
25
|
+
var cacheBabelInterop = new WeakMap();
|
|
26
|
+
var cacheNodeInterop = new WeakMap();
|
|
27
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
28
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
29
|
+
})(nodeInterop);
|
|
30
|
+
}
|
|
31
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
32
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
33
|
+
return obj;
|
|
34
|
+
}
|
|
35
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
36
|
+
return {
|
|
37
|
+
default: obj
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
41
|
+
if (cache && cache.has(obj)) {
|
|
42
|
+
return cache.get(obj);
|
|
43
|
+
}
|
|
44
|
+
var newObj = {};
|
|
45
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
46
|
+
for(var key in obj){
|
|
47
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
48
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
49
|
+
if (desc && (desc.get || desc.set)) {
|
|
50
|
+
Object.defineProperty(newObj, key, desc);
|
|
51
|
+
} else {
|
|
52
|
+
newObj[key] = obj[key];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
newObj.default = obj;
|
|
57
|
+
if (cache) {
|
|
58
|
+
cache.set(obj, newObj);
|
|
59
|
+
}
|
|
60
|
+
return newObj;
|
|
61
|
+
}
|
|
62
|
+
function isEmptyListValue(value) {
|
|
63
|
+
return value === null || value.length === 0;
|
|
64
|
+
}
|
|
65
|
+
function getOptions(field, id) {
|
|
66
|
+
const validations = (0, _get.default)(field, [
|
|
67
|
+
'items',
|
|
68
|
+
'validations'
|
|
69
|
+
], []);
|
|
70
|
+
const predefinedValues = validations.filter((validation)=>validation.in).map((validation)=>validation.in);
|
|
71
|
+
const firstPredefinedValues = predefinedValues.length > 0 ? predefinedValues[0] : [];
|
|
72
|
+
return firstPredefinedValues.map((value, index)=>({
|
|
73
|
+
id: [
|
|
74
|
+
'entity',
|
|
75
|
+
field.id,
|
|
76
|
+
field.locale,
|
|
77
|
+
index,
|
|
78
|
+
id
|
|
79
|
+
].join('.'),
|
|
80
|
+
value,
|
|
81
|
+
label: value
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
const getInvalidValues = (field, values, options)=>{
|
|
85
|
+
const getValueFromOptions = options.map((item)=>item.value);
|
|
86
|
+
const invalidValues = values.filter((value)=>!getValueFromOptions.includes(value)).map((value, index)=>({
|
|
87
|
+
id: [
|
|
88
|
+
'entity',
|
|
89
|
+
field.id,
|
|
90
|
+
field.locale,
|
|
91
|
+
index,
|
|
92
|
+
'invalid'
|
|
93
|
+
].join('.'),
|
|
94
|
+
label: value,
|
|
95
|
+
invalid: true,
|
|
96
|
+
value
|
|
97
|
+
}));
|
|
98
|
+
return invalidValues;
|
|
99
|
+
};
|
|
100
|
+
function CheckboxEditor(props) {
|
|
101
|
+
const [id] = (0, _react.useState)(()=>(0, _nanoid.nanoid)(6));
|
|
102
|
+
const { field , locales } = props;
|
|
103
|
+
const options = getOptions(field, id);
|
|
104
|
+
const misconfigured = options.length === 0;
|
|
105
|
+
if (misconfigured) {
|
|
106
|
+
return _react.createElement(_fieldeditorshared.PredefinedValuesError, null);
|
|
107
|
+
}
|
|
108
|
+
const direction = locales.direction[field.locale] || 'ltr';
|
|
109
|
+
return _react.createElement(_fieldeditorshared.FieldConnector, {
|
|
110
|
+
throttle: 0,
|
|
111
|
+
isEmptyValue: isEmptyListValue,
|
|
112
|
+
field: field,
|
|
113
|
+
isInitiallyDisabled: props.isInitiallyDisabled
|
|
114
|
+
}, ({ disabled , value , setValue })=>{
|
|
115
|
+
const values = value || [];
|
|
116
|
+
const addValue = (value)=>{
|
|
117
|
+
const newValues = [
|
|
118
|
+
...values.filter((item)=>item !== value),
|
|
119
|
+
value
|
|
120
|
+
];
|
|
121
|
+
setValue(newValues);
|
|
122
|
+
};
|
|
123
|
+
const removeValue = (value)=>{
|
|
124
|
+
const newValues = values.filter((item)=>item !== value);
|
|
125
|
+
setValue(newValues);
|
|
126
|
+
};
|
|
127
|
+
const invalidValues = getInvalidValues(field, values, options);
|
|
128
|
+
const mergedOptions = [
|
|
129
|
+
...options,
|
|
130
|
+
...invalidValues
|
|
131
|
+
];
|
|
132
|
+
return _react.createElement(_f36components.Form, {
|
|
133
|
+
testId: "checkbox-editor",
|
|
134
|
+
className: (0, _emotion.cx)(_styles.form, direction === 'rtl' ? _styles.rightToLeft : '')
|
|
135
|
+
}, mergedOptions.map((item)=>_react.createElement(_f36components.Box, {
|
|
136
|
+
key: item.id,
|
|
137
|
+
marginBottom: "spacingS"
|
|
138
|
+
}, _react.createElement(_f36components.Checkbox, {
|
|
139
|
+
key: item.id,
|
|
140
|
+
id: item.id,
|
|
141
|
+
isChecked: values.includes(item.value),
|
|
142
|
+
isDisabled: disabled,
|
|
143
|
+
value: item.value,
|
|
144
|
+
name: `${field.id}.${field.locale}`,
|
|
145
|
+
onChange: (e)=>{
|
|
146
|
+
if (e.target.checked) {
|
|
147
|
+
addValue(item.value);
|
|
148
|
+
} else {
|
|
149
|
+
removeValue(item.value);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}, item.label), item.invalid && _react.createElement(_react.Fragment, null, _react.createElement("span", {
|
|
153
|
+
"data-test-id": "invalid-text",
|
|
154
|
+
className: _styles.invalidText
|
|
155
|
+
}, "(invalid)"), _react.createElement(_f36components.TextLink, {
|
|
156
|
+
as: "button",
|
|
157
|
+
className: _styles.removeBtn,
|
|
158
|
+
onClick: ()=>removeValue(item.value)
|
|
159
|
+
}, "Remove")))));
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
CheckboxEditor.defaultProps = {
|
|
163
|
+
isInitiallyDisabled: true
|
|
164
|
+
};
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _react = _interop_require_wildcard(require("react"));
|
|
6
|
+
const _fieldeditortestutils = require("@contentful/field-editor-test-utils");
|
|
7
|
+
require("@testing-library/jest-dom/extend-expect");
|
|
8
|
+
const _react1 = require("@testing-library/react");
|
|
9
|
+
const _CheckboxEditor = require("./CheckboxEditor");
|
|
10
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
11
|
+
if (typeof WeakMap !== "function") return null;
|
|
12
|
+
var cacheBabelInterop = new WeakMap();
|
|
13
|
+
var cacheNodeInterop = new WeakMap();
|
|
14
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
15
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
16
|
+
})(nodeInterop);
|
|
17
|
+
}
|
|
18
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
19
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
20
|
+
return obj;
|
|
21
|
+
}
|
|
22
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
23
|
+
return {
|
|
24
|
+
default: obj
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
28
|
+
if (cache && cache.has(obj)) {
|
|
29
|
+
return cache.get(obj);
|
|
30
|
+
}
|
|
31
|
+
var newObj = {};
|
|
32
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
33
|
+
for(var key in obj){
|
|
34
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
35
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
36
|
+
if (desc && (desc.get || desc.set)) {
|
|
37
|
+
Object.defineProperty(newObj, key, desc);
|
|
38
|
+
} else {
|
|
39
|
+
newObj[key] = obj[key];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
newObj.default = obj;
|
|
44
|
+
if (cache) {
|
|
45
|
+
cache.set(obj, newObj);
|
|
46
|
+
}
|
|
47
|
+
return newObj;
|
|
48
|
+
}
|
|
49
|
+
(0, _react1.configure)({
|
|
50
|
+
testIdAttribute: 'data-test-id'
|
|
51
|
+
});
|
|
52
|
+
describe('CheckboxEditor', ()=>{
|
|
53
|
+
afterEach(_react1.cleanup);
|
|
54
|
+
it('renders a warning if no options are present', ()=>{
|
|
55
|
+
const [field] = (0, _fieldeditortestutils.createFakeFieldAPI)((mock)=>{
|
|
56
|
+
return {
|
|
57
|
+
...mock,
|
|
58
|
+
items: {
|
|
59
|
+
type: '',
|
|
60
|
+
validations: []
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
const { getByTestId , queryByTestId } = (0, _react1.render)(_react.createElement(_CheckboxEditor.CheckboxEditor, {
|
|
65
|
+
field: field,
|
|
66
|
+
locales: (0, _fieldeditortestutils.createFakeLocalesAPI)(),
|
|
67
|
+
isInitiallyDisabled: false
|
|
68
|
+
}));
|
|
69
|
+
expect(getByTestId('predefined-values-warning')).toBeInTheDocument();
|
|
70
|
+
expect(queryByTestId('dropdown-editor')).not.toBeInTheDocument();
|
|
71
|
+
});
|
|
72
|
+
it('renders checkboxes for predefined values', ()=>{
|
|
73
|
+
const predefined = [
|
|
74
|
+
'banana',
|
|
75
|
+
'orange',
|
|
76
|
+
'strawberry'
|
|
77
|
+
];
|
|
78
|
+
const [field] = (0, _fieldeditortestutils.createFakeFieldAPI)((mock)=>{
|
|
79
|
+
return {
|
|
80
|
+
...mock,
|
|
81
|
+
items: {
|
|
82
|
+
type: '',
|
|
83
|
+
validations: [
|
|
84
|
+
{
|
|
85
|
+
in: predefined
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
const { container } = (0, _react1.render)(_react.createElement(_CheckboxEditor.CheckboxEditor, {
|
|
92
|
+
field: field,
|
|
93
|
+
locales: (0, _fieldeditortestutils.createFakeLocalesAPI)(),
|
|
94
|
+
isInitiallyDisabled: false
|
|
95
|
+
}));
|
|
96
|
+
const $inputs = container.querySelectorAll('input[type="checkbox"]');
|
|
97
|
+
expect($inputs).toHaveLength(3);
|
|
98
|
+
predefined.forEach((item, index)=>{
|
|
99
|
+
expect($inputs[index].value).toEqual(item);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
it('calls setValue for every check event and removeValue if all items are unclicked', ()=>{
|
|
103
|
+
const predefined = [
|
|
104
|
+
'banana',
|
|
105
|
+
'orange',
|
|
106
|
+
'strawberry'
|
|
107
|
+
];
|
|
108
|
+
const [field] = (0, _fieldeditortestutils.createFakeFieldAPI)((mock)=>{
|
|
109
|
+
jest.spyOn(mock, 'setValue');
|
|
110
|
+
jest.spyOn(mock, 'removeValue');
|
|
111
|
+
return {
|
|
112
|
+
...mock,
|
|
113
|
+
items: {
|
|
114
|
+
type: '',
|
|
115
|
+
validations: [
|
|
116
|
+
{
|
|
117
|
+
in: predefined
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
});
|
|
123
|
+
const { container } = (0, _react1.render)(_react.createElement(_CheckboxEditor.CheckboxEditor, {
|
|
124
|
+
field: field,
|
|
125
|
+
locales: (0, _fieldeditortestutils.createFakeLocalesAPI)(),
|
|
126
|
+
isInitiallyDisabled: false
|
|
127
|
+
}));
|
|
128
|
+
const $inputs = container.querySelectorAll('input[type="checkbox"]');
|
|
129
|
+
_react1.fireEvent.click($inputs[0]);
|
|
130
|
+
expect(field.setValue).toHaveBeenCalledWith([
|
|
131
|
+
predefined[0]
|
|
132
|
+
]);
|
|
133
|
+
expect(field.setValue).toHaveBeenCalledTimes(1);
|
|
134
|
+
_react1.fireEvent.click($inputs[2]);
|
|
135
|
+
expect(field.setValue).toHaveBeenCalledWith([
|
|
136
|
+
predefined[0],
|
|
137
|
+
predefined[2]
|
|
138
|
+
]);
|
|
139
|
+
expect(field.setValue).toHaveBeenCalledTimes(2);
|
|
140
|
+
_react1.fireEvent.click($inputs[1]);
|
|
141
|
+
expect(field.setValue).toHaveBeenCalledWith([
|
|
142
|
+
predefined[0],
|
|
143
|
+
predefined[2],
|
|
144
|
+
predefined[1]
|
|
145
|
+
]);
|
|
146
|
+
expect(field.setValue).toHaveBeenCalledTimes(3);
|
|
147
|
+
$inputs.forEach(($input)=>{
|
|
148
|
+
_react1.fireEvent.click($input);
|
|
149
|
+
});
|
|
150
|
+
expect(field.removeValue).toHaveBeenCalledTimes(1);
|
|
151
|
+
});
|
|
152
|
+
it('renders invalid text and remove link when value set is not in predefined values', ()=>{
|
|
153
|
+
const predefined = [
|
|
154
|
+
'banana',
|
|
155
|
+
'orange',
|
|
156
|
+
'strawberry'
|
|
157
|
+
];
|
|
158
|
+
const [field] = (0, _fieldeditortestutils.createFakeFieldAPI)((mock)=>{
|
|
159
|
+
jest.spyOn(mock, 'setValue');
|
|
160
|
+
jest.spyOn(mock, 'removeValue');
|
|
161
|
+
return {
|
|
162
|
+
...mock,
|
|
163
|
+
items: {
|
|
164
|
+
type: '',
|
|
165
|
+
validations: [
|
|
166
|
+
{
|
|
167
|
+
in: predefined
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
});
|
|
173
|
+
field.setValue([
|
|
174
|
+
'mango'
|
|
175
|
+
]);
|
|
176
|
+
const { getByTestId } = (0, _react1.render)(_react.createElement(_CheckboxEditor.CheckboxEditor, {
|
|
177
|
+
field: field,
|
|
178
|
+
locales: (0, _fieldeditortestutils.createFakeLocalesAPI)(),
|
|
179
|
+
isInitiallyDisabled: false
|
|
180
|
+
}));
|
|
181
|
+
expect(getByTestId('invalid-text')).toBeInTheDocument();
|
|
182
|
+
expect(getByTestId('cf-ui-text-link')).toBeInTheDocument();
|
|
183
|
+
_react1.fireEvent.click(getByTestId('cf-ui-text-link'));
|
|
184
|
+
expect(field.removeValue).toHaveBeenCalledTimes(1);
|
|
185
|
+
});
|
|
186
|
+
it('renders checkboxes with unique ids', async ()=>{
|
|
187
|
+
const predefined = [
|
|
188
|
+
'banana',
|
|
189
|
+
'orange',
|
|
190
|
+
'strawberry'
|
|
191
|
+
];
|
|
192
|
+
const [field] = (0, _fieldeditortestutils.createFakeFieldAPI)((mock)=>{
|
|
193
|
+
return {
|
|
194
|
+
...mock,
|
|
195
|
+
items: {
|
|
196
|
+
type: '',
|
|
197
|
+
validations: [
|
|
198
|
+
{
|
|
199
|
+
in: predefined
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
});
|
|
205
|
+
const locales = (0, _fieldeditortestutils.createFakeLocalesAPI)();
|
|
206
|
+
const { findAllByTestId } = (0, _react1.render)(_react.createElement("div", null, _react.createElement(_CheckboxEditor.CheckboxEditor, {
|
|
207
|
+
field: field,
|
|
208
|
+
locales: locales,
|
|
209
|
+
isInitiallyDisabled: false
|
|
210
|
+
}), _react.createElement(_CheckboxEditor.CheckboxEditor, {
|
|
211
|
+
field: field,
|
|
212
|
+
locales: locales,
|
|
213
|
+
isInitiallyDisabled: false
|
|
214
|
+
})));
|
|
215
|
+
const $labels = await findAllByTestId('cf-ui-checkbox');
|
|
216
|
+
const uniqueIds = Array.from(new Set($labels.map((label)=>label.getAttribute('for'))));
|
|
217
|
+
expect(uniqueIds).toHaveLength(6);
|
|
218
|
+
});
|
|
219
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "CheckboxEditor", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return _CheckboxEditor.CheckboxEditor;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _CheckboxEditor = require("./CheckboxEditor");
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
form: function() {
|
|
13
|
+
return form;
|
|
14
|
+
},
|
|
15
|
+
rightToLeft: function() {
|
|
16
|
+
return rightToLeft;
|
|
17
|
+
},
|
|
18
|
+
invalidText: function() {
|
|
19
|
+
return invalidText;
|
|
20
|
+
},
|
|
21
|
+
removeBtn: function() {
|
|
22
|
+
return removeBtn;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const _f36tokens = _interop_require_default(require("@contentful/f36-tokens"));
|
|
26
|
+
const _emotion = require("emotion");
|
|
27
|
+
function _interop_require_default(obj) {
|
|
28
|
+
return obj && obj.__esModule ? obj : {
|
|
29
|
+
default: obj
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const form = (0, _emotion.css)({
|
|
33
|
+
marginTop: _f36tokens.default.spacingS
|
|
34
|
+
});
|
|
35
|
+
const rightToLeft = (0, _emotion.css)({
|
|
36
|
+
direction: 'rtl'
|
|
37
|
+
});
|
|
38
|
+
const invalidText = (0, _emotion.css)({
|
|
39
|
+
color: _f36tokens.default.red500,
|
|
40
|
+
marginLeft: _f36tokens.default.spacing2Xs
|
|
41
|
+
});
|
|
42
|
+
const removeBtn = (0, _emotion.css)({
|
|
43
|
+
marginLeft: _f36tokens.default.spacingL
|
|
44
|
+
});
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Checkbox, Box } from '@contentful/f36-components';
|
|
4
|
+
import { TextLink, Form } from '@contentful/f36-components';
|
|
5
|
+
import { FieldConnector, PredefinedValuesError } from '@contentful/field-editor-shared';
|
|
6
|
+
import { cx } from 'emotion';
|
|
7
|
+
import get from 'lodash/get';
|
|
8
|
+
import { nanoid } from 'nanoid';
|
|
9
|
+
import * as styles from './styles';
|
|
10
|
+
function isEmptyListValue(value) {
|
|
11
|
+
return value === null || value.length === 0;
|
|
12
|
+
}
|
|
13
|
+
function getOptions(field, id) {
|
|
14
|
+
const validations = get(field, [
|
|
15
|
+
'items',
|
|
16
|
+
'validations'
|
|
17
|
+
], []);
|
|
18
|
+
const predefinedValues = validations.filter((validation)=>validation.in).map((validation)=>validation.in);
|
|
19
|
+
const firstPredefinedValues = predefinedValues.length > 0 ? predefinedValues[0] : [];
|
|
20
|
+
return firstPredefinedValues.map((value, index)=>({
|
|
21
|
+
id: [
|
|
22
|
+
'entity',
|
|
23
|
+
field.id,
|
|
24
|
+
field.locale,
|
|
25
|
+
index,
|
|
26
|
+
id
|
|
27
|
+
].join('.'),
|
|
28
|
+
value,
|
|
29
|
+
label: value
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
const getInvalidValues = (field, values, options)=>{
|
|
33
|
+
const getValueFromOptions = options.map((item)=>item.value);
|
|
34
|
+
const invalidValues = values.filter((value)=>!getValueFromOptions.includes(value)).map((value, index)=>({
|
|
35
|
+
id: [
|
|
36
|
+
'entity',
|
|
37
|
+
field.id,
|
|
38
|
+
field.locale,
|
|
39
|
+
index,
|
|
40
|
+
'invalid'
|
|
41
|
+
].join('.'),
|
|
42
|
+
label: value,
|
|
43
|
+
invalid: true,
|
|
44
|
+
value
|
|
45
|
+
}));
|
|
46
|
+
return invalidValues;
|
|
47
|
+
};
|
|
48
|
+
export function CheckboxEditor(props) {
|
|
49
|
+
const [id] = useState(()=>nanoid(6));
|
|
50
|
+
const { field , locales } = props;
|
|
51
|
+
const options = getOptions(field, id);
|
|
52
|
+
const misconfigured = options.length === 0;
|
|
53
|
+
if (misconfigured) {
|
|
54
|
+
return React.createElement(PredefinedValuesError, null);
|
|
55
|
+
}
|
|
56
|
+
const direction = locales.direction[field.locale] || 'ltr';
|
|
57
|
+
return React.createElement(FieldConnector, {
|
|
58
|
+
throttle: 0,
|
|
59
|
+
isEmptyValue: isEmptyListValue,
|
|
60
|
+
field: field,
|
|
61
|
+
isInitiallyDisabled: props.isInitiallyDisabled
|
|
62
|
+
}, ({ disabled , value , setValue })=>{
|
|
63
|
+
const values = value || [];
|
|
64
|
+
const addValue = (value)=>{
|
|
65
|
+
const newValues = [
|
|
66
|
+
...values.filter((item)=>item !== value),
|
|
67
|
+
value
|
|
68
|
+
];
|
|
69
|
+
setValue(newValues);
|
|
70
|
+
};
|
|
71
|
+
const removeValue = (value)=>{
|
|
72
|
+
const newValues = values.filter((item)=>item !== value);
|
|
73
|
+
setValue(newValues);
|
|
74
|
+
};
|
|
75
|
+
const invalidValues = getInvalidValues(field, values, options);
|
|
76
|
+
const mergedOptions = [
|
|
77
|
+
...options,
|
|
78
|
+
...invalidValues
|
|
79
|
+
];
|
|
80
|
+
return React.createElement(Form, {
|
|
81
|
+
testId: "checkbox-editor",
|
|
82
|
+
className: cx(styles.form, direction === 'rtl' ? styles.rightToLeft : '')
|
|
83
|
+
}, mergedOptions.map((item)=>React.createElement(Box, {
|
|
84
|
+
key: item.id,
|
|
85
|
+
marginBottom: "spacingS"
|
|
86
|
+
}, React.createElement(Checkbox, {
|
|
87
|
+
key: item.id,
|
|
88
|
+
id: item.id,
|
|
89
|
+
isChecked: values.includes(item.value),
|
|
90
|
+
isDisabled: disabled,
|
|
91
|
+
value: item.value,
|
|
92
|
+
name: `${field.id}.${field.locale}`,
|
|
93
|
+
onChange: (e)=>{
|
|
94
|
+
if (e.target.checked) {
|
|
95
|
+
addValue(item.value);
|
|
96
|
+
} else {
|
|
97
|
+
removeValue(item.value);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}, item.label), item.invalid && React.createElement(React.Fragment, null, React.createElement("span", {
|
|
101
|
+
"data-test-id": "invalid-text",
|
|
102
|
+
className: styles.invalidText
|
|
103
|
+
}, "(invalid)"), React.createElement(TextLink, {
|
|
104
|
+
as: "button",
|
|
105
|
+
className: styles.removeBtn,
|
|
106
|
+
onClick: ()=>removeValue(item.value)
|
|
107
|
+
}, "Remove")))));
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
CheckboxEditor.defaultProps = {
|
|
111
|
+
isInitiallyDisabled: true
|
|
112
|
+
};
|