@contentful/field-editor-json 3.1.7 → 3.3.0

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.
@@ -0,0 +1,140 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) {
3
+ Object.defineProperty(obj, key, {
4
+ value: value,
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true
8
+ });
9
+ } else {
10
+ obj[key] = value;
11
+ }
12
+ return obj;
13
+ }
14
+ import * as React from 'react';
15
+ import { FieldConnector } from '@contentful/field-editor-shared';
16
+ import deepEqual from 'deep-equal';
17
+ import throttle from 'lodash/throttle';
18
+ import { JsonEditorField } from './JsonEditorField';
19
+ import { JsonEditorToolbar } from './JsonEditorToolbar';
20
+ import { JsonInvalidStatus } from './JsonInvalidStatus';
21
+ import { stringifyJSON, parseJSON } from './utils';
22
+ var _React_Component;
23
+ class ConnectedJsonEditor extends (_React_Component = React.Component) {
24
+ render() {
25
+ return React.createElement("div", {
26
+ "data-test-id": "json-editor"
27
+ }, React.createElement(JsonEditorToolbar, {
28
+ isRedoDisabled: this.props.disabled || this.state.redoStack.length === 0,
29
+ isUndoDisabled: this.props.disabled || this.state.undoStack.length === 0,
30
+ onUndo: this.onUndo,
31
+ onRedo: this.onRedo
32
+ }), React.createElement(JsonEditorField, {
33
+ value: this.state.value,
34
+ onChange: this.onChange,
35
+ isDisabled: this.props.disabled
36
+ }), !this.state.isValidJson && React.createElement(JsonInvalidStatus, null));
37
+ }
38
+ constructor(props){
39
+ super(props);
40
+ _define_property(this, "setValidJson", (value)=>{
41
+ this.setState({
42
+ isValidJson: value
43
+ });
44
+ });
45
+ _define_property(this, "pushUndo", throttle((value)=>{
46
+ this.setState((state)=>({
47
+ undoStack: [
48
+ ...state.undoStack,
49
+ value
50
+ ]
51
+ }));
52
+ }, 400));
53
+ _define_property(this, "onChange", (value)=>{
54
+ const parsed = parseJSON(value);
55
+ if (value !== this.state.lastUndo) {
56
+ this.pushUndo(this.state.value);
57
+ }
58
+ this.setState({
59
+ value,
60
+ isValidJson: parsed.valid
61
+ });
62
+ if (parsed.valid) {
63
+ this.props.setValue(parsed.value);
64
+ }
65
+ });
66
+ _define_property(this, "onUndo", ()=>{
67
+ const undoStack = this.state.undoStack;
68
+ if (undoStack.length === 0) {
69
+ return;
70
+ }
71
+ const value = undoStack.pop() || '';
72
+ const parsedValue = parseJSON(value);
73
+ this.setState((state)=>({
74
+ ...state,
75
+ value,
76
+ isValidJson: parsedValue.valid,
77
+ undoStack,
78
+ redoStack: [
79
+ ...state.redoStack,
80
+ state.value
81
+ ],
82
+ lastUndo: value
83
+ }), ()=>{
84
+ if (parsedValue.valid) {
85
+ this.props.setValue(parsedValue.value);
86
+ }
87
+ });
88
+ });
89
+ _define_property(this, "onRedo", ()=>{
90
+ const redoStack = [
91
+ ...this.state.redoStack
92
+ ];
93
+ if (redoStack.length === 0) {
94
+ return;
95
+ }
96
+ const value = redoStack.pop() || '';
97
+ const parsedValue = parseJSON(value);
98
+ this.setState((state)=>({
99
+ ...state,
100
+ value,
101
+ isValidJson: parsedValue.valid,
102
+ redoStack,
103
+ undoStack: [
104
+ ...state.undoStack,
105
+ state.value
106
+ ]
107
+ }), ()=>{
108
+ if (parsedValue.valid) {
109
+ this.props.setValue(parsedValue.value);
110
+ }
111
+ });
112
+ });
113
+ this.state = {
114
+ value: stringifyJSON(props.initialValue),
115
+ isValidJson: true,
116
+ undoStack: [],
117
+ redoStack: [],
118
+ lastUndo: ''
119
+ };
120
+ }
121
+ }
122
+ _define_property(ConnectedJsonEditor, "defaultProps", {
123
+ isInitiallyDisabled: true
124
+ });
125
+ export default function JsonEditor(props) {
126
+ return React.createElement(FieldConnector, {
127
+ field: props.field,
128
+ isInitiallyDisabled: props.isInitiallyDisabled,
129
+ isEqualValues: (value1, value2)=>{
130
+ return deepEqual(value1, value2);
131
+ }
132
+ }, ({ value , disabled , setValue , externalReset })=>{
133
+ return React.createElement(ConnectedJsonEditor, {
134
+ key: `json-editor-${externalReset}`,
135
+ initialValue: value,
136
+ disabled: disabled,
137
+ setValue: setValue
138
+ });
139
+ });
140
+ }
@@ -0,0 +1,73 @@
1
+ import * as React from 'react';
2
+ import { json } from '@codemirror/lang-json';
3
+ import { EditorView } from '@codemirror/view';
4
+ import tokens from '@contentful/f36-tokens';
5
+ import CodeMirror from '@uiw/react-codemirror';
6
+ import { css, cx } from 'emotion';
7
+ const styles = {
8
+ root: css({
9
+ cursor: 'text',
10
+ padding: tokens.spacingS,
11
+ border: `1px solid ${tokens.gray200}`,
12
+ borderTop: 'none',
13
+ borderBottomLeftRadius: tokens.borderRadiusSmall,
14
+ borderBottomRightRadius: tokens.borderRadiusSmall,
15
+ fontSize: tokens.fontSizeM,
16
+ '.cm-editor': {
17
+ color: tokens.gray900,
18
+ '&.cm-focused': {
19
+ outline: 'none'
20
+ }
21
+ },
22
+ '.cm-scroller': {
23
+ fontFamily: tokens.fontStackMonospace,
24
+ minHeight: '6rem'
25
+ },
26
+ '&.disabled': {
27
+ cursor: 'auto',
28
+ '.cm-scroller ': {
29
+ minHeight: '6rem',
30
+ backgroundColor: tokens.gray100,
31
+ cursor: 'not-allowed'
32
+ },
33
+ '.cm-editor': {
34
+ border: `1px solid ${tokens.gray200}`
35
+ },
36
+ '.cm-line': {
37
+ cursor: 'not-allowed'
38
+ },
39
+ '.cm-lines': {
40
+ cursor: 'not-allowed'
41
+ }
42
+ }
43
+ })
44
+ };
45
+ export function JsonEditorField(props) {
46
+ return React.createElement("div", {
47
+ className: cx(styles.root, {
48
+ disabled: props.isDisabled
49
+ }),
50
+ "data-test-id": "json-editor-code-mirror"
51
+ }, React.createElement(CodeMirror, {
52
+ value: props.value,
53
+ onChange: props.onChange,
54
+ theme: "light",
55
+ extensions: [
56
+ json(),
57
+ EditorView.lineWrapping
58
+ ],
59
+ basicSetup: {
60
+ closeBrackets: false,
61
+ lineNumbers: false,
62
+ highlightActiveLineGutter: false,
63
+ searchKeymap: false,
64
+ highlightActiveLine: false,
65
+ foldGutter: false,
66
+ bracketMatching: false,
67
+ syntaxHighlighting: false
68
+ },
69
+ width: "100%",
70
+ editable: !props.isDisabled,
71
+ indentWithTab: true
72
+ }));
73
+ }
@@ -0,0 +1,52 @@
1
+ import * as React from 'react';
2
+ import { Button } from '@contentful/f36-components';
3
+ import tokens from '@contentful/f36-tokens';
4
+ import { css } from 'emotion';
5
+ const styles = {
6
+ toolbar: css({
7
+ display: 'flex',
8
+ alignItems: 'center',
9
+ padding: tokens.spacingXs,
10
+ justifyContent: 'space-between',
11
+ backgroundColor: tokens.gray100,
12
+ border: `1px solid ${tokens.gray200}`,
13
+ borderTopLeftRadius: tokens.borderRadiusSmall,
14
+ borderTopRightRadius: tokens.borderRadiusSmall,
15
+ borderBottom: 'none'
16
+ }),
17
+ title: css({
18
+ fontFamily: tokens.fontStackPrimary,
19
+ fontSize: tokens.fontSizeM,
20
+ color: tokens.gray600
21
+ }),
22
+ actions: css({
23
+ button: {
24
+ marginLeft: tokens.spacingS
25
+ }
26
+ })
27
+ };
28
+ export function JsonEditorToolbar(props) {
29
+ return React.createElement("div", {
30
+ className: styles.toolbar
31
+ }, React.createElement("div", {
32
+ className: styles.title
33
+ }, "JSON Editor"), React.createElement("div", {
34
+ className: styles.actions
35
+ }, React.createElement(Button, {
36
+ variant: "secondary",
37
+ size: "small",
38
+ isDisabled: props.isUndoDisabled,
39
+ testId: "json-editor-undo",
40
+ onClick: ()=>{
41
+ props.onUndo();
42
+ }
43
+ }, "Undo"), React.createElement(Button, {
44
+ variant: "secondary",
45
+ size: "small",
46
+ isDisabled: props.isRedoDisabled,
47
+ testId: "json-editor-redo",
48
+ onClick: ()=>{
49
+ props.onRedo();
50
+ }
51
+ }, "Redo")));
52
+ }
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ import { ValidationMessage } from '@contentful/f36-components';
3
+ import tokens from '@contentful/f36-tokens';
4
+ import { css } from 'emotion';
5
+ export function JsonInvalidStatus() {
6
+ return React.createElement("div", {
7
+ role: "status",
8
+ "data-test-id": "json-editor.invalid-json",
9
+ className: css({
10
+ marginTop: tokens.spacingS
11
+ })
12
+ }, React.createElement(ValidationMessage, null, "This is not valid JSON"));
13
+ }
@@ -0,0 +1,2 @@
1
+ import JsonEditor from './JsonEditor';
2
+ export { JsonEditor };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,37 @@
1
+ export function stringifyJSON(obj) {
2
+ if (obj === null || obj === undefined) {
3
+ return '';
4
+ } else {
5
+ return JSON.stringify(obj, null, 4);
6
+ }
7
+ }
8
+ export function isValidJson(str) {
9
+ let parsed;
10
+ try {
11
+ parsed = JSON.parse(str);
12
+ } catch (e) {
13
+ return false;
14
+ }
15
+ if (typeof parsed !== 'object') {
16
+ return false;
17
+ }
18
+ return true;
19
+ }
20
+ export function parseJSON(str) {
21
+ if (str === '') {
22
+ return {
23
+ value: undefined,
24
+ valid: true
25
+ };
26
+ } else if (isValidJson(str)) {
27
+ return {
28
+ value: JSON.parse(str),
29
+ valid: true
30
+ };
31
+ } else {
32
+ return {
33
+ value: undefined,
34
+ valid: false
35
+ };
36
+ }
37
+ }
@@ -1,13 +1,13 @@
1
- /// <reference types="react" />
2
- import { FieldAPI } from '@contentful/field-editor-shared';
3
- export interface JsonEditorProps {
4
- /**
5
- * is the field disabled initially
6
- */
7
- isInitiallyDisabled: boolean;
8
- /**
9
- * sdk.field
10
- */
11
- field: FieldAPI;
12
- }
13
- export default function JsonEditor(props: JsonEditorProps): JSX.Element;
1
+ import * as React from 'react';
2
+ import { FieldAPI } from '@contentful/field-editor-shared';
3
+ export interface JsonEditorProps {
4
+ /**
5
+ * is the field disabled initially
6
+ */
7
+ isInitiallyDisabled: boolean;
8
+ /**
9
+ * sdk.field
10
+ */
11
+ field: FieldAPI;
12
+ }
13
+ export default function JsonEditor(props: JsonEditorProps): React.JSX.Element;
@@ -1,8 +1,8 @@
1
- /// <reference types="react" />
2
- declare type JsonEditorFieldProps = {
3
- isDisabled: boolean;
4
- value: string;
5
- onChange: (value: string) => void;
6
- };
7
- export declare function JsonEditorField(props: JsonEditorFieldProps): JSX.Element;
8
- export {};
1
+ import * as React from 'react';
2
+ type JsonEditorFieldProps = {
3
+ isDisabled: boolean;
4
+ value: string;
5
+ onChange: (value: string) => void;
6
+ };
7
+ export declare function JsonEditorField(props: JsonEditorFieldProps): React.JSX.Element;
8
+ export {};
@@ -1,9 +1,9 @@
1
- /// <reference types="react" />
2
- declare type JsonEditorToolbarProps = {
3
- isUndoDisabled: boolean;
4
- isRedoDisabled: boolean;
5
- onRedo: () => void;
6
- onUndo: () => void;
7
- };
8
- export declare function JsonEditorToolbar(props: JsonEditorToolbarProps): JSX.Element;
9
- export {};
1
+ import * as React from 'react';
2
+ type JsonEditorToolbarProps = {
3
+ isUndoDisabled: boolean;
4
+ isRedoDisabled: boolean;
5
+ onRedo: () => void;
6
+ onUndo: () => void;
7
+ };
8
+ export declare function JsonEditorToolbar(props: JsonEditorToolbarProps): React.JSX.Element;
9
+ export {};
@@ -0,0 +1,2 @@
1
+ import * as React from 'react';
2
+ export declare function JsonInvalidStatus(): React.JSX.Element;
@@ -1,2 +1,2 @@
1
- import JsonEditor from './JsonEditor';
2
- export { JsonEditor };
1
+ import JsonEditor from './JsonEditor';
2
+ export { JsonEditor };
@@ -0,0 +1,7 @@
1
+ export type JSONPrimitive = string | number | boolean | null;
2
+ export type JSONValue = JSONPrimitive | JSONObject | JSONArray;
3
+ export type JSONObject = {
4
+ [member: string]: JSONValue;
5
+ };
6
+ export interface JSONArray extends Array<JSONValue> {
7
+ }
@@ -1,7 +1,7 @@
1
- import { JSONObject } from './types';
2
- export declare function stringifyJSON(obj: JSONObject | null | undefined): string;
3
- export declare function isValidJson(str: string): boolean;
4
- export declare function parseJSON(str: string): {
5
- valid: boolean;
6
- value?: JSONObject;
7
- };
1
+ import { JSONObject } from './types';
2
+ export declare function stringifyJSON(obj: JSONObject | null | undefined): string;
3
+ export declare function isValidJson(str: string): boolean;
4
+ export declare function parseJSON(str: string): {
5
+ valid: boolean;
6
+ value?: JSONObject;
7
+ };
package/package.json CHANGED
@@ -1,9 +1,17 @@
1
1
  {
2
2
  "name": "@contentful/field-editor-json",
3
- "version": "3.1.7",
4
- "main": "dist/index.js",
5
- "module": "dist/field-editor-json.esm.js",
6
- "typings": "dist/index.d.ts",
3
+ "version": "3.3.0",
4
+ "main": "dist/cjs/index.js",
5
+ "module": "dist/esm/index.js",
6
+ "types": "dist/types/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/types/index.d.ts",
10
+ "require": "./dist/cjs/index.js",
11
+ "default": "./dist/esm/index.js"
12
+ },
13
+ "./package.json": "./package.json"
14
+ },
7
15
  "files": [
8
16
  "dist"
9
17
  ],
@@ -14,15 +22,21 @@
14
22
  "url": "https://github.com/contentful/field-editors"
15
23
  },
16
24
  "scripts": {
17
- "watch": "tsdx watch",
18
- "build": "tsdx build",
25
+ "watch": "yarn concurrently \"yarn:watch:*\"",
26
+ "watch:cjs": "yarn build:cjs -w",
27
+ "watch:esm": "yarn build:esm -w",
28
+ "watch:types": "yarn build:types --watch",
29
+ "build": "yarn build:types && yarn build:cjs && yarn build:esm",
30
+ "build:types": "tsc --outDir dist/types --emitDeclarationOnly",
31
+ "build:cjs": "swc src --config-file ../../.swcrc -d dist/cjs -C module.type=commonjs",
32
+ "build:esm": "swc src --config-file ../../.swcrc -d dist/esm",
19
33
  "tsc": "tsc -p ./ --noEmit"
20
34
  },
21
35
  "dependencies": {
22
36
  "@codemirror/lang-json": "^6.0.0",
23
37
  "@contentful/f36-components": "^4.0.27",
24
38
  "@contentful/f36-tokens": "^4.0.0",
25
- "@contentful/field-editor-shared": "^1.1.8",
39
+ "@contentful/field-editor-shared": "^1.3.0",
26
40
  "@types/deep-equal": "1.0.1",
27
41
  "@types/react-codemirror": "1.0.3",
28
42
  "@uiw/react-codemirror": "^4.11.4",
@@ -32,10 +46,10 @@
32
46
  "lodash-es": "^4.17.15"
33
47
  },
34
48
  "devDependencies": {
35
- "@contentful/field-editor-test-utils": "^1.2.7"
49
+ "@contentful/field-editor-test-utils": "^1.4.0"
36
50
  },
37
51
  "peerDependencies": {
38
52
  "react": ">=16.8.0"
39
53
  },
40
- "gitHead": "4fff7b9534374dcc44cb477240d369fc34f46415"
54
+ "gitHead": "543e02672a8dd4edc810f9f3568d6b69c454e1f9"
41
55
  }